215 lines
5.0 KiB
Go
215 lines
5.0 KiB
Go
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)
|
|
}
|
|
}
|