431 lines
21 KiB
Rust
431 lines
21 KiB
Rust
// file: crates/ksp-store-postgres-lib/tests/dependency_boundary.rs
|
|
// version: 25
|
|
|
|
#![warn(missing_docs)]
|
|
#![deny(unreachable_pub)]
|
|
#![forbid(unsafe_code)]
|
|
|
|
//! Dependency and ownership canaries for the physical PostgreSQL Store backend.
|
|
|
|
#[test]
|
|
fn pre_005_backend_owns_exact_physical_runtime_dependencies_without_reverse_facade_edge() {
|
|
let manifest = include_str!("../Cargo.toml");
|
|
for required in
|
|
["deadpool-postgres", "ksp-logging-lib", "ksp-store-api", "rustls", "rustls-native-certs", "sha2", "tokio-postgres", "tokio-postgres-rustls"]
|
|
{
|
|
assert!(manifest.contains(required), "missing PostgreSQL backend dependency: {required}");
|
|
}
|
|
for forbidden in ["ksp-store-lib", "ksp-config-lib", "ksp-materializer", "ksp-program", "ksp-onchain-transport-lib", "ksp-offchain-transport-lib", "sqlx"] {
|
|
assert!(!manifest.contains(forbidden), "forbidden PostgreSQL backend dependency detected: {forbidden}");
|
|
}
|
|
let migration = include_str!("../src/migration.rs");
|
|
let schema = include_str!("../src/schema.rs");
|
|
let bootstrap_sql = include_str!("../migrations/v000_bootstrap/tables/001_ksp_store_schema_migrations.sql");
|
|
assert!(migration.contains("crate::V000_RESOURCES"));
|
|
assert!(migration.contains("crate::V001_RESOURCES"));
|
|
assert!(migration.contains("crate::V002_RESOURCES"));
|
|
assert!(schema.contains("../migrations/v000_bootstrap/tables/001_ksp_store_schema_migrations.sql"));
|
|
assert!(schema.contains("../migrations/v001_raw_transaction/tables/001_ksp_store_identity.sql"));
|
|
assert!(bootstrap_sql.contains("ksp_store_schema_migrations"));
|
|
for forbidden in ["RawTransaction", "RawAccountState", "raw_transaction", "raw_account", "CORE", "DECODE", "SPECIALIZED"] {
|
|
assert!(!bootstrap_sql.contains(forbidden), "business schema leaked into immutable V000 SQL: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_005_backend_keeps_environment_sql_migrations_and_physical_types_private() {
|
|
let crate_root = include_str!("../src/lib.rs");
|
|
assert!(crate_root.contains("mod error;"));
|
|
assert!(crate_root.contains("mod health;"));
|
|
assert!(crate_root.contains("mod migration;"));
|
|
assert!(crate_root.contains("mod raw_transaction;"));
|
|
assert!(crate_root.contains("mod runtime;"));
|
|
assert!(crate_root.contains("mod schema;"));
|
|
assert!(crate_root.contains("const _: &str = crate::TRACING_TARGET;"));
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
for forbidden in [
|
|
"pub mod ",
|
|
"ksp_store_lib",
|
|
"ksp_config_lib",
|
|
"tokio_postgres::Client",
|
|
"tokio_postgres::Row",
|
|
"tokio_postgres::Statement",
|
|
"deadpool_postgres::Pool;",
|
|
] {
|
|
assert!(!crate_root.contains(forbidden), "forbidden PostgreSQL crate-root surface detected: {forbidden}");
|
|
}
|
|
for forbidden in [
|
|
"std::env",
|
|
"dotenv",
|
|
"KSP_",
|
|
"KSPB_",
|
|
"PGHOST",
|
|
"PGPORT",
|
|
"PGUSER",
|
|
"PGPASSWORD",
|
|
".pgpass",
|
|
"CREATE TABLE",
|
|
"INSERT INTO",
|
|
"UPDATE ",
|
|
"DELETE FROM",
|
|
"SELECT ",
|
|
] {
|
|
assert!(!runtime.contains(forbidden), "forbidden PostgreSQL backend ownership/scope content detected: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_007_health_probe_remains_foundation_only_and_private_sql() {
|
|
let health = include_str!("../src/health.rs");
|
|
assert!(health.contains("SELECT 1::BIGINT"));
|
|
assert!(health.contains("ksp_store_schema_migrations"));
|
|
for forbidden in
|
|
["RawTransaction", "RawAccountState", "raw_transaction", "raw_account", "CORE", "DECODE", "SPECIALIZED", "std::env", "dotenv", "KSP_SECRET_"]
|
|
{
|
|
assert!(!health.contains(forbidden), "forbidden health ownership/scope content detected: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_003_fix_001_migration_engine_uses_split_schema_contract_and_binds_network_without_repository_scope() {
|
|
let migration = include_str!("../src/migration.rs");
|
|
let schema = include_str!("../src/schema.rs");
|
|
let identity_table = include_str!("../migrations/v001_raw_transaction/tables/001_ksp_store_identity.sql");
|
|
let raw_table = include_str!("../migrations/v001_raw_transaction/tables/002_ksp_raw_transactions.sql");
|
|
let observation_table = include_str!("../migrations/v001_raw_transaction/tables/003_ksp_raw_transaction_observations.sql");
|
|
let archive_table = include_str!("../migrations/v001_raw_transaction/tables/004_ksp_raw_transaction_archive_payloads.sql");
|
|
let index = include_str!("../migrations/v001_raw_transaction/indexes/001_ix_ksp_raw_transactions_slot_signature.sql");
|
|
assert!(migration.contains("const EMBEDDED_MIGRATIONS: &[EmbeddedMigration]"));
|
|
assert!(migration.contains("MigrationHook::StoreIdentity"));
|
|
assert!(migration.contains("MigrationHookContext::AppliedNow"));
|
|
assert!(migration.contains("MigrationHookContext::Existing"));
|
|
assert!(migration.contains("schema_autocreate"));
|
|
assert!(migration.contains("schema_autoupdate"));
|
|
assert!(migration.contains("INSERT INTO ksp_store_identity (singleton, network) VALUES (1, $1)"));
|
|
assert!(migration.contains("SELECT singleton, network FROM ksp_store_identity ORDER BY singleton LIMIT 2"));
|
|
assert!(migration.contains("ksp_store_api::RawNetworkId::new(stored_network)"));
|
|
assert!(schema.contains("SchemaResourceState"));
|
|
assert!(schema.contains("verify_v001_external_compatibility"));
|
|
assert!(identity_table.contains("CREATE TABLE IF NOT EXISTS ksp_store_identity"));
|
|
assert!(raw_table.contains("CREATE TABLE IF NOT EXISTS ksp_raw_transactions"));
|
|
assert!(observation_table.contains("CREATE TABLE IF NOT EXISTS ksp_raw_transaction_observations"));
|
|
assert!(archive_table.contains("CREATE TABLE IF NOT EXISTS ksp_raw_transaction_archive_payloads"));
|
|
assert!(index.contains("CREATE INDEX IF NOT EXISTS ix_ksp_raw_transactions_slot_signature"));
|
|
for forbidden in ["impl ksp_store_api::RawTransaction", "impl ksp_store_api::RawAccount", "repository", "sqlx"] {
|
|
assert!(!migration.contains(forbidden), "repository/cross-scope implementation leaked into migration engine: {forbidden}");
|
|
assert!(!schema.contains(forbidden), "repository/cross-scope implementation leaked into schema contract: {forbidden}");
|
|
}
|
|
for removed in ["migrations/V000__bootstrap.sql", "migrations/V001__raw_transaction.sql"] {
|
|
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(removed);
|
|
assert!(!path.exists(), "obsolete monolithic migration must be deleted by pre.003-fix.001: {removed}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_003_v002_schema_is_complete_and_keeps_capability_implementation_out_of_schema_layers() {
|
|
let migration = include_str!("../src/migration.rs");
|
|
let schema = include_str!("../src/schema.rs");
|
|
let states = include_str!("../migrations/v002_raw_account_state/tables/001_ksp_raw_account_states.sql");
|
|
let observations = include_str!("../migrations/v002_raw_account_state/tables/002_ksp_raw_account_observations.sql");
|
|
let slot_check = include_str!("../migrations/v002_raw_account_state/constraints/005_ck_ksp_raw_account_states_slot.sql");
|
|
let index = include_str!("../migrations/v002_raw_account_state/indexes/001_ix_ksp_raw_account_states_slot_pubkey_state_hash.sql");
|
|
assert!(migration.contains("name: \"raw_account_state\""));
|
|
assert!(migration.contains("resources: crate::V002_RESOURCES"));
|
|
assert!(migration.contains("V002_PROVISIONAL_CHECKSUM_PRE_002"));
|
|
assert!(migration.contains("HISTORY_UPDATE_CHECKSUM_SQL"));
|
|
assert!(migration.contains("reconcile_applied_history_checksums"));
|
|
assert!(schema.contains("pub(crate) const V002_RESOURCES"));
|
|
assert!(schema.contains("verify_v002_external_compatibility"));
|
|
assert!(schema.contains("ksp_raw_account_states', 'ksp_raw_account_observations"));
|
|
assert!(states.contains("ksp_raw_account_states"));
|
|
assert!(observations.contains("ksp_raw_account_observations"));
|
|
assert!(slot_check.contains("slot >= 0 AND slot <= 18446744073709551615"));
|
|
assert!(index.contains("ON ksp_raw_account_states (slot, pubkey, state_hash)"));
|
|
assert!(!index.contains("WHERE"));
|
|
assert!(!migration.contains("impl ksp_store_api::RawAccount"));
|
|
assert!(!schema.contains("impl ksp_store_api::RawAccount"));
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_005_raw_account_acquisition_is_atomic_idempotent_and_keeps_trait_impls_out_of_sql_module() {
|
|
let crate_root = include_str!("../src/lib.rs");
|
|
let raw = include_str!("../src/raw_account.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
assert!(crate_root.contains("mod raw_account;"));
|
|
assert!(!crate_root.contains("pub mod raw_account"));
|
|
for required in [
|
|
"GET_ACCOUNT_STATE_SQL",
|
|
"GET_ACCOUNT_OBSERVATION_SQL",
|
|
"INSERT_ACCOUNT_STATE_SQL",
|
|
"INSERT_ACCOUNT_OBSERVATION_SQL",
|
|
"LOCK_ACCOUNT_STATE_SQL",
|
|
"LOCK_ACCOUNT_OBSERVATION_SQL",
|
|
"ON CONFLICT (pubkey, slot, state_hash) DO NOTHING",
|
|
"ON CONFLICT (observation_key) DO NOTHING",
|
|
"FOR UPDATE",
|
|
"persist_raw_account_acquisition",
|
|
"raw_account_states_equal",
|
|
"RawAccountState::try_new",
|
|
"RawAccountObservation::new",
|
|
"PostgresBackendErrorKind::Conflict",
|
|
"PostgresBackendErrorKind::DataInvalid",
|
|
"PostgresBackendErrorKind::WrongNetwork",
|
|
"PostgresBackendErrorKind::WriteFailed",
|
|
] {
|
|
assert!(raw.contains(required), "missing private RAW account acquisition contract: {required}");
|
|
}
|
|
assert!(runtime.contains("pub async fn persist_raw_account_acquisition"));
|
|
for forbidden in ["UPDATE ", "DELETE FROM", "ON CONFLICT DO UPDATE", " OFFSET "] {
|
|
assert!(!raw.contains(forbidden), "pre.005 account module contains later/destructive scope: {forbidden}");
|
|
}
|
|
for implementation in [
|
|
"impl ksp_store_api::RawAccountStateRead for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountStateWrite for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountObservationRead for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountObservationWrite for PostgresBackend",
|
|
] {
|
|
assert!(!raw.contains(implementation), "account capability implementation leaked into SQL/mapping module: {implementation}");
|
|
assert_eq!(runtime.matches(implementation).count(), 1, "missing or duplicated account runtime bridge implementation: {implementation}");
|
|
}
|
|
for forbidden in ["std::env", "dotenv", "ksp_store_lib", "ksp_config_lib", "sqlx::", "SELECT *"] {
|
|
assert!(!raw.contains(forbidden), "RAW account module contains forbidden ownership/query material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_006_raw_account_additional_observation_is_reference_guarded_cancellation_safe_and_keeps_destructive_scope_closed() {
|
|
let raw = include_str!("../src/raw_account.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
for required in [
|
|
"LOCK_ACCOUNT_REFERENCE_SQL",
|
|
"FOR KEY SHARE",
|
|
"record_raw_account_observation",
|
|
"reference_not_found(\"raw_account_observation_reference\")",
|
|
"persist_account_observation_row",
|
|
"RawObservationWriteOutcome",
|
|
"raw_account_observation_commit",
|
|
] {
|
|
assert!(raw.contains(required), "missing pre.006 additional-observation contract: {required}");
|
|
}
|
|
assert!(runtime.contains("pub async fn record_raw_account_observation"));
|
|
for forbidden in ["UPDATE ", "DELETE FROM", "ON CONFLICT DO UPDATE", " OFFSET "] {
|
|
assert!(!raw.contains(forbidden), "pre.006 account module contains later/destructive scope: {forbidden}");
|
|
}
|
|
for implementation in [
|
|
"impl ksp_store_api::RawAccountStateRead for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountStateWrite for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountObservationRead for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountObservationWrite for PostgresBackend",
|
|
] {
|
|
assert!(!raw.contains(implementation), "account capability implementation leaked into SQL/mapping module: {implementation}");
|
|
assert_eq!(runtime.matches(implementation).count(), 1, "missing or duplicated account runtime bridge implementation: {implementation}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_004_raw_read_sql_and_mapping_remain_backend_private() {
|
|
let crate_root = include_str!("../src/lib.rs");
|
|
let raw = include_str!("../src/raw_transaction.rs");
|
|
assert!(crate_root.contains("mod raw_transaction;"));
|
|
assert!(!crate_root.contains("pub mod raw_transaction"));
|
|
for required in [
|
|
"SELECT transaction_row.signature",
|
|
"ksp_raw_transaction_observations",
|
|
"slot::text AS slot_text",
|
|
"RawPayload::try_new",
|
|
"RawTransactionTombstone::try_new",
|
|
"PostgresBackendErrorKind::DataInvalid",
|
|
"PostgresBackendErrorKind::WrongNetwork",
|
|
] {
|
|
assert!(raw.contains(required), "missing private RAW read mapping contract: {required}");
|
|
}
|
|
for forbidden in ["std::env", "dotenv", "ksp_store_lib", "ksp_config_lib"] {
|
|
assert!(!raw.contains(forbidden), "RAW module contains forbidden ownership material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_005_raw_write_sql_is_atomic_idempotent_and_keeps_direct_trait_scope_closed() {
|
|
let raw = include_str!("../src/raw_transaction.rs");
|
|
for required in [
|
|
"INSERT INTO ksp_raw_transactions",
|
|
"ON CONFLICT (signature) DO NOTHING RETURNING signature",
|
|
"FOR UPDATE",
|
|
"INSERT INTO ksp_raw_transaction_observations",
|
|
"ON CONFLICT (observation_key) DO NOTHING RETURNING observation_key",
|
|
"REHYDRATE_TRANSACTION_SQL",
|
|
"RawEntityWriteOutcome::SkippedPurged",
|
|
"RawEntityWriteOutcome::Rehydrated",
|
|
"RawObservationWriteOutcome::NotRecorded",
|
|
"PostgresBackendErrorKind::Conflict",
|
|
"PostgresBackendErrorKind::ReferenceNotFound",
|
|
"PostgresBackendErrorKind::WriteFailed",
|
|
] {
|
|
assert!(raw.contains(required), "missing pre.005 RAW write contract: {required}");
|
|
}
|
|
for forbidden in ["impl ksp_store_api::RawTransactionWrite", "impl ksp_store_api::RawTransactionObservationWrite"] {
|
|
assert!(!raw.contains(forbidden), "pre.005 opened direct Store trait scope prematurely: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_006_raw_pagination_is_keyset_cursor_bound_and_policy_free() {
|
|
let raw = include_str!("../src/raw_transaction.rs");
|
|
let cursor = include_str!("../src/raw_transaction/cursor.rs");
|
|
let index = include_str!("../migrations/v001_raw_transaction/indexes/001_ix_ksp_raw_transactions_slot_signature.sql");
|
|
for required in [
|
|
"LIST_TRANSACTIONS_ASC_SQL",
|
|
"LIST_TRANSACTIONS_DESC_SQL",
|
|
"retention_state <> 'purged'",
|
|
"(slot, signature) >",
|
|
"(slot, signature) <",
|
|
"ORDER BY slot ASC, signature ASC",
|
|
"ORDER BY slot DESC, signature DESC",
|
|
"LIMIT $5",
|
|
"list_raw_transactions",
|
|
] {
|
|
assert!(raw.contains(required), "missing pre.006 keyset pagination contract: {required}");
|
|
}
|
|
for required in [
|
|
"CURSOR_BYTES: usize = 109",
|
|
"CURSOR_MAGIC",
|
|
"b\"KSPT\"",
|
|
"CURSOR_VERSION: u8 = 1",
|
|
"KSP/raw-transaction-cursor/v1",
|
|
"sha2::Sha256",
|
|
"query.network().as_str()",
|
|
"query.direction()",
|
|
"query.slots().start_inclusive()",
|
|
"query.slots().end_inclusive()",
|
|
"last_slot",
|
|
"last_signature",
|
|
"PageLimitUnsupported",
|
|
"9_223_372_036_854_775_806",
|
|
] {
|
|
assert!(cursor.contains(required), "missing pre.006 cursor/binding contract: {required}");
|
|
}
|
|
assert!(index.contains("ON ksp_raw_transactions (slot, signature)"));
|
|
assert!(index.contains("WHERE retention_state <> 'purged'"));
|
|
for forbidden in [" OFFSET ", "limit.min(", "clamp(", "500", "1000"] {
|
|
assert!(!raw.contains(forbidden), "pre.006 contains forbidden pagination/policy/later-scope material: {forbidden}");
|
|
assert!(!cursor.contains(forbidden), "pre.006 cursor contains forbidden pagination/policy/later-scope material: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_007_raw_account_pagination_is_keyset_cursor_bound_and_policy_free() {
|
|
let raw = include_str!("../src/raw_account.rs");
|
|
let cursor = include_str!("../src/raw_account/cursor.rs");
|
|
let index = include_str!("../migrations/v002_raw_account_state/indexes/001_ix_ksp_raw_account_states_slot_pubkey_state_hash.sql");
|
|
for required in [
|
|
"LIST_ACCOUNT_STATES_ASC_SQL",
|
|
"LIST_ACCOUNT_STATES_DESC_SQL",
|
|
"LIST_ACCOUNT_STATES_BY_PUBKEY_ASC_SQL",
|
|
"LIST_ACCOUNT_STATES_BY_PUBKEY_DESC_SQL",
|
|
"(slot, pubkey, state_hash) >",
|
|
"(slot, pubkey, state_hash) <",
|
|
"ORDER BY slot ASC, pubkey ASC, state_hash ASC",
|
|
"ORDER BY slot DESC, pubkey DESC, state_hash DESC",
|
|
"list_raw_account_states",
|
|
] {
|
|
assert!(raw.contains(required), "missing pre.007 account keyset pagination contract: {required}");
|
|
}
|
|
for required in [
|
|
"CURSOR_BYTES: usize = 109",
|
|
"b\"KSPA\"",
|
|
"CURSOR_VERSION: u8 = 1",
|
|
"KSP/raw-account-state-cursor/v1",
|
|
"sha2::Sha256",
|
|
"query.network().as_str()",
|
|
"query.pubkey()",
|
|
"query.direction()",
|
|
"query.slots().start_inclusive()",
|
|
"query.slots().end_inclusive()",
|
|
"last_slot",
|
|
"last_pubkey",
|
|
"last_state_hash",
|
|
"PageLimitUnsupported",
|
|
"9_223_372_036_854_775_806",
|
|
] {
|
|
assert!(cursor.contains(required), "missing pre.007 account cursor/binding contract: {required}");
|
|
}
|
|
assert!(index.contains("ON ksp_raw_account_states (slot, pubkey, state_hash)"));
|
|
for forbidden in [" OFFSET ", "limit.min(", "clamp(", "500", "1000"] {
|
|
assert!(!raw.contains(forbidden), "pre.007 account source contains forbidden pagination/policy material: {forbidden}");
|
|
assert!(!cursor.contains(forbidden), "pre.007 account cursor contains forbidden pagination/policy material: {forbidden}");
|
|
}
|
|
for forbidden in [
|
|
"impl ksp_store_api::RawAccountStateRead for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountStateWrite for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountObservationRead for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountObservationWrite for PostgresBackend",
|
|
] {
|
|
assert!(!raw.contains(forbidden), "account trait implementation leaked into raw account SQL/mapping module: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_007_raw_retention_is_atomic_compare_and_transition_without_fake_compaction() {
|
|
let raw = include_str!("../src/raw_transaction.rs");
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
for required in [
|
|
"LOCK_RETENTION_TRANSACTION_SQL",
|
|
"FOR UPDATE",
|
|
"INSERT_ARCHIVE_PAYLOAD_SQL",
|
|
"INSERT INTO ksp_raw_transaction_archive_payloads (signature, payload)",
|
|
"UPDATE_ARCHIVED_TRANSACTION_SQL",
|
|
"SET payload = NULL, retention_state = 'archived'",
|
|
"DELETE_ARCHIVE_PAYLOAD_SQL",
|
|
"DELETE FROM ksp_raw_transaction_archive_payloads",
|
|
"UPDATE_PURGED_TRANSACTION_SQL",
|
|
"SET block_time_unix_millis = NULL, payload = NULL, retention_state = 'purged'",
|
|
"if current == target",
|
|
"if current != expected",
|
|
"RawRetentionWriteOutcome::AlreadyAtTarget",
|
|
"RawRetentionWriteOutcome::ExpectedStateMismatch",
|
|
"RawRetentionWriteOutcome::Applied",
|
|
"RetentionCompactionUnsupported",
|
|
"transition_raw_transaction_retention",
|
|
] {
|
|
assert!(raw.contains(required), "missing pre.007 retention contract: {required}");
|
|
}
|
|
assert!(runtime.contains("pub async fn transition_raw_transaction_retention"));
|
|
for forbidden in ["retention_state = 'compacted'", "impl ksp_store_api::RawTransactionRetentionWrite", "flate", "zstd", "lz4", "snappy"] {
|
|
assert!(!raw.contains(forbidden), "pre.007 contains fake compaction/direct-trait scope: {forbidden}");
|
|
}
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn v0_3_8_pre_004_backend_trait_implementations_cover_exact_eleven_raw_capabilities_in_runtime_bridge() {
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
for implementation in [
|
|
"impl ksp_store_api::RawAccountObservationRead for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountObservationWrite for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountStateRead for PostgresBackend",
|
|
"impl ksp_store_api::RawAccountStateWrite for PostgresBackend",
|
|
"impl ksp_store_api::RawTransactionInspectionRead for PostgresBackend",
|
|
"impl ksp_store_api::RawTransactionObservationRead for PostgresBackend",
|
|
"impl ksp_store_api::RawTransactionObservationWrite for PostgresBackend",
|
|
"impl ksp_store_api::RawTransactionRead for PostgresBackend",
|
|
"impl ksp_store_api::RawTransactionRetentionRead for PostgresBackend",
|
|
"impl ksp_store_api::RawTransactionRetentionWrite for PostgresBackend",
|
|
"impl ksp_store_api::RawTransactionWrite for PostgresBackend",
|
|
] {
|
|
assert_eq!(runtime.matches(implementation).count(), 1, "unexpected PostgreSQL RAW capability inventory: {implementation}");
|
|
}
|
|
assert_eq!(runtime.matches("impl ksp_store_api::Raw").count(), 11);
|
|
return;
|
|
}
|