mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-06-05 22:44:17 +00:00
307 lines
6.8 KiB
Go
307 lines
6.8 KiB
Go
package traefikoidc
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestCache(t *testing.T) {
|
|
t.Run("Basic Set and Get", func(t *testing.T) {
|
|
cache := NewCache()
|
|
key := "test-key"
|
|
value := "test-value"
|
|
expiration := 1 * time.Second
|
|
|
|
// Test Set
|
|
cache.Set(key, value, expiration)
|
|
|
|
// Test Get
|
|
got, found := cache.Get(key)
|
|
if !found {
|
|
t.Error("Expected to find key in cache")
|
|
}
|
|
if got != value {
|
|
t.Errorf("Expected value %v, got %v", value, got)
|
|
}
|
|
})
|
|
|
|
t.Run("Expiration", func(t *testing.T) {
|
|
cache := NewCache()
|
|
key := "test-key"
|
|
value := "test-value"
|
|
expiration := 10 * time.Millisecond
|
|
|
|
// Set with short expiration
|
|
cache.Set(key, value, expiration)
|
|
|
|
// Wait for expiration
|
|
time.Sleep(20 * time.Millisecond)
|
|
|
|
// Should not find expired key
|
|
_, found := cache.Get(key)
|
|
if found {
|
|
t.Error("Expected key to be expired")
|
|
}
|
|
})
|
|
|
|
t.Run("Delete", func(t *testing.T) {
|
|
cache := NewCache()
|
|
key := "test-key"
|
|
value := "test-value"
|
|
expiration := 1 * time.Second
|
|
|
|
// Set and then delete
|
|
cache.Set(key, value, expiration)
|
|
cache.Delete(key)
|
|
|
|
// Should not find deleted key
|
|
_, found := cache.Get(key)
|
|
if found {
|
|
t.Error("Expected key to be deleted")
|
|
}
|
|
})
|
|
|
|
t.Run("Cleanup", func(t *testing.T) {
|
|
cache := NewCache()
|
|
// Add multiple items with different expirations
|
|
cache.Set("expired1", "value1", 10*time.Millisecond)
|
|
cache.Set("expired2", "value2", 10*time.Millisecond)
|
|
cache.Set("valid", "value3", 1*time.Second)
|
|
|
|
// Wait for some items to expire
|
|
time.Sleep(20 * time.Millisecond)
|
|
|
|
// Run cleanup
|
|
cache.Cleanup()
|
|
|
|
// Check expired items are removed
|
|
_, found1 := cache.Get("expired1")
|
|
_, found2 := cache.Get("expired2")
|
|
_, found3 := cache.Get("valid")
|
|
|
|
if found1 {
|
|
t.Error("Expected expired1 to be cleaned up")
|
|
}
|
|
if found2 {
|
|
t.Error("Expected expired2 to be cleaned up")
|
|
}
|
|
if !found3 {
|
|
t.Error("Expected valid item to remain in cache")
|
|
}
|
|
})
|
|
|
|
t.Run("Concurrent Access", func(t *testing.T) {
|
|
cache := NewCache()
|
|
done := make(chan bool)
|
|
|
|
// Start multiple goroutines to access cache concurrently
|
|
for i := 0; i < 10; i++ {
|
|
go func(id int) {
|
|
key := "key"
|
|
value := "value"
|
|
expiration := 1 * time.Second
|
|
|
|
// Perform multiple operations
|
|
cache.Set(key, value, expiration)
|
|
cache.Get(key)
|
|
cache.Delete(key)
|
|
cache.Cleanup()
|
|
|
|
done <- true
|
|
}(i)
|
|
}
|
|
|
|
// Wait for all goroutines to complete
|
|
for i := 0; i < 10; i++ {
|
|
<-done
|
|
}
|
|
})
|
|
|
|
t.Run("Zero Expiration", func(t *testing.T) {
|
|
cache := NewCache()
|
|
key := "test-key"
|
|
value := "test-value"
|
|
|
|
// Set with zero expiration
|
|
cache.Set(key, value, 0)
|
|
|
|
// Should not find the key
|
|
_, found := cache.Get(key)
|
|
if found {
|
|
t.Error("Expected key with zero expiration to be immediately expired")
|
|
}
|
|
})
|
|
|
|
t.Run("Negative Expiration", func(t *testing.T) {
|
|
cache := NewCache()
|
|
key := "test-key"
|
|
value := "test-value"
|
|
|
|
// Set with negative expiration
|
|
cache.Set(key, value, -1*time.Second)
|
|
|
|
// Should not find the key
|
|
_, found := cache.Get(key)
|
|
if found {
|
|
t.Error("Expected key with negative expiration to be immediately expired")
|
|
}
|
|
})
|
|
|
|
t.Run("Update Existing Key", func(t *testing.T) {
|
|
cache := NewCache()
|
|
key := "test-key"
|
|
value1 := "value1"
|
|
value2 := "value2"
|
|
expiration := 1 * time.Second
|
|
|
|
// Set initial value
|
|
cache.Set(key, value1, expiration)
|
|
|
|
// Update value
|
|
cache.Set(key, value2, expiration)
|
|
|
|
// Check updated value
|
|
got, found := cache.Get(key)
|
|
if !found {
|
|
t.Error("Expected to find key in cache")
|
|
}
|
|
if got != value2 {
|
|
t.Errorf("Expected updated value %v, got %v", value2, got)
|
|
}
|
|
})
|
|
|
|
t.Run("Different Value Types", func(t *testing.T) {
|
|
cache := NewCache()
|
|
expiration := 1 * time.Second
|
|
|
|
// Test with different value types
|
|
testCases := []struct {
|
|
key string
|
|
value interface{}
|
|
}{
|
|
{"string", "test"},
|
|
{"int", 42},
|
|
{"float", 3.14},
|
|
{"bool", true},
|
|
{"slice", []string{"a", "b", "c"}},
|
|
{"map", map[string]int{"a": 1, "b": 2}},
|
|
{"struct", struct{ Name string }{"test"}},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.key, func(t *testing.T) {
|
|
cache.Set(tc.key, tc.value, expiration)
|
|
got, found := cache.Get(tc.key)
|
|
if !found {
|
|
t.Error("Expected to find key in cache")
|
|
}
|
|
// Use reflect.DeepEqual for comparing complex types like slices and maps
|
|
if !reflect.DeepEqual(got, tc.value) {
|
|
t.Errorf("Expected value %v, got %v", tc.value, got)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestTokenCache(t *testing.T) {
|
|
t.Run("Basic Operations", func(t *testing.T) {
|
|
tc := NewTokenCache()
|
|
token := "test-token"
|
|
claims := map[string]interface{}{
|
|
"sub": "1234567890",
|
|
"name": "John Doe",
|
|
"admin": true,
|
|
}
|
|
expiration := 1 * time.Second
|
|
|
|
// Test Set and Get
|
|
tc.Set(token, claims, expiration)
|
|
gotClaims, found := tc.Get(token)
|
|
if !found {
|
|
t.Error("Expected to find token in cache")
|
|
}
|
|
if len(gotClaims) != len(claims) {
|
|
t.Errorf("Expected %d claims, got %d", len(claims), len(gotClaims))
|
|
}
|
|
for k, v := range claims {
|
|
if gotClaims[k] != v {
|
|
t.Errorf("Expected claim %s to be %v, got %v", k, v, gotClaims[k])
|
|
}
|
|
}
|
|
|
|
// Test Delete
|
|
tc.Delete(token)
|
|
_, found = tc.Get(token)
|
|
if found {
|
|
t.Error("Expected token to be deleted")
|
|
}
|
|
})
|
|
|
|
t.Run("Expiration", func(t *testing.T) {
|
|
tc := NewTokenCache()
|
|
token := "test-token"
|
|
claims := map[string]interface{}{"sub": "1234567890"}
|
|
expiration := 10 * time.Millisecond
|
|
|
|
// Set with short expiration
|
|
tc.Set(token, claims, expiration)
|
|
|
|
// Wait for expiration
|
|
time.Sleep(20 * time.Millisecond)
|
|
|
|
// Should not find expired token
|
|
_, found := tc.Get(token)
|
|
if found {
|
|
t.Error("Expected token to be expired")
|
|
}
|
|
})
|
|
|
|
t.Run("Cleanup", func(t *testing.T) {
|
|
tc := NewTokenCache()
|
|
|
|
// Add multiple tokens with different expirations
|
|
tc.Set("expired1", map[string]interface{}{"sub": "1"}, 10*time.Millisecond)
|
|
tc.Set("expired2", map[string]interface{}{"sub": "2"}, 10*time.Millisecond)
|
|
tc.Set("valid", map[string]interface{}{"sub": "3"}, 1*time.Second)
|
|
|
|
// Wait for some tokens to expire
|
|
time.Sleep(20 * time.Millisecond)
|
|
|
|
// Run cleanup
|
|
tc.Cleanup()
|
|
|
|
// Check expired tokens are removed
|
|
_, found1 := tc.Get("expired1")
|
|
_, found2 := tc.Get("expired2")
|
|
_, found3 := tc.Get("valid")
|
|
|
|
if found1 {
|
|
t.Error("Expected expired1 to be cleaned up")
|
|
}
|
|
if found2 {
|
|
t.Error("Expected expired2 to be cleaned up")
|
|
}
|
|
if !found3 {
|
|
t.Error("Expected valid token to remain in cache")
|
|
}
|
|
})
|
|
|
|
t.Run("Token Prefix", func(t *testing.T) {
|
|
tc := NewTokenCache()
|
|
token := "test-token"
|
|
claims := map[string]interface{}{"sub": "1234567890"}
|
|
expiration := 1 * time.Second
|
|
|
|
// Set token
|
|
tc.Set(token, claims, expiration)
|
|
|
|
// Verify internal storage uses prefix
|
|
_, found := tc.cache.Get("t-" + token)
|
|
if !found {
|
|
t.Error("Expected to find prefixed token in underlying cache")
|
|
}
|
|
})
|
|
}
|