package loggerx_test import ( "context" "fmt" "os" "path/filepath" "strings" "sync" "testing" "time" "github.com/yuninks/loggerx" ) // 归档滚动后,源文件不该留下(对应「压缩完成但无法删除原文件」这个报错) // 覆盖单线程滚动 func TestArchiveSourceRemovable(t *testing.T) { for round := 0; round < 3; round++ { dir := t.TempDir() l := loggerx.NewLogger(context.Background(), loggerx.SetDir(dir), loggerx.SetSizeSplit(4*1024), loggerx.SetCompress(true), ) for i := 0; i < 600; i++ { l.Infof(context.Background(), "ROLL-%d-%s", i, strings.Repeat("z", 60)) } if err := l.Close(); err != nil { t.Fatalf("第 %d 轮 Close: %v", round, err) } if leftover := findLeftoverArchives(t, dir); len(leftover) > 0 { t.Errorf("第 %d 轮:这些归档的源文件没删掉(白占一份磁盘): %v", round, leftover) } } } // 并发 + 多 channel + 异步 + 高频刷盘同时压,归档源文件同样不能残留 func TestArchiveSourceRemovableConcurrent(t *testing.T) { dir := t.TempDir() l := loggerx.NewLogger(context.Background(), loggerx.SetDir(dir), loggerx.SetSizeSplit(2*1024), loggerx.SetCompress(true), loggerx.SetWriteAsync(), loggerx.SetFlushInterval(5*time.Millisecond), ) var wg sync.WaitGroup ctx := context.Background() for w := 0; w < 8; w++ { wg.Add(1) go func(w int) { defer wg.Done() for i := 0; i < 200; i++ { l.Channel(fmt.Sprintf("c%d", w%3)).Infof(ctx, "CONC-%d-%d-%s", w, i, strings.Repeat("q", 40)) l.Infof(ctx, "ROOT-%d-%d", w, i) _ = l.MustSync() } }(w) } wg.Wait() if err := l.Close(); err != nil { t.Fatalf("Close: %v", err) } if leftover := findLeftoverArchives(t, dir); len(leftover) > 0 { t.Errorf("并发滚动下这些归档的源文件没删掉: %v", leftover) } } // findLeftoverArchives 找出「.gz 与同名 .log 成对存在」的冗余源文件 func findLeftoverArchives(t *testing.T, dir string) []string { t.Helper() var leftover []string _ = filepath.Walk(dir, func(p string, info os.FileInfo, err error) error { if err != nil || info.IsDir() || !strings.HasSuffix(p, ".gz") { return nil } base := strings.TrimSuffix(p, ".gz") if _, serr := os.Stat(base); serr == nil { leftover = append(leftover, filepath.Base(base)) } return nil }) return leftover }