diff --git a/tests/common/nip09_helpers.rs b/tests/common/nip09_helpers.rs index 3a48e84..060d2c2 100644 --- a/tests/common/nip09_helpers.rs +++ b/tests/common/nip09_helpers.rs @@ -37,17 +37,16 @@ where F: FnMut() -> Fut, Fut: std::future::Future, { - let deadline = tokio::time::Instant::now() + timeout; - loop { - if condition().await { - return; + tokio::time::timeout(timeout, async { + loop { + if condition().await { + return; + } + tokio::time::sleep(Duration::from_millis(50)).await; } - assert!( - tokio::time::Instant::now() < deadline, - "{description} did not hold within {timeout:?}" - ); - tokio::time::sleep(Duration::from_millis(50)).await; - } + }) + .await + .unwrap_or_else(|_| panic!("{description} did not hold within {timeout:?}")); } /// Wait until the relay serves `event_id`, bounded by diff --git a/tests/fixture_lifecycle.rs b/tests/fixture_lifecycle.rs index 266ca1e..7cc6940 100644 --- a/tests/fixture_lifecycle.rs +++ b/tests/fixture_lifecycle.rs @@ -56,3 +56,18 @@ async fn flapping_relay_closes_connections_on_stop() { async fn setup_drop_relay_closes_connections_on_stop() { check_shutdown!(SetupDropRelay::start().await); } + +#[tokio::test(start_paused = true)] +#[should_panic(expected = "stalled query did not hold within")] +async fn observable_wait_deadline_cancels_a_stalled_query() { + // The outer timer makes a missing inner deadline fail deterministically + // rather than hanging this regression. Paused time avoids a wall-clock wait. + tokio::time::timeout( + Duration::from_secs(20), + common::wait_for("stalled query", Duration::from_secs(10), || { + std::future::pending::() + }), + ) + .await + .expect("wait helper failed to enforce its own deadline"); +}