88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package lru
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/benbjohnson/clock"
|
|
)
|
|
|
|
// These tests mirror the MRU-style behavior present in this LRU package
|
|
// implementation (eviction removes the most-recently-used entry).
|
|
func TestBasicCacheEviction(t *testing.T) {
|
|
mock := clock.NewMock()
|
|
c := NewStringKeyCache[int](2)
|
|
c.clock = mock
|
|
|
|
if err := c.ConsistencyCheck(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if c.Len() != 0 {
|
|
t.Fatal("cache should have size 0")
|
|
}
|
|
|
|
c.evict()
|
|
if err := c.ConsistencyCheck(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
c.Store("raven", 1)
|
|
if err := c.ConsistencyCheck(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(c.store) != 1 {
|
|
t.Fatalf("store should have length=1, have length=%d", len(c.store))
|
|
}
|
|
|
|
mock.Add(time.Second)
|
|
c.Store("owl", 2)
|
|
if err := c.ConsistencyCheck(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(c.store) != 2 {
|
|
t.Fatalf("store should have length=2, have length=%d", len(c.store))
|
|
}
|
|
|
|
mock.Add(time.Second)
|
|
c.Store("goat", 3)
|
|
if err := c.ConsistencyCheck(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if len(c.store) != 2 {
|
|
t.Fatalf("store should have length=2, have length=%d", len(c.store))
|
|
}
|
|
|
|
// Since this implementation evicts the most-recently-used item, inserting
|
|
// "goat" when full evicts "owl" (the most recent at that time).
|
|
mock.Add(time.Second)
|
|
if _, ok := c.Get("owl"); ok {
|
|
t.Fatal("store should not have an entry for owl (MRU-evicted)")
|
|
}
|
|
if err := c.ConsistencyCheck(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
mock.Add(time.Second)
|
|
c.Store("elk", 4)
|
|
if err := c.ConsistencyCheck(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !c.Has("elk") {
|
|
t.Fatal("store should contain an entry for 'elk'")
|
|
}
|
|
|
|
// Before storing elk, keys were: raven (older), goat (newer). Evict MRU -> goat.
|
|
if !c.Has("raven") {
|
|
t.Fatal("store should contain an entry for 'raven'")
|
|
}
|
|
|
|
if c.Has("goat") {
|
|
t.Fatal("store should not contain an entry for 'goat'")
|
|
}
|
|
}
|