From e7774e3605dc26ea6e6a0416137a09eab119e11d Mon Sep 17 00:00:00 2001 From: PierrunoYT Date: Fri, 2 Oct 2026 19:29:29 +0200 Subject: [PATCH] test(tools): poll for listening address in foreground server test TestExecCommandForegroundServerReturnsSessionAndServesHTTP parsed the helper's listening address from the first exec_command result only, with a 500 ms yield. On a loaded Windows runner the helper had not printed its address yet, so the test failed even though the session was running. Poll the session with write_stdin until the address appears (20 s deadline), and register the cleanup before the address check so the server is stopped on early failure too. Fixes #1097 Co-Authored-By: Claude Sonnet 5.5 --- internal/tools/exec_command_test.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/internal/tools/exec_command_test.go b/internal/tools/exec_command_test.go index ab45823f1..510e59c27 100644 --- a/internal/tools/exec_command_test.go +++ b/internal/tools/exec_command_test.go @@ -373,20 +373,34 @@ func TestExecCommandForegroundServerReturnsSessionAndServesHTTP(t *testing.T) { if err != nil { t.Fatalf("foreground server should return session_id, meta=%#v output=%q", start.Meta, start.Output) } - addr := parseListeningAddress(start.Output) - if addr == "" { - t.Fatalf("server output did not include listening address: %q", start.Output) - } t.Cleanup(func() { writeTool.Run(context.Background(), map[string]any{ "session_id": sessionID, "chars": "\u0003", }) }) + // Process start-up and net.Listen can outlast the first yield on a loaded + // runner, so keep polling the session until the address shows up. + output := start.Output + addr := parseListeningAddress(output) + for deadline := time.Now().Add(20 * time.Second); addr == "" && time.Now().Before(deadline); { + poll := writeTool.Run(context.Background(), map[string]any{ + "session_id": sessionID, + "yield_time_ms": 250, + }) + if poll.Status != StatusOK { + t.Fatalf("write_stdin poll status = %s: %s", poll.Status, poll.Output) + } + output += "\n" + poll.Output + addr = parseListeningAddress(output) + } + if addr == "" { + t.Fatalf("server output did not include listening address: %q", output) + } response, err := http.Get("http://" + addr) if err != nil { - t.Fatalf("foreground exec server was not reachable at %s: %v; output=%q", addr, err, start.Output) + t.Fatalf("foreground exec server was not reachable at %s: %v; output=%q", addr, err, output) } defer response.Body.Close() bytes, err := io.ReadAll(response.Body)