Files
2026-06-24 18:28:14 +08:00

208 lines
5.7 KiB
Go

package services
import (
"os"
"path/filepath"
"testing"
"time"
)
func TestCleanupExpiredRepos(t *testing.T) {
tmpDir := t.TempDir()
// Create "old" repo (modify time in the past)
oldDir := filepath.Join(tmpDir, "old-repo")
os.MkdirAll(oldDir, 0o755)
os.WriteFile(filepath.Join(oldDir, "file.txt"), []byte("old"), 0o644)
oldTime := time.Now().AddDate(0, 0, -10) // 10 days ago
os.Chtimes(oldDir, oldTime, oldTime)
// Create "new" repo (recent)
newDir := filepath.Join(tmpDir, "new-repo")
os.MkdirAll(newDir, 0o755)
os.WriteFile(filepath.Join(newDir, "file.txt"), []byte("new"), 0o644)
result, err := CleanupExpiredRepos(tmpDir, 7)
if err != nil {
t.Fatalf("CleanupExpiredRepos() error: %v", err)
}
if result.RemovedCount != 1 {
t.Errorf("RemovedCount = %d, want 1", result.RemovedCount)
}
if len(result.RemovedPaths) != 1 || result.RemovedPaths[0] != "old-repo" {
t.Errorf("RemovedPaths = %v, want [old-repo]", result.RemovedPaths)
}
if result.FreedBytes <= 0 {
t.Errorf("FreedBytes = %d, want > 0", result.FreedBytes)
}
// Verify new repo still exists
if _, err := os.Stat(newDir); os.IsNotExist(err) {
t.Error("new-repo should still exist")
}
// Verify old repo was removed
if _, err := os.Stat(oldDir); !os.IsNotExist(err) {
t.Error("old-repo should have been removed")
}
}
func TestCleanupExpiredRepos_NonexistentDir(t *testing.T) {
result, err := CleanupExpiredRepos("/nonexistent/path/12345", 7)
if err != nil {
t.Fatalf("CleanupExpiredRepos() error: %v", err)
}
if result.RemovedCount != 0 {
t.Errorf("RemovedCount = %d, want 0", result.RemovedCount)
}
}
func TestCleanupExpiredRepos_NoExpired(t *testing.T) {
tmpDir := t.TempDir()
// Create only recent repos
for _, name := range []string{"repo1", "repo2"} {
dir := filepath.Join(tmpDir, name)
os.MkdirAll(dir, 0o755)
}
result, err := CleanupExpiredRepos(tmpDir, 7)
if err != nil {
t.Fatalf("CleanupExpiredRepos() error: %v", err)
}
if result.RemovedCount != 0 {
t.Errorf("RemovedCount = %d, want 0", result.RemovedCount)
}
}
func TestCleanupBySize(t *testing.T) {
tmpDir := t.TempDir()
// Create repos with known sizes; set mod times so ordering is deterministic
for i, name := range []string{"oldest", "middle", "newest"} {
dir := filepath.Join(tmpDir, name)
os.MkdirAll(dir, 0o755)
// Each repo: ~100 bytes
os.WriteFile(filepath.Join(dir, "data.txt"), make([]byte, 100), 0o644)
modTime := time.Now().AddDate(0, 0, -10+i) // -10, -9, -8 days
os.Chtimes(dir, modTime, modTime)
os.Chtimes(filepath.Join(dir, "data.txt"), modTime, modTime)
}
// Set max to 150 bytes — should remove oldest repos until under limit
result, err := CleanupBySize(tmpDir, 0) // 0 MB = 0 bytes limit
if err != nil {
t.Fatalf("CleanupBySize() error: %v", err)
}
// With 0 MB limit, all repos should be removed
if result.RemovedCount != 3 {
t.Errorf("RemovedCount = %d, want 3", result.RemovedCount)
}
}
func TestCleanupBySize_UnderLimit(t *testing.T) {
tmpDir := t.TempDir()
dir := filepath.Join(tmpDir, "small-repo")
os.MkdirAll(dir, 0o755)
os.WriteFile(filepath.Join(dir, "data.txt"), []byte("tiny"), 0o644)
result, err := CleanupBySize(tmpDir, 100) // 100 MB limit
if err != nil {
t.Fatalf("CleanupBySize() error: %v", err)
}
if result.RemovedCount != 0 {
t.Errorf("RemovedCount = %d, want 0", result.RemovedCount)
}
}
func TestCleanupBySize_NonexistentDir(t *testing.T) {
result, err := CleanupBySize("/nonexistent/path/12345", 100)
if err != nil {
t.Fatalf("CleanupBySize() error: %v", err)
}
if result.RemovedCount != 0 {
t.Errorf("RemovedCount = %d, want 0", result.RemovedCount)
}
}
func TestGetCacheStats(t *testing.T) {
tmpDir := t.TempDir()
// Create 3 repo dirs with files
for _, name := range []string{"repo1", "repo2", "repo3"} {
dir := filepath.Join(tmpDir, name)
os.MkdirAll(dir, 0o755)
os.WriteFile(filepath.Join(dir, "data.txt"), make([]byte, 50), 0o644)
}
// Create a file (not a dir) — should be ignored
os.WriteFile(filepath.Join(tmpDir, "not-a-repo.txt"), []byte("ignored"), 0o644)
count, totalBytes := GetCacheStats(tmpDir)
if count != 3 {
t.Errorf("count = %d, want 3", count)
}
if totalBytes < 150 { // 3 * 50 bytes minimum
t.Errorf("totalBytes = %d, want >= 150", totalBytes)
}
}
func TestGetCacheStats_EmptyDir(t *testing.T) {
tmpDir := t.TempDir()
count, totalBytes := GetCacheStats(tmpDir)
if count != 0 {
t.Errorf("count = %d, want 0", count)
}
if totalBytes != 0 {
t.Errorf("totalBytes = %d, want 0", totalBytes)
}
}
func TestGetCacheStats_NonexistentDir(t *testing.T) {
count, totalBytes := GetCacheStats("/nonexistent/path/12345")
if count != 0 {
t.Errorf("count = %d, want 0", count)
}
if totalBytes != 0 {
t.Errorf("totalBytes = %d, want 0", totalBytes)
}
}
func TestSortReposByModTime(t *testing.T) {
now := time.Now()
repos := []repoEntry{
{name: "newest", modTime: now},
{name: "oldest", modTime: now.AddDate(0, 0, -10)},
{name: "middle", modTime: now.AddDate(0, 0, -5)},
}
sortReposByModTime(repos)
if repos[0].name != "oldest" {
t.Errorf("repos[0] = %q, want %q", repos[0].name, "oldest")
}
if repos[1].name != "middle" {
t.Errorf("repos[1] = %q, want %q", repos[1].name, "middle")
}
if repos[2].name != "newest" {
t.Errorf("repos[2] = %q, want %q", repos[2].name, "newest")
}
}
func TestSortReposByModTime_Empty(t *testing.T) {
repos := []repoEntry{}
sortReposByModTime(repos) // should not panic
if len(repos) != 0 {
t.Errorf("expected empty slice")
}
}
func TestSortReposByModTime_Single(t *testing.T) {
repos := []repoEntry{{name: "only", modTime: time.Now()}}
sortReposByModTime(repos) // should not panic
if repos[0].name != "only" {
t.Errorf("repos[0] = %q, want %q", repos[0].name, "only")
}
}