Skip to content

Commit 8f8764f

Browse files
committed
test: Add tests for eviction callback
This adds tests to verify that calling Add, ContainsOrAdd, or PeekOrAdd with a key that is already in the cache does not trigger an eviction or an eviction callback.
1 parent 0ed35fd commit 8f8764f

File tree

3 files changed

+239
-1
lines changed

3 files changed

+239
-1
lines changed

expirable/expirable_lru_test.go

+44
Original file line numberDiff line numberDiff line change
@@ -517,3 +517,47 @@ func getRand(tb testing.TB) int64 {
517517
}
518518
return out.Int64()
519519
}
520+
521+
func (c *LRU[K, V]) wantKeys(t *testing.T, want []K) {
522+
t.Helper()
523+
got := c.Keys()
524+
if !reflect.DeepEqual(got, want) {
525+
t.Errorf("wrong keys got: %v, want: %v ", got, want)
526+
}
527+
}
528+
529+
func TestCache_EvictionSameKey(t *testing.T) {
530+
var evictedKeys []int
531+
532+
cache := NewLRU[int, struct{}](
533+
2,
534+
func(key int, _ struct{}) {
535+
evictedKeys = append(evictedKeys, key)
536+
},
537+
0)
538+
539+
if evicted := cache.Add(1, struct{}{}); evicted {
540+
t.Error("First 1: got unexpected eviction")
541+
}
542+
cache.wantKeys(t, []int{1})
543+
544+
if evicted := cache.Add(2, struct{}{}); evicted {
545+
t.Error("2: got unexpected eviction")
546+
}
547+
cache.wantKeys(t, []int{1, 2})
548+
549+
if evicted := cache.Add(1, struct{}{}); evicted {
550+
t.Error("Second 1: got unexpected eviction")
551+
}
552+
cache.wantKeys(t, []int{2, 1})
553+
554+
if evicted := cache.Add(3, struct{}{}); !evicted {
555+
t.Error("3: did not get expected eviction")
556+
}
557+
cache.wantKeys(t, []int{1, 3})
558+
559+
want := []int{2}
560+
if !reflect.DeepEqual(evictedKeys, want) {
561+
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
562+
}
563+
}

lru_test.go

+148
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package lru
55

66
import (
7+
"reflect"
78
"testing"
89
)
910

@@ -293,3 +294,150 @@ func TestLRUResize(t *testing.T) {
293294
t.Errorf("Cache should have contained 2 elements")
294295
}
295296
}
297+
298+
func (c *Cache[K, V]) wantKeys(t *testing.T, want []K) {
299+
t.Helper()
300+
got := c.Keys()
301+
if !reflect.DeepEqual(got, want) {
302+
t.Errorf("wrong keys got: %v, want: %v ", got, want)
303+
}
304+
}
305+
306+
func TestCache_EvictionSameKey(t *testing.T) {
307+
t.Run("Add", func(t *testing.T) {
308+
var evictedKeys []int
309+
310+
cache, _ := NewWithEvict(
311+
2,
312+
func(key int, _ struct{}) {
313+
evictedKeys = append(evictedKeys, key)
314+
})
315+
316+
if evicted := cache.Add(1, struct{}{}); evicted {
317+
t.Error("First 1: got unexpected eviction")
318+
}
319+
cache.wantKeys(t, []int{1})
320+
321+
if evicted := cache.Add(2, struct{}{}); evicted {
322+
t.Error("2: got unexpected eviction")
323+
}
324+
cache.wantKeys(t, []int{1, 2})
325+
326+
if evicted := cache.Add(1, struct{}{}); evicted {
327+
t.Error("Second 1: got unexpected eviction")
328+
}
329+
cache.wantKeys(t, []int{2, 1})
330+
331+
if evicted := cache.Add(3, struct{}{}); !evicted {
332+
t.Error("3: did not get expected eviction")
333+
}
334+
cache.wantKeys(t, []int{1, 3})
335+
336+
want := []int{2}
337+
if !reflect.DeepEqual(evictedKeys, want) {
338+
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
339+
}
340+
})
341+
342+
t.Run("ContainsOrAdd", func(t *testing.T) {
343+
var evictedKeys []int
344+
345+
cache, _ := NewWithEvict(
346+
2,
347+
func(key int, _ struct{}) {
348+
evictedKeys = append(evictedKeys, key)
349+
})
350+
351+
contained, evicted := cache.ContainsOrAdd(1, struct{}{})
352+
if contained {
353+
t.Error("First 1: got unexpected contained")
354+
}
355+
if evicted {
356+
t.Error("First 1: got unexpected eviction")
357+
}
358+
cache.wantKeys(t, []int{1})
359+
360+
contained, evicted = cache.ContainsOrAdd(2, struct{}{})
361+
if contained {
362+
t.Error("2: got unexpected contained")
363+
}
364+
if evicted {
365+
t.Error("2: got unexpected eviction")
366+
}
367+
cache.wantKeys(t, []int{1, 2})
368+
369+
contained, evicted = cache.ContainsOrAdd(1, struct{}{})
370+
if !contained {
371+
t.Error("Second 1: did not get expected contained")
372+
}
373+
if evicted {
374+
t.Error("Second 1: got unexpected eviction")
375+
}
376+
cache.wantKeys(t, []int{1, 2})
377+
378+
contained, evicted = cache.ContainsOrAdd(3, struct{}{})
379+
if contained {
380+
t.Error("3: got unexpected contained")
381+
}
382+
if !evicted {
383+
t.Error("3: did not get expected eviction")
384+
}
385+
cache.wantKeys(t, []int{2, 3})
386+
387+
want := []int{1}
388+
if !reflect.DeepEqual(evictedKeys, want) {
389+
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
390+
}
391+
})
392+
393+
t.Run("PeekOrAdd", func(t *testing.T) {
394+
var evictedKeys []int
395+
396+
cache, _ := NewWithEvict(
397+
2,
398+
func(key int, _ struct{}) {
399+
evictedKeys = append(evictedKeys, key)
400+
})
401+
402+
_, contained, evicted := cache.PeekOrAdd(1, struct{}{})
403+
if contained {
404+
t.Error("First 1: got unexpected contained")
405+
}
406+
if evicted {
407+
t.Error("First 1: got unexpected eviction")
408+
}
409+
cache.wantKeys(t, []int{1})
410+
411+
_, contained, evicted = cache.PeekOrAdd(2, struct{}{})
412+
if contained {
413+
t.Error("2: got unexpected contained")
414+
}
415+
if evicted {
416+
t.Error("2: got unexpected eviction")
417+
}
418+
cache.wantKeys(t, []int{1, 2})
419+
420+
_, contained, evicted = cache.PeekOrAdd(1, struct{}{})
421+
if !contained {
422+
t.Error("Second 1: did not get expected contained")
423+
}
424+
if evicted {
425+
t.Error("Second 1: got unexpected eviction")
426+
}
427+
cache.wantKeys(t, []int{1, 2})
428+
429+
_, contained, evicted = cache.PeekOrAdd(3, struct{}{})
430+
if contained {
431+
t.Error("3: got unexpected contained")
432+
}
433+
if !evicted {
434+
t.Error("3: did not get expected eviction")
435+
}
436+
cache.wantKeys(t, []int{2, 3})
437+
438+
want := []int{1}
439+
if !reflect.DeepEqual(evictedKeys, want) {
440+
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
441+
}
442+
})
443+
}

simplelru/lru_test.go

+47-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
package simplelru
55

6-
import "testing"
6+
import (
7+
"reflect"
8+
"testing"
9+
)
710

811
func TestLRU(t *testing.T) {
912
evictCounter := 0
@@ -207,3 +210,46 @@ func TestLRU_Resize(t *testing.T) {
207210
t.Errorf("Cache should have contained 2 elements")
208211
}
209212
}
213+
214+
func (c *LRU[K, V]) wantKeys(t *testing.T, want []K) {
215+
t.Helper()
216+
got := c.Keys()
217+
if !reflect.DeepEqual(got, want) {
218+
t.Errorf("wrong keys got: %v, want: %v ", got, want)
219+
}
220+
}
221+
222+
func TestCache_EvictionSameKey(t *testing.T) {
223+
var evictedKeys []int
224+
225+
cache, _ := NewLRU(
226+
2,
227+
func(key int, _ struct{}) {
228+
evictedKeys = append(evictedKeys, key)
229+
})
230+
231+
if evicted := cache.Add(1, struct{}{}); evicted {
232+
t.Error("First 1: got unexpected eviction")
233+
}
234+
cache.wantKeys(t, []int{1})
235+
236+
if evicted := cache.Add(2, struct{}{}); evicted {
237+
t.Error("2: got unexpected eviction")
238+
}
239+
cache.wantKeys(t, []int{1, 2})
240+
241+
if evicted := cache.Add(1, struct{}{}); evicted {
242+
t.Error("Second 1: got unexpected eviction")
243+
}
244+
cache.wantKeys(t, []int{2, 1})
245+
246+
if evicted := cache.Add(3, struct{}{}); !evicted {
247+
t.Error("3: did not get expected eviction")
248+
}
249+
cache.wantKeys(t, []int{1, 3})
250+
251+
want := []int{2}
252+
if !reflect.DeepEqual(evictedKeys, want) {
253+
t.Errorf("evictedKeys got: %v want: %v", evictedKeys, want)
254+
}
255+
}

0 commit comments

Comments
 (0)