mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
fix(cli): use quartz mock clock in PausedDuringWaitForReady test (#25811)
PausedDuringWaitForReady used the real clock, so the 5s poll in waitForTaskIdle could race with an in-flight stop build. The SQL view (tasks_with_status) returns "unknown" for stop builds with job_status != "succeeded" because the build_status CASE has no branch for (stop, pending) or (stop, running). On macOS CI, where the provisioner is slower, the poll fires during this transient window and hits the TaskStatusUnknown case instead of TaskStatusPaused, failing with "task entered unknown state" rather than the expected "was paused". Convert to the same quartz mock clock pattern that PR #25648 applied to WaitsForWorkingAppState: inject a mock clock via NewWithClock, trap ticker creation and reset, then advance time deterministically so the poll fires after the stop build completes. Closes CODAGT-482
This commit is contained in:
committed by
GitHub
parent
5b10268827
commit
2af037ce02
+26
-1
@@ -245,8 +245,15 @@ func Test_TaskSend(t *testing.T) {
|
|||||||
pauseTask(setupCtx, t, setup.userClient, setup.task)
|
pauseTask(setupCtx, t, setup.userClient, setup.task)
|
||||||
resumeTask(setupCtx, t, setup.userClient, setup.task)
|
resumeTask(setupCtx, t, setup.userClient, setup.task)
|
||||||
|
|
||||||
|
// Set up mock clock and traps before starting the command.
|
||||||
|
// Without a mock clock the poll can race with the stop build
|
||||||
|
// and see a transient 'unknown' status instead of 'paused'.
|
||||||
|
mClock := quartz.NewMock(t)
|
||||||
|
tickTrap := mClock.Trap().NewTicker("task_send", "poll")
|
||||||
|
resetTrap := mClock.Trap().TickerReset("task_send", "poll")
|
||||||
|
|
||||||
// When: We attempt to send input to the initializing task.
|
// When: We attempt to send input to the initializing task.
|
||||||
inv, root := clitest.New(t, "task", "send", setup.task.Name, "some task input")
|
inv, root := clitest.NewWithClock(t, mClock, "task", "send", setup.task.Name, "some task input")
|
||||||
clitest.SetupConfig(t, setup.userClient, root)
|
clitest.SetupConfig(t, setup.userClient, root)
|
||||||
|
|
||||||
ctx := testutil.Context(t, testutil.WaitLong)
|
ctx := testutil.Context(t, testutil.WaitLong)
|
||||||
@@ -259,11 +266,29 @@ func Test_TaskSend(t *testing.T) {
|
|||||||
// of waitForTaskIdle.
|
// of waitForTaskIdle.
|
||||||
pty.ExpectMatchContext(ctx, "Waiting for task to become idle")
|
pty.ExpectMatchContext(ctx, "Waiting for task to become idle")
|
||||||
|
|
||||||
|
// Wait for ticker creation and release it.
|
||||||
|
tickCall := tickTrap.MustWait(ctx)
|
||||||
|
tickCall.MustRelease(ctx)
|
||||||
|
tickTrap.Close()
|
||||||
|
|
||||||
|
// Fire the immediate first poll (time.Nanosecond initial interval).
|
||||||
|
// This poll sees 'initializing' because no agent is connected.
|
||||||
|
mClock.Advance(time.Nanosecond).MustWait(ctx)
|
||||||
|
|
||||||
|
// Wait for Reset (confirms first poll completed).
|
||||||
|
resetCall := resetTrap.MustWait(ctx)
|
||||||
|
resetCall.MustRelease(ctx)
|
||||||
|
resetTrap.Close()
|
||||||
|
|
||||||
// Pause the task while waitForTaskIdle is polling. Since
|
// Pause the task while waitForTaskIdle is polling. Since
|
||||||
// no agent is connected, the task stays initializing until
|
// no agent is connected, the task stays initializing until
|
||||||
// we pause it, at which point the status becomes paused.
|
// we pause it, at which point the status becomes paused.
|
||||||
pauseTask(ctx, t, setup.userClient, setup.task)
|
pauseTask(ctx, t, setup.userClient, setup.task)
|
||||||
|
|
||||||
|
// Fire second poll at the regular 5s interval. The stop
|
||||||
|
// build has completed, so the poll sees 'paused'.
|
||||||
|
mClock.Advance(5 * time.Second).MustWait(ctx)
|
||||||
|
|
||||||
// Then: The command should fail because the task was paused.
|
// Then: The command should fail because the task was paused.
|
||||||
err := w.Wait()
|
err := w.Wait()
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|||||||
Reference in New Issue
Block a user