From 1f1a644e3bc27d3bb703e53152fae4bf6b8908c5 Mon Sep 17 00:00:00 2001 From: Kevin Dunglas Date: Sat, 18 Jul 2026 17:41:51 +0200 Subject: [PATCH] fix(tests): wait for listener readiness in TestWorkerWithInactiveWatcher --- caddy/watcher_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/caddy/watcher_test.go b/caddy/watcher_test.go index 63801b8705..b53afae291 100644 --- a/caddy/watcher_test.go +++ b/caddy/watcher_test.go @@ -3,12 +3,32 @@ package caddy_test import ( + "net" "net/http" "testing" + "time" "github.com/caddyserver/caddy/v2/caddytest" + "github.com/stretchr/testify/require" ) +// waitForListener polls a raw TCP connection instead of an HTTP request so it +// doesn't consume a request from the worker's counter (unlike the initServer +// helper), while still covering the same listener hot-swap race it guards against. +func waitForListener(t *testing.T, addr string) { + t.Helper() + + require.Eventually(t, func() bool { + conn, err := net.DialTimeout("tcp", addr, 200*time.Millisecond) + if err != nil { + return false + } + _ = conn.Close() + + return true + }, 5*time.Second, 100*time.Millisecond, "server failed to become ready") +} + func TestWorkerWithInactiveWatcher(t *testing.T) { tester := caddytest.NewTester(t) tester.InitServer(` @@ -33,6 +53,8 @@ func TestWorkerWithInactiveWatcher(t *testing.T) { } `, "caddyfile") + waitForListener(t, "localhost:"+testPort) + tester.AssertGetResponse("http://localhost:"+testPort, http.StatusOK, "requests:1") tester.AssertGetResponse("http://localhost:"+testPort, http.StatusOK, "requests:2") }