Skip to content

Fix the three Linux and macOS test failures - #7

Merged
packetloss404 merged 1 commit into
mainfrom
fix/posix-test-failures
Sep 5, 2026
Merged

Fix the three Linux and macOS test failures#7
packetloss404 merged 1 commit into
mainfrom
fix/posix-test-failures

Conversation

@packetloss404

Copy link
Copy Markdown
Owner

The three test failures that were left red on main after the lint, TUI-golden and backlog PRs landed. Three separate causes, and none of them is the behaviour the tests exist to check.

TestKillTreeOnExitedProcessIsConfirmed / TestKillTreeBeforeReapIsUnconfirmedWithReason

Failing on both Linux and macOS with:

exec: command with a non-nil Cancel was not created with CommandContext

Both tests built their command with exec.Command and then called ConfigureTreeCancel, which sets cmd.Cancel. os/exec refuses to start a command that has a Cancel func but no context, and the refusal comes at Start() rather than at the call that installed it.

Every production caller already gets this right — internal/hooks, internal/statusline, internal/mcp, internal/computers all use exec.CommandContext. Only these two tests did not, and they live in a //go:build !windows file, so Windows never compiled them and the mistake went unnoticed on the one platform where the suite was otherwise green.

Fixed by using exec.CommandContext, matching the sibling test in the same file that always passed. ConfigureTreeCancel now documents the requirement, since nothing at the call site hints at it.

TestApp_Undo_RestoreAndDepth

Failing on Linux with:

conversation does not contain "depth now: 0"; got:
· restored /tmp/TestApp_Undo_RestoreAndDepth955380699/001/sample.txt (depth
  now: 0)

Look at the "got". Every character is there. The conversation view soft-wrapped between depth and now:, and the assertion was a literal substring that straddled the break.

Where the wrap lands depends on the length of the message, which embeds a t.TempDir() path — different on every platform. That is the whole reason it passed on Windows and failed on Linux, and it would have kept doing so intermittently.

convContains now compares with whitespace collapsed on both sides, so none of its ~90 call sites can fail over where a line happened to break. The failure message says it is ignoring wrapping, so a future reader is not misled about what was compared.

TestLoopSelfPaced_StartedWhileStreamingKeepsOwnership

Failing on macOS with:

TempDir RemoveAll cleanup: unlinkat .../001/sessions: directory not empty

This one is a real race rather than an assertion artefact. The test starts a turn, which calls agent.Run and therefore starts a goroutine that writes the session via AddMessage into a directory under t.TempDir(). The test then cancels the turn and returns. Cancelling only signals the goroutine, so its final write could still be in flight when t.TempDir()'s RemoveAll ran — and unlinkat fails with directory not empty when a file appears mid-sweep.

It now cancels and then drains, using the drainPump the cancellation tests in app_cancel_test.go already use. Draining is safe here and cannot start a second turn: a cancelled turn ends its loop through stopLoopAfterFailedTurn rather than re-running the body.

TestLoopSelfPaced_StartedIdleClaimsOwnership has the identical shape and the identical race. It had simply not lost it yet, so it is fixed too rather than left to fail on some future macOS run.

Verification

Run on windows/amd64 against the branch tip:

check result
golangci-lint run --max-issues-per-linter=0 --max-same-issues=0 ./... under GOOS=linux, darwin, windows 0 findings each
GOOS=linux go vet ./internal/app/ ./internal/procrun/ exit 0
go test -count=1 ./internal/app/ ./internal/procrun/ ok

Windows is the weakest possible witness here: it cannot compile the two procrun tests at all, and it is the platform on which the undo test already passed. CI on Linux and macOS is the real check, which is what this PR is for.

🤖 Generated with Claude Code

Three separate causes, none of them the behaviour under test.

procrun: TestKillTreeOnExitedProcessIsConfirmed and
TestKillTreeBeforeReapIsUnconfirmedWithReason built their command with
exec.Command and then called ConfigureTreeCancel, which sets cmd.Cancel.
os/exec refuses to start such a command unless it came from
exec.CommandContext, so both failed at Start with "command with a non-nil
Cancel was not created with CommandContext". Every production caller
already uses CommandContext; only these two tests did not, and they live
in a !windows file, so Windows never compiled them and the mistake sat
there. ConfigureTreeCancel now documents the requirement, because the
refusal surfaces at Start rather than at the call.

app: TestApp_Undo_RestoreAndDepth was not failing at all in the sense that
matters. Every character it asserted was present; the view had soft-wrapped
between "depth" and "now:", because the message embeds a t.TempDir() path
and its length decides where the break lands. convContains now compares
with whitespace collapsed, so none of its ninety-odd call sites can fail
for where a line happened to break.

app: TestLoopSelfPaced_StartedWhileStreamingKeepsOwnership was a real race.
It starts a turn, which starts an agent goroutine that writes the session
into a directory under t.TempDir(), then cancels and returns. Cancelling
only signals, so that goroutine's last write raced the TempDir cleanup and
macOS reported "sessions: directory not empty". It now cancels and drains
through the pump the cancellation tests already use. A cancelled turn stops
its loop via stopLoopAfterFailedTurn rather than re-running the body, so
draining cannot start a second turn.

TestLoopSelfPaced_StartedIdleClaimsOwnership has the identical shape and
the identical race; it had simply not lost it yet, and is fixed too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 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-05T18:03:34.901801Z 04dc4c2 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.

@packetloss404
packetloss404 merged commit f0538e7 into main Sep 5, 2026
29 of 32 checks passed
@packetloss404
packetloss404 deleted the fix/posix-test-failures branch September 5, 2026 18:09
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