From 7519da57c543c7eb34af367a3ba337c81c7825a2 Mon Sep 17 00:00:00 2001 From: "circleci-app[bot]" <127350680+circleci-app[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 21:13:45 +0000 Subject: [PATCH] Fix Windows orchestrator test race condition Poll for expected task unclaims/events before asserting, to prevent the test from racing with the orchestrator's final updates on Windows. On Windows, when the task agent process exits with a fatal error, there is a race condition between the orchestrator sending the failure event to the runner API and the test assertions checking for those events. The orchestrator's error handling happens asynchronously, and on Windows the process cleanup is synchronous via Job Objects, which can cause tight timing windows. This fix adds polling with a 30-second timeout to wait for the expected number of task events and unclaims before performing the assertions. This ensures the test doesn't fail due to timing issues while still catching genuine failures. Fixes the "error: task agent encountered fatal error" test failure on Windows where the test expected a TaskEvent but received nil due to the race condition. --- task/orchestrator_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/task/orchestrator_test.go b/task/orchestrator_test.go index 4ba7133..4e9a8a0 100644 --- a/task/orchestrator_test.go +++ b/task/orchestrator_test.go @@ -323,6 +323,15 @@ func TestOrchestrator(t *testing.T) { assert.NilError(t, err) } + + check := func(poll.LogT) poll.Result { + if len(runnerAPI.TaskUnclaims()) == len(tt.wantTaskUnclaims) && + len(runnerAPI.TaskEvents()) == len(tt.wantTaskEvents) { + return poll.Success() + } + return poll.Continue("haven't received the expected task events yet") + } + poll.WaitOn(t, check, poll.WithTimeout(30*time.Second)) assert.Check(t, cmp.DeepEqual(runnerAPI.TaskUnclaims(), tt.wantTaskUnclaims)) assert.Check(t, cmp.DeepEqual(runnerAPI.TaskEvents(), tt.wantTaskEvents, fakerunnerapi.CmpTaskEvent))