Skip to content

Commit 3ca35e1

Browse files
committed
fix(integration): replace fragile sleep with Notify in contention test
Use Arc<Notify> so Tenant B starts deterministically after Tenant A completes its encrypted insert, instead of relying on a 50ms sleep that can be unreliable under CI/cold-TLS conditions.
1 parent c0d77c2 commit 3ca35e1

1 file changed

Lines changed: 16 additions & 6 deletions

File tree

  • packages/cipherstash-proxy-integration/src/multitenant

packages/cipherstash-proxy-integration/src/multitenant/contention.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
#[cfg(test)]
1414
mod tests {
1515
use crate::common::{clear, connect_with_tls, random_id, random_string, trace, PROXY};
16+
use std::sync::Arc;
1617
use std::time::Instant;
18+
use tokio::sync::Notify;
1719
use tokio::task::JoinSet;
1820

1921
/// Number of tenant connections per test phase.
@@ -212,10 +214,11 @@ mod tests {
212214

213215
/// Verifies that a slow tenant connection does not block other tenants.
214216
///
215-
/// Tenant A: encrypted insert then pg_sleep(0.5).
216-
/// Tenant B (different keyset, spawned 50ms later): 10 encrypted inserts, timed.
217+
/// Tenant A: encrypted insert, signals readiness, then pg_sleep(0.5).
218+
/// Tenant B (different keyset): waits for A's signal, then does 10 encrypted inserts, timed.
217219
///
218-
/// Connection setup is excluded from timing.
220+
/// Connection setup is excluded from timing. A `Notify` ensures B starts only after
221+
/// A has completed its encrypted insert and entered pg_sleep, avoiding timing fragility.
219222
///
220223
/// With shared mutex contention, B may be blocked while A holds a lock.
221224
/// After per-connection cipher fix, B should complete independently of A's sleep.
@@ -230,7 +233,11 @@ mod tests {
230233
let client_a = connect_as_tenant(&keyset_ids[0]).await;
231234
let client_b = connect_as_tenant(&keyset_ids[1]).await;
232235

233-
// Tenant A: encrypted insert then sleep
236+
// A signals after its encrypted insert completes, just before entering pg_sleep.
237+
let a_ready = Arc::new(Notify::new());
238+
let a_ready_tx = a_ready.clone();
239+
240+
// Tenant A: encrypted insert, signal, then sleep
234241
let a_handle = tokio::spawn(async move {
235242
let id = random_id();
236243
let val = random_string();
@@ -242,12 +249,15 @@ mod tests {
242249
.await
243250
.unwrap();
244251

252+
// Signal that the encrypted insert is done; A is now entering pg_sleep
253+
a_ready_tx.notify_one();
254+
245255
// Hold this connection busy with a sleep
246256
client_a.simple_query("SELECT pg_sleep(0.5)").await.unwrap();
247257
});
248258

249-
// Small delay so A is likely in-flight before B starts
250-
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
259+
// Wait for A to complete its encrypted insert before starting B
260+
a_ready.notified().await;
251261

252262
// Tenant B: encrypted inserts, timed
253263
let b_handle = tokio::spawn(async move {

0 commit comments

Comments
 (0)