package main import ( "os" "path/filepath" "strings" "testing" "time" ) // TestAuditDailyRotation 验证跨日 lazy rotation // 模拟 4 天的写入, 期望产出 4 个不同日期的文件 func TestAuditDailyRotation(t *testing.T) { tmp := t.TempDir() // 临时改全局 auditDir, 函数返回后恢复 oldDir := *auditDir *auditDir = tmp defer func() { *auditDir = oldDir // 关闭可能打开的文件 if auditFile != nil { auditFile.Close() auditFile = nil } auditCurDay = "" }() // 模拟连续 4 天的写入 base := time.Date(2026, 6, 20, 10, 0, 0, 0, time.UTC) for i := range 4 { day := base.Add(time.Duration(i) * 24 * time.Hour) auditMu.Lock() if err := openAuditFor(day); err != nil { t.Fatalf("day %d: openAuditFor: %v", i, err) } if _, err := auditFile.Write([]byte("event on " + day.Format("2006-01-02") + "\n")); err != nil { t.Fatalf("day %d: write: %v", i, err) } auditMu.Unlock() } // 验证: 4 个文件, 每个含 1 条事件 entries, err := os.ReadDir(tmp) if err != nil { t.Fatal(err) } if len(entries) != 4 { t.Fatalf("expected 4 files, got %d: %v", len(entries), entries) } for _, e := range entries { name := e.Name() if !strings.HasSuffix(name, ".log") { t.Errorf("unexpected file: %s", name) } body, _ := os.ReadFile(filepath.Join(tmp, name)) expected := "event on " + strings.TrimSuffix(name, ".log") if string(body) != expected+"\n" { t.Errorf("%s: got %q, want %q", name, body, expected+"\n") } } } // TestAuditNoRotateSameDay 验证同一天多次调用不会关闭/重开文件 func TestAuditNoRotateSameDay(t *testing.T) { tmp := t.TempDir() oldDir := *auditDir *auditDir = tmp defer func() { *auditDir = oldDir if auditFile != nil { auditFile.Close() auditFile = nil } auditCurDay = "" }() day := time.Date(2026, 6, 23, 14, 30, 0, 0, time.UTC) auditMu.Lock() if err := openAuditFor(day); err != nil { t.Fatal(err) } f1 := auditFile if err := openAuditFor(day.Add(1 * time.Hour)); err != nil { t.Fatal(err) } f2 := auditFile auditMu.Unlock() if f1 != f2 { t.Error("expected same file handle for same day") } } // TestAuditRotateClosesOld 验证跨日时旧文件被 close func TestAuditRotateClosesOld(t *testing.T) { tmp := t.TempDir() oldDir := *auditDir *auditDir = tmp defer func() { *auditDir = oldDir if auditFile != nil { auditFile.Close() auditFile = nil } auditCurDay = "" }() day1 := time.Date(2026, 6, 23, 23, 59, 0, 0, time.UTC) day2 := day1.Add(2 * time.Minute) // 跨过午夜 auditMu.Lock() if err := openAuditFor(day1); err != nil { t.Fatal(err) } oldFile := auditFile if err := openAuditFor(day2); err != nil { t.Fatal(err) } newFile := auditFile auditMu.Unlock() if oldFile == newFile { t.Error("expected different file handles after rotation") } // 旧文件应已被 close if _, err := oldFile.WriteString("test"); err == nil { t.Error("old file should be closed") } }