diff --git a/agent/cache/cache_test.go b/agent/cache/cache_test.go index 8988b3bf61..8b77773f9e 100644 --- a/agent/cache/cache_test.go +++ b/agent/cache/cache_test.go @@ -1430,3 +1430,49 @@ func TestCache_ExpiryLoop_ExitsWhenStopped(t *testing.T) { t.Fatalf("expected loop to exit when stopped") } } + +func TestCache_Prepopulate(t *testing.T) { + typ := &fakeType{index: 5} + c := New(Options{}) + c.RegisterType("t", typ) + + c.Prepopulate("t", FetchResult{Value: 17, Index: 1}, "dc1", "token", "v1") + + ctx := context.Background() + req := fakeRequest{ + info: RequestInfo{ + Key: "v1", + Token: "token", + Datacenter: "dc1", + MinIndex: 1, + }, + } + result, _, err := c.Get(ctx, "t", req) + require.NoError(t, err) + require.Equal(t, 17, result) +} + +type fakeType struct { + index uint64 +} + +func (f fakeType) Fetch(_ FetchOptions, _ Request) (FetchResult, error) { + idx := atomic.LoadUint64(&f.index) + return FetchResult{Value: int(idx * 2), Index: idx}, nil +} + +func (f fakeType) RegisterOptions() RegisterOptions { + return RegisterOptions{Refresh: true} +} + +var _ Type = (*fakeType)(nil) + +type fakeRequest struct { + info RequestInfo +} + +func (f fakeRequest) CacheInfo() RequestInfo { + return f.info +} + +var _ Request = (*fakeRequest)(nil) diff --git a/lib/ttlcache/eviction.go b/lib/ttlcache/eviction.go index c04855a9bf..df9624bdcb 100644 --- a/lib/ttlcache/eviction.go +++ b/lib/ttlcache/eviction.go @@ -66,6 +66,10 @@ func (h *ExpiryHeap) Add(key string, expiry time.Duration) *Entry { // // Must be synchronized by the caller. func (h *ExpiryHeap) Update(idx int, expiry time.Duration) { + if idx < 0 { + // the previous entry did not have a valid index, its not in the heap + return + } entry := h.entries[idx] entry.expiry = time.Now().Add(expiry) heap.Fix((*entryHeap)(h), idx)