fix(hooks): smoke suite の ETXTBSY を staging/spawn の相互排除で解消する - #423
Conversation
hooks-pre-tool-validate の smoke テスト 2 本が並列に exe を tempdir へ copy → spawn するため、Linux で copy 側の書き込み fd を並列 spawn が fork した子が継承し、 exec が ETXTBSY (Text file busy) で落ちる。PR #376 の CI (ubuntu-latest) で実観測。 WSL Ubuntu-24.04 の ext4 上で再現させ (200 run 中 43 回)、対処案 3 つを実測比較した うえで、copy と spawn (fork〜exec) を static Mutex で相互排除する形を採った。 テストごとの tempdir 分離と後始末を保ったまま、fd 継承の窓を構造的に閉じる。 同型パターンの棚卸しで hooks-stop-quality の t7_cwd_independence (5 テスト全部が copy→spawn) が見つかったため、同じガードを入れた。現状 cfg(windows) で POSIX 経路は 踏まないが、cfg を外した瞬間に同じ flake が出る箇所。 回帰 seal として #[ignore] のストレステストを追加した。ロックを外すと Linux で 10/10 落ち、戻すと 0/10 (ADR-049)。CI の --ignored --test-threads=1 leg で走る。 順位 396 のエントリ (todo21.md / todo-summary2.md) を削除し、計画書と harness-improvement-plan.md の該当行を更新した。
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
💤 Files with no reviewable changes (2)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughLinux の ChangesETXTBSY 同期対策
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The change addresses the test flake with no actionable merge-blocking risk remaining; it is merge-ready after normal checks and review. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🤖 PR Monitor 分析 (GitHub Actions バックストップ)
Applicable Findings (Critical / High / Major)(該当なし) Applicable Findings (Medium 以下)(該当なし) Filtered (not applicable)(該当なし — レビュー指摘自体が存在しない) 次のアクション
|
背景 (順位 396)
hooks-pre-tool-validateの smoke テスト 2 本が並列に exe を tempdir へfs::copy→spawn するため、Linux で
ETXTBSY(Text file busy, os error 26) が出る。PR #376 の CI (ubuntu-latest のみ、当該クレートは無変更) で実観測した flake。
flaky を放置すると「また flake だろう」で実バグを見落とす経路になり、両 OS matrix
(ADR-065) の信号品質そのものが下がるため Tier 1 として着手した。
再現 (実測)
WSL Ubuntu-24.04 の ext4 上にリポジトリを複製してテストバイナリを回した結果:
--test-threads=1→ 2 テストの並列実行に固有と確定。
/mnt/c(drvfs) 上では再現しない。対処の選定
台帳が挙げていた 3 案はすべて ETXTBSY を 0 件にした (各 200 run)。決め手は副作用:
--test-threads=1: 穴が残る。smoke テストは専用 step (ci.yml:175) だけでなくcargo test --workspace(ci.yml:168) でも走るため、専用 step の直列化では塞がらない。LazyLock):TempDirが drop されず、1 run あたり 37MB が/tmpに残った (200 run で 7.2GB)。固定パス staging へ変えれば消えるが「
target/debugを汚さない」という smoke.rs の設計意図と衝突する。採ったのは 3 案のどれでもなく、
static Mutexによる copy と spawn (fork〜exec) の相互排除。
Command::spawnは子の exec 完了まで親へ返らないため、spawn 呼び出しを囲めば fd 継承の窓が構造的に閉じる。テストごとの tempdir 分離と後始末はそのまま。
回帰 seal
concurrent_staging_and_spawn_survives_etxtbsy(#[ignore]、8 スレッド × 16 ラウンド)。ロックを外すと Linux で 10/10 落ち、戻すと 0/10 (ADR-049「修正前に落ちることを確認」)。
CI は
--ignored --test-threads=1の leg で回す。所要 Linux 2.1s / Windows 9.7s。同型パターンの棚卸し
リポジトリ全体で「exe を copy してから spawn」は 2 ファイルのみ。
hooks-stop-quality/tests/t7_cwd_independence.rs: 5 テスト全部が copy→spawn。現状
#![cfg(windows)]で POSIX 経路は踏まないが、cfg を外した瞬間に smoke.rs 以上の危険度になるため同じガードを入れた。複製を残す判断根拠 (ADR-044 層 1「2 crate 重複」
は要 dogfood 区分 / test 専用の同期プリミティブを production surface に載せない) は
コード内に明記した。
hooks-post-tool-linter/tests/incident_eval.rs/hooks-stop-tool-call-leak/tests/e2e.rs:exe をコピーせず直接 spawn するため対象外。
検証
cargo test --workspacegreen /cargo clippy --workspace --all-targets --all-features -D warningscleancargo test --workspacegreen / 通常テスト 200 run で ETXTBSY 0 件pnpm lint:docs/pnpm lint:mdOK後始末
順位 396 のエントリ (
todo21.mdの節 +todo-summary2.mdの行) を削除し、harness-improvement-plan.mdの該当行とbugfix-batch-plan.mdを更新した。Summary by CodeRabbit
バグ修正
ETXTBSYエラーを解消しました。テスト
ドキュメント