commit eb6bbb08883400f359b5dd6917f84c4209ff212b
parent d1f3df0bc7123e804dca57d528f979c919793619
Author: Antoine A <>
Date: Wed, 25 Mar 2026 11:51:09 +0100
common: reuse databases for tests
Diffstat:
1 file changed, 29 insertions(+), 12 deletions(-)
diff --git a/common/taler-test-utils/src/db.rs b/common/taler-test-utils/src/db.rs
@@ -48,6 +48,7 @@ pub async fn db_test_setup_manual(
dbinit(&mut conn, sql_dir, component_name, true)
.await
.unwrap();
+
(conn, pool)
}
@@ -55,18 +56,34 @@ async fn test_db() -> PgConnectOptions {
let mut conn = PgConnection::connect("postgres:///taler_rust_check")
.await
.unwrap();
- let id = uuid::Uuid::new_v4();
- // Cleanup test db
- let name = format!("taler_rust_test_{}", id.to_string().replace('-', "_"));
- sqlx::raw_sql(&format!("DROP DATABASE IF EXISTS {name}"))
- .execute(&mut conn)
- .await
- .unwrap();
- sqlx::raw_sql(&format!("CREATE DATABASE {name}"))
- .execute(&mut conn)
- .await
- .unwrap();
- drop(conn);
+
+ // Find a free slot via Advisory Locks
+ let row: Option<(String, bool)> = sqlx::query_as(
+ "
+ SELECT
+ 'taler_rust_test_' || s.id,
+ EXISTS (SELECT FROM pg_database WHERE datname = 'taler_rust_test_' || s.id)
+ FROM generate_series(1, 1000) AS s(id)
+ WHERE pg_try_advisory_lock(s.id)
+ LIMIT 1
+ ",
+ )
+ .fetch_optional(&mut conn)
+ .await
+ .unwrap();
+
+ let Some((name, exists)) = row else {
+ panic!("Could not find a free database slot after 1000 attempts.")
+ };
+ if !exists {
+ sqlx::raw_sql(&format!("CREATE DATABASE {name}"))
+ .execute(&mut conn)
+ .await
+ .unwrap();
+ }
+ // We need this connection to stay open to keep the advisory lock in place
+ // Leaking it is OK in tests
+ std::mem::forget(conn);
let db_url = format!("postgresql:/{name}");
info!("Running on db {db_url}");
PgConnectOptions::from_str(&db_url).unwrap()