From bb473baaf31b16cd02a328c6d66bfb27115dc2cd Mon Sep 17 00:00:00 2001 From: Alvaro Aleman Date: Mon, 13 Oct 2025 17:13:35 -0400 Subject: [PATCH] Deflake should execute the Warmup function when Warmup group is started The test is flaky as visible in both PRs and the periodic. The reason is that it calls Start() which asynchronously starts a runnable and expects said runnable to finish immediately after which may or may not work out depending on how busy the box the test is run on is. Use `synctest` instead, as that allows us to explicitly block until all asynchronous operations that can finish are finished. --- pkg/manager/runnable_group_test.go | 56 +++++++++++++++++------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/pkg/manager/runnable_group_test.go b/pkg/manager/runnable_group_test.go index 6f9b879e0e..e22f2c00d5 100644 --- a/pkg/manager/runnable_group_test.go +++ b/pkg/manager/runnable_group_test.go @@ -5,6 +5,8 @@ import ( "errors" "fmt" "sync/atomic" + "testing" + "testing/synctest" "time" . "github.com/onsi/ginkgo/v2" @@ -110,30 +112,6 @@ var _ = Describe("runnables", func() { Expect(r.Others.startQueue).To(BeEmpty()) }) - It("should execute the Warmup function when Warmup group is started", func(ctx SpecContext) { - var warmupExecuted atomic.Bool - - warmupRunnable := newWarmupRunnableFunc( - func(c context.Context) error { - <-c.Done() - return nil - }, - func(c context.Context) error { - warmupExecuted.Store(true) - return nil - }, - ) - - r := newRunnables(defaultBaseContext, errCh) - Expect(r.Add(warmupRunnable)).To(Succeed()) - - // Start the Warmup group - Expect(r.Warmup.Start(ctx)).To(Succeed()) - - // Verify warmup function was called - Expect(warmupExecuted.Load()).To(BeTrue()) - }) - It("should propagate errors from Warmup function to error channel", func(ctx SpecContext) { expectedErr := fmt.Errorf("expected warmup error") @@ -384,3 +362,33 @@ func newLeaderElectionAndWarmupRunnable( func (r leaderElectionAndWarmupRunnable) NeedLeaderElection() bool { return r.needLeaderElection } + +func TestWarmupFunctionIsExecutedWhenWarmupGroupIsStarted(t *testing.T) { + t.Parallel() + synctest.Test(t, func(t *testing.T) { + g := NewWithT(t) + var warmupExecuted atomic.Bool + + warmupRunnable := newWarmupRunnableFunc( + func(c context.Context) error { + <-c.Done() + return nil + }, + func(c context.Context) error { + warmupExecuted.Store(true) + return nil + }, + ) + + r := newRunnables(defaultBaseContext, make(chan error)) + g.Expect(r.Add(warmupRunnable)).To(Succeed()) + + // Start the Warmup group + g.Expect(r.Warmup.Start(t.Context())).To(Succeed()) + synctest.Wait() + + // Verify warmup function was called + g.Expect(warmupExecuted.Load()).To(BeTrue()) + r.Warmup.StopAndWait(t.Context()) + }) +}