Repository navigation
test(tools): stop the tty session before removing its root - #1175
Conversation
TestExecCommandTTYSkipsInteractiveBlock runs ssh to a bogus host under tty with a 250ms yield. When ssh is still resolving the host after the yield, the session keeps running in the test's directory and nothing stops it, so on Windows t.TempDir's cleanup fails with a sharing violation. It failed Smoke (windows-latest) on a README-only PR. Stop the session in a cleanup, and build the tool on execTestRoot, which retries the removal while Windows still holds the directory right after the stop, as the other exec tests that leave a session do.
Zero automated PR reviewVerdict: No blockers found Blockers
Validation
ScopeHead: This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality. |
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Update TTY test setup internal/tools/exec_command_test.go |
The test uses execTestRoot and a named session manager, and registers cleanup to stop sessions. Its comment allows for SSH to still be resolving after the initial yield. |
Priority:
Estimated code review effort: 1 (Trivial) | ~4 minutes
Change: Bug fix
Suggested reviewers: anandh8x
Merge Risk: 
Minimal · up to a4578
-
No actionable merge-blocking risk is identified in this test-only change.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passedFull details: Docstring Coverage
-
Explanation
Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 1 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Warning
Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.
Comment @coderabbitai help to get the list of available commands.
jatmn
left a comment
There was a problem hiding this comment.
🟢 Thanks for the contribution. I do not see any actionable issues from my review.
Reviewed head a4578dacc0c805a700e9483d361f9d2484257c0f against merge base 164150633a8b2e6ae864ae02fd7105b201eeb68e and live main at b837448dd4fbf2915b65a471ea4c63d50512cc89.
Merge readiness
GitHub reports MERGEABLE, CLEAN, and APPROVED; all 13 checks pass, including Windows/macOS/Linux smoke, race detection, lint, security, and CodeQL. Main's two intervening commits only change README content and assets; there is no overlapping code or release-metadata drift. The author's verified collaborator status qualifies for the internal contribution process. No duplicate or superseding open repair was identified; merged #1110 addresses a different foreground-server startup race.
Changed contract
| Surface | Verified behavior |
|---|---|
| Session ownership | The tool and cleanup use the same test-local manager. |
| Lifecycle and ordering | Create root → launch/register session → check interactive guard → stop sessions → remove root. Cleanup LIFO preserves this order after both ordinary return and assertion failure. |
| Completion and failure | Empty/already completed sessions are safe; a retained session receives tree termination and the existing bounded wait before root removal retries. |
| Siblings and claims | Only this test changes. Its SSH input and interactive-guard assertion are preserved; no operator-facing surface, production API, persistence, dependency, or workflow changes. |
Validation
- Focused Linux race tests covering this test, the paired interactive guard, session StopAll, and PTY input passed with
-count=5. - A review-only overlay used the existing long-sleep helper to guarantee a retained process and independently check that teardown leaves no live session and removes the root. It passed five times under the race detector. Removing the stop callback caused the intended live-session assertion to fail; the probe then cleaned up its process.
- Formatting and diff hygiene passed. The current Windows smoke log confirms the tools package, release build, and smoke passed. The earlier README-only PR's failed Windows attempt independently confirms this exact test's directory-sharing failure.
- Local Windows/macOS execution was unavailable; platform validation comes from the current CI runs. Full-repository build, test, vet, and security results come from CI. The reviewed checkout was unchanged.
What changed
TestExecCommandTTYSkipsInteractiveBlocknow stops its session in a cleanup and builds its tool onexecTestRoot(t)instead of a baret.TempDir(), the way the other exec tests that leave a session running already do. Test-only.Why
The test runs
ssh host.example.comwithtty: trueand a 250 ms yield. When ssh is still resolving the host after 250 ms, the tool returns with the session running in the test's directory, and nothing ever stops it. On Windows,t.TempDir's cleanup then fails:That is what failed
Smoke (windows-latest)on #1174, which only touches the READMEs, and on #1167 before it.StopAllterminates the session and waits for it.execTestRootthen retries the removal for the moment Windows still holds the directory after the stop, which is what it is there for.Linked issue
None. Maintainer fix for a recurring Windows CI flake, opened through the internal development process.
Verification
On Windows:
long-sleephelper undertty: true) fails on a baret.TempDir()with the same sharing-violation error, and passes with this change.execTestRootwithout the stop passes but waits about 6 s for the sleeping process; the stop withoutexecTestRootpasses here but leaves the release windowexecTestRootexists for. Both together pass in under a second.go vet ./...for windows, linux and darwin,gofmt,git diff --check,go test ./..., the release build and smoke, andgovulncheckfor linux and windows all pass. The pinnedgolangci-lintrun overinternal/toolsreports only the existingweb_fetch.go:315QF1008 note.Summary by CodeRabbit