diff options
Diffstat (limited to 'internal/executor/executor_test.go')
| -rw-r--r-- | internal/executor/executor_test.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/internal/executor/executor_test.go b/internal/executor/executor_test.go index a2228c3..c40f274 100644 --- a/internal/executor/executor_test.go +++ b/internal/executor/executor_test.go @@ -2170,3 +2170,73 @@ func TestPool_Shutdown_TimesOut(t *testing.T) { } close(unblock) // cleanup } + +// makeStaleWorkspaceDir creates a real directory matching the +// "claudomator-workspace-*" glob cleanupStaleWorkspaces looks for, backdates +// its mtime by age, and registers it for cleanup at test end regardless of +// whether the function under test already removed it. +func makeStaleWorkspaceDir(t *testing.T, age time.Duration) string { + t.Helper() + dir, err := os.MkdirTemp("", "claudomator-workspace-*") + if err != nil { + t.Fatalf("MkdirTemp: %v", err) + } + t.Cleanup(func() { os.RemoveAll(dir) }) + old := time.Now().Add(-age) + if err := os.Chtimes(dir, old, old); err != nil { + t.Fatalf("Chtimes: %v", err) + } + return dir +} + +func TestPool_CleanupStaleWorkspaces_RemovesOldUnreferencedDir(t *testing.T) { + store := testStore(t) + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + pool := NewPool(2, map[string]Runner{"claude": &mockRunner{}}, store, logger) + + dir := makeStaleWorkspaceDir(t, 48*time.Hour) + + pool.cleanupStaleWorkspaces(24 * time.Hour) + + if _, err := os.Stat(dir); !os.IsNotExist(err) { + t.Errorf("expected stale unreferenced workspace dir to be removed, stat err = %v", err) + } +} + +func TestPool_CleanupStaleWorkspaces_KeepsRecentDir(t *testing.T) { + store := testStore(t) + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + pool := NewPool(2, map[string]Runner{"claude": &mockRunner{}}, store, logger) + + dir := makeStaleWorkspaceDir(t, 1*time.Hour) + + pool.cleanupStaleWorkspaces(24 * time.Hour) + + if _, err := os.Stat(dir); err != nil { + t.Errorf("expected recent workspace dir to be kept, got stat err = %v", err) + } +} + +func TestPool_CleanupStaleWorkspaces_KeepsBlockedTaskSandboxDirRegardlessOfAge(t *testing.T) { + store := testStore(t) + logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) + pool := NewPool(2, map[string]Runner{"claude": &mockRunner{}}, store, logger) + + dir := makeStaleWorkspaceDir(t, 30*24*time.Hour) // deliberately far older than maxAge + + tk := makeTask("blocked-with-sandbox") + tk.State = task.StateBlocked + store.CreateTask(tk) + store.CreateExecution(&storage.Execution{ + ID: "exec-blocked-1", TaskID: tk.ID, + StartTime: time.Now().Add(-30 * 24 * time.Hour), + Status: "BLOCKED", + SandboxDir: dir, + }) + + pool.cleanupStaleWorkspaces(24 * time.Hour) + + if _, err := os.Stat(dir); err != nil { + t.Errorf("expected a BLOCKED task's sandbox_dir to be preserved regardless of age, got stat err = %v", err) + } +} |
