package security import ( "context" "testing" "time" ) func TestEnhancedRateLimiter(t *testing.T) { config := &RateLimiterConfig{ IPRequestsPerSecond: 5, IPBurstSize: 10, GlobalRequestsPerSecond: 10000, // Set high global limit GlobalBurstSize: 20000, // Set high global burst UserRequestsPerSecond: 1000, // Set high user limit UserBurstSize: 2000, // Set high user burst SlidingWindowEnabled: false, // Disabled for testing basic burst logic SlidingWindowSize: time.Minute, SlidingWindowPrecision: time.Second, AdaptiveEnabled: false, // Disabled for testing basic burst logic AdaptiveAdjustInterval: 100 * time.Millisecond, SystemLoadThreshold: 80.0, BypassDetectionEnabled: true, BypassThreshold: 3, CleanupInterval: time.Minute, BucketTTL: time.Hour, } rl := NewEnhancedRateLimiter(config) defer rl.Stop() ctx := context.Background() headers := make(map[string]string) // Test basic rate limiting for i := 0; i < 3; i++ { result := rl.CheckRateLimitEnhanced(ctx, "127.0.0.1", "test-user", "TestAgent", "test", headers) if !result.Allowed { t.Errorf("Request %d should be allowed, but got: %s - %s", i+1, result.ReasonCode, result.Message) } } // Test burst capacity (should allow up to burst size) // We already made 3 requests, so we can make 7 more before hitting the limit for i := 0; i < 7; i++ { result := rl.CheckRateLimitEnhanced(ctx, "127.0.0.1", "test-user", "TestAgent", "test", headers) if !result.Allowed { t.Errorf("Request %d should be allowed within burst, but got: %s - %s", i+4, result.ReasonCode, result.Message) } } // Now we should exceed the burst limit and be rate limited for i := 0; i < 5; i++ { result := rl.CheckRateLimitEnhanced(ctx, "127.0.0.1", "test-user", "TestAgent", "test", headers) if result.Allowed { t.Errorf("Request %d should be rate limited (exceeded burst)", i+11) } } } func TestSlidingWindow(t *testing.T) { window := NewSlidingWindow(5, time.Minute, time.Second) // Test within limit for i := 0; i < 5; i++ { if !window.IsAllowed() { t.Errorf("Request %d should be allowed", i+1) } } // Test exceeding limit if window.IsAllowed() { t.Error("Request should be denied after exceeding limit") } } func TestBypassDetection(t *testing.T) { detector := NewBypassDetector(3, time.Hour, time.Minute) headers := make(map[string]string) // Test normal behavior result := detector.DetectBypass("127.0.0.1", "TestAgent", headers, false) if result.BypassDetected { t.Error("Normal behavior should not trigger bypass detection") } // Test bypass pattern (multiple rate limit hits) for i := 0; i < 25; i++ { // Increased to trigger MEDIUM severity result = detector.DetectBypass("127.0.0.1", "TestAgent", headers, true) } if !result.BypassDetected { t.Error("Multiple rate limit hits should trigger bypass detection") } if result.Severity != "MEDIUM" && result.Severity != "HIGH" { t.Errorf("Expected MEDIUM or HIGH severity, got %s", result.Severity) } } func TestSystemLoadMonitor(t *testing.T) { monitor := NewSystemLoadMonitor(100 * time.Millisecond) defer monitor.Stop() // Allow some time for monitoring to start time.Sleep(200 * time.Millisecond) cpu, memory, load, goroutines := monitor.GetCurrentLoad() if cpu < 0 || cpu > 100 { t.Errorf("CPU usage should be between 0-100, got %f", cpu) } if memory < 0 || memory > 100 { t.Errorf("Memory usage should be between 0-100, got %f", memory) } if load < 0 { t.Errorf("Load average should be positive, got %f", load) } if goroutines <= 0 { t.Errorf("Goroutine count should be positive, got %d", goroutines) } } func TestEnhancedMetrics(t *testing.T) { config := &RateLimiterConfig{ IPRequestsPerSecond: 10, SlidingWindowEnabled: true, AdaptiveEnabled: true, AdaptiveAdjustInterval: 100 * time.Millisecond, BypassDetectionEnabled: true, CleanupInterval: time.Second, BypassThreshold: 5, BypassDetectionWindow: time.Minute, BypassAlertCooldown: time.Minute, } rl := NewEnhancedRateLimiter(config) defer rl.Stop() metrics := rl.GetEnhancedMetrics() // Check that all expected metrics are present expectedKeys := []string{ "sliding_window_enabled", "adaptive_enabled", "bypass_detection_enabled", "system_cpu_usage", "system_memory_usage", "system_load_average", "system_goroutines", } for _, key := range expectedKeys { if _, exists := metrics[key]; !exists { t.Errorf("Expected metric %s not found", key) } } // Verify boolean flags if metrics["sliding_window_enabled"] != true { t.Error("sliding_window_enabled should be true") } if metrics["adaptive_enabled"] != true { t.Error("adaptive_enabled should be true") } if metrics["bypass_detection_enabled"] != true { t.Error("bypass_detection_enabled should be true") } }