From ab02676e2e1e93a0ebdb48aa65b254422bf5ba28 Mon Sep 17 00:00:00 2001 From: Forrest Marshall Date: Mon, 18 Jul 2022 16:42:47 +0000 Subject: [PATCH] reduce sensitivity of fncache cancellation test --- lib/utils/fncache_test.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/utils/fncache_test.go b/lib/utils/fncache_test.go index f811bc4b392ee..aa33e4c422044 100644 --- a/lib/utils/fncache_test.go +++ b/lib/utils/fncache_test.go @@ -157,35 +157,46 @@ func testFnCacheSimple(t *testing.T, ttl time.Duration, delay time.Duration) { func TestFnCacheCancellation(t *testing.T) { t.Parallel() - const timeout = time.Millisecond * 10 + const longTimeout = time.Second * 10 // should never be hit cache, err := NewFnCache(FnCacheConfig{TTL: time.Minute}) require.NoError(t, err) - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - + // used to artificially block the load function blocker := make(chan struct{}) + // set up a context that we can cancel from within the load function to + // simulate a scenario where the calling context is canceled or times out. + // if we actually hit the timeout, that is a bug. + ctx, cancel := context.WithTimeout(context.Background(), longTimeout) + defer cancel() + v, err := cache.Get(ctx, "key", func(context.Context) (interface{}, error) { + cancel() <-blocker return "val", nil }) require.Nil(t, v) - require.Equal(t, context.DeadlineExceeded, trace.Unwrap(err)) + require.Equal(t, context.Canceled, trace.Unwrap(err), "context should have been canceled immediately") // unblock the loading operation which is still in progress close(blocker) - ctx, cancel = context.WithTimeout(context.Background(), timeout) + // since we unblocked the loadfn, we expect the next Get to return almost + // immediately. we still use a fairly long timeout just to ensure that failure + // is due to an actual bug and not due to resource constraints in the test env. + ctx, cancel = context.WithTimeout(context.Background(), longTimeout) defer cancel() + loadFnWasRun := atomic.NewBool(false) v, err = cache.Get(ctx, "key", func(context.Context) (interface{}, error) { - t.Fatal("this should never run!") + loadFnWasRun.Store(true) return nil, nil }) + require.False(t, loadFnWasRun.Load(), "loadfn should not have been run") + require.NoError(t, err) require.Equal(t, "val", v.(string)) }