taler-rust

GNU Taler code in Rust. Largely core banking integrations.
Log | Files | Refs | Submodules | README | LICENSE

commit eb6bbb08883400f359b5dd6917f84c4209ff212b
parent d1f3df0bc7123e804dca57d528f979c919793619
Author: Antoine A <>
Date:   Wed, 25 Mar 2026 11:51:09 +0100

common: reuse databases for tests

Diffstat:
Mcommon/taler-test-utils/src/db.rs | 41+++++++++++++++++++++++++++++------------
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()