Wait for test Postgres readiness
This commit is contained in:
@@ -7,6 +7,7 @@ use sqlx::{Connection, Executor, PgConnection};
|
||||
use testcontainers::{Container, ImageExt, runners::SyncRunner};
|
||||
use testcontainers_modules::postgres::Postgres;
|
||||
use tokio::sync::OnceCell;
|
||||
use tokio::time::{Duration, sleep};
|
||||
|
||||
static POSTGRES: OnceCell<TestPostgres> = OnceCell::const_new();
|
||||
static CLEANUP_REGISTERED: OnceLock<()> = OnceLock::new();
|
||||
@@ -24,9 +25,7 @@ pub async fn postgres_database_url() -> &'static str {
|
||||
pub async fn postgres_schema_url(prefix: &str) -> String {
|
||||
let database_url = postgres_database_url().await;
|
||||
let schema = unique_schema_name(prefix);
|
||||
let mut connection = PgConnection::connect(database_url)
|
||||
.await
|
||||
.expect("test PostgreSQL container must accept admin connections");
|
||||
let mut connection = connect_admin_with_retry(database_url).await;
|
||||
|
||||
connection
|
||||
.execute(sqlx::query(&format!("create schema {schema}")))
|
||||
@@ -36,6 +35,27 @@ pub async fn postgres_schema_url(prefix: &str) -> String {
|
||||
format!("{database_url}?options=-csearch_path%3D{schema}")
|
||||
}
|
||||
|
||||
async fn connect_admin_with_retry(database_url: &str) -> PgConnection {
|
||||
let mut last_error = None;
|
||||
|
||||
for _ in 0..80 {
|
||||
match PgConnection::connect(database_url).await {
|
||||
Ok(connection) => return connection,
|
||||
Err(error) => {
|
||||
last_error = Some(error);
|
||||
sleep(Duration::from_millis(250)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
panic!(
|
||||
"test PostgreSQL container must accept admin connections after readiness wait: {}",
|
||||
last_error
|
||||
.map(|error| error.to_string())
|
||||
.unwrap_or_else(|| "connection was not attempted".to_owned())
|
||||
);
|
||||
}
|
||||
|
||||
pub fn unique_schema_name(prefix: &str) -> String {
|
||||
let normalized_prefix: String = prefix
|
||||
.chars()
|
||||
|
||||
Reference in New Issue
Block a user