Skip to content

test: fail the test when a shell setup command exits with a non-zero status - #570

Merged
ThomasK33 merged 4 commits into
mainfrom
fix/tests-os-execute-asserts
Nov 12, 2026
Merged

ThomasK33 merged 4 commits into
mainfrom
fix/tests-os-execute-asserts

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Why

assert(os.execute(...)) never fails under LuaJIT. Neovim, busted and the test rocks all run on LuaJIT. Its os.execute returns the raw status: 0 for success and 256 for exit status 1. Every number is truthy in Lua, so the assert passes whatever the command did. A mkdir, ln or touch that failed left the test to run on a setup that did not exist, and the test could pass for the wrong reason. A verifier of #561 found this.

I checked it on busted's LuaJIT (2.1.1744318430) and on Neovim 0.8.0 and 0.12.3 (both Lua 5.1 with LuaJIT): os.execute("exit 1") returns 256 and os.execute("true") returns 0 on each.

What changed

  1. tests/lockfile_test.lua gets a local shell(command) helper that asserts status == 0 or status == true, and names the command when it fails. The or status == true part keeps it right on Lua 5.2 and later, where os.execute returns true for success. It replaces nine assert(os.execute(...)) calls, two of them spread over three lines.
  2. tests/unit/temp_dir_spec.lua checks its one mkdir -p the same way, inline.
  3. A second commit, from the Opus verdict: the chmod that the folder-swap test runs ("should not delete a folder that takes the place of the lock file after the check", lockfile_test.lua line 669) now goes through shell too. That test has no probe, so a failed chmod 000 left its "mode 000" pass running on a readable file, and the test stayed green. With chmod forced to fail, the file gave 33 successes and 0 failures before, and gives 1 failure (failed: false && chmod 000 ...) now. Normally it gives 33 successes.

Only two files had the bug, so there is no new shared helper. Every other place in tests/ that reads an os.execute result already tests == 0 or == true (diff_spec.lua, integration_runner_spec.lua, test_order_helper_spec.lua, tmpdir_suite_spec.lua and the status checks inside lockfile_test.lua). tests/unit/cwd_spec.lua has two more of the broken calls, from #561. They are not in this PR. A forced failure there still turns the test red, at a later line. They go to a tracking issue (F27) that this run files after it lands.

Verification

I made each of the ten commands fail on purpose (false && <command>) and ran its file on origin/main and on this branch. The full table is in the details below.

  • Two sites stayed green before the change and go red now: lockfile_test.lua 958 and 972 on main, which are 964 and 977 after the change (two authentication token tests: a folder named like a lock file, and a link that points nowhere).
  • Seven sites were already red before, but only at a later assertion that hides the cause. Now each fails at the setup, with the command in the message (failed: false && mkdir ...).
  • The temp_dir_spec.lua site passed its setup before, and three later tests failed at temp_dir_spec.lua:47. It now fails at once with cannot create ....
Failure demonstration, each site on origin/main and on this branch

Each site was made to fail by putting false && in front of its command. Each row runs the whole file once.

file and site (line before -> after) before the change after the change
lockfile_test.lua 610 -> 618 32 successes / 1 failure / 0 errors / 0 pending - a later assertion fails: lockfile_test.lua:618: the folder is gone 32 successes / 1 failure / 0 errors / 0 pending - failed: false && mkdir '/tmp/claudecode.CuDPK8/.claud
lockfile_test.lua 670 -> 678 32 successes / 1 failure / 0 errors / 0 pending - a later assertion fails: lockfile_test.lua:685: mode 000: remove returned true: nil 32 successes / 1 failure / 0 errors / 0 pending - remove raised: tests/lockfile_test.lua:347: failed: fa
lockfile_test.lua 709 -> 716 32 successes / 1 failure / 0 errors / 0 pending - a later assertion fails: lockfile_test.lua:701: remove returned false: Lock file does not exist: /tmp/cla 32 successes / 1 failure / 0 errors / 0 pending - failed: false && ln -s '/tmp/claudecode.ybk2Ov/.claud
lockfile_test.lua 721 -> 727 32 successes / 1 failure / 0 errors / 0 pending - a later assertion fails: lockfile_test.lua:701: remove returned false: Lock file does not exist: /tmp/cla 32 successes / 1 failure / 0 errors / 0 pending - failed: false && ln -s '/tmp/claudecode.YPFHbg/.claud
lockfile_test.lua 735 -> 741 32 successes / 1 failure / 0 errors / 0 pending - a later assertion fails: lockfile_test.lua:701: remove returned false: Lock file does not exist: /tmp/cla 32 successes / 1 failure / 0 errors / 0 pending - failed: false && ln '/tmp/claudecode.sIlyBK/.claude/i
lockfile_test.lua 747 -> 753 32 successes / 1 failure / 0 errors / 0 pending - a later assertion fails: lockfile_test.lua:703: the target is gone 32 successes / 1 failure / 0 errors / 0 pending - failed: false && mkdir '/tmp/claudecode.gPmemX/.claud
lockfile_test.lua 748 -> 754 32 successes / 1 failure / 0 errors / 0 pending - a later assertion fails: lockfile_test.lua:701: remove returned false: Lock file does not exist: /tmp/cla 32 successes / 1 failure / 0 errors / 0 pending - failed: false && ln -s '/tmp/claudecode.rDzhLZ/.claud
lockfile_test.lua 958 -> 964 33 successes / 0 failures / 0 errors / 0 pending - the test stays green 32 successes / 1 failure / 0 errors / 0 pending - failed: false && mkdir '/tmp/claudecode.ro
lockfile_test.lua 972 -> 977 33 successes / 0 failures / 0 errors / 0 pending - the test stays green 32 successes / 1 failure / 0 errors / 0 pending - failed: false && ln -s '/tmp/claudecode.K94nha/.cl
temp_dir_spec.lua 15 -> 16 the setup passes and three later tests fail: temp_dir_spec.lua:47: /tmp/claudecode.3gRUQA/dir it's/fixture_spec.lua: No the setup fails at once, 1 error - cannot create /tmp/claudecode.YmMEJ1/dir it's/back\sla

Left as it is

Three other chmod 000 and chmod 555 calls in lockfile_test.lua (lines 583, 633 and 904) have no check either, and I left them. Each is followed by a probe: if the file is still readable or the folder is still writable, the test returns pending("... (root)"). So a chmod that failed shows as a pending test in the run output, but the run stays green and the shown reason wrongly says "(root)". The same tracking issue (F27) covers these three calls and the mkdir -p at line 416, together with moving shell to tests/helpers/. The chmod 600 and chmod 755 calls only restore a mode in cleanup. lockfile_test.lua and integration_runner_spec.lua now each hold a local shell helper. A change that fixes tests/unit/cwd_spec.lua can move it to tests/helpers/.

Gates on c71fe8e9, which merges origin/main 48ca93b into the branch (private XDG folders). A first round of Codex review on 55bc57be found nothing. The chmod commit and the merge came after it:

  • mise run all: native exit 0. luacheck: 0 warnings / 0 errors in 190 files. busted: 1832 successes / 0 failures / 0 errors / 30 pending.
  • mise run format-check: native exit 0 (432 files, 0 changed). check.sh --hash-only matches on all four skills..
  • scripts/run_integration_tests_individually.sh on Neovim 0.12.3: 600 successes, 0 failed, 0 errors, native exit 0. On Neovim 0.8.0: 582 successes, 0 failed, 0 errors, native exit 0.

Generated with xum • Model: anthropic:claude-sonnet-5-5 • Thinking: xhigh

…status

`assert(os.execute(...))` never fails under LuaJIT, which Neovim, busted and
the test rocks all run on. It returns the raw status: 0 for success and 256
for exit status 1, and every number is truthy. So a mkdir, ln or touch that
failed left the test to run on a setup that did not exist, and the test could
pass for the wrong reason.

lockfile_test.lua gets a local `shell` helper that asserts `status == 0 or
status == true`, which holds on LuaJIT and on Lua 5.2 and later. It replaces
nine assert(os.execute(...)) calls, two of them spread over three lines.
temp_dir_spec.lua checks its one mkdir the same way. The other files that run
shell commands already test the status that way.
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

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

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-12T17:50:52.166999Z c71fe8e Manual request
🔒 Security Review ✅ Completed 2026-11-12T17:51:33.695030Z c71fe8e Manual request
ℹ️ 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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 55bc57beb1

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The "should not delete a folder that takes the place of the lock file after the
check" test runs `chmod 000` and `chmod 600` on the lock file, with no check of
the result. Unlike the other chmod calls in the file, it has no probe that
marks the test pending when the mode did not change. So if chmod failed, the
"mode 000" pass ran on a readable file, and the test stayed green.

It now calls the file's `shell` helper, which fails the test and names the
command. With chmod forced to fail, the file gave 33 successes before and 1
failure with `failed: false && chmod 000 ...` now.
@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 55bc57beb1

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: c71fe8e9d9

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: c71fe8e9d9

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 added this pull request to the merge queue Nov 12, 2026
Merged via the queue into main with commit 24b2089 Nov 12, 2026
8 checks passed
@ThomasK33
ThomasK33 deleted the fix/tests-os-execute-asserts branch November 12, 2026 18:38
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