From ba4bdd35fb21cb47743f9c1150438f8f8cda4d2f Mon Sep 17 00:00:00 2001 From: Dodothereal <129273127+Dodothereal@users.noreply.github.com> Date: Fri, 6 Nov 2026 14:54:42 +0100 Subject: [PATCH] test(cache): sample metrics before final read in refresh_dropped_when_hard_miss_races Fixes #877. In refresh_dropped_when_hard_miss_races, read the metrics snapshot immediately after the slow refresh finishes rather than after reading the post-hard-miss value. Because soft_ttl is 50ms and the post- hard-miss entry is ~150ms old at the time of the read, the read was triggering a background refresh that could finish and increment refresh_success before metrics were sampled. --- crates/cache/src/tests.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/crates/cache/src/tests.rs b/crates/cache/src/tests.rs index 3315e025f..e5b356251 100644 --- a/crates/cache/src/tests.rs +++ b/crates/cache/src/tests.rs @@ -619,15 +619,9 @@ async fn refresh_dropped_when_hard_miss_races() { // discarded by the identity guard, NOT inserted on top of n=3. tokio::time::sleep(Duration::from_millis(150)).await; - // 6. Subsequent reads still see n=3. The post-hard-miss entry is ~150ms - // old now (well within the 200ms hard TTL). If the refresh had clobbered, - // we'd see n=2 here. - let v4 = cache.get("k".into()).await.unwrap().unwrap(); - assert_eq!( - v4, "n=3", - "stale refresh must not overwrite the post-hard-miss value" - ); - + // 6. Check metrics immediately after the slow refresh finishes, before any + // subsequent read. The slow refresh (n=2) must have been dropped by the + // identity guard, not written back. let m = cache.metrics().snapshot(); assert_eq!( m.refresh_success, 0, @@ -637,6 +631,15 @@ async fn refresh_dropped_when_hard_miss_races() { m.refresh_dropped_epoch >= 1, "the slow refresh must be counted as dropped; got {m:?}" ); + + // 7. Subsequent reads still see n=3. The post-hard-miss entry is ~150ms + // old now (well within the 200ms hard TTL). If the refresh had clobbered, + // we'd see n=2 here. + let v4 = cache.get("k".into()).await.unwrap().unwrap(); + assert_eq!( + v4, "n=3", + "stale refresh must not overwrite the post-hard-miss value" + ); } /// PR1 H4: a panicking loader must NOT leak `refresh_in_flight = true`.