From a1f60dd3238ecd183f988c38dccd5ad489ea8c85 Mon Sep 17 00:00:00 2001 From: Simon Koudijs Date: Tue, 6 Oct 2026 08:39:43 +0000 Subject: [PATCH] test(examples): wait for the refused session's release before disconnecting TestGatewayRouteRefusesAndDisconnects flaked in CI with "closed 2 gateway connections, want 1". The refused session's handler flushes its terminal frame before its deferred release removes it from the connection registry, so on a slow runner the forced disconnect could still count it. Wait for the registry to drop it first. Co-Authored-By: Claude Opus 5.5 --- .../examples/comparison/comparison_test.go | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/gateway/kube/examples/comparison/comparison_test.go b/gateway/kube/examples/comparison/comparison_test.go index e80eb5b..73b6b34 100644 --- a/gateway/kube/examples/comparison/comparison_test.go +++ b/gateway/kube/examples/comparison/comparison_test.go @@ -230,6 +230,15 @@ func TestGatewayRouteRefusesAndDisconnects(t *testing.T) { if n := backend.watches.Load(); n != 0 { t.Fatalf("a refused session opened %d upstream watches", n) } + // The terminal frame is flushed before the handler returns and releases its connection, so + // wait for that release; otherwise the forced disconnect below can still count it. + deadline := time.Now().Add(5 * time.Second) + for openConnections(h.connections, "gateway") != 0 { + if time.Now().After(deadline) { + t.Fatal("the refused session's connection was never released") + } + time.Sleep(10 * time.Millisecond) + } // The viewer: a projected snapshot. The Secret's value is withheld, and its path is named. res, r = open("v") @@ -253,7 +262,7 @@ func TestGatewayRouteRefusesAndDisconnects(t *testing.T) { if _, err := r.ReadString(0); err == nil { t.Fatal("the stream survived a forced disconnect") } - deadline := time.Now().Add(5 * time.Second) + deadline = time.Now().Add(5 * time.Second) for h.metrics.Snapshot().Gauges["gateway.full.upstream_watches_active"] != 0 { if time.Now().After(deadline) { t.Fatal("the upstream watch was not stopped after its stream ended") @@ -265,3 +274,16 @@ func TestGatewayRouteRefusesAndDisconnects(t *testing.T) { t.Fatalf("counters: %v", c) } } + +// openConnections reports how many connections of kind are still registered. +func openConnections(c *connections, kind string) int { + c.mu.Lock() + defer c.mu.Unlock() + n := 0 + for _, conn := range c.conns { + if conn.kind == kind { + n++ + } + } + return n +}