Skip to content

test(win32): use a portable no-op verify command (#292)#301

Merged
pbean merged 2 commits into
bmad-code-org:mainfrom
dracic:fix/env-fault-verify-script-292
Jul 26, 2026
Merged

test(win32): use a portable no-op verify command (#292)#301
pbean merged 2 commits into
bmad-code-org:mainfrom
dracic:fix/env-fault-verify-script-292

Conversation

@dracic

@dracic dracic commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Closes #292

Note: the approach changed during review (see the review comment); this description was updated by a maintainer to match what ships. The original diagnosis, the Windows reproduction, and the write_script_launcher fix are @dracic's.

Problem

test_fix_phase_session_env_fault_escalates put a POSIX check.sh into a VerifyPolicy command tuple. Verify commands run through the host shell (run_verify_commands is shell=True, verify.py:1379), so on Windows cmd hands that path to ShellExecute — two failure modes, neither of which the test can see:

  • no .sh association (stock Windows): the interactive "How do you want to open this file?" picker pops mid-run and steals focus.
  • .sh associated (e.g. Git for Windows): the associated app launches and the command returns success without the script ever running — a silent false pass.

Either way the test passes, because the fault it asserts comes from an injected SessionResult(env_fault=True), so CI stayed green and only local full-suite runs saw the dialog.

Fix

Two commits, both test-only.

1. tests/test_engine.py — drop the script entirely and use conftest's _OK as the second verify command.

The script was inert: written once as exit 0, never mutated, referenced by no assertion. run_verify_commands does not short-circuit, so its whole contribution was rc 0, twice. It is copy-paste residue from the sibling test_fix_phase_env_fault_escalates_instead_of_looping (tests/test_engine.py:5314), which chmod(0o644)s it mid-run to produce rc=126 — there it is the point. Here the only verify signal is the marker command, and the escalation is the session's.

tests/conftest.py:79-82 is the sanctioned spot for this — the block headed "host-shell verify/lifecycle stub commands (single platform-detection spot)", whose comment reads "These build them per-OS in one place instead of each test file re-deriving the win32 branch." It exports _OK = "exit 0", already imported by tests/test_engine_worktree.py:14.

-    script = project.project / "check.sh"
-    script.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8")
-    script.chmod(0o755)
...
-        verify=VerifyPolicy(commands=(_file_exists_cmd(marker), f'"{script}"')),
+        verify=VerifyPolicy(commands=(_file_exists_cmd(marker), _OK)),

Net +5/−5, no sys.platform branch in the test. A win32 skip was also rejected: the subject (#194 — a fix session that lost its API connection escalates instead of burning dev budget) is not POSIX-specific, unlike the three sibling tests, which skip on win32 because they depend on sh rc 126/127.

2. tests/conftest.pywrite_script_launcher's win32 launcher wrote an explicit \r\n. Path.write_text uses newline=None and already translates to CRLF on Windows, so the explicit \r landed on disk as \r\r\n (reproduced). Harmless for a one-line launcher, and unrelated to #292 once the test stops hand-rolling a launcher — kept as an acknowledged drive-by because the defect is real and the fix is correct.

Verification

  • Windows 11 (original per-OS revision): pytest tests/test_engine.py → 194 passed, 3 skipped, no dialog; pytest tests/test_engine_plugin.py tests/test_opencode_http.py (the write_script_launcher callers) → 112 passed, 4 skipped
  • Linux: pytest tests/test_engine.py → 198 passed; -k env_fault → 6 passed, 0 skipped (unchanged from baseline)
  • Linux: full suite → 2960 passed, 1 skipped; trunk check clean
  • CI: all 11 checks green, including both Windows jobs

Two ablations, since nothing in the suite catches this class on its own — the test's assertions never depended on the script:

  • env_fault=TrueFalse fails the test (the escalation path is still load-bearing)
  • _OKexit 3 fails the test (the second command is genuinely executed, so _OK occupies the same slot the script did)

What _OK buys over a per-OS branch is that the failure mode becomes structurally impossible rather than handled: no script file exists for any shell to mis-handle.

Scope

The three other inline .sh verify sites (_self_disarming_script and test_fix_phase_env_fault_escalates_instead_of_looping) are already @pytest.mark.skipif(sys.platform == "win32"), so this was the only unguarded one. test_install.py's POSIX-script sites are likewise win32-skipped, and the git-hook sites run under git's own sh.

No CHANGELOG entry: test-only.

Follow-up: #302

One finding from this review is deliberately out of scope and filed as its own issue: ENV_FAULT_RCS = frozenset({126, 127}) never matches on Windows — cmd reports a missing or non-executable verify tool as 9009/1, so the charged-attempt behavior #126 exists to prevent still happens on win32, and the three skips above hide it. Reclassifying rc 1 carries a real false-positive risk (under cmd it is also the ordinary "tests failed" code), so it needs its own decision rather than riding a test-only fix.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The env-fault escalation test now creates check.cmd on Windows and an executable check.sh elsewhere, ensuring verify commands use a host-compatible script.

Changes

Test platform compatibility

Layer / File(s) Summary
Platform-specific verify script setup
tests/test_engine.py
The test generates a Windows batch script with exit /b 0, while non-Windows platforms continue using an executable shell script.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Suggested reviewers: pbean

Poem

A bunny hops where scripts run,
check.cmd greets the Windows sun.
Bash still burrows, neat and bright,
No dialog interrupts the night.
Tests leap onward—what a sight!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The test now uses check.cmd on Windows and check.sh elsewhere, preserving Windows coverage as requested in #292.
Out of Scope Changes check ✅ Passed The changes stay confined to the env-fault test and directly support the linked Windows script fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the Windows verify-command fix and matches the main change in the test update.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

dracic and others added 2 commits July 25, 2026 20:39
…rg#292 review)

`Path.write_text` uses `newline=None`, so `\n` is already translated to CRLF on
Windows — the explicit `\r` put `\r\r\n` on disk. `cmd` tolerates it for a
one-line launcher, but it is a parse hazard the moment the helper grows labels
or `goto`, and it is the same defect the per-OS script in the previous commit
was written to avoid.
The env-fault escalation test wrote a POSIX check.sh into its VerifyPolicy
tuple. Verify commands run shell=True, so on Windows cmd hands that path to
ShellExecute: with no .sh association it pops the interactive file picker
mid-run, and with one it launches the associated app and returns success.
Neither is visible to the test — the fault it asserts comes from an injected
SessionResult(env_fault=True) — so CI stayed green.

The script was inert scaffolding: written once as `exit 0`, never mutated,
referenced by no assertion. It is copy-paste residue from the sibling
test_fix_phase_env_fault_escalates_instead_of_looping, which chmods it to 644
mid-run to produce rc=126 — there it is the point. Here the only verify signal
is the marker command.

So drop the file rather than branch on sys.platform for it, and use conftest's
`_OK` for the second command: the host-shell stub block is the sanctioned
single platform-detection spot, and no script file means no shell to mis-handle
one. No behavior change on any platform — `exit 0` either way.
@pbean
pbean force-pushed the fix/env-fault-verify-script-292 branch from 2b6b5ad to 8d06aa5 Compare July 26, 2026 03:41
@pbean

pbean commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

Diagnosis is right and the Windows verification is appreciated — I reproduced the reasoning end to end: run_verify_commands is shell=True (verify.py:1379), so cmd really does hand "…\check.sh" to ShellExecute, and the test can't see it because the fault it asserts comes from the injected SessionResult(env_fault=True). Both of your side observations check out too: Path.write_text uses newline=None, so an explicit \r\n genuinely lands as \r\r\n, and exit /b is the correct form in a batch file. Your scope claim also holds — I swept tests/ and the other POSIX-script sites are either skipif(win32) or run under git's own sh.

I pushed an amendment that changes the approach, so flagging it here rather than merging silently.

The script in that test is inert. It's written once as exit 0, never mutated, and no assertion references it. run_verify_commands doesn't short-circuit, so its entire contribution is rc 0, twice. It's copy-paste residue from the sibling test_fix_phase_env_fault_escalates_instead_of_looping (tests/test_engine.py:5314), where the script is chmod(0o644)-ed mid-run to produce rc=126 — there it's the whole point. Here the only verify signal is the marker command, and the escalation is the session's.

And tests/conftest.py:79-82 is the sanctioned spot for this. That block is headed "host-shell verify/lifecycle stub commands (single platform-detection spot)" and its comment says: "These build them per-OS in one place instead of each test file re-deriving the win32 branch." It exports _OK = "exit 0", already imported by tests/test_engine_worktree.py:14.

So the amendment drops the file instead of branching for it:

-    script = project.project / "check.sh"
-    script.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8")
-    script.chmod(0o755)
...
-        verify=VerifyPolicy(commands=(_file_exists_cmd(marker), f'"{script}"')),
+        verify=VerifyPolicy(commands=(_file_exists_cmd(marker), _OK)),

Net +5/−5, no sys.platform branch, and the failure mode becomes structurally impossible rather than handled per-OS — there's no script file for any shell to mis-handle.

Your conftest commit is kept as-is, authorship intact. Its stated rationale (not symptom-patching the shared helper) no longer applies once the test stops hand-rolling a launcher, but the \r\r\n defect is real and the fix is correct — dropping a correct one-line fix for scope purity would be the worse trade. It's now an acknowledged drive-by.

Verification on this end:

  • pytest tests/test_engine.py → 198 passed; -k env_fault → 6 passed, 0 skipped (unchanged from baseline)
  • full suite → 2960 passed, 1 skipped; trunk check clean
  • two ablations, since nothing in the suite can catch a regression here on its own: flipping env_fault=TrueFalse fails the test (it's still load-bearing), and swapping _OKexit 3 also fails it (the second command is genuinely executed, so _OK occupies the same slot the script did)

One thing left to you: the PR description now documents the superseded per-OS approach — feel free to update it, I'd rather not edit your body. #302 stays open and untouched; the reasoning there for not riding it on a test-only fix is right.

@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown

Greptile Summary

Test-only fix for a Windows incompatibility where test_fix_phase_session_env_fault_escalates wrote a POSIX check.sh into a VerifyPolicy command tuple; on Windows, cmd hands a .sh path to ShellExecute, causing either a file-association dialog or a silent false-pass. A second independent fix corrects a doubled-CR (\r\r\n) in the shared write_script_launcher helper, where an explicit \r\n produced \r\r\n because write_text in text mode already translates \n to \r\n on Windows.

  • tests/test_engine.py: drops the check.sh script creation and replaces it with the cross-platform _OK constant ("exit 0") already defined in conftest.py; the second verify command was always a no-op, so signal for this test was never lost.
  • tests/conftest.py: changes '\r\n' to '\n' in the win32 .cmd launcher line so the file lands on disk with the correct \r\n, not \r\r\n.

Confidence Score: 5/5

Safe to merge; both changes are test-only and confined to fixing Windows-specific file-writing and shell-execution quirks.

The two changes are straightforward: swapping
for
in a .cmd launcher string, and replacing a POSIX-only shell script path with a cross-platform exit 0 constant. Neither touches production code, no logic is inverted, and the semantic intent of each test is preserved.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
tests/conftest.py Fixed double-CR bug in win32 .cmd launcher: explicit \r before \n was producing \r\r\n on disk because write_text text mode already translates \n to \r\n on Windows.
tests/test_engine.py Replaced an inline check.sh verify command with the cross-platform _OK constant ("exit 0"), preventing Windows from routing the .sh path through ShellExecute; also adds _OK to the conftest import list.

Reviews (1): Last reviewed commit: "test(win32): use a portable no-op verify..." | Re-trigger Greptile

@pbean pbean changed the title test(win32): build the env-fault verify script for the host shell (#292) test(win32): use a portable no-op verify command (#292) Jul 26, 2026
@pbean
pbean merged commit 5432c81 into bmad-code-org:main Jul 26, 2026
11 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.

Windows: env-fault engine test replays check.sh through cmd — pops the 'How do you want to open this file?' dialog on every local full-suite run

2 participants