From 3ff5f62b73140cd19771a305f5155ebde39c1c79 Mon Sep 17 00:00:00 2001 From: platex-rehor-bot Date: Mon, 17 Aug 2026 12:45:32 +0000 Subject: [PATCH] OCPBUGS-86511: Fix flaky TestAsyncCache backend test Move initializationRetryInterval and initializationTimeout overrides before NewAsyncCache so they take effect for the error case test. Replace fixed time.Sleep assertions with require.Eventually to tolerate slow CI environments. Re-grab the reference item after Run() fires its immediate reload to avoid races with the first refresh. Co-Authored-By: Claude Opus 4.6 --- .../asynccache/asyncccache_test.go | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/pkg/serverutils/asynccache/asyncccache_test.go b/pkg/serverutils/asynccache/asyncccache_test.go index cca45c80f13..ecfa2fae7ad 100644 --- a/pkg/serverutils/asynccache/asyncccache_test.go +++ b/pkg/serverutils/asynccache/asyncccache_test.go @@ -24,6 +24,17 @@ func (i *testItem) isContextCancelled() bool { } func TestAsyncCache(t *testing.T) { + // Override initialization settings before any NewAsyncCache call + // so they take effect for the error case test. + origRetryInterval := initializationRetryInterval + origTimeout := initializationTimeout + initializationRetryInterval = 5 * time.Millisecond + initializationTimeout = 10 * time.Millisecond + t.Cleanup(func() { + initializationRetryInterval = origRetryInterval + initializationTimeout = origTimeout + }) + cacheTime := func(ctx context.Context) (*testItem, error) { return &testItem{ctx: ctx, t: time.Now()}, nil } @@ -31,39 +42,33 @@ func TestAsyncCache(t *testing.T) { c, err := NewAsyncCache(context.Background(), 2*time.Second, cacheTime) require.NoError(t, err) - initializationRetryInterval = 5 * time.Millisecond - initializationTimeout = 10 * time.Millisecond // test that initialization was successful item := c.GetItem() - if item.t.IsZero() { - t.Error("expected non-zero time") - } - - time.Sleep(1 * time.Second) - if item.isContextCancelled() { - t.Error("expected usable context") - } + require.False(t, item.t.IsZero(), "expected non-zero time") + require.False(t, item.isContextCancelled(), "expected usable context") timedCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() c.Run(timedCtx) - // test the values get properly changed - var matches int - var changed bool - for i := 0; i < 3; i++ { - newItem := c.GetItem() - if newItem == item { - matches++ - } else { - changed = true - } - - time.Sleep(1 * time.Second) - } + // wait.UntilWithContext fires runCache immediately; wait for the + // first refresh before capturing the baseline. + require.Eventually(t, func() bool { + return c.GetItem() != item + }, 5*time.Second, 10*time.Millisecond, "expected item to be refreshed after Run()") + + // Re-grab the reference after the immediate reload + item = c.GetItem() + + // Within the 2s refresh interval the cached item should stay the same + time.Sleep(500 * time.Millisecond) + require.Equal(t, item, c.GetItem(), "item should not change within refresh interval") + + // After the refresh interval the item should be replaced + require.Eventually(t, func() bool { + return c.GetItem() != item + }, 5*time.Second, 100*time.Millisecond, "item should change after refresh interval") - require.Greater(t, matches, 0) - require.True(t, changed) cancel() // test that the cache returns error properly