test: add stable json output fixtures

This commit is contained in:
Eric Wendland 2026-07-05 18:04:25 +02:00
commit 2921e5e976
6 changed files with 112 additions and 4 deletions

View file

@ -32,6 +32,40 @@ fn run_geth(home: &std::path::Path, args: &[&str]) -> std::process::Output {
.expect("run geth") .expect("run geth")
} }
fn json_fixture(name: &str) -> serde_json::Value {
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/json")
.join(name);
serde_json::from_str(&std::fs::read_to_string(&path).expect("read json fixture"))
.expect("decode json fixture")
}
fn command_json(output: &std::process::Output) -> serde_json::Value {
assert!(
output.status.success(),
"stderr: {}",
String::from_utf8_lossy(&output.stderr)
);
serde_json::from_slice(&output.stdout).expect("decode command json")
}
fn normalize_node_id_json(mut value: serde_json::Value) -> serde_json::Value {
let object = value.as_object_mut().expect("node id json object");
object.insert(
"agent_id".to_owned(),
serde_json::Value::String("agent:<normalized>".to_owned()),
);
object.insert(
"node_id".to_owned(),
serde_json::Value::String("node:<normalized>".to_owned()),
);
object.insert(
"endpoint_id".to_owned(),
serde_json::Value::String("<endpoint-id>".to_owned()),
);
value
}
fn spawn_daemon(home: &std::path::Path) -> Child { fn spawn_daemon(home: &std::path::Path) -> Child {
Command::new(geth_bin()) Command::new(geth_bin())
.env("GETH_HOME", home) .env("GETH_HOME", home)
@ -248,6 +282,43 @@ fn geth_status_against_running_daemon() {
)); ));
} }
#[test]
fn stable_json_output_matches_fixtures() {
let home = tempfile::tempdir().expect("tempdir");
if !unix_sockets_available(home.path()) {
return;
}
assert!(run_geth(home.path(), &["init"]).status.success());
std::fs::write(
home.path().join("config.toml"),
"[iroh]\nrelay_mode = \"disabled\"\nlocal_discovery = false\n",
)
.expect("write config");
let mut daemon = spawn_daemon(home.path());
wait_for_socket(&home.path().join("run/geth.sock"));
let node_id = run_geth(home.path(), &["--json", "node", "id"]);
let resource_list = run_geth(home.path(), &["--json", "resource", "list"]);
let sync_status = run_geth(home.path(), &["--json", "sync", "status"]);
let _ = daemon.kill();
let _ = daemon.wait();
assert_eq!(
normalize_node_id_json(command_json(&node_id)),
json_fixture("node-id.json")
);
assert_eq!(
command_json(&resource_list),
json_fixture("resource-list-fresh.json")
);
assert_eq!(
command_json(&sync_status),
json_fixture("sync-status-empty.json")
);
}
#[test] #[test]
fn peer_ping_uses_daemon_owned_iroh_endpoint() { fn peer_ping_uses_daemon_owned_iroh_endpoint() {
if skip_iroh_integration_tests() { if skip_iroh_integration_tests() {

View file

@ -0,0 +1,9 @@
# JSON Fixtures
These fixtures define reviewed, script-facing `geth --json` shapes. Tests may
normalize volatile local values such as generated node IDs, agent IDs, endpoint
IDs, and temporary paths before comparing output.
Changing a fixture is a compatibility decision. Update the matching roadmap
item and compatibility notes when a stable field is added, removed, renamed, or
retyped.

View file

@ -0,0 +1,6 @@
{
"type": "node-id",
"agent_id": "agent:<normalized>",
"node_id": "node:<normalized>",
"endpoint_id": "<endpoint-id>"
}

View file

@ -0,0 +1,17 @@
{
"type": "resource-list",
"resources": [
{
"id": "resource:cas:local",
"kind": "cas",
"name": "local-cas",
"authority": {
"kind": "local"
},
"local_role": "owner",
"replication": "local-only",
"retention": "keep",
"status": "active"
}
]
}

View file

@ -0,0 +1,5 @@
{
"type": "sync-status",
"peers": [],
"note": "sync status is local daemon health for best-effort live sync; signed logs remain the durable source of truth"
}

View file

@ -79,7 +79,7 @@ behavior.
- `[x]` Sync stream selection, watermarks, and run result helpers live in a - `[x]` Sync stream selection, watermarks, and run result helpers live in a
sync-focused module. sync-focused module.
- `[x]` Per-module sync handlers have consistent interfaces. - `[x]` Per-module sync handlers have consistent interfaces.
- `[ ]` `geth sync status --json` output remains stable. - `[x]` `geth sync status --json` output remains stable.
## Phase 2: Stable Automation Contracts ## Phase 2: Stable Automation Contracts
@ -94,12 +94,12 @@ and downstream projects.
- `[x]` Peer wire protocol compatibility is documented. - `[x]` Peer wire protocol compatibility is documented.
- `[x]` SQLite and signed-operation compatibility are documented. - `[x]` SQLite and signed-operation compatibility are documented.
- `[ ]` Add golden JSON tests. - `[~]` Add golden JSON tests.
Acceptance criteria: Acceptance criteria:
- `[ ]` Important script-facing commands have stable JSON fixture tests. - `[x]` Important script-facing commands have stable JSON fixture tests.
- `[ ]` Error JSON includes stable codes for common operator and automation - `[ ]` Error JSON includes stable codes for common operator and automation
failures. failures.
- `[ ]` Fixture updates require intentional review. - `[x]` Fixture updates require intentional review.
- `[~]` Expand protocol roundtrip tests. - `[~]` Expand protocol roundtrip tests.
Acceptance criteria: Acceptance criteria: