test: add upgrade home fixture coverage

This commit is contained in:
Eric Wendland 2026-07-05 23:40:39 +02:00
commit 3fbd64f131
3 changed files with 120 additions and 4 deletions

View file

@ -207,6 +207,106 @@ fn backup_create_and_restore_use_separate_home_without_private_identity_keys() {
assert!(!restore_home.join("identity/agent.ed25519").exists());
}
#[test]
fn synthetic_pre_release_home_migrates_forward() {
let home = tempfile::tempdir().expect("tempdir");
let init = run_geth(home.path(), &["init"]);
assert!(
init.status.success(),
"stderr: {}",
String::from_utf8_lossy(&init.stderr)
);
let db_path = home.path().join("geth.sqlite");
let conn = rusqlite::Connection::open(&db_path).expect("open metadata");
conn.execute(
"INSERT OR REPLACE INTO keychain_ops(op_id, op_json, created_at_ms) VALUES (?1, ?2, ?3)",
(
"keychain-op:upgrade-fixture",
r#"{"id":"keychain-op:upgrade-fixture"}"#,
10_i64,
),
)
.expect("insert keychain op");
conn.execute(
"INSERT OR REPLACE INTO auth_ops(op_id, resource_id, op_json, created_at_ms) VALUES (?1, ?2, ?3, ?4)",
(
"auth-op:upgrade-fixture",
"resource:kv:prefs",
r#"{"id":"auth-op:upgrade-fixture"}"#,
11_i64,
),
)
.expect("insert auth op");
conn.execute(
"INSERT OR REPLACE INTO cas_objects(hash, size_bytes, path, created_at_ms) VALUES (?1, ?2, ?3, ?4)",
(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
4_i64,
"cas/blobs/fixture",
12_i64,
),
)
.expect("insert cas object");
conn.execute(
"INSERT OR REPLACE INTO cas_pins(hash, pinned_at_ms) VALUES (?1, ?2)",
(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
13_i64,
),
)
.expect("insert cas pin");
conn.execute(
"INSERT OR REPLACE INTO peer_cards(peer_id, card_json, updated_at_ms) VALUES (?1, ?2, ?3)",
(
"node:upgrade-peer",
r#"{"node_id":"node:upgrade-peer","fixture":true}"#,
14_i64,
),
)
.expect("insert peer card");
conn.execute(
"INSERT INTO meta(key, value) VALUES ('schema_version', '1')
ON CONFLICT(key) DO UPDATE SET value = excluded.value",
[],
)
.expect("downgrade schema marker");
drop(conn);
let upgrade = run_geth(home.path(), &["init"]);
assert!(
upgrade.status.success(),
"stderr: {}",
String::from_utf8_lossy(&upgrade.stderr)
);
let conn = rusqlite::Connection::open(&db_path).expect("open upgraded metadata");
let schema_version: String = conn
.query_row(
"SELECT value FROM meta WHERE key = 'schema_version'",
[],
|row| row.get(0),
)
.expect("schema version");
assert_eq!(
schema_version,
geth_store::CURRENT_SCHEMA_VERSION.to_string()
);
for (table, column) in [
("keychain_ops", "op_id"),
("auth_ops", "op_id"),
("cas_pins", "hash"),
("peer_cards", "peer_id"),
] {
let count: i64 = conn
.query_row(&format!("SELECT COUNT({column}) FROM {table}"), [], |row| {
row.get(0)
})
.expect("fixture count");
assert!(count > 0, "{table} fixture row should survive upgrade");
}
}
#[test]
fn cli_help_documents_owner_init_keys() {
let home = tempfile::tempdir().expect("tempdir");

View file

@ -308,12 +308,15 @@ Goal: make first deployment the start of a controlled compatibility story.
`cargo run`.
- `[x]` Archives include relevant docs and license files.
- `[ ]` Add upgrade tests.
- `[x]` Add upgrade tests.
Acceptance criteria:
- `[ ]` Fixture homes from previous tagged pre-releases migrate forward.
- `[ ]` Upgrade tests include store schema, config, keychain/auth logs, CAS
- `[x]` Fixture homes from previous tagged pre-releases migrate forward.
There are no tagged pre-releases yet, so the current test uses a synthetic
pre-release home and the release policy requires retaining real tagged
fixture homes once tags exist.
- `[x]` Upgrade tests include store schema, config, keychain/auth logs, CAS
metadata, and peer cards.
- `[ ]` Rollback expectations are documented.
- `[x]` Rollback expectations are documented.
- `[x]` Publish release and support policy.
Acceptance criteria:

View file

@ -34,6 +34,19 @@ After the first deployment tag:
- Signed operation formats must not be changed without a new version or
explicit migration behavior.
## Upgrade And Rollback
Before the first deployment tag, upgrade tests use synthetic pre-release homes
that exercise the same on-disk contracts as tagged fixtures: config, SQLite
schema, signed keychain/auth logs, CAS metadata, and peer-card metadata. Once a
tagged pre-release exists, its fixture home must be kept and migrated by the
current test suite.
Store migrations are forward-only. A newer daemon may upgrade `geth.sqlite` in
place, so rollback means restoring a backup made before the upgrade or using a
copied fixture home. Downgrading a migrated home with an older binary is not a
supported recovery path unless a release note explicitly says so.
## Security Updates
Security fixes should be released as soon as practical after validation. The