Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 14:45 UTC
caddytest: make TestReverseProxyHealthCheck deterministic with poll instead of sleep (#7474)
Start lightweight backend servers before starting Caddy so active health checks probe a ready backend instead of the same Caddy instance during provisioning. This removes the startup race without fixed sleeps or polling.
Amirhf committed
Feb 17, 2026 at 15:11 UTC
091add5ae3dc0ab3265e45b4417fc06fb8a05a39
1 file changed
+35
-9
caddytest/integration/reverseproxy_test.go
+35
-9
@@ -8,7 +8,6 @@ import (
8
"runtime"
9
"strings"
10
"testing"
11
- "time"
11
12
"github.com/caddyserver/caddy/v2/caddytest"
13
)
@@ -327,6 +326,41 @@ func TestReverseProxyWithPlaceholderTCPDialAddress(t *testing.T) {
326
}
327
328
func TestReverseProxyHealthCheck(t *testing.T) {
329
+ // Start lightweight backend servers so they're ready before Caddy's
330
+ // active health checker runs; this avoids a startup race where the
331
+ // health checker probes backends that haven't yet begun accepting
332
+ // connections and marks them unhealthy.
333
+ //
334
+ // This mirrors how health checks are typically used in practice (to a separate
335
+ // backend service) and avoids probing the same Caddy instance while it's still
336
+ // provisioning and not ready to accept connections.
337
+
338
+ // backend server that responds to proxied requests
339
+ helloSrv := &http.Server{
340
+ Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
341
+ _, _ = w.Write([]byte("Hello, World!"))
342
+ }),
343
+ }
344
+ ln0, err := net.Listen("tcp", "127.0.0.1:2020")
345
+ if err != nil {
346
+ t.Fatalf("failed to listen on 127.0.0.1:2020: %v", err)
347
+ }
348
+ go helloSrv.Serve(ln0)
349
+ t.Cleanup(func() { helloSrv.Close(); ln0.Close() })
350
+
351
+ // backend server that serves health checks
352
+ healthSrv := &http.Server{
353
+ Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
354
+ _, _ = w.Write([]byte("ok"))
355
+ }),
356
+ }
357
+ ln1, err := net.Listen("tcp", "127.0.0.1:2021")
358
+ if err != nil {
359
+ t.Fatalf("failed to listen on 127.0.0.1:2021: %v", err)
360
+ }
361
+ go healthSrv.Serve(ln1)
362
+ t.Cleanup(func() { healthSrv.Close(); ln1.Close() })
363
+
364
tester := caddytest.NewTester(t)
365
tester.InitServer(`
366
{
@@ -336,12 +370,6 @@ func TestReverseProxyHealthCheck(t *testing.T) {
370
https_port 9443
371
grace_period 1ns
372
}
339
- http://localhost:2020 {
340
- respond "Hello, World!"
341
- }
342
- http://localhost:2021 {
343
- respond "ok"
344
- }
373
http://localhost:9080 {
374
reverse_proxy {
375
to localhost:2020
@@ -355,8 +383,6 @@ func TestReverseProxyHealthCheck(t *testing.T) {
383
}
384
}
385
`, "caddyfile")
358
-
359
- time.Sleep(100 * time.Millisecond) // TODO: for some reason this test seems particularly flaky, getting 503 when it should be 200, unless we wait
386
tester.AssertGetResponse("http://localhost:9080/", 200, "Hello, World!")
387
}
388