mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
test(search): serialize pgcrypto install to fix parallel-setup race
fts_integration.rs setup() applies migration 0001, which contains CREATE EXTENSION IF NOT EXISTS pgcrypto. pg_extension is database- global with a unique index on extname; IF NOT EXISTS is a check-then- insert, not an atomic upsert. When 18 tests run in parallel, the first wave all see the extension as absent, all attempt the insert, and all but one hit SQLSTATE 23505 (duplicate key on pg_extension_name_index). Fix: take a session-level pg_advisory_lock on the admin connection before the extension create, release it after. This serializes the install across all parallel test workers so exactly one does the real CREATE; the rest treat it as a no-op on lock acquisition. The advisory lock is released automatically when the session ends. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
co-authored by
Will Pfleger
parent
6dda6fd7c3
commit
6eb6ab1a1e
@@ -38,6 +38,31 @@ async fn setup() -> (PgPool, String) {
|
||||
.connect(&url)
|
||||
.await
|
||||
.expect("connect");
|
||||
|
||||
// Serialize the pgcrypto extension install across all parallel test workers.
|
||||
//
|
||||
// `CREATE EXTENSION IF NOT EXISTS pgcrypto` targets `pg_extension`, which is
|
||||
// database-global with a unique index on `extname`. PostgreSQL's IF NOT EXISTS
|
||||
// is a check-then-insert, not an atomic upsert: when many test workers run
|
||||
// concurrently they all see the extension as absent, all attempt the insert,
|
||||
// and all but one hit SQLSTATE 23505 (unique violation). A session-level
|
||||
// advisory lock (arbitrary but stable key) serializes the install so that
|
||||
// exactly one worker does the real CREATE; the rest treat it as a no-op when
|
||||
// they enter the lock. The lock is released automatically when the session
|
||||
// ends, so there is no risk of wedging subsequent runs.
|
||||
sqlx::query("SELECT pg_advisory_lock(3723742987654321)")
|
||||
.execute(&admin_pool)
|
||||
.await
|
||||
.expect("acquire pgcrypto advisory lock");
|
||||
sqlx::query("CREATE EXTENSION IF NOT EXISTS pgcrypto")
|
||||
.execute(&admin_pool)
|
||||
.await
|
||||
.expect("install pgcrypto extension");
|
||||
sqlx::query("SELECT pg_advisory_unlock(3723742987654321)")
|
||||
.execute(&admin_pool)
|
||||
.await
|
||||
.expect("release pgcrypto advisory lock");
|
||||
|
||||
let create_sql = format!("CREATE SCHEMA \"{schema}\"");
|
||||
sqlx::query(sqlx::AssertSqlSafe(create_sql))
|
||||
.execute(&admin_pool)
|
||||
|
||||
Reference in New Issue
Block a user