mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-06-05 22:44:17 +00:00
ae59a5e88a
* Add ability to disable replay protection. - This is useful for runs with multiple traefik replicas to avoid false positives and tokens re-creation. * Enhance the CI/CD pipelines * Increase test coverage. * Update vendored dependencies. * Update behaviour on forceHTTPS as per issue #82
226 lines
5.4 KiB
Go
226 lines
5.4 KiB
Go
package traefikoidc
|
|
|
|
import (
|
|
"net/http"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestNewLazyBackgroundTaskUnit tests LazyBackgroundTask creation without leak detection
|
|
func TestNewLazyBackgroundTaskUnit(t *testing.T) {
|
|
logger := GetSingletonNoOpLogger()
|
|
callCount := 0
|
|
taskFunc := func() {
|
|
callCount++
|
|
}
|
|
|
|
task := NewLazyBackgroundTask("test-task", 50*time.Millisecond, taskFunc, logger)
|
|
|
|
require.NotNil(t, task)
|
|
assert.NotNil(t, task.BackgroundTask)
|
|
assert.False(t, task.started)
|
|
|
|
// Should not execute before StartIfNeeded
|
|
time.Sleep(100 * time.Millisecond)
|
|
assert.Equal(t, 0, callCount, "task should not execute before StartIfNeeded")
|
|
|
|
// Cleanup
|
|
if task.started {
|
|
task.Stop()
|
|
}
|
|
}
|
|
|
|
// TestLazyBackgroundTaskStartIfNeededUnit tests the StartIfNeeded method
|
|
func TestLazyBackgroundTaskStartIfNeededUnit(t *testing.T) {
|
|
logger := GetSingletonNoOpLogger()
|
|
callCount := 0
|
|
var mu sync.Mutex
|
|
taskFunc := func() {
|
|
mu.Lock()
|
|
callCount++
|
|
mu.Unlock()
|
|
}
|
|
|
|
task := NewLazyBackgroundTask("test-start", 30*time.Millisecond, taskFunc, logger)
|
|
require.NotNil(t, task)
|
|
|
|
// Start the task
|
|
task.StartIfNeeded()
|
|
assert.True(t, task.started)
|
|
|
|
// Wait for execution
|
|
time.Sleep(100 * time.Millisecond)
|
|
mu.Lock()
|
|
firstCount := callCount
|
|
mu.Unlock()
|
|
assert.Greater(t, firstCount, 0, "task should execute after StartIfNeeded")
|
|
|
|
// Multiple calls should be idempotent
|
|
task.StartIfNeeded()
|
|
task.StartIfNeeded()
|
|
|
|
// Cleanup
|
|
task.Stop()
|
|
}
|
|
|
|
// TestLazyBackgroundTaskStopUnit tests the Stop method
|
|
func TestLazyBackgroundTaskStopUnit(t *testing.T) {
|
|
logger := GetSingletonNoOpLogger()
|
|
callCount := 0
|
|
var mu sync.Mutex
|
|
taskFunc := func() {
|
|
mu.Lock()
|
|
callCount++
|
|
mu.Unlock()
|
|
}
|
|
|
|
task := NewLazyBackgroundTask("test-stop", 30*time.Millisecond, taskFunc, logger)
|
|
require.NotNil(t, task)
|
|
|
|
// Start and let it run
|
|
task.StartIfNeeded()
|
|
time.Sleep(100 * time.Millisecond)
|
|
mu.Lock()
|
|
countAfterStart := callCount
|
|
mu.Unlock()
|
|
assert.Greater(t, countAfterStart, 0)
|
|
|
|
// Stop the task
|
|
task.Stop()
|
|
assert.False(t, task.started)
|
|
|
|
// Wait and verify it stopped
|
|
time.Sleep(100 * time.Millisecond)
|
|
mu.Lock()
|
|
countAfterStop := callCount
|
|
mu.Unlock()
|
|
|
|
// Allow 1 in-flight execution
|
|
assert.LessOrEqual(t, countAfterStop, countAfterStart+1, "task should stop executing")
|
|
}
|
|
|
|
// TestNewLazyCacheUnit tests NewLazyCache creation
|
|
func TestNewLazyCacheUnit(t *testing.T) {
|
|
cache := NewLazyCache()
|
|
|
|
require.NotNil(t, cache)
|
|
|
|
// Test basic operations
|
|
cache.Set("test-key", "test-value", time.Minute)
|
|
val, found := cache.Get("test-key")
|
|
|
|
assert.True(t, found)
|
|
assert.Equal(t, "test-value", val)
|
|
}
|
|
|
|
// TestNewLazyCacheWithLoggerUnit tests NewLazyCacheWithLogger creation
|
|
func TestNewLazyCacheWithLoggerUnit(t *testing.T) {
|
|
logger := GetSingletonNoOpLogger()
|
|
cache := NewLazyCacheWithLogger(logger)
|
|
|
|
require.NotNil(t, cache)
|
|
|
|
// Test with multiple entries
|
|
for i := 0; i < 10; i++ {
|
|
key := "key-" + string(rune('0'+i))
|
|
cache.Set(key, i, time.Minute)
|
|
}
|
|
|
|
// Verify entries
|
|
for i := 0; i < 10; i++ {
|
|
key := "key-" + string(rune('0'+i))
|
|
val, found := cache.Get(key)
|
|
assert.True(t, found, "should find key %s", key)
|
|
assert.Equal(t, i, val, "should get correct value for key %s", key)
|
|
}
|
|
}
|
|
|
|
// TestNewLazyCacheWithLoggerNilUnit tests NewLazyCacheWithLogger with nil logger
|
|
func TestNewLazyCacheWithLoggerNilUnit(t *testing.T) {
|
|
cache := NewLazyCacheWithLogger(nil)
|
|
|
|
require.NotNil(t, cache)
|
|
|
|
// Should work with nil logger (uses no-op logger)
|
|
cache.Set("nil-test", "value", time.Minute)
|
|
val, found := cache.Get("nil-test")
|
|
|
|
assert.True(t, found)
|
|
assert.Equal(t, "value", val)
|
|
}
|
|
|
|
// TestCleanupIdleConnectionsUnit tests CleanupIdleConnections function
|
|
func TestCleanupIdleConnectionsUnit(t *testing.T) {
|
|
t.Run("basic cleanup cycle", func(t *testing.T) {
|
|
client := &http.Client{
|
|
Transport: &http.Transport{
|
|
MaxIdleConns: 10,
|
|
IdleConnTimeout: 30 * time.Second,
|
|
DisableCompression: true,
|
|
},
|
|
}
|
|
|
|
stopChan := make(chan struct{})
|
|
|
|
// Start cleanup in background
|
|
go CleanupIdleConnections(client, 40*time.Millisecond, stopChan)
|
|
|
|
// Let it run a couple of cycles
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
// Stop cleanup
|
|
close(stopChan)
|
|
|
|
// Wait for cleanup to finish
|
|
time.Sleep(50 * time.Millisecond)
|
|
})
|
|
|
|
t.Run("immediate stop", func(t *testing.T) {
|
|
client := &http.Client{
|
|
Transport: &http.Transport{
|
|
MaxIdleConns: 10,
|
|
IdleConnTimeout: 30 * time.Second,
|
|
},
|
|
}
|
|
|
|
stopChan := make(chan struct{})
|
|
|
|
// Start and immediately stop
|
|
go CleanupIdleConnections(client, 100*time.Millisecond, stopChan)
|
|
time.Sleep(10 * time.Millisecond)
|
|
close(stopChan)
|
|
|
|
// Wait for cleanup
|
|
time.Sleep(50 * time.Millisecond)
|
|
})
|
|
|
|
t.Run("nil transport", func(t *testing.T) {
|
|
client := &http.Client{
|
|
Transport: nil,
|
|
}
|
|
|
|
stopChan := make(chan struct{})
|
|
|
|
// Should handle gracefully
|
|
go CleanupIdleConnections(client, 40*time.Millisecond, stopChan)
|
|
time.Sleep(80 * time.Millisecond)
|
|
close(stopChan)
|
|
time.Sleep(50 * time.Millisecond)
|
|
})
|
|
}
|
|
|
|
// TestDefaultOptimizedConfigUnit tests DefaultOptimizedConfig function (already has 100% coverage)
|
|
func TestDefaultOptimizedConfigUnit(t *testing.T) {
|
|
config := DefaultOptimizedConfig()
|
|
|
|
require.NotNil(t, config)
|
|
assert.True(t, config.DelayBackgroundTasks)
|
|
assert.True(t, config.ReducedCleanupIntervals)
|
|
assert.True(t, config.AggressiveConnectionCleanup)
|
|
assert.True(t, config.MinimalCacheSize)
|
|
}
|