Skip to content

fix(hooks): smoke suite の ETXTBSY を staging/spawn の相互排除で解消する - #423

Merged
aloekun merged 1 commit into
masterfrom
fix/smoke-etxtbsy
Aug 19, 2026
Merged

fix(hooks): smoke suite の ETXTBSY を staging/spawn の相互排除で解消する#423
aloekun merged 1 commit into
masterfrom
fix/smoke-etxtbsy

Conversation

@aloekun

@aloekun aloekun commented Aug 18, 2026

Copy link
Copy Markdown
Owner

背景 (順位 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 上にリポジトリを複製してテストバイナリを回した結果:

条件 結果
並列 (cargo 既定) 43 / 200 run が ETXTBSY (別測定 30/200)
--test-threads=1 0 / 100
各テスト単独 0 / 100

→ 2 テストの並列実行に固有と確定。/mnt/c (drvfs) 上では再現しない。

対処の選定

台帳が挙げていた 3 案はすべて ETXTBSY を 0 件にした (各 200 run)。決め手は副作用:

  • (a) --test-threads=1: 穴が残る。smoke テストは専用 step (ci.yml:175) だけでなく
    cargo test --workspace (ci.yml:168) でも走るため、専用 step の直列化では塞がらない。
  • (c) 共有 staging (LazyLock): TempDir が drop されず、1 run あたり 37MB が
    /tmp に残った
    (200 run で 7.2GB)。固定パス staging へ変えれば消えるが
    target/debug を汚さない」という smoke.rs の設計意図と衝突する。
  • (b) spawn リトライ: 原因 (fd 継承) に触れず症状を待つ形。

採ったのは 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 するため対象外。

検証

  • Windows: cargo test --workspace green / cargo clippy --workspace --all-targets --all-features -D warnings clean
  • Linux (WSL Ubuntu-24.04 ext4): cargo test --workspace green / 通常テスト 200 run で ETXTBSY 0 件
  • pnpm lint:docs / pnpm lint:md OK

後始末

順位 396 のエントリ (todo21.md の節 + todo-summary2.md の行) を削除し、
harness-improvement-plan.md の該当行と bugfix-batch-plan.md を更新した。

Summary by CodeRabbit

  • バグ修正

    • Linux環境でフックの並列実行時に発生していた ETXTBSY エラーを解消しました。
    • テスト用実行ファイルの準備と起動を適切に同期し、並列テストの安定性を向上しました。
  • テスト

    • 高負荷な並列実行を再現する回帰テストを追加しました。
    • 関連するフックのテストにも同様の安定化対策を適用しました。
  • ドキュメント

    • 修正内容、検証結果、今後の確認事項を開発計画に反映しました。

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 の該当行を更新した。
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b083b48f-57aa-4629-bab5-b8f4e19683d2

📥 Commits

Reviewing files that changed from the base of the PR and between 519b9fb and 30b84bf.

📒 Files selected for processing (6)
  • docs/bugfix-batch-plan.md
  • docs/harness-improvement-plan.md
  • docs/todo-summary2.md
  • docs/todo21.md
  • src/hooks-pre-tool-validate/tests/smoke.rs
  • src/hooks-stop-quality/tests/t7_cwd_independence.rs
💤 Files with no reviewable changes (2)
  • docs/todo-summary2.md
  • docs/todo21.md

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

Linux の ETXTBSY を防ぐため、実行ファイルの staging と spawn を共有 Mutex で同期した。2つのテストスイートに適用し、並列負荷テストと関連ドキュメントを更新した。

Changes

ETXTBSY 同期対策

Layer / File(s) Summary
staging と spawn の同期
src/hooks-pre-tool-validate/tests/smoke.rs, src/hooks-stop-quality/tests/t7_cwd_independence.rs
EXEC_STAGING_LOCK と poisoning を無視するガード取得処理を追加した。exe のコピーと Command::spawn を同期し、spawn 直後にロックを解放する。smoke.rs に並列負荷テストを追加した。
計画とタスク記録の更新
docs/bugfix-batch-plan.md, docs/harness-improvement-plan.md, docs/todo-summary2.md, docs/todo21.md
ETXTBSY 対策の完了状態、実測結果、回帰テスト、運用手順、保留事項を記録した。関連タスクを削除または実装箇所へ移動した。

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 30b84

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)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルは、LinuxのETXTBSYフレークをstagingとspawnの相互排他で解消する主要変更を明確に示しています。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/smoke-etxtbsy

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 PR Monitor 分析 (GitHub Actions バックストップ)

  • トリガー: issue_comment (created) / 実行 run
  • CI: rust (ubuntu-latest) pending / rust (windows-latest) pending / request skipping / CodeRabbit チェックは pass (レビュー自体は skip)
  • レビュー状況: CodeRabbit — 本リポジトリは star 10 未満のため自動レビュー未実施 (Review skipped: manual review required for this OSS repository)。人間レビューなし (reviewDecision 空、reviews API も空配列)。インラインコメントなし
  • Verdict: approved (applicable findings 0 件)

Applicable Findings (Critical / High / Major)

(該当なし)

Applicable Findings (Medium 以下)

(該当なし)

Filtered (not applicable)

(該当なし — レビュー指摘自体が存在しない)

次のアクション

  • CodeRabbit のレビューはこのリポジトリでは常時 skip される設定 (star 数条件) のため、待っても着かない。人間レビューが必要なら別途依頼する
  • CI (rust (ubuntu-latest) / rust (windows-latest)) が pending のため、完了後に結果を確認する。mergeStateStatus は BLOCKED (CI 未完了によるものと推測)
  • 変更内容は diff から見る限り妥当: docs/bugfix-batch-plan.md 等 4 ドキュメントの台帳更新と、smoke.rs / t7_cwd_independence.rs への EXEC_STAGING_LOCK (copy と spawn の相互排除) 追加による ETXTBSY flaky fix。PR タイトルと整合しており、追加の懸念点は無し

@aloekun
aloekun merged commit fec62d4 into master Aug 19, 2026
4 checks passed
@aloekun
aloekun deleted the fix/smoke-etxtbsy branch August 19, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant