package orchestrator import ( "context" "testing" ) func TestStopReasonAccountStatus(t *testing.T) { if got := stopPaused.accountStatus(); got != "paused" { t.Fatalf("stopPaused = %q want paused", got) } if got := stopCancelled.accountStatus(); got != "cancelled" { t.Fatalf("stopCancelled = %q want cancelled", got) } // A run stopped without an operator reason (per-account cancel, stall // watchdog) must not look like a pause, or Resume would pick it up. if got := stopNone.accountStatus(); got != "cancelled" { t.Fatalf("stopNone = %q want cancelled", got) } } // The first stop wins: a cancel arriving after a pause must not downgrade the // accounts a pause already promised to keep resumable, and vice versa. func TestRunHandleFirstStopWins(t *testing.T) { for _, tc := range []struct { name string first, later stopReason }{ {"pause then cancel", stopPaused, stopCancelled}, {"cancel then pause", stopCancelled, stopPaused}, } { t.Run(tc.name, func(t *testing.T) { _, cancel := context.WithCancel(context.Background()) defer cancel() h := &runHandle{cancel: cancel} h.stopWith(tc.first) h.stopWith(tc.later) if got := h.stopReason(); got != tc.first { t.Fatalf("reason = %v want %v", got, tc.first) } }) } } func TestRunHandleStopCancelsContext(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() h := &runHandle{cancel: cancel} if ctx.Err() != nil { t.Fatal("context cancelled before stop") } h.stopWith(stopPaused) if ctx.Err() == nil { t.Fatal("stop must cancel the run context") } } // Pause/Cancel report false for a task with no live run, which the HTTP layer // turns into 409 instead of pretending it stopped something. func TestStopRunWithoutLiveRun(t *testing.T) { o := &Orchestrator{runs: map[int64]*runHandle{}} if o.PauseTask(1) { t.Fatal("PauseTask must report false with no live run") } if o.CancelTask(1) { t.Fatal("CancelTask must report false with no live run") } _, cancel := context.WithCancel(context.Background()) defer cancel() h := &runHandle{cancel: cancel} o.registerRun(1, h) if !o.PauseTask(1) { t.Fatal("PauseTask must report true for a live run") } if got := h.stopReason(); got != stopPaused { t.Fatalf("reason = %v want stopPaused", got) } o.unregisterRun(1) if o.CancelTask(1) { t.Fatal("unregistered run must not be stoppable") } }