From 06b55ab50f54c67e4b9f06f8955286b34f39ad30 Mon Sep 17 00:00:00 2001 From: Andrew Dunham Date: Tue, 1 Nov 2022 18:16:10 -0400 Subject: [PATCH] prober: fix test flake This was tested by running 10000 test iterations and observing no flakes after this change was made. Change-Id: Ib036fd03a3a17800132c53c838cc32bfe2961306 Signed-off-by: Andrew Dunham --- prober/prober_test.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/prober/prober_test.go b/prober/prober_test.go index cb4c3ddb3..838f461ec 100644 --- a/prober/prober_test.go +++ b/prober/prober_test.go @@ -97,7 +97,7 @@ func TestProberTimingSpread(t *testing.T) { } } - p.Run("test-spread-probe", probeInterval, nil, func(context.Context) error { + probe := p.Run("test-spread-probe", probeInterval, nil, func(context.Context) error { invoked <- struct{}{} return nil }) @@ -110,6 +110,36 @@ func TestProberTimingSpread(t *testing.T) { clk.Advance(halfProbeInterval) called() notCalled() + + // We need to wait until the main (non-initial) ticker in Probe.loop is + // waiting, or we could race and advance the test clock between when + // the initial delay ticker completes and before the ticker for the + // main loop is created. In this race, we'd first advance the test + // clock, then the ticker would be registered, and the test would fail + // because that ticker would never be fired. + err := tstest.WaitFor(convergenceTimeout, func() error { + clk.Lock() + defer clk.Unlock() + for _, tick := range clk.tickers { + tick.Lock() + stopped, interval := tick.stopped, tick.interval + tick.Unlock() + + if stopped { + continue + } + // Test for the main loop, not the initialDelay + if interval == probe.interval { + return nil + } + } + + return fmt.Errorf("no ticker with interval %d found", probe.interval) + }) + if err != nil { + t.Fatal(err) + } + clk.Advance(quarterProbeInterval) notCalled() clk.Advance(probeInterval)