Skip to content

test(config): remove Windows startup timing assumptions - #800

Merged
kevincodex1 merged 1 commit into
mainfrom
fix/windows-provider-command-tests
Jul 24, 2026
Merged

test(config): remove Windows startup timing assumptions#800
kevincodex1 merged 1 commit into
mainfrom
fix/windows-provider-command-tests

Conversation

@anandh8x

@anandh8x anandh8x commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • remove cold PowerShell startup assumptions from provider-command timeout tests
  • bound background-child completion by the child's natural lifetime instead of an arbitrary four seconds
  • retain strict PID and liveness checks for synchronized background children

Why

Windows smoke runs repeatedly failed even though provider-command cleanup was working:

  • the basic timeout fixture could be terminated before cold PowerShell startup recorded its PID
  • background-child setup could consume more than three seconds under concurrent CI load, making the one-second WaitDelay path exceed a fixed four-second assertion

The actual safety contract is that execution returns before the 10-second child finishes naturally and that every child known to have started is dead afterward. These tests now assert that behavior directly.

Verification

  • repeated focused provider-command tests
  • Windows/amd64 test-binary cross-compilation
  • make fmt-check
  • go vet ./...
  • go test ./...
  • go run ./cmd/zero-release build
  • go run ./cmd/zero-release smoke
  • go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./...
  • pinned advisory lint (existing unrelated findings only)
  • git diff origin/main...HEAD --check

Summary by CodeRabbit

  • Tests
    • Improved command timeout and background-process termination test reliability.
    • Added platform-tolerant handling for processes that exit before recording their process ID.
    • Strengthened timing checks to verify commands return before background processes naturally finish.

Cold PowerShell startup under concurrent Windows CI can consume most of the provider timeout, so an unsynchronized PID file may never be written and a fixed four-second bound can fail despite correct process-tree cleanup. Treat an absent PID as a helper that never reached startup, retain strict liveness checks for synchronized children, and bound completion by the child's natural lifetime instead.
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 36f8df4f-33d6-4b5c-9b81-11f4c3d67883

📥 Commits

Reviewing files that changed from the base of the PR and between 97ef90d and e7e36fd.

📒 Files selected for processing (1)
  • internal/config/command_test.go

Walkthrough

Provider command termination tests now tolerate missing PID files and use a shared 10-second child lifetime for background-process timing assertions.

Changes

Provider command termination tests

Layer / File(s) Summary
PID-file-aware termination assertions
internal/config/command_test.go
The timeout test uses a helper that skips termination checks when no PID file was created; the helper detects missing files with errors.Is.
Background-child lifetime assertions
internal/config/command_test.go
Success and failure tests derive detached-child sleep durations and elapsed-time checks from childLifetime := 10 * time.Second.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • Gitlawb/zero#690: Updates related LoadProviderCommand timeout and background-child termination tests using PID files.

Suggested reviewers: pierrunoyt, vasanthdev2004

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main test change: removing Windows startup timing assumptions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/windows-provider-command-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.

@github-actions

Copy link
Copy Markdown
Contributor

Zero automated PR review

Verdict: No blockers found

Blockers

  • None found.

Validation

  • [pass] Diff hygiene: git diff --check
  • [pass] Tests: go test ./...
  • [pass] Build: go run ./cmd/zero-release build
  • [pass] Smoke build: go run ./cmd/zero-release smoke

Scope

Head: e7e36fddec21
Changed files (1): internal/config/command_test.go

This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality.

@anandh8x

Copy link
Copy Markdown
Collaborator Author

@kevincodex1 could you please merge this when ready? The same Windows provider-command timing failure is repeatedly blocking unrelated PRs, including #801, even though their Windows-specific changes pass. Landing #800 will stop this known test flake from affecting other PRs.

@kevincodex1

Copy link
Copy Markdown
Contributor

good to merge

@kevincodex1
kevincodex1 merged commit 9d5c82d into main Jul 24, 2026
9 checks passed
kevincodex1 pushed a commit that referenced this pull request Jul 27, 2026
…#810)

Both background-child tests fail intermittently on the Windows runner, and
have since #690. #800 and #802 each relaxed an assertion, which is why neither
held: the deadline itself was the problem.

The tests drove LoadProviderCommand, so the fixture's own startup was billed to
the production 5s budget. On a loaded runner the outer timer won the select in
runProviderCommand, and both symptoms follow from that. The nonzero-exit test
saw a timeout instead of the exit status it asserts, because the timer
preempted the shell's exit. The other test lost its PID file, because the
timer's Terminate killed the background child before it could record a PID,
putting the file permanently out of reach however long the assertion polled.

Neither test is a claim about the 5s budget. They assert which error each
cmd.Wait path yields and that the leftover descendant is killed, so they now
call runProviderCommand directly with a budget of their own and the production
deadline stops competing with process startup. Making the child outlive that
budget lets both drop their elapsed-versus-lifetime bounds as well, so no
wall-clock assertion is left in either test.

That is only worth doing if the two timeout paths can be told apart, and they
could not: the WaitDelay path and the outer-timer path both returned the same
bare sentinel, so asserting on it would have been satisfied by the very timeout
the tests exist to rule out. The WaitDelay path now wraps rather than replaces.
Callers asking errors.Is for the sentinel are unaffected, so no user-visible
message changes.

The Windows fixture also waited for its ready marker by launching a second
PowerShell. That cold start is pure overhead added after the PID is already
written, so the wait now runs in cmd itself and is bounded.

Verified by looping both tests under CPU contention: 7 failures in 16
iterations before, none in 32 after, with per-iteration time going from a
spread of 2.3s to 66s down to a steady 2.1s. Removing the wrap makes the
WaitDelay assertion fail, so it is load-bearing rather than decorative.
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