Files
docker-compose-backup/internal/backup/retention_test.go
T
2026-07-04 17:20:28 +08:00

164 lines
3.9 KiB
Go

package backup
import (
"os"
"path/filepath"
"sort"
"testing"
"time"
)
func TestApplyRetentionByCount(t *testing.T) {
dir := t.TempDir()
projDir := filepath.Join(dir, "testapp")
os.MkdirAll(projDir, 0755)
for i := 0; i < 5; i++ {
name := "testapp-20250101-00000" + string(rune('1'+i)) + ".tar.gz"
f, err := os.Create(filepath.Join(projDir, name))
if err != nil {
t.Fatal(err)
}
f.Close()
mt := time.Now().Add(-time.Duration(5-i) * time.Hour)
os.Chtimes(f.Name(), mt, mt)
}
removed, err := ApplyRetention(dir, "testapp", RetentionPolicy{Count: 3})
if err != nil {
t.Fatal(err)
}
if removed != 2 {
t.Errorf("expected 2 removed, got %d", removed)
}
entries, _ := os.ReadDir(projDir)
if len(entries) != 3 {
t.Errorf("expected 3 remaining, got %d", len(entries))
}
}
func TestApplyRetentionByDays(t *testing.T) {
dir := t.TempDir()
projDir := filepath.Join(dir, "testapp")
os.MkdirAll(projDir, 0755)
oldTime := time.Now().AddDate(0, 0, -10)
recentTime := time.Now().Add(-1 * time.Hour)
f1, _ := os.Create(filepath.Join(projDir, "testapp-old.tar.gz"))
f1.Close()
os.Chtimes(f1.Name(), oldTime, oldTime)
f2, _ := os.Create(filepath.Join(projDir, "testapp-recent.tar.gz"))
f2.Close()
os.Chtimes(f2.Name(), recentTime, recentTime)
removed, err := ApplyRetention(dir, "testapp", RetentionPolicy{Count: 0, Days: 7})
if err != nil {
t.Fatal(err)
}
if removed != 1 {
t.Errorf("expected 1 removed, got %d", removed)
}
entries, _ := os.ReadDir(projDir)
if len(entries) != 1 {
t.Errorf("expected 1 remaining, got %d", len(entries))
}
}
func TestApplyRetentionIgnoresNonBackupFiles(t *testing.T) {
dir := t.TempDir()
projDir := filepath.Join(dir, "testapp")
os.MkdirAll(projDir, 0755)
keepNames := []string{"README.txt", "otherapp-20250101.tar.gz", "testapp-note.txt"}
for _, name := range keepNames {
f, err := os.Create(filepath.Join(projDir, name))
if err != nil {
t.Fatal(err)
}
f.Close()
}
for i := 0; i < 3; i++ {
name := "testapp-20250101-00000" + string(rune('1'+i)) + ".tar.gz"
f, err := os.Create(filepath.Join(projDir, name))
if err != nil {
t.Fatal(err)
}
f.Close()
mt := time.Now().Add(-time.Duration(3-i) * time.Hour)
os.Chtimes(f.Name(), mt, mt)
}
removed, err := ApplyRetention(dir, "testapp", RetentionPolicy{Count: 1})
if err != nil {
t.Fatal(err)
}
if removed != 2 {
t.Errorf("expected 2 removed, got %d", removed)
}
for _, name := range keepNames {
if _, err := os.Stat(filepath.Join(projDir, name)); err != nil {
t.Fatalf("non-backup file %s should remain: %v", name, err)
}
}
}
func TestApplyRetentionEmptyDir(t *testing.T) {
dir := t.TempDir()
removed, err := ApplyRetention(dir, "nonexistent", RetentionPolicy{Count: 7})
if err != nil {
t.Fatal(err)
}
if removed != 0 {
t.Errorf("expected 0 removed, got %d", removed)
}
}
func TestApplyRetentionSortOrder(t *testing.T) {
dir := t.TempDir()
projDir := filepath.Join(dir, "testapp")
os.MkdirAll(projDir, 0755)
times := []time.Time{
time.Now().Add(-5 * time.Hour),
time.Now().Add(-1 * time.Hour),
time.Now().Add(-3 * time.Hour),
}
for i, mt := range times {
name := "testapp-2025010" + string(rune('1'+i)) + "-000001.tar.gz"
f, _ := os.Create(filepath.Join(projDir, name))
f.Close()
os.Chtimes(f.Name(), mt, mt)
}
removed, err := ApplyRetention(dir, "testapp", RetentionPolicy{Count: 2})
if err != nil {
t.Fatal(err)
}
if removed != 1 {
t.Fatalf("expected 1 removed, got %d", removed)
}
entries, _ := os.ReadDir(projDir)
names := make([]string, len(entries))
for i, e := range entries {
names[i] = e.Name()
}
sort.Strings(names)
expected := []string{"testapp-20250102-000001.tar.gz", "testapp-20250103-000001.tar.gz"}
if len(names) != len(expected) {
t.Fatalf("expected %v, got %v", expected, names)
}
for i := range expected {
if expected[i] != names[i] {
t.Errorf("expected[%d]=%s, got %s", i, expected[i], names[i])
}
}
}