62 lines
1.3 KiB
Go
62 lines
1.3 KiB
Go
// Copyright 2026 tamakyi. All rights reserved.
|
|
// Use of this source code is governed by a MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package cache
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestTTLCacheBasic(t *testing.T) {
|
|
c := NewTTLCache(8)
|
|
if _, ok := c.Get("missing"); ok {
|
|
t.Fatal("expected miss for empty cache")
|
|
}
|
|
c.Set("k", "v", time.Minute)
|
|
v, ok := c.Get("k")
|
|
if !ok || v.(string) != "v" {
|
|
t.Fatalf("expected hit with v, got %v %v", v, ok)
|
|
}
|
|
}
|
|
|
|
func TestTTLCacheExpiry(t *testing.T) {
|
|
c := NewTTLCache(8)
|
|
c.Set("k", "v", time.Nanosecond)
|
|
time.Sleep(2 * time.Millisecond)
|
|
if _, ok := c.Get("k"); ok {
|
|
t.Fatal("expected expired entry to miss")
|
|
}
|
|
}
|
|
|
|
func TestTTLCacheCapacityEviction(t *testing.T) {
|
|
c := NewTTLCache(4)
|
|
for i := 0; i < 100; i++ {
|
|
c.Set(string(rune('a'+i%26))+string(rune('0'+i%10)), i, time.Minute)
|
|
}
|
|
// 不 panic 且仍可读
|
|
if _, ok := c.Get("a0"); ok {
|
|
// 命中与否均可,关键是内存不失控且无 panic
|
|
_ = ok
|
|
}
|
|
}
|
|
|
|
func TestTTLCacheConcurrent(t *testing.T) {
|
|
c := NewTTLCache(16)
|
|
var wg sync.WaitGroup
|
|
for g := 0; g < 20; g++ {
|
|
wg.Add(1)
|
|
go func(n int) {
|
|
defer wg.Done()
|
|
for i := 0; i < 200; i++ {
|
|
key := string(rune('a' + (n+i)%26))
|
|
c.Set(key, n, time.Minute)
|
|
c.Get(key)
|
|
}
|
|
}(g)
|
|
}
|
|
wg.Wait()
|
|
}
|