Files
at-container-registry/pkg/auth/cache_test.go

196 lines
5.0 KiB
Go

package auth
import (
"testing"
"time"
)
func TestGetServiceToken_NotCached(t *testing.T) {
// Clear cache first
globalServiceTokensMu.Lock()
globalServiceTokens = make(map[string]*serviceTokenEntry)
globalServiceTokensMu.Unlock()
did := "did:plc:test123"
holdDID := "did:web:hold.example.com"
token, expiresAt := GetServiceToken(did, holdDID)
if token != "" {
t.Errorf("Expected empty token for uncached entry, got %q", token)
}
if !expiresAt.IsZero() {
t.Error("Expected zero time for uncached entry")
}
}
func TestSetServiceToken_ManualExpiry(t *testing.T) {
// Clear cache first
globalServiceTokensMu.Lock()
globalServiceTokens = make(map[string]*serviceTokenEntry)
globalServiceTokensMu.Unlock()
did := "did:plc:test123"
holdDID := "did:web:hold.example.com"
token := "invalid_jwt_token" // Will fall back to 50s default
// This should succeed with default 50s TTL since JWT parsing will fail
err := SetServiceToken(did, holdDID, token)
if err != nil {
t.Fatalf("SetServiceToken() error = %v", err)
}
// Verify token was cached
cachedToken, expiresAt := GetServiceToken(did, holdDID)
if cachedToken != token {
t.Errorf("Expected token %q, got %q", token, cachedToken)
}
if expiresAt.IsZero() {
t.Error("Expected non-zero expiry time")
}
// Expiry should be approximately 50s from now (with 10s margin subtracted in some cases)
expectedExpiry := time.Now().Add(50 * time.Second)
diff := expiresAt.Sub(expectedExpiry)
if diff < -5*time.Second || diff > 5*time.Second {
t.Errorf("Expiry time off by %v (expected ~50s from now)", diff)
}
}
func TestGetServiceToken_Expired(t *testing.T) {
// Manually insert an expired token
did := "did:plc:test123"
holdDID := "did:web:hold.example.com"
cacheKey := did + ":" + holdDID
globalServiceTokensMu.Lock()
globalServiceTokens[cacheKey] = &serviceTokenEntry{
token: "expired_token",
expiresAt: time.Now().Add(-1 * time.Hour), // 1 hour ago
}
globalServiceTokensMu.Unlock()
// Try to get - should return empty since expired
token, expiresAt := GetServiceToken(did, holdDID)
if token != "" {
t.Errorf("Expected empty token for expired entry, got %q", token)
}
if !expiresAt.IsZero() {
t.Error("Expected zero time for expired entry")
}
// Verify token was removed from cache
globalServiceTokensMu.RLock()
_, exists := globalServiceTokens[cacheKey]
globalServiceTokensMu.RUnlock()
if exists {
t.Error("Expected expired token to be removed from cache")
}
}
func TestInvalidateServiceToken(t *testing.T) {
// Set a token
did := "did:plc:test123"
holdDID := "did:web:hold.example.com"
token := "test_token"
err := SetServiceToken(did, holdDID, token)
if err != nil {
t.Fatalf("SetServiceToken() error = %v", err)
}
// Verify it's cached
cachedToken, _ := GetServiceToken(did, holdDID)
if cachedToken != token {
t.Fatal("Token should be cached")
}
// Invalidate
InvalidateServiceToken(did, holdDID)
// Verify it's gone
cachedToken, _ = GetServiceToken(did, holdDID)
if cachedToken != "" {
t.Error("Expected token to be invalidated")
}
}
func TestCleanExpiredTokens(t *testing.T) {
// Clear cache first
globalServiceTokensMu.Lock()
globalServiceTokens = make(map[string]*serviceTokenEntry)
globalServiceTokensMu.Unlock()
// Add expired and valid tokens
globalServiceTokensMu.Lock()
globalServiceTokens["expired:hold1"] = &serviceTokenEntry{
token: "expired1",
expiresAt: time.Now().Add(-1 * time.Hour),
}
globalServiceTokens["valid:hold2"] = &serviceTokenEntry{
token: "valid1",
expiresAt: time.Now().Add(1 * time.Hour),
}
globalServiceTokensMu.Unlock()
// Clean expired
CleanExpiredTokens()
// Verify only valid token remains
globalServiceTokensMu.RLock()
_, expiredExists := globalServiceTokens["expired:hold1"]
_, validExists := globalServiceTokens["valid:hold2"]
globalServiceTokensMu.RUnlock()
if expiredExists {
t.Error("Expected expired token to be removed")
}
if !validExists {
t.Error("Expected valid token to remain")
}
}
func TestGetCacheStats(t *testing.T) {
// Clear cache first
globalServiceTokensMu.Lock()
globalServiceTokens = make(map[string]*serviceTokenEntry)
globalServiceTokensMu.Unlock()
// Add some tokens
globalServiceTokensMu.Lock()
globalServiceTokens["did1:hold1"] = &serviceTokenEntry{
token: "token1",
expiresAt: time.Now().Add(1 * time.Hour),
}
globalServiceTokens["did2:hold2"] = &serviceTokenEntry{
token: "token2",
expiresAt: time.Now().Add(1 * time.Hour),
}
globalServiceTokensMu.Unlock()
stats := GetCacheStats()
if stats == nil {
t.Fatal("Expected non-nil stats")
}
// GetCacheStats returns map[string]any with "total_entries" key
totalEntries, ok := stats["total_entries"].(int)
if !ok {
t.Fatalf("Expected total_entries in stats map, got: %v", stats)
}
if totalEntries != 2 {
t.Errorf("Expected 2 entries, got %d", totalEntries)
}
// Also check valid_tokens
validTokens, ok := stats["valid_tokens"].(int)
if !ok {
t.Fatal("Expected valid_tokens in stats map")
}
if validTokens != 2 {
t.Errorf("Expected 2 valid tokens, got %d", validTokens)
}
}