Files
khadhroony-solana-project/crates/ksp-store-postgres-lib/unit_tests/migration.rs
2026-08-30 08:41:26 +02:00

90 lines
4.5 KiB
Rust

// file: crates/ksp-store-postgres-lib/unit_tests/migration.rs
// version: 2
fn applied(version: i64, name: &str, checksum: &str) -> super::AppliedMigration {
return super::AppliedMigration { checksum: checksum.to_owned(), name: name.to_owned(), version };
}
fn embedded(version: i64, name: &'static str, sql: &'static str) -> super::EmbeddedMigration {
return super::EmbeddedMigration { hook: super::MigrationHook::None, name, sql, version };
}
#[test]
fn pre_002_embedded_registry_keeps_v000_immutable_and_current_version_registry_driven() {
assert_eq!(super::EMBEDDED_MIGRATIONS.len(), 1);
let migration = &super::EMBEDDED_MIGRATIONS[0];
assert_eq!(migration.version, 0);
assert_eq!(migration.name, "bootstrap");
assert_eq!(migration.hook, super::MigrationHook::None);
assert!(migration.sql.contains("CREATE TABLE ksp_store_schema_migrations"));
for forbidden in ["RawTransaction", "RawAccountState", "raw_transaction", "raw_account", "CORE", "DECODE", "SPECIALIZED"] {
assert!(!migration.sql.contains(forbidden), "business schema leaked into bootstrap SQL: {forbidden}");
}
assert!(super::validate_embedded_registry(super::EMBEDDED_MIGRATIONS).is_ok());
assert_eq!(crate::current_migration_version(), 0);
let checksum = super::migration_checksum(migration.sql);
assert_eq!(checksum.len(), 64);
assert_eq!(checksum, "d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450");
return;
}
#[test]
fn pre_002_ordered_registry_accepts_exact_history_prefix_and_full_history() {
let v000 = super::EMBEDDED_MIGRATIONS[0];
let v001 = embedded(1, "synthetic", "SELECT 1;");
let registry = [v000, v001];
assert!(super::validate_embedded_registry(&registry).is_ok());
let v000_checksum = super::migration_checksum(v000.sql);
let prefix = [applied(0, v000.name, v000_checksum.as_str())];
assert_eq!(super::validate_history(&prefix, &registry).ok(), std::option::Option::Some(1));
let v001_checksum = super::migration_checksum(v001.sql);
let full = [applied(0, v000.name, v000_checksum.as_str()), applied(1, v001.name, v001_checksum.as_str())];
assert_eq!(super::validate_history(&full, &registry).ok(), std::option::Option::Some(2));
return;
}
#[test]
fn pre_002_registry_rejects_empty_nonzero_gap_and_empty_metadata_entries() {
let empty: [super::EmbeddedMigration; 0] = [];
let starts_at_one = [embedded(1, "future", "SELECT 1;")];
let gap = [embedded(0, "bootstrap", "SELECT 0;"), embedded(2, "future", "SELECT 2;")];
let empty_name = [embedded(0, "", "SELECT 0;")];
let empty_sql = [embedded(0, "bootstrap", "")];
for registry in [&empty[..], &starts_at_one[..], &gap[..], &empty_name[..], &empty_sql[..]] {
let result = super::validate_embedded_registry(registry);
assert_eq!(result.err().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::MigrationMismatch));
}
return;
}
#[test]
fn pre_002_divergent_missing_or_gapped_history_is_terminal_mismatch() {
let v000 = super::EMBEDDED_MIGRATIONS[0];
let v001 = embedded(1, "synthetic", "SELECT 1;");
let registry = [v000, v001];
let v000_checksum = super::migration_checksum(v000.sql);
let v001_checksum = super::migration_checksum(v001.sql);
let wrong_name = [applied(0, "changed", v000_checksum.as_str())];
let wrong_checksum = [applied(0, v000.name, "00")];
let missing: [super::AppliedMigration; 0] = [];
let missing_v000 = [applied(1, v001.name, v001_checksum.as_str())];
for history in [&wrong_name[..], &wrong_checksum[..], &missing[..], &missing_v000[..]] {
let result = super::validate_history(history, &registry);
assert_eq!(result.err().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::MigrationMismatch));
}
return;
}
#[test]
fn pre_002_newer_history_is_rejected_without_down_migration() {
let v000 = super::EMBEDDED_MIGRATIONS[0];
let v001 = embedded(1, "synthetic", "SELECT 1;");
let registry = [v000, v001];
let v000_checksum = super::migration_checksum(v000.sql);
let v001_checksum = super::migration_checksum(v001.sql);
let history = [applied(0, v000.name, v000_checksum.as_str()), applied(1, v001.name, v001_checksum.as_str()), applied(2, "future", "future-checksum")];
let result = super::validate_history(&history, &registry);
assert_eq!(result.err().map(|value| return value.kind()), std::option::Option::Some(crate::PostgresBackendErrorKind::SchemaNewer));
return;
}