Skip to content

test(eval): avoid writing executable runtimes during parallel tests - #4527

Merged
aheritier merged 1 commit into
mainfrom
test/eval-parallel-runtime-etxtbsy
Oct 6, 2026
Merged

aheritier merged 1 commit into
mainfrom
test/eval-parallel-runtime-etxtbsy

Conversation

@aheritier

Copy link
Copy Markdown
Collaborator

🤖 Automated implementer agent — this comment was posted by the implementer bot from Docker Agentic Platform, not by a human developer

Fixes #4520

Change

Write one immutable shell runtime fixture before the parent t.Parallel() barrier. Each parallel case symlinks that executable and writes only non-executable response/exit-marker files. This is test-only: the existing 12-case table, every assertion and both levels of parallelism remain unchanged. No production changes, retries, sleeps or relaxed assertions.

Diagnosis

The original parallel cases write executable scripts immediately before executing them. Natural reproduction surfaces Linux ETXTBSY (text file busy). An inspect execution error takes the intentional production fallback, leaving inspect-args absent and sometimes the Dockerfile's COPY unpinned; build execution errors expose the errno directly. The recovered CI log includes both no_manifest_digest and default_image failures.

A concurrent fork temporarily inheriting a sibling executable's writer descriptor is a plausible explanation, not syscall-proven. Prior diagnostic logging exposed inspect ETXTBSY; strace changed scheduling and did not reproduce it. The fix removes concurrent writes to the executed fixture inode.

Validation

Prior investigation (separate runs, not fresh PR-arc measurements):

Fixture/revision Failing parent iterations Failing subtests
Original, failing 6bf72739 30/100 37/1,200
Original, main 28569802 34/100 39/1,200
Candidate, both revisions combined 0/1,200 0/14,400

Fresh PR-arc validation on main 285698023342389523089b3a36171eb88fb8dc40:

Command Result
Original target: go test -json -race -shuffle=1791198938208945572 -count=100 -run '^TestBuildEvalImagePinsLocalAgentDigest$' ./pkg/evaluation 33/100 parent failures; 41/1,200 subtest failures; explicit text-file-busy errors
Candidate: same focused command 0/100 parent failures; 0/1,200 subtest failures
Candidate: focused -race -shuffle=on -count=100 0/100 parent failures; 0/1,200 subtest failures; seed 1791278474244450004
Candidate: whole evaluation package -race -shuffle=1791198938208945572 -count=3 Passed
task build, task test, task lint Passed; lint 0 issues/no custom-cop offenses; module tidiness clean
CGO_ENABLED=1 task test-race Passed, full repository

Focused commands source .env.test and set CGO_ENABLED=1. Local Go1.27.0/Linux Ubuntu26.04 differs from CI Ubuntu24.04.5; Windows remains skipped, macOS untested. PR CI runs race tests only on main pushes, so these are local race results, not PR-CI results. Finite passes are not a suite-wide flake-freedom claim.

Other observed flakes (not changed)

  • Prior full task test first failed the unrelated pkg/cache/TestFileCache_dedupSkipsRedundantWrite modtime assertion, then passed on retry. Fresh unpatched cache control failed 17/20 repeats; this PR's fresh full task test passed first time. Cache source is unchanged.
  • Initial fresh random whole-package race/count3 run (seed 1791278540484914705) failed once in unchanged TestEvalContainerForwardsOrderedFlavors/#00, flavors_test.go:37, executing its own per-case script: fork/exec .../runtime: text file busy. That fixture has the same parallel write-then-exec pattern. Target digest test passed all three repetitions. Clean unpatched-main controls did not reproduce the sibling failure (100 focused race runs, 10 same-seed package race runs); candidate same-seed package/count3 rerun and subsequent full race suite passed. The sibling's frequency and pre-existing attribution are not established by these samples. Left outside this one-test fix.

Create the shared shell fixture before the parent parallel barrier and use per-case symlinks and data files. Preserve digest pinning and fallback assertions without concurrent writes to executable fixture inodes.

Signed-off-by: Arnaud Héritier <aheritier@users.noreply.github.com>
@aheritier
aheritier marked this pull request as ready for review October 6, 2026 09:43
@aheritier
aheritier requested a review from a team as a code owner October 6, 2026 09:43
Copilot AI balanced review requested due to automatic review settings October 6, 2026 09:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

The focused test-only change preserves existing coverage while addressing the demonstrated race condition.

Review effort: Balanced
Findings: None

What changed in this PR

Stabilizes the parallel evaluation image tests by sharing a prewritten runtime fixture.

Changes:

  • Creates the executable fixture before parallel execution.
  • Uses per-test symlinks and non-executable response files.
File Description
pkg/​evaluation/​build_test.go Prevents concurrent executable writes that caused ETXTBSY failures.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@aheritier aheritier added area/testing Test infrastructure, CI/CD, test runners, evaluation kind/test Test-only changes labels Oct 6, 2026
@aheritier
aheritier added this pull request to the merge queue Oct 6, 2026
Merged via the queue into main with commit c6258fc Oct 6, 2026
17 checks passed
@aheritier
aheritier deleted the test/eval-parallel-runtime-etxtbsy branch October 6, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/testing Test infrastructure, CI/CD, test runners, evaluation kind/test Test-only changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Flaky test] TestBuildEvalImagePinsLocalAgentDigest

3 participants