mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-06-05 22:44:17 +00:00
c3f23cb99b
* Resolve issue with opaque tokens not being parsed correctly * Increase test coverage * Further improvements to test coverage and code quality * Add new providers. * fixup! Add new providers. * Cleanup. * fixup! Cleanup. * fixup! fixup! Cleanup. * fixup! fixup! fixup! Cleanup. * fixup! fixup! fixup! fixup! Cleanup. * Memory management optimisation 24 bytes per Put < 256-4096 bytes per buffer allocation avoided (10-170x difference) * Pooling cleanup.
315 lines
7.4 KiB
Go
315 lines
7.4 KiB
Go
package traefikoidc
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// Helper function to ensure we have a working cache manager for tests
|
|
func getTestCacheManager(t *testing.T) *CacheManager {
|
|
cm := GetGlobalCacheManager(&sync.WaitGroup{})
|
|
if cm == nil {
|
|
t.Fatal("Failed to get cache manager")
|
|
}
|
|
if cm.manager == nil {
|
|
t.Fatal("Cache manager has nil internal manager")
|
|
}
|
|
return cm
|
|
}
|
|
|
|
// TestCacheManager_Close tests cache manager close functionality
|
|
func TestCacheManager_Close(t *testing.T) {
|
|
// Get a fresh cache manager
|
|
wg := &sync.WaitGroup{}
|
|
cm := GetGlobalCacheManager(wg)
|
|
|
|
if cm == nil {
|
|
t.Fatal("Expected cache manager to be created")
|
|
}
|
|
|
|
// Test closing the cache manager
|
|
err := cm.Close()
|
|
if err != nil {
|
|
t.Errorf("Unexpected error closing cache manager: %v", err)
|
|
}
|
|
}
|
|
|
|
// TestCleanupGlobalCacheManager tests global cleanup
|
|
func TestCleanupGlobalCacheManager(t *testing.T) {
|
|
// Test cleanup when no instance exists (should not error)
|
|
originalInstance := globalCacheManagerInstance
|
|
globalCacheManagerInstance = nil
|
|
err := CleanupGlobalCacheManager()
|
|
if err != nil {
|
|
t.Errorf("Unexpected error during cleanup of nil instance: %v", err)
|
|
}
|
|
|
|
// Restore original instance
|
|
globalCacheManagerInstance = originalInstance
|
|
}
|
|
|
|
// TestCacheInterfaceWrapper_Delete tests delete functionality
|
|
func TestCacheInterfaceWrapper_Delete(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
// Add an item
|
|
cache.Set("test-key", "test-value", time.Hour)
|
|
|
|
// Verify it exists
|
|
value, found := cache.Get("test-key")
|
|
if !found {
|
|
t.Fatal("Expected key to be found after setting")
|
|
}
|
|
if value != "test-value" {
|
|
t.Errorf("Expected 'test-value', got %v", value)
|
|
}
|
|
|
|
// Delete it
|
|
cache.Delete("test-key")
|
|
|
|
// Verify it's gone
|
|
_, found = cache.Get("test-key")
|
|
if found {
|
|
t.Error("Expected key to be deleted")
|
|
}
|
|
}
|
|
|
|
// TestCacheInterfaceWrapper_Size tests size functionality
|
|
func TestCacheInterfaceWrapper_Size(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
// Clear cache first
|
|
cache.Clear()
|
|
|
|
// Check initial size
|
|
initialSize := cache.Size()
|
|
if initialSize != 0 {
|
|
t.Errorf("Expected initial size 0, got %d", initialSize)
|
|
}
|
|
|
|
// Add some items
|
|
cache.Set("key1", "value1", time.Hour)
|
|
cache.Set("key2", "value2", time.Hour)
|
|
|
|
// Check size increased
|
|
newSize := cache.Size()
|
|
if newSize != 2 {
|
|
t.Errorf("Expected size 2, got %d", newSize)
|
|
}
|
|
}
|
|
|
|
// TestCacheInterfaceWrapper_Clear tests clear functionality
|
|
func TestCacheInterfaceWrapper_Clear(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
// Add some items
|
|
cache.Set("key1", "value1", time.Hour)
|
|
cache.Set("key2", "value2", time.Hour)
|
|
|
|
// Verify items exist
|
|
size := cache.Size()
|
|
if size != 2 {
|
|
t.Errorf("Expected 2 items before clear, got %d", size)
|
|
}
|
|
|
|
// Clear all
|
|
cache.Clear()
|
|
|
|
// Verify cache is empty
|
|
size = cache.Size()
|
|
if size != 0 {
|
|
t.Errorf("Expected 0 items after clear, got %d", size)
|
|
}
|
|
|
|
// Verify specific items are gone
|
|
_, found := cache.Get("key1")
|
|
if found {
|
|
t.Error("Expected key1 to be cleared")
|
|
}
|
|
|
|
_, found = cache.Get("key2")
|
|
if found {
|
|
t.Error("Expected key2 to be cleared")
|
|
}
|
|
}
|
|
|
|
// TestCacheInterfaceWrapper_Close tests wrapper close functionality
|
|
func TestCacheInterfaceWrapper_Close(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
// Test close - should not panic
|
|
wrapper, ok := cache.(*CacheInterfaceWrapper)
|
|
if !ok {
|
|
t.Fatal("Expected CacheInterfaceWrapper")
|
|
}
|
|
|
|
wrapper.Close() // Should not panic
|
|
|
|
// Test close with nil cache
|
|
nilWrapper := &CacheInterfaceWrapper{cache: nil}
|
|
nilWrapper.Close() // Should not panic
|
|
}
|
|
|
|
// TestCacheInterfaceWrapper_GetStats tests stats functionality
|
|
func TestCacheInterfaceWrapper_GetStats(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
wrapper, ok := cache.(*CacheInterfaceWrapper)
|
|
if !ok {
|
|
t.Fatal("Expected CacheInterfaceWrapper")
|
|
}
|
|
|
|
// Get stats
|
|
stats := wrapper.GetStats()
|
|
if stats == nil {
|
|
t.Error("Expected non-nil stats")
|
|
}
|
|
|
|
// Stats should be accessible (len() never returns negative values)
|
|
// Just verify it's accessible by checking it's not nil (already done above)
|
|
}
|
|
|
|
// TestCacheInterfaceWrapper_Cleanup tests cleanup functionality
|
|
func TestCacheInterfaceWrapper_Cleanup(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
// Add an item that will expire quickly
|
|
cache.Set("expire-key", "expire-value", time.Millisecond)
|
|
|
|
// Wait for expiration
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
// Trigger cleanup
|
|
cache.Cleanup()
|
|
|
|
// Item should be cleaned up
|
|
_, found := cache.Get("expire-key")
|
|
if found {
|
|
t.Error("Expected expired key to be cleaned up")
|
|
}
|
|
}
|
|
|
|
// TestCacheInterfaceWrapper_SetMaxSize tests max size setting
|
|
func TestCacheInterfaceWrapper_SetMaxSize(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
// Test setting max size (should not panic)
|
|
cache.SetMaxSize(1000)
|
|
|
|
// We can't easily verify the size was set without exposing internals,
|
|
// but we can ensure the method doesn't panic
|
|
}
|
|
|
|
// TestGetSharedCaches tests getting shared cache instances
|
|
func TestGetSharedCaches(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
|
|
// Test getting shared token blacklist
|
|
blacklist := cm.GetSharedTokenBlacklist()
|
|
if blacklist == nil {
|
|
t.Error("Expected non-nil token blacklist")
|
|
}
|
|
|
|
// Test getting shared token cache
|
|
tokenCache := cm.GetSharedTokenCache()
|
|
if tokenCache == nil {
|
|
t.Error("Expected non-nil token cache")
|
|
}
|
|
|
|
// Test getting shared metadata cache
|
|
metadataCache := cm.GetSharedMetadataCache()
|
|
if metadataCache == nil {
|
|
t.Error("Expected non-nil metadata cache")
|
|
}
|
|
|
|
// Test getting shared JWK cache
|
|
jwkCache := cm.GetSharedJWKCache()
|
|
if jwkCache == nil {
|
|
t.Error("Expected non-nil JWK cache")
|
|
}
|
|
}
|
|
|
|
// TestConcurrentCacheAccess tests thread safety
|
|
func TestConcurrentCacheAccess(t *testing.T) {
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
var wg sync.WaitGroup
|
|
goroutines := 10
|
|
iterations := 10
|
|
|
|
// Concurrent operations
|
|
for i := 0; i < goroutines; i++ {
|
|
wg.Add(1)
|
|
go func(id int) {
|
|
defer wg.Done()
|
|
for j := 0; j < iterations; j++ {
|
|
key := fmt.Sprintf("key-%d-%d", id, j)
|
|
value := fmt.Sprintf("value-%d-%d", id, j)
|
|
|
|
cache.Set(key, value, time.Hour)
|
|
|
|
retrieved, found := cache.Get(key)
|
|
if found && retrieved != value {
|
|
t.Errorf("Concurrent access failed: expected %s, got %v", value, retrieved)
|
|
}
|
|
|
|
cache.Delete(key)
|
|
}
|
|
}(i)
|
|
}
|
|
|
|
wg.Wait()
|
|
}
|
|
|
|
// Benchmark tests for performance
|
|
func BenchmarkCacheInterfaceWrapper_Set(b *testing.B) {
|
|
t := &testing.T{}
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
cache.Set("benchmark-key", "benchmark-value", time.Hour)
|
|
}
|
|
}
|
|
|
|
func BenchmarkCacheInterfaceWrapper_Get(b *testing.B) {
|
|
t := &testing.T{}
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
// Pre-populate cache
|
|
cache.Set("benchmark-key", "benchmark-value", time.Hour)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
cache.Get("benchmark-key")
|
|
}
|
|
}
|
|
|
|
func BenchmarkCacheInterfaceWrapper_Delete(b *testing.B) {
|
|
t := &testing.T{}
|
|
cm := getTestCacheManager(t)
|
|
cache := cm.GetSharedTokenBlacklist()
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
b.StopTimer()
|
|
key := fmt.Sprintf("benchmark-key-%d", i)
|
|
cache.Set(key, "value", time.Hour)
|
|
b.StartTimer()
|
|
|
|
cache.Delete(key)
|
|
}
|
|
}
|