From a75aef8ded06d5b816545425291566e455ffdb6d Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sun, 25 Oct 2026 20:22:09 +1100 Subject: [PATCH] Make serve_stale refresh test deterministic (#172) TestServeStaleMemberDoesNotBlockMerge reads the fetch counter right after the merges return, but the counted fetch runs inside the background refresh goroutine, so a slow schedule sees 1 instead of 2. - signal from the stub fetch when the background refresh starts - wait on that signal (5s timeout) before checking the fetch count - raise the refresh-reaches-merge deadline to 5s Reviewed-on: https://git.unkin.net/unkin/artifactapi/pulls/172 Co-authored-by: unkin-agent Co-committed-by: unkin-agent --- internal/virtual/engine_stale_test.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/internal/virtual/engine_stale_test.go b/internal/virtual/engine_stale_test.go index c7d0e16..6f7c759 100644 --- a/internal/virtual/engine_stale_test.go +++ b/internal/virtual/engine_stale_test.go @@ -55,9 +55,14 @@ func fetchRepomd(t *testing.T, e *Engine) string { func TestServeStaleMemberDoesNotBlockMerge(t *testing.T) { release := make(chan struct{}) + refreshing := make(chan struct{}, 1) var slow atomic.Bool e, calls := staleEngine(true, func() *RPMMember { if slow.Load() { + select { + case refreshing <- struct{}{}: + default: + } <-release return rpmPkgMember("a", "2") } @@ -78,12 +83,17 @@ func TestServeStaleMemberDoesNotBlockMerge(t *testing.T) { t.Fatal("merge blocked on a serve_stale member refresh") } } + select { + case <-refreshing: + case <-time.After(5 * time.Second): + t.Fatal("background refresh never started") + } if n := calls.Load(); n != 2 { t.Fatalf("member fetched %d times, want 2 (cold + one single-flighted refresh)", n) } close(release) - deadline := time.Now().Add(time.Second) + deadline := time.Now().Add(5 * time.Second) for fetchRepomd(t, e) == v1 { if time.Now().After(deadline) { t.Fatal("background refresh never reached a merge")