Skip to content

[Flaky test fix] TestSandboxAssetPrewarmDownloads - atelet: make the sandbox prewarm worker joinable, fixing the race - #1940

Merged
Benjamin Elder (BenTheElder) merged 2 commits into
agent-substrate:mainfrom
aditya-shantanu:fix/flaky-sandbox-asset-prewarm-race
Oct 6, 2026
Merged

Benjamin Elder (BenTheElder) merged 2 commits into
agent-substrate:mainfrom
aditya-shantanu:fix/flaky-sandbox-asset-prewarm-race

Conversation

@aditya-shantanu

Copy link
Copy Markdown
Collaborator

Summary

Fixes the flaky TestSandboxAssetPrewarmDownloads (unit lane).

Root cause: the test patches nodepath.StaticFilesDir / prewarmMaxJitter and restores them in t.Cleanup, but returns as soon as the prewarmed asset appears on disk. The prewarm worker goroutine is still running its tail at that point (pause-image pull) and reads nodepath.StaticFilesDir in downloadVerified while the cleanup writes it — a data race that -race turns into a hard failure whenever the CI runner is slow enough for the two to overlap.

Fix: the worker was not joinable — after context cancellation nothing could wait for it to exit. startSandboxAssetPrewarm now returns the prewarmer; its worker closes a done channel on exit and exposes wait(). The test registers t.Cleanup(p.wait) after the globals-restore cleanup, so (LIFO, and t.Context() cancels first) the order becomes: cancel → join worker → restore globals. main.go ignores the new return value.

Closes #1939

Evidence

Cross-PR failures at ~1.5% of runs over the last week, including twice on main and once on the benchmarking-only #1934 — run links in #1939. The race trace pins write (test cleanup, sandbox_prewarm_test.go:360) against read (sandbox_assets.go:285 inside the worker).

Test plan

  • go test -race -run TestSandboxAssetPrewarm -count=200 ./cmd/atelet/ — clean
  • go test -race ./cmd/atelet/ — full package clean
  • Confirmed the direct &sandboxPrewarmer{...} test constructors never call run(), so the nil done channel is never closed there

…race

TestSandboxAssetPrewarmDownloads patches nodepath.StaticFilesDir and
restores it in t.Cleanup, but returned as soon as the prewarmed asset
appeared on disk — while the prewarm worker was still running its
tail (the pause-image pull) and reading that global. On a loaded
runner the overlap trips the race detector and fails the run-tests
job; nothing let a caller wait for the worker to exit.

startSandboxAssetPrewarm now returns the prewarmer, whose worker
closes a done channel on exit and exposes wait(). The test joins the
worker via t.Cleanup, which runs after t.Context() is canceled and
before the earlier-registered cleanup restores the globals.
TestActorEgressHTTPSByHostnameMITM failed because the live upstream
the egress e2e tests fetch (example.com/example.org) served 404s to
the runner for ~30s; unrelated egress-HTTPS tests failed the same way
on another branch minutes later. Nothing in this change touches the
egress path.
@mayawang Maya Wang (mayawang) added area/node area/tests Enhancing / fixing test coverage. kind/bug Something isn't working / bugfixes labels Sep 29, 2026
@zoez7
Zoe Zhao (zoez7) self-requested a review September 30, 2026 16:38
@aditya-shantanu Aditya Shantanu (aditya-shantanu) changed the title atelet: make the sandbox prewarm worker joinable, fixing the TestSandboxAssetPrewarmDownloads race [Flaky test fix] TestSandboxAssetPrewarmDownloads - atelet: make the sandbox prewarm worker joinable, fixing the race Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not going to block on this nit to pickup test fix but

Comment on lines +388 to +393
// The worker reads the patched globals above. t.Context() is canceled
// before cleanups run, and cleanups run last-registered-first, so this
// joins the worker before the earlier cleanup restores the globals —
// without it the restore races the worker's tail (pause-image pull
// after the asset lands) and trips the race detector.
t.Cleanup(p.wait)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 nit 🟢 – The pause-image pull runs concurrently with the asset download in prewarm, not after the asset lands. The comment could also be shorter, for example: "Join the worker before the earlier cleanup restores the globals it reads. t.Context() is canceled before cleanups run."

@BenTheElder
Benjamin Elder (BenTheElder) added this pull request to the merge queue Oct 5, 2026
Merged via the queue into agent-substrate:main with commit 61af9e1 Oct 6, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/node area/tests Enhancing / fixing test coverage. kind/bug Something isn't working / bugfixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

flaky: TestSandboxAssetPrewarmDownloads

3 participants