sing/common/cache/lrucache_test.go
2024-11-18 12:37:59 +08:00

113 lines
2.3 KiB
Go

package cache_test
import (
"testing"
"time"
"github.com/sagernet/sing/common/cache"
"github.com/stretchr/testify/require"
)
func TestLRUCache(t *testing.T) {
t.Run("basic operations", func(t *testing.T) {
t.Parallel()
c := cache.New[string, int]()
c.Store("key1", 1)
value, exists := c.Load("key1")
require.True(t, exists)
require.Equal(t, 1, value)
value, exists = c.Load("missing")
require.False(t, exists)
require.Zero(t, value)
c.Delete("key1")
_, exists = c.Load("key1")
require.False(t, exists)
})
t.Run("max size", func(t *testing.T) {
t.Parallel()
c := cache.New[string, int](cache.WithSize[string, int](2))
c.Store("key1", 1)
c.Store("key2", 2)
c.Store("key3", 3)
_, exists := c.Load("key1")
require.False(t, exists)
value, exists := c.Load("key2")
require.True(t, exists)
require.Equal(t, 2, value)
})
t.Run("expiration", func(t *testing.T) {
t.Parallel()
c := cache.New[string, int](cache.WithAge[string, int](1))
c.Store("key1", 1)
value, exists := c.Load("key1")
require.True(t, exists)
require.Equal(t, 1, value)
time.Sleep(time.Second * 2)
value, exists = c.Load("key1")
require.False(t, exists)
require.Zero(t, value)
})
t.Run("clear", func(t *testing.T) {
t.Parallel()
evicted := make(map[string]int)
c := cache.New[string, int](
cache.WithEvict[string, int](func(key string, value int) {
evicted[key] = value
}),
)
c.Store("key1", 1)
c.Store("key2", 2)
c.Clear()
require.Equal(t, map[string]int{"key1": 1, "key2": 2}, evicted)
_, exists := c.Load("key1")
require.False(t, exists)
})
t.Run("load or store", func(t *testing.T) {
t.Parallel()
c := cache.New[string, int]()
value, loaded := c.LoadOrStore("key1", func() int { return 1 })
require.False(t, loaded)
require.Equal(t, 1, value)
value, loaded = c.LoadOrStore("key1", func() int { return 2 })
require.True(t, loaded)
require.Equal(t, 1, value)
})
t.Run("update age on get", func(t *testing.T) {
t.Parallel()
c := cache.New[string, int](
cache.WithAge[string, int](5),
cache.WithUpdateAgeOnGet[string, int](),
)
c.Store("key1", 1)
time.Sleep(time.Second * 3)
_, exists := c.Load("key1")
require.True(t, exists)
time.Sleep(time.Second * 3)
_, exists = c.Load("key1")
require.True(t, exists)
})
}