test: add upgrade home fixture coverage
This commit is contained in:
parent
1a6d9db913
commit
3fbd64f131
3 changed files with 120 additions and 4 deletions
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue