mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-15 04:18:03 +00:00
242 lines
5.0 KiB
Go
242 lines
5.0 KiB
Go
package cache
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestCacheBasicOperations(t *testing.T) {
|
|
config := DefaultConfig()
|
|
cache := New(config)
|
|
defer cache.Close()
|
|
|
|
// Test Set and Get
|
|
key := "test-key"
|
|
value := "test-value"
|
|
ttl := 1 * time.Hour
|
|
|
|
err := cache.Set(key, value, ttl)
|
|
if err != nil {
|
|
t.Fatalf("Failed to set cache value: %v", err)
|
|
}
|
|
|
|
retrieved, exists := cache.Get(key)
|
|
if !exists {
|
|
t.Fatal("Expected value to exist in cache")
|
|
}
|
|
|
|
if retrieved != value {
|
|
t.Fatalf("Expected %s, got %v", value, retrieved)
|
|
}
|
|
|
|
// Test Delete
|
|
cache.Delete(key)
|
|
_, exists = cache.Get(key)
|
|
if exists {
|
|
t.Fatal("Expected value to be deleted from cache")
|
|
}
|
|
}
|
|
|
|
func TestCacheConcurrency(t *testing.T) {
|
|
config := DefaultConfig()
|
|
cache := New(config)
|
|
defer cache.Close()
|
|
|
|
var wg sync.WaitGroup
|
|
numGoroutines := 100
|
|
numOperations := 100
|
|
|
|
// Concurrent writes
|
|
wg.Add(numGoroutines)
|
|
for i := 0; i < numGoroutines; i++ {
|
|
go func(id int) {
|
|
defer wg.Done()
|
|
for j := 0; j < numOperations; j++ {
|
|
key := "key"
|
|
value := id*numOperations + j
|
|
_ = cache.Set(key, value, 1*time.Hour)
|
|
}
|
|
}(i)
|
|
}
|
|
|
|
// Concurrent reads
|
|
wg.Add(numGoroutines)
|
|
for i := 0; i < numGoroutines; i++ {
|
|
go func() {
|
|
defer wg.Done()
|
|
for j := 0; j < numOperations; j++ {
|
|
cache.Get("key")
|
|
}
|
|
}()
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|
|
|
|
func TestTypedCache(t *testing.T) {
|
|
config := DefaultConfig()
|
|
baseCache := New(config)
|
|
defer baseCache.Close()
|
|
|
|
// Test TokenCache
|
|
tokenCache := NewTokenCache(baseCache)
|
|
|
|
token := "test-token"
|
|
claims := map[string]interface{}{
|
|
"sub": "user123",
|
|
"exp": time.Now().Add(1 * time.Hour).Unix(),
|
|
}
|
|
|
|
err := tokenCache.Set(token, claims, 1*time.Hour)
|
|
if err != nil {
|
|
t.Fatalf("Failed to set token: %v", err)
|
|
}
|
|
|
|
retrievedClaims, exists := tokenCache.Get(token)
|
|
if !exists {
|
|
t.Fatal("Expected token to exist in cache")
|
|
}
|
|
|
|
if retrievedClaims["sub"] != claims["sub"] {
|
|
t.Fatalf("Claims mismatch: expected %v, got %v", claims["sub"], retrievedClaims["sub"])
|
|
}
|
|
|
|
// Test blacklist
|
|
err = tokenCache.SetBlacklisted(token, 24*time.Hour)
|
|
if err != nil {
|
|
t.Fatalf("Failed to blacklist token: %v", err)
|
|
}
|
|
|
|
if !tokenCache.IsBlacklisted(token) {
|
|
t.Fatal("Expected token to be blacklisted")
|
|
}
|
|
}
|
|
|
|
func TestCacheManager(t *testing.T) {
|
|
manager := NewManager(nil)
|
|
defer manager.Close()
|
|
|
|
// Test getting different cache types
|
|
tokenCache := manager.GetTokenCache()
|
|
if tokenCache == nil {
|
|
t.Fatal("Expected token cache to be initialized")
|
|
}
|
|
|
|
metadataCache := manager.GetMetadataCache()
|
|
if metadataCache == nil {
|
|
t.Fatal("Expected metadata cache to be initialized")
|
|
}
|
|
|
|
jwkCache := manager.GetJWKCache()
|
|
if jwkCache == nil {
|
|
t.Fatal("Expected JWK cache to be initialized")
|
|
}
|
|
|
|
sessionCache := manager.GetSessionCache()
|
|
if sessionCache == nil {
|
|
t.Fatal("Expected session cache to be initialized")
|
|
}
|
|
|
|
// Test stats
|
|
stats := manager.GetStats()
|
|
if len(stats) != 5 {
|
|
t.Fatalf("Expected 5 cache stats, got %d", len(stats))
|
|
}
|
|
}
|
|
|
|
func TestCacheEviction(t *testing.T) {
|
|
config := DefaultConfig()
|
|
config.MaxSize = 3
|
|
cache := New(config)
|
|
defer cache.Close()
|
|
|
|
// Add items to fill the cache
|
|
_ = cache.Set("key1", "value1", 1*time.Hour)
|
|
_ = cache.Set("key2", "value2", 1*time.Hour)
|
|
_ = cache.Set("key3", "value3", 1*time.Hour)
|
|
|
|
// Verify all items exist
|
|
for i := 1; i <= 3; i++ {
|
|
key := "key" + string(rune('0'+i))
|
|
if _, exists := cache.Get(key); !exists {
|
|
t.Fatalf("Expected %s to exist", key)
|
|
}
|
|
}
|
|
|
|
// Add another item to trigger eviction
|
|
_ = cache.Set("key4", "value4", 1*time.Hour)
|
|
|
|
// Check that we still have only 3 items
|
|
if cache.Size() != 3 {
|
|
t.Fatalf("Expected cache size to be 3, got %d", cache.Size())
|
|
}
|
|
|
|
// The least recently used item (key1) should be evicted
|
|
if _, exists := cache.Get("key1"); exists {
|
|
t.Fatal("Expected key1 to be evicted")
|
|
}
|
|
|
|
// Other items should still exist
|
|
if _, exists := cache.Get("key4"); !exists {
|
|
t.Fatal("Expected key4 to exist")
|
|
}
|
|
}
|
|
|
|
func TestCacheExpiration(t *testing.T) {
|
|
config := DefaultConfig()
|
|
cache := New(config)
|
|
defer cache.Close()
|
|
|
|
// Set item with short TTL
|
|
_ = cache.Set("short-ttl", "value", 100*time.Millisecond)
|
|
|
|
// Item should exist immediately
|
|
if _, exists := cache.Get("short-ttl"); !exists {
|
|
t.Fatal("Expected item to exist immediately after setting")
|
|
}
|
|
|
|
// Wait for expiration
|
|
time.Sleep(200 * time.Millisecond)
|
|
|
|
// Item should be expired
|
|
if _, exists := cache.Get("short-ttl"); exists {
|
|
t.Fatal("Expected item to be expired")
|
|
}
|
|
}
|
|
|
|
func BenchmarkCacheSet(b *testing.B) {
|
|
config := DefaultConfig()
|
|
cache := New(config)
|
|
defer cache.Close()
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
i := 0
|
|
for pb.Next() {
|
|
key := "key"
|
|
_ = cache.Set(key, i, 1*time.Hour)
|
|
i++
|
|
}
|
|
})
|
|
}
|
|
|
|
func BenchmarkCacheGet(b *testing.B) {
|
|
config := DefaultConfig()
|
|
cache := New(config)
|
|
defer cache.Close()
|
|
|
|
// Pre-populate cache
|
|
for i := 0; i < 1000; i++ {
|
|
key := "key"
|
|
_ = cache.Set(key, i, 1*time.Hour)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
for pb.Next() {
|
|
cache.Get("key")
|
|
}
|
|
})
|
|
}
|