Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v10] reduce sensitivity of fncache cancellation test #15069

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions lib/utils/fncache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,35 +151,48 @@ func testFnCacheSimple(t *testing.T, ttl time.Duration, delay time.Duration) {
// in-progress loading continues, and the entry is correctly updated, even if the call to Get
// which happened to trigger the load needs to be unblocked early.
func TestFnCacheCancellation(t *testing.T) {
const timeout = time.Millisecond * 10
t.Parallel()

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))
}
Expand Down