Repository navigation
Write unit-test executables from a child process - #483
Merged
Merged
Conversation
Unit tests that wrote a fake CLI with fs::write and then ran it failed now and then with "Text file busy": the write's file descriptor was inherited by a process another test thread spawned meanwhile, so the file couldn't be executed until that process exec'd. test_support::write_executable has a child process write the file instead, as the scenario tests already copy thirdshift with cp for the same reason. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ts55nZd9iVAg8GP3QxHo9Y
This was referenced Oct 7, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Linux CI fails now and then with
Text file busy (os error 26)in unit tests that write a fake CLI and then run it. Tonight that failed CI on #478 (a_transport_failure_stays_pending_while_the_child_saves_work) and #433 (distinct_children_deliver_out_of_order_with_their_own_endings_and_accounts).Cause:
fs::writeholds the file open for writing in the test process. If another test thread forks a process while it's open, that process inherits the descriptor until it execs, and running the file fails meanwhile. The scenario tests already avoid this by copying thirdshift withcp(tests/support/mod.rs).test_support::write_executablenow has a childshwrite the file andchmod 755it, so the test process never holds it open. All six unit-test sites that wrote an executable use it: the git, github, session, child_run and harness interpretation fixtures and the git hook test.Evidence
cargo clippy --all-targets -- -D warningsandcargo fmt --checkclean.cargo test --bin thirdshift: 676 passed, then the unit binary 5 more times: 4 clean runs, and 1 that hit the unrelated interrupt-timing flake inharness::settingstests (not touched here).Not addressed
harness::settingsinterrupt tests (an_interrupted_model_check_is_an_error_instead_of_retrying_the_pair,an_interrupted_catalog_read_is_an_error_instead_of_retention) are flaky: SIGINT's handler can run on another thread after the code under test has already checked for the interrupt.session::execution_tests::startup_failure_preserves_its_cause_without_completion_reportingruns the realopencodewhen one is installed: with the fake made non-executable, the PATH search skips it and finds the real CLI, so locally the test hangs (and starts a real session). CI has no OpenCode installed.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ts55nZd9iVAg8GP3QxHo9Y