151 lines
3.3 KiB
Go
151 lines
3.3 KiB
Go
package storage
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestHoldCache_SetAndGet(t *testing.T) {
|
|
cache := &HoldCache{
|
|
cache: make(map[string]*holdCacheEntry),
|
|
}
|
|
|
|
did := "did:plc:test123"
|
|
repo := "myapp"
|
|
holdDID := "did:web:hold01.atcr.io"
|
|
ttl := 10 * time.Minute
|
|
|
|
// Set a value
|
|
cache.Set(did, repo, holdDID, ttl)
|
|
|
|
// Get the value - should succeed
|
|
gotHoldDID, ok := cache.Get(did, repo)
|
|
if !ok {
|
|
t.Fatal("Expected Get to return true, got false")
|
|
}
|
|
if gotHoldDID != holdDID {
|
|
t.Errorf("Expected hold DID %q, got %q", holdDID, gotHoldDID)
|
|
}
|
|
}
|
|
|
|
func TestHoldCache_GetNonExistent(t *testing.T) {
|
|
cache := &HoldCache{
|
|
cache: make(map[string]*holdCacheEntry),
|
|
}
|
|
|
|
// Get non-existent value
|
|
_, ok := cache.Get("did:plc:nonexistent", "repo")
|
|
if ok {
|
|
t.Error("Expected Get to return false for non-existent key")
|
|
}
|
|
}
|
|
|
|
func TestHoldCache_ExpiredEntry(t *testing.T) {
|
|
cache := &HoldCache{
|
|
cache: make(map[string]*holdCacheEntry),
|
|
}
|
|
|
|
did := "did:plc:test123"
|
|
repo := "myapp"
|
|
holdDID := "did:web:hold01.atcr.io"
|
|
|
|
// Set with very short TTL
|
|
cache.Set(did, repo, holdDID, 10*time.Millisecond)
|
|
|
|
// Wait for expiration
|
|
time.Sleep(20 * time.Millisecond)
|
|
|
|
// Get should return false
|
|
_, ok := cache.Get(did, repo)
|
|
if ok {
|
|
t.Error("Expected Get to return false for expired entry")
|
|
}
|
|
}
|
|
|
|
func TestHoldCache_Cleanup(t *testing.T) {
|
|
cache := &HoldCache{
|
|
cache: make(map[string]*holdCacheEntry),
|
|
}
|
|
|
|
// Add multiple entries with different TTLs
|
|
cache.Set("did:plc:1", "repo1", "hold1", 10*time.Millisecond)
|
|
cache.Set("did:plc:2", "repo2", "hold2", 1*time.Hour)
|
|
cache.Set("did:plc:3", "repo3", "hold3", 10*time.Millisecond)
|
|
|
|
// Wait for some to expire
|
|
time.Sleep(20 * time.Millisecond)
|
|
|
|
// Run cleanup
|
|
cache.Cleanup()
|
|
|
|
// Verify expired entries are removed
|
|
if _, ok := cache.Get("did:plc:1", "repo1"); ok {
|
|
t.Error("Expected expired entry 1 to be removed")
|
|
}
|
|
if _, ok := cache.Get("did:plc:3", "repo3"); ok {
|
|
t.Error("Expected expired entry 3 to be removed")
|
|
}
|
|
|
|
// Verify non-expired entry remains
|
|
if _, ok := cache.Get("did:plc:2", "repo2"); !ok {
|
|
t.Error("Expected non-expired entry to remain")
|
|
}
|
|
}
|
|
|
|
func TestHoldCache_ConcurrentAccess(t *testing.T) {
|
|
cache := &HoldCache{
|
|
cache: make(map[string]*holdCacheEntry),
|
|
}
|
|
|
|
done := make(chan bool)
|
|
|
|
// Concurrent writes
|
|
for i := 0; i < 10; i++ {
|
|
go func(id int) {
|
|
did := "did:plc:concurrent"
|
|
repo := "repo" + string(rune(id))
|
|
holdDID := "hold" + string(rune(id))
|
|
cache.Set(did, repo, holdDID, 1*time.Minute)
|
|
done <- true
|
|
}(i)
|
|
}
|
|
|
|
// Concurrent reads
|
|
for i := 0; i < 10; i++ {
|
|
go func(id int) {
|
|
repo := "repo" + string(rune(id))
|
|
cache.Get("did:plc:concurrent", repo)
|
|
done <- true
|
|
}(i)
|
|
}
|
|
|
|
// Wait for all goroutines
|
|
for i := 0; i < 20; i++ {
|
|
<-done
|
|
}
|
|
}
|
|
|
|
func TestHoldCache_KeyFormat(t *testing.T) {
|
|
cache := &HoldCache{
|
|
cache: make(map[string]*holdCacheEntry),
|
|
}
|
|
|
|
did := "did:plc:test"
|
|
repo := "myrepo"
|
|
holdDID := "did:web:hold"
|
|
|
|
cache.Set(did, repo, holdDID, 1*time.Minute)
|
|
|
|
// Verify the key is stored correctly (did:repo)
|
|
expectedKey := did + ":" + repo
|
|
if _, exists := cache.cache[expectedKey]; !exists {
|
|
t.Errorf("Expected key %q to exist in cache", expectedKey)
|
|
}
|
|
}
|
|
|
|
// TODO: Add more comprehensive tests:
|
|
// - Test GetGlobalHoldCache()
|
|
// - Test cache size monitoring
|
|
// - Benchmark cache performance under load
|
|
// - Test cleanup goroutine timing
|