Skip to content

test: if-サブシェル条件内で無効化されていた中間アサーションを拘束化 - #173

Merged
okash1n merged 1 commit into
mainfrom
test/bind-if-subshell-assertions
Sep 8, 2026
Merged

test: if-サブシェル条件内で無効化されていた中間アサーションを拘束化#173
okash1n merged 1 commit into
mainfrom
test/bind-if-subshell-assertions

Conversation

@okash1n

@okash1n okash1n commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

概要

Bash は if の条件として実行されるコマンド(( ... ) サブシェルを含む)に対して errexit を無視し、サブシェル内で set -e を宣言していても効かない(bash 5.3 / 3.2 の両方で実測)。( ... ) || rc=$? の形も同じ。そのため

if (
  cmd1
  [[ a == b ]]
  cmd3
); then pass; else fail; fi

では最後のコマンドの終了コードしか判定に使われず、途中の [[ ]] の失敗は無視される。PR #170 のレビューで tests/unit/test-native-file-tools.sh の 3 ブロックがこの形で非拘束だったことが見つかり同 PR で修正したが、同じ書き方が他の単体テストにも残っていたので全ファイルを監査した。

監査結果

tests/unit/*.shif ( ... ); then / if ! ( ... ); then / ( ... ) || rc=$? ブロックをファイルごとに 1 エージェントが全数確認し、別エージェントが差分を独立検証した。

ファイル ブロック数 結果
test-fonts.sh / test-prerequisites.sh / test-update-refactor.sh / test-setup-refactor.sh / test-mdm-detect.sh 5 / 1 / 6 / 21 / 3 既に拘束済み(最終アサーションのみ、&& 連結、|| exit 1、rc 捕捉)で変更なし
test-deploy-refactor.sh 22 2 箇所: build_settings_file の終了コードが捨てられていた。特に MDM 側は最終判定が ! jq -e ... file なので、ビルドが失敗してファイルが無くても空振りで pass していた(stub で再現)
test-ghostty.sh 15 5 箇所: 否定テストの fixture 生成(_ghostty_test_make_appln -s)と deploy_ghostty_config の終了コード。fixture が作れなくても「拒否された」扱いで pass していた(stub で再現)
test-mdm-install.sh ( ... ) || _rc=$? 11 箇所 5 箇所: launcher の quiescence / quick-exit ケースは最後のコマンドが trap - EXITwhile ループで _rc が常に 0 になり、PGID・group 状態のアサーション 5 件が死んでいた

修正はすべて house style(対象文に || exit 1 を付ける)で、ブロックの再構成や set -e の追加はしていない。stub 関数本体・heredoc・jq テキストには触れていない。

確認

  • 修正した各ブロックで mutation check(アサーションを一時的に反転して FAIL することを確認し、復元)
  • 単体実行: test-deploy-refactor 28/28、test-ghostty 15/15、test-fonts 17/17、test-prerequisites 76/76、test-update-refactor 17/17(brew bash 5.3)
  • test-mdm-install.sh は MDM runner でしか実行できないため、/bin/bash -n(3.2)・/opt/homebrew/bin/bash -n・shellcheck と、対象 2 ケースだけを抽出した scratch harness で PASS を確認。5 並列負荷でも新たに拘束した PGID / group アサーションは一度も落ちていない。本番の実行は CI の unit-tests(MDM スイート含む)で検証
  • shellcheck -S warning: 指摘 0

補足

  • test-mdm-install.sh の quick-exit ケースには今回の変更と無関係な既存の負荷依存 flake がある(set -m 下の setpgid 競合で bash 自身が stderr に child setpgid ...: Operation not permitted を出し、既存の ! -s "$_diagnostic" 判定に引っかかる)。5 並列負荷でのみ再現し、単独 300 回では再現しない。MDM runner は 1 ファイル 1 プロセスで直列実行するため通常は影響しない。今回は手を付けていない
  • テスト専用の変更のため CHANGELOG / バージョンは変更しない(test: pr-creation-log のアサーションを matcher ではなくコマンドで選ぶよう修正 #169 と同じ扱い)

https://claude.ai/code/session_01C9mrbbXQgV9fJ8Zy5UoEYc

Bash は if の条件として実行される ( ... ) サブシェルとその内部の set -e に
対して errexit を無視し、( ... ) || rc=$? も同じ扱いになる。最後のコマンド
の終了コードしか判定に使われないため、途中の [[ ]] や関数呼び出しの失敗は
無視されていた(#170 で test-native-file-tools.sh の 3 ブロックを修正済み)。

tests/unit/*.sh の該当ブロックを全数監査し、実際に非拘束だった 12 文に
house style の `|| exit 1` を付けた。

- test-deploy-refactor.sh (2): build_settings_file の終了コードが捨てられ、
  MDM 側は最終判定が `! jq -e` なのでビルド失敗でも空振りで pass していた
- test-ghostty.sh (5): 否定テストの fixture 生成(_ghostty_test_make_app、
  ln -s)と deploy_ghostty_config の終了コード。fixture が作れなくても
  「拒否された」扱いで pass していた
- test-mdm-install.sh (5): launcher の quiescence / quick-exit ケースは
  最後のコマンドが trap - EXIT や while で _rc が常に 0 になり、PGID と
  group 状態のアサーションが死んでいた

他の 5 ファイル(fonts / prerequisites / update-refactor / setup-refactor /
mdm-detect)は既に拘束済みで変更なし。各修正はアサーションを反転させる
mutation check で FAIL に転じることを確認した。MDM ファイルは CI の
run-mdm-tests.sh が実行時検証。

Claude-Session: https://claude.ai/code/session_01C9mrbbXQgV9fJ8Zy5UoEYc
Copilot AI lite review requested due to automatic review settings September 8, 2026 05:00
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-08T05:12:39.411382Z c6ee0a6 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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.

🟢 Approval recommended

The changes are narrowly scoped to unit-test strictness, follow an established pattern (|| exit 1 in subshell conditions), and don’t introduce functional code-path risk.

Pull request overview

This PR hardens Bash unit tests by ensuring intermediate assertions inside if ( ... ); then subshell condition blocks are binding, avoiding false-positive passes caused by Bash ignoring errexit in conditional command contexts.

Changes:

  • Enforce failure propagation in MDM launcher tests by adding || exit 1 to key assertions inside subshell condition blocks.
  • Make Ghostty unit tests fail fast when fixture creation or config deployment steps fail inside if ( ... ) conditions.
  • Ensure build_settings_file failures are not silently ignored in deploy refactor unit tests.
File summaries
File Description
tests/unit/test-mdm-install.sh Adds `
tests/unit/test-ghostty.sh Adds `
tests/unit/test-deploy-refactor.sh Ensures build_settings_file failures inside subshell conditions abort the condition (prevents “missing output file” from being treated as a pass).
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Lite

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

@okash1n
okash1n merged commit 46e3cb1 into main Sep 8, 2026
12 checks passed
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.

2 participants