diff options
Diffstat (limited to 'internal/executor/executor_test.go')
| -rw-r--r-- | internal/executor/executor_test.go | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/internal/executor/executor_test.go b/internal/executor/executor_test.go index e6b8f0b..2292aa5 100644 --- a/internal/executor/executor_test.go +++ b/internal/executor/executor_test.go @@ -461,6 +461,41 @@ func TestPool_FailureHistoryInjectedOnRetry(t *testing.T) { } } +func TestPool_RecoverStaleRunning(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) + + // Create a task already in RUNNING state (simulating a crashed server). + tk := makeTask("stale-1") + tk.State = task.StateRunning + store.CreateTask(tk) + + // Add an open execution record (no end time, status RUNNING). + store.CreateExecution(&storage.Execution{ + ID: "exec-stale-1", TaskID: tk.ID, + StartTime: time.Now().Add(-5 * time.Minute), + Status: "RUNNING", + }) + + pool.RecoverStaleRunning() + + recovered, err := store.GetTask(tk.ID) + if err != nil { + t.Fatalf("get task: %v", err) + } + if recovered.State != task.StateFailed { + t.Errorf("state: want FAILED, got %q", recovered.State) + } + execs, _ := store.ListExecutions(tk.ID) + if len(execs) == 0 || execs[0].Status != "FAILED" { + t.Errorf("execution status: want FAILED, got %+v", execs) + } + if execs[0].ErrorMsg == "" { + t.Error("expected non-empty error message on recovered execution") + } +} + func TestPool_UnsupportedAgent(t *testing.T) { store := testStore(t) runners := map[string]Runner{"claude": &mockRunner{}} |
