Skip to content

Fix ETXTBSY flake in process command_for spawn test - #1377

Merged
Mikola Lysenko (mikolalysenko) merged 1 commit into
mainfrom
ci/etxtbsy-process-test
Oct 10, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 1 commit into
mainfrom
ci/etxtbsy-process-test

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Failing run

The coverage job in CI run 37999238426 failed on 2026-10-09 in utils::process::tests::command_for_spawns_the_resolved_path_directly_on_unix:

spawn the shim: Os { code: 26, kind: ExecutableFileBusy, message: "Text file busy" }

Root cause

This is the known ETXTBSY fork/exec race. The test writes a shell shim, chmods it and spawns it at once. fs::write closes our handle, but other test threads in the same process fork children. A child forked between our open() and its own exec() inherits the shim's write fd, and Linux refuses to exec a file while any process holds it open for writing. Writing to a temp file and renaming it would not help, because the inherited fd still refers to the same inode.

Fix

The test now spawns through a test-local output_of_fresh_shim helper. It retries ErrorKind::ExecutableFileBusy only, with a 10 s deadline and 20 ms sleeps, the same pattern as sanity_exec in update/download.rs and the CLI's exec_freshly_written fixture. Any other spawn error still panics, and the test's assertions are unchanged.

I checked the other core tests that write executables. The only other test that writes and runs a shim is a_hung_probe_answers_none_within_its_budget. It expects None, so an ETXTBSY there can't fail it, and I left it alone.

Verification

  • cargo test -p socket-patch-core --lib utils::process: 25/25 serial runs and 10/10 runs with --test-threads=64 passed.
  • Full cargo test -p socket-patch-core --lib passed once (6164 tests).
  • cargo clippy --locked --workspace --all-features -- -D warnings is clean.

🤖 Generated with Claude Code


Note

Low Risk
Test-only change in utils::process tests; no production spawn or resolver logic is modified.

Overview
Fixes intermittent CI failure in command_for_spawns_the_resolved_path_directly_on_unix when parallel test threads hit Linux ETXTBSY (“Text file busy”) after writing and immediately exec’ing a temp shim.

Adds a Unix-only test helper output_of_fresh_shim that retries spawn on ErrorKind::ExecutableFileBusy only (10s cap, 20ms backoff), matching sanity_exec / CLI exec_freshly_written. The test now spawns the resolved shim through that helper; assertions and production command_for behavior are unchanged.

Reviewed by Cursor Bugbot for commit 256d857. Configure here.

command_for_spawns_the_resolved_path_directly_on_unix writes a shell
shim, chmods it and spawns it at once. A sibling test thread that forks
between our open() and its own exec() inherits the shim's write fd, and
exec'ing the shim in that window fails with "Text file busy" (os error
26). Seen in the coverage job of CI run 37999238426.

Spawn through a test-local output_of_fresh_shim helper that retries
ErrorKind::ExecutableFileBusy only, with a 10s deadline and 20ms sleeps.
This is the same pattern as sanity_exec in update/download.rs and the
CLI's exec_freshly_written fixture. Any other spawn error still panics,
and the assertions are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko Mikola Lysenko (mikolalysenko) added the ci-janitor Opened by the CI janitor routine (flakes, redundant tests, CI perf) label Oct 9, 2026
Merged via the queue into main with commit ade046a Oct 10, 2026
54 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the ci/etxtbsy-process-test branch October 10, 2026 01:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-janitor Opened by the CI janitor routine (flakes, redundant tests, CI perf)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants