mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-07-25 10:21:47 +00:00
Apply Go 1.21+ min/max builtins and improved switch pattern matching across test files and utilities. No functional changes.
96 lines
2.0 KiB
Go
96 lines
2.0 KiB
Go
package audio_test
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/nextlevelbuilder/goclaw/internal/audio"
|
|
)
|
|
|
|
func TestVoiceCache_SetGetHit(t *testing.T) {
|
|
c := audio.NewVoiceCache(time.Hour, 100)
|
|
tid := uuid.New()
|
|
voices := []audio.Voice{{ID: "v1", Name: "Bella"}}
|
|
|
|
c.Set(tid, voices)
|
|
got, ok := c.Get(tid)
|
|
if !ok {
|
|
t.Fatal("expected cache hit")
|
|
}
|
|
if len(got) != 1 || got[0].ID != "v1" {
|
|
t.Errorf("unexpected voices: %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestVoiceCache_ExpiredMiss(t *testing.T) {
|
|
c := audio.NewVoiceCache(10*time.Millisecond, 100)
|
|
tid := uuid.New()
|
|
c.Set(tid, []audio.Voice{{ID: "v1"}})
|
|
|
|
time.Sleep(20 * time.Millisecond)
|
|
_, ok := c.Get(tid)
|
|
if ok {
|
|
t.Fatal("expected cache miss after TTL expiry")
|
|
}
|
|
}
|
|
|
|
func TestVoiceCache_LRUEviction(t *testing.T) {
|
|
cap := 3
|
|
c := audio.NewVoiceCache(time.Hour, cap)
|
|
|
|
ids := make([]uuid.UUID, cap+1)
|
|
for i := range ids {
|
|
ids[i] = uuid.New()
|
|
}
|
|
voices := []audio.Voice{{ID: "x"}}
|
|
|
|
// Fill to capacity
|
|
for i := range cap {
|
|
c.Set(ids[i], voices)
|
|
}
|
|
// Access ids[0] to make it recently used
|
|
c.Get(ids[0])
|
|
|
|
// Insert one more — should evict the LRU entry (ids[1] was least recently used)
|
|
c.Set(ids[cap], voices)
|
|
|
|
_, ok := c.Get(ids[1])
|
|
if ok {
|
|
t.Fatal("ids[1] should have been evicted as LRU")
|
|
}
|
|
// ids[0] and ids[cap] must still be present
|
|
if _, ok := c.Get(ids[0]); !ok {
|
|
t.Error("ids[0] should still be cached (recently accessed)")
|
|
}
|
|
if _, ok := c.Get(ids[cap]); !ok {
|
|
t.Error("ids[cap] should be cached (just inserted)")
|
|
}
|
|
}
|
|
|
|
func TestVoiceCache_Invalidate(t *testing.T) {
|
|
c := audio.NewVoiceCache(time.Hour, 100)
|
|
tid := uuid.New()
|
|
c.Set(tid, []audio.Voice{{ID: "v1"}})
|
|
c.Invalidate(tid)
|
|
_, ok := c.Get(tid)
|
|
if ok {
|
|
t.Fatal("expected miss after invalidate")
|
|
}
|
|
}
|
|
|
|
func TestVoiceCache_ConcurrentSafe(t *testing.T) {
|
|
c := audio.NewVoiceCache(time.Hour, 500)
|
|
var wg sync.WaitGroup
|
|
for range 100 {
|
|
wg.Go(func() {
|
|
tid := uuid.New()
|
|
c.Set(tid, []audio.Voice{{ID: "v"}})
|
|
c.Get(tid)
|
|
c.Invalidate(tid)
|
|
})
|
|
}
|
|
wg.Wait()
|
|
}
|