Files
3x-ui/internal/logger/logger_test.go
T
MHSanaei 249b38e156 fix(logger): reuse the open log rotator when InitLogger runs again
Every InitLogger call built a new lumberjack rotator and dropped the old
one without closing it, leaking a handle on 3xui.log per call, and
loggers still writing through an old rotator kept it alive. On Windows
the open handles block deleting the file, so
TestInitLoggerConcurrentWithLogging failed its t.TempDir cleanup there.
InitLogger now reuses the open rotator for the same path and closes it
only when the path changes, and the test closes the logger it opened.
Neither half is enough alone: with only one of them the test stays red
on Windows.
2026-09-27 15:32:20 +02:00

62 lines
1.3 KiB
Go

package logger
import (
"fmt"
"sync"
"testing"
golog "github.com/op/go-logging"
)
// TestGetLogs_ReturnsAtMostC guards the documented "up to c entries" contract.
// The loop condition must cap output at c (ERROR entries are queried at "debug"
// level so the level filter passes all of them, isolating the count).
func TestGetLogs_ReturnsAtMostC(t *testing.T) {
logBufferMu.Lock()
logBuffer = nil
logBufferMu.Unlock()
for i := range 5 {
addToBuffer("ERROR", fmt.Sprintf("m%d", i))
}
cases := []struct{ c, want int }{
{0, 0},
{2, 2},
{5, 5},
{10, 5}, // capped at what's available
}
for _, tc := range cases {
if got := GetLogs(tc.c, "debug"); len(got) != tc.want {
t.Errorf("GetLogs(%d) returned %d entries, want %d", tc.c, len(got), tc.want)
}
}
}
// InitLogger replaces the package logger while other goroutines are already
// logging — CI caught that as a data race between InitLogger and Warningf.
func TestInitLoggerConcurrentWithLogging(t *testing.T) {
t.Setenv("XUI_LOG_FOLDER", t.TempDir())
t.Cleanup(CloseLogger)
stop := make(chan struct{})
var logging sync.WaitGroup
logging.Add(1)
go func() {
defer logging.Done()
for {
select {
case <-stop:
return
default:
Warningf("concurrent %s", "log")
}
}
}()
for range 10 {
InitLogger(golog.CRITICAL)
}
close(stop)
logging.Wait()
}