Files
agents_and_robots/shell/logger/cleanup_test.go
T
egutierrez 71079962ca feat: add structured JSONL logging package with rotation and query
Nuevo paquete shell/logger/ que implementa logging estructurado JSONL
para agentes. Incluye DailyRotatingWriter con rotación diaria y por
tamaño (50MB default), limpieza automática de archivos viejos (7 días),
compresión gzip de logs rotados, y funciones de consulta (ReadLogs,
SearchLogs, ListAgents, ListDates) para que agentes LLM puedan leer
logs de otros agentes. Basado en log/slog de stdlib, sin dependencias
externas. 18 tests unitarios cubren rotación, concurrencia y consultas.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:26:56 +00:00

111 lines
2.4 KiB
Go

package logger
import (
"context"
"os"
"path/filepath"
"testing"
"time"
)
func TestCleanOldLogs(t *testing.T) {
dir := t.TempDir()
agentDir := filepath.Join(dir, "bot1")
os.MkdirAll(agentDir, 0o755)
// Create files: 10 days ago, 5 days ago, today.
files := []string{
"2026-02-24.jsonl",
"2026-02-24.jsonl.gz",
"2026-03-01.jsonl",
"2026-03-06.jsonl",
}
for _, f := range files {
os.WriteFile(filepath.Join(agentDir, f), []byte("{}"), 0o644)
}
// Retain 7 days → should remove 2026-02-24 files.
cleanOldLogs(dir, "bot1", 7)
remaining, _ := os.ReadDir(agentDir)
names := make(map[string]bool)
for _, e := range remaining {
names[e.Name()] = true
}
if names["2026-02-24.jsonl"] {
t.Error("2026-02-24.jsonl should have been removed")
}
if names["2026-02-24.jsonl.gz"] {
t.Error("2026-02-24.jsonl.gz should have been removed")
}
if !names["2026-03-01.jsonl"] {
t.Error("2026-03-01.jsonl should still exist")
}
if !names["2026-03-06.jsonl"] {
t.Error("2026-03-06.jsonl should still exist")
}
}
func TestParseDateFromFilename(t *testing.T) {
tests := []struct {
name string
want string
}{
{"2026-03-06.jsonl", "2026-03-06"},
{"2026-03-06.1.jsonl", "2026-03-06"},
{"2026-03-06.jsonl.gz", "2026-03-06"},
{"2026-03-06.2.jsonl.gz", "2026-03-06"},
{"invalid.jsonl", ""},
}
for _, tt := range tests {
d := parseDateFromFilename(tt.name)
got := ""
if !d.IsZero() {
got = d.Format("2006-01-02")
}
if got != tt.want {
t.Errorf("parseDateFromFilename(%q) = %q, want %q", tt.name, got, tt.want)
}
}
}
func TestCleanOldLogs_EmptyDir(t *testing.T) {
dir := t.TempDir()
// Should not panic on non-existent agent dir.
cleanOldLogs(dir, "nonexistent", 7)
}
func TestIsLogFile(t *testing.T) {
if !isLogFile("2026-03-06.jsonl") {
t.Error("should match .jsonl")
}
if !isLogFile("2026-03-06.jsonl.gz") {
t.Error("should match .jsonl.gz")
}
if isLogFile("readme.txt") {
t.Error("should not match .txt")
}
}
func TestRunCleanup_Cancellation(t *testing.T) {
dir := t.TempDir()
os.MkdirAll(filepath.Join(dir, "bot1"), 0o755)
ctx, cancel := context.WithCancel(context.Background())
done := make(chan struct{})
go func() {
runCleanup(ctx, dir, "bot1", 7, 50*time.Millisecond)
close(done)
}()
time.Sleep(150 * time.Millisecond)
cancel()
select {
case <-done:
case <-time.After(2 * time.Second):
t.Error("cleanup goroutine did not exit after cancel")
}
}