mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-10-18 04:47:28 +00:00
fixup! fixup! fixup! fixup! Further pursue of perfection.
This commit is contained in:
@@ -0,0 +1,310 @@
|
||||
package traefikoidc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// SimpleMemoryTestSuite provides focused memory verification tests using unified infrastructure
|
||||
type SimpleMemoryTestSuite struct {
|
||||
runner *TestSuiteRunner
|
||||
factory *TestDataFactory
|
||||
edgeGen *EdgeCaseGenerator
|
||||
perfTest *PerformanceTestHelper
|
||||
logger *Logger
|
||||
}
|
||||
|
||||
// NewSimpleMemoryTestSuite creates a new test suite for simple memory verification
|
||||
func NewSimpleMemoryTestSuite() *SimpleMemoryTestSuite {
|
||||
return &SimpleMemoryTestSuite{
|
||||
runner: NewTestSuiteRunner(),
|
||||
factory: NewTestDataFactory(),
|
||||
edgeGen: NewEdgeCaseGenerator(),
|
||||
perfTest: NewPerformanceTestHelper(),
|
||||
logger: GetSingletonNoOpLogger(),
|
||||
}
|
||||
}
|
||||
|
||||
// TestSimpleCacheOperations verifies basic cache operations using table-driven tests
|
||||
func TestSimpleCacheOperations(t *testing.T) {
|
||||
config := GetTestConfig()
|
||||
if config.ShouldSkipTest(t, TestTypeQuick) {
|
||||
return
|
||||
}
|
||||
|
||||
suite := NewSimpleMemoryTestSuite()
|
||||
|
||||
tests := []MemoryLeakTestCase{
|
||||
{
|
||||
Name: "Basic cache creation and cleanup",
|
||||
Description: "Verify cache can be created, used briefly, and cleaned up without leaks",
|
||||
Operation: func() error {
|
||||
cache := NewOptimizedCache()
|
||||
if cache == nil {
|
||||
return fmt.Errorf("cache creation failed")
|
||||
}
|
||||
|
||||
// Use the cache briefly
|
||||
cache.Set("test", "value", time.Minute)
|
||||
val, found := cache.Get("test")
|
||||
if !found {
|
||||
return fmt.Errorf("cache get failed: key not found")
|
||||
}
|
||||
if val != "value" {
|
||||
return fmt.Errorf("cache get failed: expected 'value', got %v", val)
|
||||
}
|
||||
|
||||
// Close immediately
|
||||
cache.Close()
|
||||
|
||||
// Brief wait for cleanup
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
return nil
|
||||
},
|
||||
Iterations: 3,
|
||||
MaxGoroutineGrowth: 2, // Allow minimal framework overhead
|
||||
MaxMemoryGrowthMB: 0.5, // Very strict for simple operations
|
||||
GCBetweenRuns: true,
|
||||
Timeout: 5 * time.Second,
|
||||
},
|
||||
{
|
||||
Name: "Cache with multiple quick operations",
|
||||
Description: "Test cache with rapid set/get operations",
|
||||
Operation: func() error {
|
||||
cache := NewOptimizedCache()
|
||||
defer cache.Close()
|
||||
|
||||
// Perform multiple quick operations
|
||||
for i := 0; i < 10; i++ {
|
||||
key := fmt.Sprintf("key-%d", i)
|
||||
value := fmt.Sprintf("value-%d", i)
|
||||
cache.Set(key, value, time.Minute)
|
||||
|
||||
val, found := cache.Get(key)
|
||||
if !found {
|
||||
return fmt.Errorf("cache get failed for key %s", key)
|
||||
}
|
||||
if val != value {
|
||||
return fmt.Errorf("cache value mismatch for key %s: expected %s, got %v", key, value, val)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Iterations: 5,
|
||||
MaxGoroutineGrowth: 2,
|
||||
MaxMemoryGrowthMB: 1.0,
|
||||
GCBetweenRuns: true,
|
||||
Timeout: 8 * time.Second,
|
||||
},
|
||||
{
|
||||
Name: "Cache with edge case values",
|
||||
Description: "Test cache with edge case string values",
|
||||
Operation: func() error {
|
||||
cache := NewOptimizedCache()
|
||||
defer cache.Close()
|
||||
|
||||
// Test with edge case strings from the generator
|
||||
edgeCases := suite.edgeGen.GenerateStringEdgeCases()
|
||||
for i, value := range edgeCases[:5] { // Limit to first 5 for simplicity
|
||||
key := fmt.Sprintf("edge-key-%d", i)
|
||||
cache.Set(key, value, time.Minute)
|
||||
|
||||
val, found := cache.Get(key)
|
||||
if !found {
|
||||
return fmt.Errorf("cache get failed for edge case key %s", key)
|
||||
}
|
||||
if val != value {
|
||||
return fmt.Errorf("cache value mismatch for edge case key %s", key)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Iterations: 3,
|
||||
MaxGoroutineGrowth: 2,
|
||||
MaxMemoryGrowthMB: 1.0,
|
||||
GCBetweenRuns: true,
|
||||
Timeout: 10 * time.Second,
|
||||
},
|
||||
}
|
||||
|
||||
suite.runner.RunMemoryLeakTests(t, tests)
|
||||
}
|
||||
|
||||
// TestChunkManagerInitialization verifies chunk manager initialization using table-driven tests
|
||||
func TestChunkManagerInitialization(t *testing.T) {
|
||||
suite := NewSimpleMemoryTestSuite()
|
||||
|
||||
tests := []TableTestCase{
|
||||
{
|
||||
Name: "Basic chunk manager creation",
|
||||
Description: "Verify chunk manager can be created with proper defaults",
|
||||
Input: nil, // No specific input needed
|
||||
Expected: map[string]interface{}{
|
||||
"maxSessions": 1000,
|
||||
"sessionTTL": 24 * time.Hour,
|
||||
"notNil": true,
|
||||
},
|
||||
Timeout: 5 * time.Second,
|
||||
Setup: func(t *testing.T) error {
|
||||
// No setup needed
|
||||
return nil
|
||||
},
|
||||
Teardown: func(t *testing.T) error {
|
||||
// No teardown needed
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "Chunk manager with logger verification",
|
||||
Description: "Verify chunk manager works correctly with singleton logger",
|
||||
Input: "singleton_logger",
|
||||
Expected: map[string]interface{}{
|
||||
"hasLogger": true,
|
||||
"maxSessions": 1000,
|
||||
"sessionTTL": 24 * time.Hour,
|
||||
},
|
||||
Timeout: 5 * time.Second,
|
||||
},
|
||||
}
|
||||
|
||||
// Custom test execution since TableTestCase doesn't have built-in logic
|
||||
for _, test := range tests {
|
||||
test := test // Capture loop variable
|
||||
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
if test.Setup != nil {
|
||||
require.NoError(t, test.Setup(t))
|
||||
}
|
||||
|
||||
if test.Teardown != nil {
|
||||
defer func() {
|
||||
require.NoError(t, test.Teardown(t))
|
||||
}()
|
||||
}
|
||||
|
||||
// Execute the actual test logic
|
||||
logger := suite.logger
|
||||
cm := NewChunkManager(logger)
|
||||
|
||||
// Verify basic properties
|
||||
assert.NotNil(t, cm, "Chunk manager should not be nil")
|
||||
assert.NotNil(t, cm.sessionMap, "Session map should not be nil")
|
||||
|
||||
// Verify expected values from test case
|
||||
expected := test.Expected.(map[string]interface{})
|
||||
assert.Equal(t, expected["maxSessions"], cm.maxSessions, "Max sessions should match expected value")
|
||||
assert.Equal(t, expected["sessionTTL"], cm.sessionTTL, "Session TTL should match expected value")
|
||||
|
||||
if hasLogger, exists := expected["hasLogger"]; exists && hasLogger.(bool) {
|
||||
assert.NotNil(t, logger, "Logger should not be nil when expected")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestSimpleMemoryLeakDetection provides memory leak detection using the infrastructure
|
||||
func TestSimpleMemoryLeakDetection(t *testing.T) {
|
||||
suite := NewSimpleMemoryTestSuite()
|
||||
|
||||
tests := []MemoryLeakTestCase{
|
||||
{
|
||||
Name: "Repeated cache creation and destruction",
|
||||
Description: "Verify no leaks from repeated cache lifecycle",
|
||||
Operation: func() error {
|
||||
cache := NewOptimizedCache()
|
||||
cache.Set("test", "value", 100*time.Millisecond)
|
||||
_, _ = cache.Get("test")
|
||||
cache.Close()
|
||||
|
||||
// Small delay to allow cleanup
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
return nil
|
||||
},
|
||||
Iterations: 20,
|
||||
MaxGoroutineGrowth: 3, // Slightly more tolerance for repeated operations
|
||||
MaxMemoryGrowthMB: 2.0, // Allow for some accumulation over iterations
|
||||
GCBetweenRuns: true,
|
||||
Timeout: 15 * time.Second,
|
||||
},
|
||||
{
|
||||
Name: "Chunk manager creation cycles",
|
||||
Description: "Verify no leaks from chunk manager creation",
|
||||
Operation: func() error {
|
||||
logger := suite.logger
|
||||
cm := NewChunkManager(logger)
|
||||
|
||||
// Verify it was created properly
|
||||
if cm == nil {
|
||||
return fmt.Errorf("chunk manager creation failed")
|
||||
}
|
||||
|
||||
if cm.sessionMap == nil {
|
||||
return fmt.Errorf("chunk manager session map not initialized")
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Iterations: 15,
|
||||
MaxGoroutineGrowth: 2,
|
||||
MaxMemoryGrowthMB: 1.0,
|
||||
GCBetweenRuns: true,
|
||||
Timeout: 10 * time.Second,
|
||||
},
|
||||
}
|
||||
|
||||
suite.runner.RunMemoryLeakTests(t, tests)
|
||||
}
|
||||
|
||||
// BenchmarkSimpleCacheOperations provides basic performance benchmarks
|
||||
func BenchmarkSimpleCacheOperations(b *testing.B) {
|
||||
cache := NewOptimizedCache()
|
||||
defer cache.Close()
|
||||
|
||||
b.Run("Set operations", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
key := fmt.Sprintf("bench-key-%d", i)
|
||||
cache.Set(key, "benchmark-value", time.Minute)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("Get operations", func(b *testing.B) {
|
||||
// Pre-populate cache
|
||||
for i := 0; i < 1000; i++ {
|
||||
key := fmt.Sprintf("bench-key-%d", i)
|
||||
cache.Set(key, "benchmark-value", time.Minute)
|
||||
}
|
||||
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
key := fmt.Sprintf("bench-key-%d", i%1000)
|
||||
cache.Get(key)
|
||||
}
|
||||
})
|
||||
|
||||
b.Run("Set and Get combined", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
key := fmt.Sprintf("bench-key-%d", i)
|
||||
cache.Set(key, "benchmark-value", time.Minute)
|
||||
cache.Get(key)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// BenchmarkChunkManagerCreation provides benchmarks for chunk manager operations
|
||||
func BenchmarkChunkManagerCreation(b *testing.B) {
|
||||
logger := GetSingletonNoOpLogger()
|
||||
|
||||
b.Run("Chunk manager creation", func(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
cm := NewChunkManager(logger)
|
||||
_ = cm // Avoid compiler optimization
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user