mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-14 04:07:46 +00:00
Release 0.7.5 (#70)
* 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.
This commit is contained in:
@@ -0,0 +1,369 @@
|
||||
package traefikoidc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestNewBoundedCache tests creation of bounded cache
|
||||
func TestNewBoundedCache(t *testing.T) {
|
||||
maxSize := 500
|
||||
cache := NewBoundedCache(maxSize)
|
||||
|
||||
if cache == nil {
|
||||
t.Fatal("Expected cache to be created, got nil")
|
||||
}
|
||||
|
||||
// Verify we can use basic operations
|
||||
cache.Set("test-key", "test-value", time.Hour)
|
||||
value, found := cache.Get("test-key")
|
||||
if !found {
|
||||
t.Error("Expected key to be found in cache")
|
||||
}
|
||||
if value != "test-value" {
|
||||
t.Errorf("Expected 'test-value', got %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDefaultUnifiedCacheConfig tests default configuration
|
||||
func TestDefaultUnifiedCacheConfig(t *testing.T) {
|
||||
config := DefaultUnifiedCacheConfig()
|
||||
|
||||
if config.Type != CacheTypeGeneral {
|
||||
t.Errorf("Expected CacheTypeGeneral, got %v", config.Type)
|
||||
}
|
||||
|
||||
if config.MaxSize != 500 {
|
||||
t.Errorf("Expected MaxSize 500, got %d", config.MaxSize)
|
||||
}
|
||||
|
||||
if config.MaxMemoryBytes != 64*1024*1024 {
|
||||
t.Errorf("Expected MaxMemoryBytes 64MB, got %d", config.MaxMemoryBytes)
|
||||
}
|
||||
|
||||
if config.CleanupInterval != 2*time.Minute {
|
||||
t.Errorf("Expected CleanupInterval 2 minutes, got %v", config.CleanupInterval)
|
||||
}
|
||||
|
||||
if config.Logger == nil {
|
||||
t.Error("Expected Logger to be set")
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewUnifiedCache tests unified cache creation
|
||||
func TestNewUnifiedCache(t *testing.T) {
|
||||
config := DefaultUnifiedCacheConfig()
|
||||
cache := NewUnifiedCache(config)
|
||||
|
||||
if cache == nil {
|
||||
t.Fatal("Expected cache to be created, got nil")
|
||||
}
|
||||
|
||||
if cache.UniversalCache == nil {
|
||||
t.Error("Expected UniversalCache to be set")
|
||||
}
|
||||
|
||||
// Test basic operations
|
||||
cache.Set("test-key", "test-value", time.Hour)
|
||||
value, found := cache.Get("test-key")
|
||||
if !found {
|
||||
t.Error("Expected key to be found in cache")
|
||||
}
|
||||
if value != "test-value" {
|
||||
t.Errorf("Expected 'test-value', got %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// TestUnifiedCache_SetMaxSize tests SetMaxSize method
|
||||
func TestUnifiedCache_SetMaxSize(t *testing.T) {
|
||||
config := DefaultUnifiedCacheConfig()
|
||||
cache := NewUnifiedCache(config)
|
||||
|
||||
// Test setting max size
|
||||
newSize := 1000
|
||||
cache.SetMaxSize(newSize)
|
||||
|
||||
// We can't easily verify the size was set without exposing internal fields,
|
||||
// but we can ensure the method doesn't panic
|
||||
}
|
||||
|
||||
// TestNewCacheAdapter tests cache adapter creation
|
||||
func TestNewCacheAdapter(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cache interface{}
|
||||
expectNil bool
|
||||
description string
|
||||
}{
|
||||
{
|
||||
name: "UniversalCache",
|
||||
cache: NewUniversalCache(DefaultUnifiedCacheConfig()),
|
||||
expectNil: false,
|
||||
description: "Should create adapter for UniversalCache",
|
||||
},
|
||||
{
|
||||
name: "UnifiedCache",
|
||||
cache: NewUnifiedCache(DefaultUnifiedCacheConfig()),
|
||||
expectNil: false,
|
||||
description: "Should create adapter for UnifiedCache",
|
||||
},
|
||||
{
|
||||
name: "Invalid cache type",
|
||||
cache: "not-a-cache",
|
||||
expectNil: true,
|
||||
description: "Should return nil for invalid cache type",
|
||||
},
|
||||
{
|
||||
name: "Nil cache",
|
||||
cache: nil,
|
||||
expectNil: true,
|
||||
description: "Should return nil for nil cache",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
adapter := NewCacheAdapter(tt.cache)
|
||||
|
||||
if tt.expectNil {
|
||||
if adapter != nil {
|
||||
t.Errorf("Expected nil adapter, got %v", adapter)
|
||||
}
|
||||
} else {
|
||||
if adapter == nil {
|
||||
t.Error("Expected non-nil adapter")
|
||||
}
|
||||
// Test basic operations
|
||||
adapter.Set("test", "value", time.Hour)
|
||||
value, found := adapter.Get("test")
|
||||
if !found {
|
||||
t.Error("Expected key to be found")
|
||||
}
|
||||
if value != "value" {
|
||||
t.Errorf("Expected 'value', got %v", value)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewOptimizedCache tests optimized cache creation
|
||||
func TestNewOptimizedCache(t *testing.T) {
|
||||
cache := NewOptimizedCache()
|
||||
|
||||
if cache == nil {
|
||||
t.Fatal("Expected cache to be created, got nil")
|
||||
}
|
||||
|
||||
// Verify it works with basic operations
|
||||
cache.Set("test-key", "test-value", time.Hour)
|
||||
value, found := cache.Get("test-key")
|
||||
if !found {
|
||||
t.Error("Expected key to be found in cache")
|
||||
}
|
||||
if value != "test-value" {
|
||||
t.Errorf("Expected 'test-value', got %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewLRUStrategy tests LRU strategy creation
|
||||
func TestNewLRUStrategy(t *testing.T) {
|
||||
maxSize := 100
|
||||
strategy := NewLRUStrategy(maxSize)
|
||||
|
||||
if strategy == nil {
|
||||
t.Fatal("Expected strategy to be created, got nil")
|
||||
}
|
||||
|
||||
lruStrategy, ok := strategy.(*LRUStrategy)
|
||||
if !ok {
|
||||
t.Fatal("Expected LRUStrategy type")
|
||||
}
|
||||
|
||||
if lruStrategy.maxSize != maxSize {
|
||||
t.Errorf("Expected maxSize %d, got %d", maxSize, lruStrategy.maxSize)
|
||||
}
|
||||
|
||||
if lruStrategy.order == nil {
|
||||
t.Error("Expected order list to be initialized")
|
||||
}
|
||||
|
||||
if lruStrategy.elements == nil {
|
||||
t.Error("Expected elements map to be initialized")
|
||||
}
|
||||
}
|
||||
|
||||
// TestLRUStrategy_Name tests strategy name
|
||||
func TestLRUStrategy_Name(t *testing.T) {
|
||||
strategy := NewLRUStrategy(100)
|
||||
|
||||
name := strategy.Name()
|
||||
if name != "LRU" {
|
||||
t.Errorf("Expected 'LRU', got %s", name)
|
||||
}
|
||||
}
|
||||
|
||||
// TestLRUStrategy_ShouldEvict tests eviction logic
|
||||
func TestLRUStrategy_ShouldEvict(t *testing.T) {
|
||||
strategy := NewLRUStrategy(100)
|
||||
|
||||
// LRU strategy always returns false for ShouldEvict
|
||||
result := strategy.ShouldEvict("test-item", time.Now())
|
||||
if result != false {
|
||||
t.Error("Expected ShouldEvict to return false")
|
||||
}
|
||||
}
|
||||
|
||||
// TestLRUStrategy_OnAccess tests access callback
|
||||
func TestLRUStrategy_OnAccess(t *testing.T) {
|
||||
strategy := NewLRUStrategy(100)
|
||||
|
||||
// OnAccess should not panic
|
||||
strategy.OnAccess("test-key", "test-value")
|
||||
}
|
||||
|
||||
// TestLRUStrategy_OnRemove tests removal callback
|
||||
func TestLRUStrategy_OnRemove(t *testing.T) {
|
||||
strategy := NewLRUStrategy(100)
|
||||
|
||||
// OnRemove should not panic
|
||||
strategy.OnRemove("test-key")
|
||||
}
|
||||
|
||||
// TestLRUStrategy_EstimateSize tests size estimation
|
||||
func TestLRUStrategy_EstimateSize(t *testing.T) {
|
||||
strategy := NewLRUStrategy(100)
|
||||
|
||||
size := strategy.EstimateSize("test-item")
|
||||
if size != 64 {
|
||||
t.Errorf("Expected size 64, got %d", size)
|
||||
}
|
||||
}
|
||||
|
||||
// TestLRUStrategy_GetEvictionCandidate tests eviction candidate retrieval
|
||||
func TestLRUStrategy_GetEvictionCandidate(t *testing.T) {
|
||||
strategy := NewLRUStrategy(100)
|
||||
|
||||
key, found := strategy.GetEvictionCandidate()
|
||||
if found {
|
||||
t.Error("Expected no eviction candidate to be found")
|
||||
}
|
||||
if key != "" {
|
||||
t.Errorf("Expected empty key, got %s", key)
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewOptimizedCacheWithConfig tests optimized cache with custom config
|
||||
func TestNewOptimizedCacheWithConfig(t *testing.T) {
|
||||
config := UniversalCacheConfig{
|
||||
Type: CacheTypeGeneral,
|
||||
MaxSize: 1000,
|
||||
MaxMemoryBytes: 128 * 1024 * 1024,
|
||||
EnableMetrics: true,
|
||||
Logger: GetSingletonNoOpLogger(),
|
||||
}
|
||||
|
||||
cache := NewOptimizedCacheWithConfig(config)
|
||||
|
||||
if cache == nil {
|
||||
t.Fatal("Expected cache to be created, got nil")
|
||||
}
|
||||
|
||||
// Verify it works with basic operations
|
||||
cache.Set("test-key", "test-value", time.Hour)
|
||||
value, found := cache.Get("test-key")
|
||||
if !found {
|
||||
t.Error("Expected key to be found in cache")
|
||||
}
|
||||
if value != "test-value" {
|
||||
t.Errorf("Expected 'test-value', got %v", value)
|
||||
}
|
||||
}
|
||||
|
||||
// TestNewFixedMetadataCache tests fixed metadata cache creation
|
||||
func TestNewFixedMetadataCache(t *testing.T) {
|
||||
cache := NewFixedMetadataCache()
|
||||
|
||||
if cache == nil {
|
||||
t.Fatal("Expected cache to be created, got nil")
|
||||
}
|
||||
|
||||
// Verify it works with proper metadata operations
|
||||
metadata := &ProviderMetadata{
|
||||
Issuer: "https://example.com",
|
||||
AuthURL: "https://example.com/auth",
|
||||
TokenURL: "https://example.com/token",
|
||||
JWKSURL: "https://example.com/jwks",
|
||||
}
|
||||
|
||||
err := cache.Set("test-provider", metadata, time.Hour)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error setting metadata: %v", err)
|
||||
}
|
||||
|
||||
// Test that the cache was created (basic verification)
|
||||
// Note: We can't easily test Get without more complex setup
|
||||
}
|
||||
|
||||
// TestNewDoublyLinkedList tests doubly linked list creation
|
||||
func TestNewDoublyLinkedList(t *testing.T) {
|
||||
list := NewDoublyLinkedList()
|
||||
|
||||
if list == nil {
|
||||
t.Fatal("Expected list to be created, got nil")
|
||||
}
|
||||
|
||||
// Test it's a proper list structure
|
||||
if list.Len() != 0 {
|
||||
t.Error("Expected empty list initially")
|
||||
}
|
||||
}
|
||||
|
||||
// TestDoublyLinkedList_PopFront tests front element removal
|
||||
func TestDoublyLinkedList_PopFront(t *testing.T) {
|
||||
list := NewDoublyLinkedList()
|
||||
|
||||
// Test popping from empty list
|
||||
element := list.PopFront()
|
||||
if element != nil {
|
||||
t.Error("Expected nil when popping from empty list")
|
||||
}
|
||||
|
||||
// Add an element and test popping
|
||||
added := list.PushBack("test-value")
|
||||
if added == nil {
|
||||
t.Fatal("Expected element to be added")
|
||||
}
|
||||
|
||||
popped := list.PopFront()
|
||||
if popped == nil {
|
||||
t.Error("Expected element to be popped")
|
||||
}
|
||||
|
||||
if list.Len() != 0 {
|
||||
t.Error("Expected list to be empty after popping")
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark tests for performance
|
||||
func BenchmarkNewBoundedCache(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NewBoundedCache(1000)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkNewOptimizedCache(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
NewOptimizedCache()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkLRUStrategy_EstimateSize(b *testing.B) {
|
||||
strategy := NewLRUStrategy(1000)
|
||||
item := "test-item"
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
strategy.EstimateSize(item)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user