summaryrefslogtreecommitdiff
path: root/internal/executor/executor_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/executor/executor_test.go')
-rw-r--r--internal/executor/executor_test.go70
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)
+ }
+}