91 lines
3.8 KiB
Rust
91 lines
3.8 KiB
Rust
// file: crates/knowledge-store-postgres-lib/tests/postgres_migration.rs
|
|
// version: 2
|
|
|
|
//! Integration test for the initial PostgreSQL migration in an isolated schema.
|
|
|
|
fn test_schema_name() -> String {
|
|
let elapsed = match std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH) {
|
|
Ok(value) => value,
|
|
Err(_) => return format!("knowledge_test_{}", std::process::id()),
|
|
};
|
|
return format!("knowledge_test_{}_{}", std::process::id(), elapsed.as_nanos());
|
|
}
|
|
|
|
fn database_url_with_search_path(database_url: &str, schema: &str) -> String {
|
|
let separator = if database_url.contains('?') { '&' } else { '?' };
|
|
return format!("{database_url}{separator}options=-c%20search_path%3D{schema}");
|
|
}
|
|
|
|
async fn connect(database_url: &str) -> Option<tokio_postgres::Client> {
|
|
let connection_result = tokio_postgres::connect(database_url, tokio_postgres::NoTls).await;
|
|
assert!(connection_result.is_ok(), "test PostgreSQL connection failed");
|
|
let (client, connection) = match connection_result {
|
|
Ok(value) => value,
|
|
Err(_) => return None,
|
|
};
|
|
let _connection_task = tokio::spawn(async move {
|
|
let _connection_result = connection.await;
|
|
return;
|
|
});
|
|
return Some(client);
|
|
}
|
|
|
|
#[tokio::test]
|
|
#[ignore = "requires KNOWLEDGE_POSTGRES_TEST_URL"]
|
|
async fn initial_migration_runs_in_isolated_schema() {
|
|
let database_url_result = std::env::var("KNOWLEDGE_POSTGRES_TEST_URL");
|
|
assert!(database_url_result.is_ok(), "KNOWLEDGE_POSTGRES_TEST_URL is required");
|
|
let database_url = match database_url_result {
|
|
Ok(value) => value,
|
|
Err(_) => return,
|
|
};
|
|
let schema = test_schema_name();
|
|
let admin = match connect(database_url.as_str()).await {
|
|
Some(value) => value,
|
|
None => return,
|
|
};
|
|
let create_schema = format!("CREATE SCHEMA {schema}");
|
|
let create_result = admin.batch_execute(create_schema.as_str()).await;
|
|
assert!(create_result.is_ok(), "isolated PostgreSQL schema creation failed");
|
|
if create_result.is_err() {
|
|
return;
|
|
}
|
|
let isolated_url = database_url_with_search_path(database_url.as_str(), schema.as_str());
|
|
let config_result = knowledge_store_postgres_lib::PostgresStoreConfig::new(isolated_url.as_str(), 2);
|
|
assert!(config_result.is_ok(), "PostgreSQL store configuration failed");
|
|
let config = match config_result {
|
|
Ok(value) => value,
|
|
Err(_) => return,
|
|
};
|
|
let store_result = knowledge_store_postgres_lib::PostgresStore::new(config);
|
|
assert!(store_result.is_ok(), "PostgreSQL store construction failed");
|
|
let store = match store_result {
|
|
Ok(value) => value,
|
|
Err(_) => return,
|
|
};
|
|
let migration_result = store.apply_migrations().await;
|
|
assert!(migration_result.is_ok(), "initial PostgreSQL migration failed");
|
|
let table_result = admin
|
|
.query(
|
|
"SELECT table_name FROM information_schema.tables WHERE table_schema = $1 AND table_name IN ('knowledge_sources', 'knowledge_source_sync_state', 'refinery_schema_history') ORDER BY table_name",
|
|
&[&schema],
|
|
)
|
|
.await;
|
|
assert!(table_result.is_ok(), "PostgreSQL migration verification query failed");
|
|
let table_rows = match table_result {
|
|
Ok(value) => value,
|
|
Err(_) => return,
|
|
};
|
|
assert_eq!(table_rows.len(), 3);
|
|
if table_rows.len() == 3 {
|
|
assert_eq!(table_rows[0].get::<usize, &str>(0), "knowledge_source_sync_state");
|
|
assert_eq!(table_rows[1].get::<usize, &str>(0), "knowledge_sources");
|
|
assert_eq!(table_rows[2].get::<usize, &str>(0), "refinery_schema_history");
|
|
}
|
|
drop(store);
|
|
let drop_schema = format!("DROP SCHEMA {schema} CASCADE");
|
|
let drop_result = admin.batch_execute(drop_schema.as_str()).await;
|
|
assert!(drop_result.is_ok(), "isolated PostgreSQL schema cleanup failed");
|
|
return;
|
|
}
|