Skip to content

Commit f05ea2c

Browse files
aaltshulerclaude
andcommitted
Extract public-API tests from omnigraph.rs to integration tests
The inline `mod tests` in crates/omnigraph/src/db/omnigraph.rs had grown to ~620 lines, mixing tests that need crate-private access with tests that only exercise the public API. Splits the latter out. - tests/lifecycle.rs: 10 init/open/snapshot/drift tests - tests/schema_apply.rs: 5 plan/apply tests - omnigraph.rs: 10 tests remain inline because they use db.coordinator, db.table_store(), ManifestCoordinator, SCHEMA_APPLY_LOCK_BRANCH, or is_internal_run_branch — all crate-private and intentionally kept so. No behavior change. Zero semantic edits to the tests themselves beyond replacing db.snapshot() (pub(crate)) with snapshot_main helper at integration-test boundaries. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent a35698e commit f05ea2c

3 files changed

Lines changed: 288 additions & 268 deletions

File tree

crates/omnigraph/src/db/omnigraph.rs

Lines changed: 0 additions & 268 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,9 +1500,7 @@ mod tests {
15001500
use crate::db::is_internal_run_branch;
15011501
use crate::db::manifest::ManifestCoordinator;
15021502
use async_trait::async_trait;
1503-
use omnigraph_compiler::{SchemaMigrationStep, SchemaTypeKind};
15041503
use serde_json::Value;
1505-
use std::fs;
15061504
use std::sync::Mutex;
15071505

15081506
use crate::storage::{LocalStorageAdapter, StorageAdapter, join_uri};
@@ -1561,50 +1559,6 @@ edge WorksAt: Person -> Company
15611559
}
15621560
}
15631561

1564-
#[tokio::test]
1565-
async fn test_init_creates_repo() {
1566-
let dir = tempfile::tempdir().unwrap();
1567-
let uri = dir.path().to_str().unwrap();
1568-
1569-
let db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1570-
1571-
// Schema file written
1572-
assert!(dir.path().join("_schema.pg").exists());
1573-
assert!(dir.path().join("_schema.ir.json").exists());
1574-
assert!(dir.path().join("__schema_state.json").exists());
1575-
1576-
// Manifest created with correct entries
1577-
let snap = db.snapshot();
1578-
assert!(snap.entry("node:Person").is_some());
1579-
assert!(snap.entry("node:Company").is_some());
1580-
assert!(snap.entry("edge:Knows").is_some());
1581-
assert!(snap.entry("edge:WorksAt").is_some());
1582-
1583-
// Catalog is correct
1584-
assert_eq!(db.catalog().node_types.len(), 2);
1585-
assert_eq!(db.catalog().edge_types.len(), 2);
1586-
assert_eq!(
1587-
db.catalog().node_types["Person"].key_property(),
1588-
Some("name")
1589-
);
1590-
}
1591-
1592-
#[tokio::test]
1593-
async fn test_open_reads_existing_repo() {
1594-
let dir = tempfile::tempdir().unwrap();
1595-
let uri = dir.path().to_str().unwrap();
1596-
1597-
Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1598-
1599-
// Re-open
1600-
let db = Omnigraph::open(uri).await.unwrap();
1601-
assert_eq!(db.catalog().node_types.len(), 2);
1602-
assert_eq!(db.catalog().edge_types.len(), 2);
1603-
let snap = db.snapshot();
1604-
assert!(snap.entry("node:Person").is_some());
1605-
assert!(snap.entry("edge:Knows").is_some());
1606-
}
1607-
16081562
#[tokio::test]
16091563
async fn test_init_and_open_route_graph_metadata_through_storage_adapter() {
16101564
let dir = tempfile::tempdir().unwrap();
@@ -1649,151 +1603,6 @@ edge WorksAt: Person -> Company
16491603
);
16501604
}
16511605

1652-
#[tokio::test]
1653-
async fn test_open_bootstraps_legacy_schema_state_for_main_only_repo() {
1654-
let dir = tempfile::tempdir().unwrap();
1655-
let uri = dir.path().to_str().unwrap();
1656-
Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1657-
1658-
fs::remove_file(dir.path().join("_schema.ir.json")).unwrap();
1659-
fs::remove_file(dir.path().join("__schema_state.json")).unwrap();
1660-
1661-
let db = Omnigraph::open(uri).await.unwrap();
1662-
assert_eq!(db.catalog().node_types.len(), 2);
1663-
assert!(dir.path().join("_schema.ir.json").exists());
1664-
assert!(dir.path().join("__schema_state.json").exists());
1665-
}
1666-
1667-
#[tokio::test]
1668-
async fn test_open_rejects_legacy_repo_with_public_branch() {
1669-
let dir = tempfile::tempdir().unwrap();
1670-
let uri = dir.path().to_str().unwrap();
1671-
let mut db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1672-
db.branch_create("feature").await.unwrap();
1673-
1674-
fs::remove_file(dir.path().join("_schema.ir.json")).unwrap();
1675-
fs::remove_file(dir.path().join("__schema_state.json")).unwrap();
1676-
1677-
let err = match Omnigraph::open(uri).await {
1678-
Ok(_) => panic!("expected legacy repo with public branch to fail schema bootstrap"),
1679-
Err(err) => err,
1680-
};
1681-
let message = err.to_string();
1682-
assert!(message.contains("public branches block schema evolution entirely"));
1683-
}
1684-
1685-
#[tokio::test]
1686-
async fn test_long_lived_handle_rejects_schema_source_drift() {
1687-
let dir = tempfile::tempdir().unwrap();
1688-
let uri = dir.path().to_str().unwrap();
1689-
let db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1690-
1691-
let drifted = TEST_SCHEMA.replace("age: I32?", "age: I64?");
1692-
fs::write(dir.path().join("_schema.pg"), drifted).unwrap();
1693-
1694-
let err = match db.snapshot_of(ReadTarget::branch("main")).await {
1695-
Ok(_) => panic!("expected schema source drift to be rejected"),
1696-
Err(err) => err,
1697-
};
1698-
assert!(
1699-
err.to_string()
1700-
.contains("current _schema.pg no longer matches the accepted compiled schema")
1701-
);
1702-
}
1703-
1704-
#[tokio::test]
1705-
async fn test_long_lived_handle_rejects_schema_ir_drift() {
1706-
let dir = tempfile::tempdir().unwrap();
1707-
let uri = dir.path().to_str().unwrap();
1708-
let db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1709-
1710-
fs::write(dir.path().join("_schema.ir.json"), "{not valid json").unwrap();
1711-
1712-
let err = match db.snapshot_of(ReadTarget::branch("main")).await {
1713-
Ok(_) => panic!("expected schema IR drift to be rejected"),
1714-
Err(err) => err,
1715-
};
1716-
assert!(
1717-
err.to_string()
1718-
.contains("accepted compiled schema contract in _schema.ir.json is invalid")
1719-
);
1720-
}
1721-
1722-
#[tokio::test]
1723-
async fn test_long_lived_handle_rejects_ir_and_source_updates_without_state_update() {
1724-
let dir = tempfile::tempdir().unwrap();
1725-
let uri = dir.path().to_str().unwrap();
1726-
let db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1727-
1728-
let drifted = TEST_SCHEMA.replace("age: I32?", "age: I64?");
1729-
let drifted_ir = read_schema_ir_from_source(&drifted).unwrap();
1730-
let drifted_ir_json = omnigraph_compiler::schema_ir_pretty_json(&drifted_ir).unwrap();
1731-
fs::write(dir.path().join("_schema.pg"), drifted).unwrap();
1732-
fs::write(dir.path().join("_schema.ir.json"), drifted_ir_json).unwrap();
1733-
1734-
let err = match db.snapshot_of(ReadTarget::branch("main")).await {
1735-
Ok(_) => panic!("expected schema state mismatch to be rejected"),
1736-
Err(err) => err,
1737-
};
1738-
assert!(
1739-
err.to_string()
1740-
.contains("accepted compiled schema does not match the recorded schema state")
1741-
);
1742-
}
1743-
1744-
#[tokio::test]
1745-
async fn test_comment_only_schema_edit_keeps_schema_state_valid() {
1746-
let dir = tempfile::tempdir().unwrap();
1747-
let uri = dir.path().to_str().unwrap();
1748-
let db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1749-
1750-
let commented = format!("// comment-only drift\n{}", TEST_SCHEMA);
1751-
fs::write(dir.path().join("_schema.pg"), commented).unwrap();
1752-
1753-
let snapshot = db.snapshot_of(ReadTarget::branch("main")).await.unwrap();
1754-
assert!(snapshot.entry("node:Person").is_some());
1755-
}
1756-
1757-
#[tokio::test]
1758-
async fn test_plan_schema_reports_supported_additive_change() {
1759-
let dir = tempfile::tempdir().unwrap();
1760-
let uri = dir.path().to_str().unwrap();
1761-
let db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1762-
1763-
let desired = TEST_SCHEMA.replace(
1764-
" age: I32?\n}",
1765-
" age: I32?\n nickname: String?\n}",
1766-
);
1767-
1768-
let plan = db.plan_schema(&desired).await.unwrap();
1769-
assert!(plan.supported);
1770-
assert!(plan.steps.iter().any(|step| matches!(
1771-
step,
1772-
SchemaMigrationStep::AddProperty {
1773-
type_kind: SchemaTypeKind::Node,
1774-
type_name,
1775-
property_name,
1776-
..
1777-
} if type_name == "Person" && property_name == "nickname"
1778-
)));
1779-
}
1780-
1781-
#[tokio::test]
1782-
async fn test_plan_schema_rejects_when_schema_contract_has_drifted() {
1783-
let dir = tempfile::tempdir().unwrap();
1784-
let uri = dir.path().to_str().unwrap();
1785-
let db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1786-
1787-
let drifted = TEST_SCHEMA.replace("age: I32?", "age: I64?");
1788-
fs::write(dir.path().join("_schema.pg"), drifted).unwrap();
1789-
1790-
let err = db.plan_schema(TEST_SCHEMA).await.unwrap_err();
1791-
assert!(
1792-
err.to_string()
1793-
.contains("current _schema.pg no longer matches the accepted compiled schema")
1794-
);
1795-
}
1796-
17971606
async fn table_rows_json(db: &Omnigraph, table_key: &str) -> Vec<Value> {
17981607
let snapshot = db.snapshot();
17991608
let ds = snapshot.open(table_key).await.unwrap();
@@ -1838,18 +1647,6 @@ edge WorksAt: Person -> Company
18381647
.unwrap();
18391648
}
18401649

1841-
#[tokio::test]
1842-
async fn test_apply_schema_noop_returns_not_applied() {
1843-
let dir = tempfile::tempdir().unwrap();
1844-
let uri = dir.path().to_str().unwrap();
1845-
let mut db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1846-
1847-
let result = db.apply_schema(TEST_SCHEMA).await.unwrap();
1848-
assert!(result.supported);
1849-
assert!(!result.applied);
1850-
assert!(result.steps.is_empty());
1851-
}
1852-
18531650
#[tokio::test]
18541651
async fn test_apply_schema_adds_nullable_property_and_preserves_rows() {
18551652
let dir = tempfile::tempdir().unwrap();
@@ -1925,24 +1722,6 @@ edge WorksAt: Person -> Company
19251722
assert!(historical.entry("node:Human").is_none());
19261723
}
19271724

1928-
#[tokio::test]
1929-
async fn test_apply_schema_rejects_when_non_main_branch_exists() {
1930-
let dir = tempfile::tempdir().unwrap();
1931-
let uri = dir.path().to_str().unwrap();
1932-
let mut db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
1933-
db.branch_create("feature").await.unwrap();
1934-
1935-
let desired = TEST_SCHEMA.replace(
1936-
" age: I32?\n}",
1937-
" age: I32?\n nickname: String?\n}",
1938-
);
1939-
let err = db.apply_schema(&desired).await.unwrap_err();
1940-
assert!(
1941-
err.to_string()
1942-
.contains("schema apply requires a repo with only main")
1943-
);
1944-
}
1945-
19461725
#[tokio::test]
19471726
async fn test_apply_schema_succeeds_after_load_creates_published_run_branch() {
19481727
// Regression for MR-670: schema apply used to fail after any load or
@@ -2066,51 +1845,4 @@ edge WorksAt: Person -> Company
20661845
let branches = db.branch_list().await.unwrap();
20671846
assert_eq!(branches, vec!["main".to_string()]);
20681847
}
2069-
2070-
#[tokio::test]
2071-
async fn test_apply_schema_unsupported_plan_does_not_advance_manifest() {
2072-
let dir = tempfile::tempdir().unwrap();
2073-
let uri = dir.path().to_str().unwrap();
2074-
let mut db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
2075-
let before_version = db.snapshot().version();
2076-
2077-
let desired = TEST_SCHEMA.replace("age: I32?", "age: I64?");
2078-
let err = db.apply_schema(&desired).await.unwrap_err();
2079-
assert!(err.to_string().contains("changing property type"));
2080-
assert_eq!(db.snapshot().version(), before_version);
2081-
}
2082-
2083-
#[tokio::test]
2084-
async fn test_open_nonexistent_fails() {
2085-
let result = Omnigraph::open("/tmp/nonexistent_omnigraph_test_xyz").await;
2086-
assert!(result.is_err());
2087-
}
2088-
2089-
#[tokio::test]
2090-
async fn test_snapshot_version_is_pinned() {
2091-
let dir = tempfile::tempdir().unwrap();
2092-
let uri = dir.path().to_str().unwrap();
2093-
2094-
let mut db = Omnigraph::init(uri, TEST_SCHEMA).await.unwrap();
2095-
2096-
// Take snapshot before any writes
2097-
let snap1 = db.snapshot();
2098-
let v1 = snap1.version();
2099-
2100-
// Load data — advances manifest version
2101-
crate::loader::load_jsonl(
2102-
&mut db,
2103-
r#"{"type": "Person", "data": {"name": "Alice", "age": 30}}"#,
2104-
crate::loader::LoadMode::Overwrite,
2105-
)
2106-
.await
2107-
.unwrap();
2108-
2109-
// Snapshot from handle sees new version
2110-
let snap2 = db.snapshot();
2111-
assert!(snap2.version() > v1);
2112-
2113-
// But the old snapshot is still pinned
2114-
assert_eq!(snap1.version(), v1);
2115-
}
21161848
}

0 commit comments

Comments
 (0)