starlog/rotating_sink_test.go
2026-03-19 16:37:57 +08:00

97 lines
2.7 KiB
Go

package starlog
import (
"errors"
"path/filepath"
"strings"
"testing"
"time"
)
func waitForRotate(t *testing.T, timeout time.Duration, cond func() bool, reason string) {
t.Helper()
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
if cond() {
return
}
time.Sleep(10 * time.Millisecond)
}
t.Fatalf("timeout waiting for condition: %s", reason)
}
func TestNewRotatePolicySinkNilPolicy(t *testing.T) {
sink, err := NewRotatePolicySink(filepath.Join(testBinDir(t), "a.log"), true, nil, time.Second)
if err == nil {
t.Fatalf("expected error for nil rotate policy")
}
if sink != nil {
t.Fatalf("sink should be nil when create fails")
}
}
func TestManagedRotateBySizeSinkCreatesBackups(t *testing.T) {
path := filepath.Join(testBinDir(t), "route.log")
sink, err := NewManagedRotateBySizeSink(path, true, 64, 5*time.Millisecond, RotateManageOptions{
MaxBackups: 10,
Pattern: "route.*.log",
})
if err != nil {
t.Fatalf("create sink failed: %v", err)
}
defer sink.Close()
for idx := 0; idx < 40; idx++ {
if err = sink.Write([]byte(strings.Repeat("x", 16))); err != nil {
t.Fatalf("sink write failed: %v", err)
}
time.Sleep(3 * time.Millisecond)
}
waitForRotate(t, 2*time.Second, func() bool {
matches, _ := filepath.Glob(filepath.Join(filepath.Dir(path), "route.*.log"))
return len(matches) > 0
}, "rotating sink backups")
}
func TestRotatingFileSinkClose(t *testing.T) {
path := filepath.Join(testBinDir(t), "close.log")
sink, err := NewRotateBySizeSink(path, true, 1024, time.Second)
if err != nil {
t.Fatalf("create sink failed: %v", err)
}
if err = sink.Close(); err != nil {
t.Fatalf("close failed: %v", err)
}
if err = sink.Write([]byte("after-close")); !errors.Is(err, ErrRotatingFileSinkClosed) {
t.Fatalf("write after close should return ErrRotatingFileSinkClosed, got %v", err)
}
}
func TestRotatingFileSinkPrefersArchivePathProvider(t *testing.T) {
path := filepath.Join(testBinDir(t), "sink_provider.log")
sink, err := NewRotatePolicySink(path, true, &rotatePreferArchivePathPolicy{}, 5*time.Millisecond)
if err != nil {
t.Fatalf("create sink failed: %v", err)
}
defer sink.Close()
if err = sink.Write([]byte("first")); err != nil {
t.Fatalf("first write failed: %v", err)
}
time.Sleep(10 * time.Millisecond)
if err = sink.Write([]byte("second")); err != nil {
t.Fatalf("second write failed: %v", err)
}
waitForRotate(t, 2*time.Second, func() bool {
matches, _ := filepath.Glob(path + ".*.archive.bak")
return len(matches) > 0
}, "rotating sink archive path provider")
nextMatches, _ := filepath.Glob(path + ".*.next.bak")
if len(nextMatches) > 0 {
t.Fatalf("rotating sink should not use NextPath when ArchivePath is available")
}
}