Skip to content

Commit 3d7e539

Browse files
wesmclaude
andcommitted
fix: prevent double-consume of server error channel in test helper
Replace the buffered error channel with a done channel and a shared error variable. This prevents the startup-failure path from consuming the only value that cleanup also waits on, which could cause a 5s timeout in cleanup. Also ignore http.ErrServerClosed from Shutdown(), which is benign when the server is already stopped — matching the existing treatment of the serve goroutine's exit error. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8c35560 commit 3d7e539

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

internal/server/server_test.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,11 @@ func (te *testEnv) listenAndServe(t *testing.T) string {
125125
port := server.FindAvailablePort(40000)
126126
te.srv.SetPort(port)
127127

128-
serverErr := make(chan error, 1)
128+
var serveErr error
129+
done := make(chan struct{})
129130
go func() {
130-
serverErr <- te.srv.ListenAndServe()
131+
serveErr = te.srv.ListenAndServe()
132+
close(done)
131133
}()
132134

133135
// Wait for the port to accept connections.
@@ -149,9 +151,9 @@ func (te *testEnv) listenAndServe(t *testing.T) string {
149151
}
150152
if !ready {
151153
select {
152-
case err := <-serverErr:
154+
case <-done:
153155
t.Fatalf(
154-
"server failed to start: %v", err,
156+
"server failed to start: %v", serveErr,
155157
)
156158
default:
157159
}
@@ -166,13 +168,18 @@ func (te *testEnv) listenAndServe(t *testing.T) string {
166168
context.Background(), 5*time.Second,
167169
)
168170
defer cancel()
169-
if err := te.srv.Shutdown(ctx); err != nil {
171+
if err := te.srv.Shutdown(ctx); err != nil &&
172+
err != http.ErrServerClosed {
170173
t.Errorf("server shutdown error: %v", err)
171174
}
172175
select {
173-
case err := <-serverErr:
174-
if err != nil && err != http.ErrServerClosed {
175-
t.Errorf("server exited with error: %v", err)
176+
case <-done:
177+
if serveErr != nil &&
178+
serveErr != http.ErrServerClosed {
179+
t.Errorf(
180+
"server exited with error: %v",
181+
serveErr,
182+
)
176183
}
177184
case <-time.After(5 * time.Second):
178185
t.Error("timed out waiting for server goroutine")

0 commit comments

Comments
 (0)