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::{Container, ImageExt, runners::SyncRunner};
|
||||||
use testcontainers_modules::postgres::Postgres;
|
use testcontainers_modules::postgres::Postgres;
|
||||||
use tokio::sync::OnceCell;
|
use tokio::sync::OnceCell;
|
||||||
|
use tokio::time::{Duration, sleep};
|
||||||
|
|
||||||
static POSTGRES: OnceCell<TestPostgres> = OnceCell::const_new();
|
static POSTGRES: OnceCell<TestPostgres> = OnceCell::const_new();
|
||||||
static CLEANUP_REGISTERED: OnceLock<()> = OnceLock::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 {
|
pub async fn postgres_schema_url(prefix: &str) -> String {
|
||||||
let database_url = postgres_database_url().await;
|
let database_url = postgres_database_url().await;
|
||||||
let schema = unique_schema_name(prefix);
|
let schema = unique_schema_name(prefix);
|
||||||
let mut connection = PgConnection::connect(database_url)
|
let mut connection = connect_admin_with_retry(database_url).await;
|
||||||
.await
|
|
||||||
.expect("test PostgreSQL container must accept admin connections");
|
|
||||||
|
|
||||||
connection
|
connection
|
||||||
.execute(sqlx::query(&format!("create schema {schema}")))
|
.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}")
|
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 {
|
pub fn unique_schema_name(prefix: &str) -> String {
|
||||||
let normalized_prefix: String = prefix
|
let normalized_prefix: String = prefix
|
||||||
.chars()
|
.chars()
|
||||||
|
|||||||
Reference in New Issue
Block a user