use std::time::Duration; use remora_schema::{SCHEMA_GENERATION, generation, is_ready, migrate}; use sqlx::{PgPool, postgres::PgPoolOptions}; async fn test_pool() -> Option { 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 table_count: i64 = sqlx::query_scalar( "SELECT COUNT(*)::bigint FROM information_schema.tables WHERE table_schema = 'public' AND table_name IN ( 'mutation_records', 'principals', 'source_credentials', 'jobs', 'attempts', 'result_inventories', 'deletion_operations', 'live_event_history_state', 'worker_descriptors', 'remora_schema_state' )", ) .fetch_one(&pool) .await .expect("schema tables"); assert_eq!(table_count, 10); } #[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")); }