From 741d8db2dab320b709797c8847ef8cb7a120ced6 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Sat, 19 Sep 2026 03:11:21 +0530 Subject: [PATCH] test(gateway): trim the TIME_WAIT rebind tests to the two invariants The positive case (bind over a lingering server-side TIME_WAIT socket) lives once, on the api_server adapter, since both adapters share start_tcp_site; the webhook file keeps the negative case (a live listener still wins). That test hung: the blocker never closed the probe connection server-side, so `wait_closed()` waited forever. --- tests/gateway/test_webhook_adapter.py | 30 ++++----------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/tests/gateway/test_webhook_adapter.py b/tests/gateway/test_webhook_adapter.py index 1ced2268af..01f81bb03f 100644 --- a/tests/gateway/test_webhook_adapter.py +++ b/tests/gateway/test_webhook_adapter.py @@ -966,10 +966,8 @@ class TestDualStackBind: class TestExclusiveBindTimeWait: - """macOS binds the listener with ``reuse_address=False`` (exclusive dual-stack bind). On BSD that - also refuses the port while a TIME_WAIT connection from the previous gateway lingers (2*MSL = 30s): - a ``/restart`` re-binds within seconds and used to fail with EADDRINUSE although nobody was - listening (observed on 127.0.0.1:8644; the reconnect watcher only recovered ~50s later).""" + """The TIME_WAIT rebind (positive case: tests/gateway/test_api_server_bind_guard.py, shared + ``start_tcp_site``) must not weaken the exclusive bind: a live listener still wins.""" @staticmethod def _adapter_on(port: int) -> WebhookAdapter: @@ -979,32 +977,12 @@ class TestExclusiveBindTimeWait: port=port, ) - @pytest.mark.macos_only # the exclusive bind (reuse_address=False) is a Darwin-only path - @pytest.mark.asyncio - async def test_explicit_host_rebinds_over_time_wait(self): - """A port held only by a server-side TIME_WAIT socket must not block the bind.""" - listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - listener.bind(("127.0.0.1", 0)) - listener.listen(1) - port = listener.getsockname()[1] - client = socket.create_connection(("127.0.0.1", port)) - accepted, _ = listener.accept() - accepted.close() # the side closing first enters TIME_WAIT: the server side, as on gateway shutdown - client.close() - listener.close() - adapter = self._adapter_on(port) - try: - with patch.object(adapter, "_reload_dynamic_routes"): - assert await adapter.connect() is True - assert adapter.is_connected is True - finally: - await adapter.disconnect() - @pytest.mark.asyncio async def test_explicit_host_still_rejects_live_listener(self): """The TIME_WAIT retry must not weaken exclusivity: a live listener on the same address wins.""" + # The probe's connection must be closed server-side too, or ``wait_closed()`` never returns. blocker = await asyncio.start_server( - lambda _reader, _writer: None, host="127.0.0.1", port=0, reuse_address=False + lambda _reader, writer: writer.close(), host="127.0.0.1", port=0, reuse_address=False ) port = blocker.sockets[0].getsockname()[1] adapter = self._adapter_on(port)