Skip to content

test(tools): TestExecCommandForegroundServerReturnsSessionAndServesHTTP flakes on Windows CI #1097

Description

@PierrunoYT

Version / branch / commit

main at 99721c76 (and PR branches based on it)

OS and environment

GitHub Actions windows-latest, job Smoke (windows-latest) → step Test (Fast Non-Race)

Steps to reproduce

Intermittent. Run the Windows smoke job, e.g. go test ./internal/tools/ -run TestExecCommandForegroundServerReturnsSessionAndServesHTTP on a loaded Windows runner.

Seen on two unrelated PRs so far:

Expected behavior

The test starts the http-server helper through exec_command, reads the listening <addr> line and gets zero-server-ok over HTTP, regardless of runner speed.

Actual behavior

The first exec_command result returns before the helper has printed its address, so the test fails before it ever reaches the HTTP check:

--- FAIL: TestExecCommandForegroundServerReturnsSessionAndServesHTTP (10.52s)
    exec_command_test.go:378: server output did not include listening address: "Command is still running.\nsession_id: 1000\nUse write_stdin with session_id 1000 and empty chars to poll; send chars \"\\u0003\" to interrupt/stop it."
    exec_command_test.go:596: test root C:\Users\RUNNER~1\AppData\Local\Temp\zero-exec-test-2025076317 still held after the cleanup deadline; leaving it
FAIL	github.com/Gitlawb/zero/internal/tools	35.159s

Cause

internal/tools/exec_command_test.go:365-378 starts the server with "yield_time_ms": 500 and parses the listening address from that first result only. On a slow Windows runner, process start-up plus the helper's net.Listen can take longer than 500 ms. The session is still running correctly (session_id: 1000 is returned), and the address just hasn't been printed yet.

The "still held after the cleanup deadline" line follows from the early failure: the server process is still running when the temp root is removed.

Suggested fix

Don't depend on one fixed yield. After the start call, poll the session with write_stdin (empty chars, short yield_time_ms) and accumulate output until parseListeningAddress finds the address, with a generous deadline (e.g. 20 s). The test still checks that a foreground server returns a session_id and serves HTTP.

Activity

  1. Vasanthdev2004 commented on Sep 28, 2026

    @Vasanthdev2004
    Collaborator

    Confirmed on main at 99721c7. It's the same failure I've been hitting locally on Windows all week: the first result comes after a fixed 500 ms yield, and the address check fails if the helper hasn't printed its address yet.

    One more thing worth fixing in the same change. The Ctrl-C cleanup is registered after the address check, so when that check fails the helper server is never stopped. That's where the still held after the cleanup deadline line comes from, and a leaked server can keep the temp root busy into the next test. Registering the cleanup as soon as session_id is known, and then polling with write_stdin for the address as you describe, covers both.

    Approving.

  2. added
    issue-approvedReviewed and approved by the core team; community PRs may implement this issue.
    on Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue-approvedReviewed and approved by the core team; community PRs may implement this issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions