package logger import ( "bytes" "strings" "sync" "testing" "time" ) func TestLoggerLevels(t *testing.T) { var buf bytes.Buffer logger := New(LevelInfo, false) logger.SetOutput(&buf) // Debug should be below threshold logger.Debug("This should not appear") if buf.Len() > 0 { t.Error("Debug message appeared when it should be filtered") } // Info and above should appear logger.Info("Info message") if !strings.Contains(buf.String(), "INFO") { t.Errorf("Info message not logged, got: %q", buf.String()) } buf.Reset() logger.Warning("Warning message") if !strings.Contains(buf.String(), "WARN") { t.Errorf("Warning message not logged, got: %q", buf.String()) } buf.Reset() logger.Error("Error message") if !strings.Contains(buf.String(), "ERROR") { t.Errorf("Error message not logged, got: %q", buf.String()) } buf.Reset() // Test format strings logger.Info("Count: %d", 42) if !strings.Contains(buf.String(), "Count: 42") { t.Errorf("Formatted message not logged correctly, got: %q", buf.String()) } buf.Reset() // Test changing level logger.SetLevel(LevelError) logger.Info("This should not appear") logger.Warning("This should not appear") if buf.Len() > 0 { t.Error("Messages below threshold appeared") } logger.Error("Error should appear") if !strings.Contains(buf.String(), "ERROR") { t.Errorf("Error message not logged after level change, got: %q", buf.String()) } } func TestLoggerRateLimit(t *testing.T) { var buf bytes.Buffer logger := New(LevelDebug, false) logger.SetOutput(&buf) // Override max logs per second to something small for testing logger.maxLogsPerSec = 5 logger.limitDuration = 1 * time.Second // Send debug messages (should get limited) for i := 0; i < 20; i++ { logger.Debug("Debug message %d", i) } // Error messages should always go through logger.Error("Error message should appear") content := buf.String() // We should see some debug messages, then a warning about rate limiting, // and finally the error message if !strings.Contains(content, "Debug message 0") { t.Error("First debug message should appear") } if !strings.Contains(content, "Rate limiting logger") { t.Error("Rate limiting message should appear") } if !strings.Contains(content, "ERROR") { t.Error("Error message should always appear despite rate limiting") } } func TestLoggerConcurrency(t *testing.T) { var buf bytes.Buffer logger := New(LevelDebug, false) logger.SetOutput(&buf) // Increase log threshold for this test logger.maxLogsPerSec = 1000 // Log a bunch of messages concurrently var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func(n int) { defer wg.Done() logger.Info("Concurrent message %d", n) }(i) } wg.Wait() // Check logs were processed content := buf.String() if !strings.Contains(content, "Concurrent message") { t.Error("Concurrent messages should appear") } } func TestLoggerColors(t *testing.T) { var buf bytes.Buffer logger := New(LevelInfo, true) logger.SetOutput(&buf) // Test with color logger.Info("Colored message") content := buf.String() t.Logf("Colored output: %q", content) // Print actual output for diagnosis if !strings.Contains(content, "\033[") { t.Errorf("Color codes not present when enabled, got: %q", content) } buf.Reset() logger.DisableColors() logger.Info("Non-colored message") content = buf.String() if strings.Contains(content, "\033[") { t.Errorf("Color codes present when disabled, got: %q", content) } } func TestDefaultLogger(t *testing.T) { var buf bytes.Buffer SetOutput(&buf) Info("Test default logger") content := buf.String() if !strings.Contains(content, "INFO") { t.Errorf("Default logger not working, got: %q", content) } } func BenchmarkLogger(b *testing.B) { var buf bytes.Buffer logger := New(LevelInfo, false) logger.SetOutput(&buf) // Set very high threshold to avoid rate limiting during benchmark logger.maxLogsPerSec = int64(b.N + 1) b.ResetTimer() for i := 0; i < b.N; i++ { logger.Info("Benchmark message %d", i) } } func BenchmarkLoggerWithRateLimit(b *testing.B) { var buf bytes.Buffer logger := New(LevelDebug, false) logger.SetOutput(&buf) // Set threshold to allow about 10% of messages through logger.maxLogsPerSec = int64(b.N / 10) b.ResetTimer() for i := 0; i < b.N; i++ { logger.Debug("Benchmark message %d", i) } } func BenchmarkLoggerParallel(b *testing.B) { var buf bytes.Buffer logger := New(LevelDebug, false) logger.SetOutput(&buf) // Set very high threshold to avoid rate limiting during benchmark logger.maxLogsPerSec = int64(b.N + 1) b.ResetTimer() b.RunParallel(func(pb *testing.PB) { i := 0 for pb.Next() { logger.Debug("Parallel benchmark message %d", i) i++ } }) } func BenchmarkProductionLevels(b *testing.B) { var buf bytes.Buffer logger := New(LevelWarning, false) // Only log warnings and above logger.SetOutput(&buf) b.ResetTimer() for i := 0; i < b.N; i++ { // This should be filtered out before any processing logger.Debug("Debug message that won't be logged %d", i) } }