remora/crates/remora-schema/tests/schema.rs

67 lines
2.1 KiB
Rust

use std::time::Duration;
use remora_schema::{SCHEMA_GENERATION, generation, is_ready, migrate};
use sqlx::{PgPool, postgres::PgPoolOptions};
async fn test_pool() -> Option<PgPool> {
let Some(url) = std::env::var("DATABASE_URL")
.ok()
.filter(|value| !value.is_empty())
else {
if std::env::var("REMORA_SCHEMA_REQUIRE").is_ok() {
panic!("DATABASE_URL is required when REMORA_SCHEMA_REQUIRE is set");
}
return None;
};
Some(
PgPoolOptions::new()
.max_connections(12)
.acquire_timeout(Duration::from_secs(10))
.connect(&url)
.await
.expect("connect postgres"),
)
}
#[tokio::test]
async fn migration_is_idempotent_and_marks_the_complete_generation() {
let Some(pool) = test_pool().await else {
return;
};
migrate(&pool).await.expect("first migration");
migrate(&pool).await.expect("second migration");
assert_eq!(
generation(&pool).await.expect("schema generation"),
Some(SCHEMA_GENERATION)
);
assert!(is_ready(&pool).await.expect("schema readiness"));
let missing_tables: Vec<String> = sqlx::query_scalar(
"SELECT table_name
FROM unnest(ARRAY[
'mutation_records', 'principal_identities', 'source_credentials', 'jobs',
'attempts', 'result_inventories', 'deletion_operations',
'live_event_history_state', 'worker_descriptors', 'remora_schema_state'
]) AS expected(table_name)
WHERE to_regclass('public.' || table_name) IS NULL
ORDER BY table_name",
)
.fetch_all(&pool)
.await
.expect("schema tables");
assert!(
missing_tables.is_empty(),
"missing tables: {missing_tables:?}"
);
}
#[tokio::test]
async fn concurrent_owners_converge_before_readiness() {
let Some(pool) = test_pool().await else {
return;
};
let (first, second) = tokio::join!(migrate(&pool), migrate(&pool));
first.expect("first owner");
second.expect("second owner");
assert!(is_ready(&pool).await.expect("schema readiness"));
}