From 883590fa2c5b25d64d52202fd60d4eaf36418b12 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Sat, 18 Jul 2026 23:14:19 +0100 Subject: [PATCH] Fix flaky autobahn tests (#13173) --- requirements/constraints.txt | 3 -- requirements/dev.txt | 3 -- requirements/test-common-base.in | 1 - requirements/test-common-base.txt | 4 -- requirements/test-common.txt | 4 -- requirements/test-ft.txt | 4 -- requirements/test-mobile.txt | 4 -- requirements/test.txt | 4 -- tests/autobahn/Dockerfile.autobahn | 5 --- tests/autobahn/test_autobahn.py | 66 ++++++++++++++++-------------- 10 files changed, 35 insertions(+), 63 deletions(-) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index b206c6f34a3..5ba2fa07929 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -65,7 +65,6 @@ click==8.4.2 # via # pip-tools # towncrier - # wait-for-it coverage==7.15.1 # via # -r requirements/test-common.in @@ -336,8 +335,6 @@ valkey==6.1.1 # via -r requirements/lint.in virtualenv==21.6.1 # via pre-commit -wait-for-it==2.3.0 - # via -r requirements/test-common-base.in wheel==0.47.0 # via pip-tools yarl==1.24.2 diff --git a/requirements/dev.txt b/requirements/dev.txt index c8566f192dd..f25ae78fc3c 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -65,7 +65,6 @@ click==8.4.2 # via # pip-tools # towncrier - # wait-for-it coverage==7.15.1 # via # -r requirements/test-common.in @@ -326,8 +325,6 @@ valkey==6.1.1 # via -r requirements/lint.in virtualenv==21.6.1 # via pre-commit -wait-for-it==2.3.0 - # via -r requirements/test-common-base.in wheel==0.47.0 # via pip-tools yarl==1.24.2 diff --git a/requirements/test-common-base.in b/requirements/test-common-base.in index 07ad1eb6105..60ccd9d4b59 100644 --- a/requirements/test-common-base.in +++ b/requirements/test-common-base.in @@ -7,4 +7,3 @@ pytest-cov pytest-mock pytest-timeout setuptools-git -wait-for-it diff --git a/requirements/test-common-base.txt b/requirements/test-common-base.txt index 46133d670cf..e0c459cc5fe 100644 --- a/requirements/test-common-base.txt +++ b/requirements/test-common-base.txt @@ -14,8 +14,6 @@ attrs==26.1.0 # via aiohttp backports-asyncio-runner==1.2.0 # via pytest-asyncio -click==8.4.2 - # via wait-for-it coverage==7.15.1 # via pytest-cov exceptiongroup==1.3.1 @@ -85,8 +83,6 @@ typing-extensions==4.16.0 # exceptiongroup # multidict # pytest-asyncio -wait-for-it==2.3.0 - # via -r requirements/test-common-base.in yarl==1.24.2 # via aiohttp diff --git a/requirements/test-common.txt b/requirements/test-common.txt index 594f5da058e..1fe9c9f37a0 100644 --- a/requirements/test-common.txt +++ b/requirements/test-common.txt @@ -22,8 +22,6 @@ blockbuster==1.5.26 # via -r requirements/test-common.in cffi==2.1.0 # via cryptography -click==8.4.2 - # via wait-for-it coverage==7.15.1 # via # -r requirements/test-common.in @@ -146,8 +144,6 @@ typing-extensions==4.16.0 # typing-inspection typing-inspection==0.4.2 # via pydantic -wait-for-it==2.3.0 - # via -r requirements/test-common-base.in yarl==1.24.2 # via aiohttp zlib-ng==1.0.0 diff --git a/requirements/test-ft.txt b/requirements/test-ft.txt index d971d758968..1c94a68019c 100644 --- a/requirements/test-ft.txt +++ b/requirements/test-ft.txt @@ -38,8 +38,6 @@ cffi==2.1.0 # via # cryptography # pycares -click==8.4.2 - # via wait-for-it coverage==7.15.1 # via # -r requirements/test-common.in @@ -174,8 +172,6 @@ typing-extensions==4.16.0 ; python_version < "3.13" # typing-inspection typing-inspection==0.4.2 # via pydantic -wait-for-it==2.3.0 - # via -r requirements/test-common-base.in yarl==1.24.2 # via # -r requirements/runtime-deps.in diff --git a/requirements/test-mobile.txt b/requirements/test-mobile.txt index e29491282f8..870c0227097 100644 --- a/requirements/test-mobile.txt +++ b/requirements/test-mobile.txt @@ -34,8 +34,6 @@ cffi==2.1.0 ; sys_platform != "android" and sys_platform != "ios" # via # -r requirements/test-mobile.in # pycares -click==8.4.2 - # via wait-for-it coverage==7.15.1 # via pytest-cov exceptiongroup==1.3.1 @@ -121,8 +119,6 @@ typing-extensions==4.16.0 ; python_version < "3.13" # exceptiongroup # multidict # pytest-asyncio -wait-for-it==2.3.0 - # via -r requirements/test-common-base.in yarl==1.24.2 # via # -r requirements/runtime-deps.in diff --git a/requirements/test.txt b/requirements/test.txt index f726a405905..2d1125835ff 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -38,8 +38,6 @@ cffi==2.1.0 # via # cryptography # pycares -click==8.4.2 - # via wait-for-it coverage==7.15.1 # via # -r requirements/test-common.in @@ -176,8 +174,6 @@ typing-inspection==0.4.2 # via pydantic uvloop==0.22.1 ; platform_system != "Windows" and implementation_name == "cpython" # via -r requirements/base.in -wait-for-it==2.3.0 - # via -r requirements/test-common-base.in yarl==1.24.2 # via # -r requirements/runtime-deps.in diff --git a/tests/autobahn/Dockerfile.autobahn b/tests/autobahn/Dockerfile.autobahn index ffd90ba282e..fe4b9904aa6 100644 --- a/tests/autobahn/Dockerfile.autobahn +++ b/tests/autobahn/Dockerfile.autobahn @@ -1,6 +1 @@ FROM crossbario/autobahn-testsuite:25.10.1 - -RUN apt-get update && apt-get install python3 python3-pip -y -RUN pip3 install wait-for-it - -CMD ["wstest", "--mode", "fuzzingserver", "--spec", "/config/fuzzingserver.json"] diff --git a/tests/autobahn/test_autobahn.py b/tests/autobahn/test_autobahn.py index 1920b8f2c95..1812a3a3bec 100644 --- a/tests/autobahn/test_autobahn.py +++ b/tests/autobahn/test_autobahn.py @@ -1,6 +1,8 @@ import json import pprint +import socket import subprocess +import time from collections.abc import Iterator from pathlib import Path from typing import TYPE_CHECKING @@ -9,16 +11,27 @@ from pytest import TempPathFactory if TYPE_CHECKING: - from python_on_whales import DockerException, docker + from python_on_whales import docker else: python_on_whales = pytest.importorskip("python_on_whales") - DockerException = python_on_whales.DockerException docker = python_on_whales.docker # (Test number, test status, test report) Result = tuple[str, str, dict[str, object] | None] +def wait_for_port(port: int, timeout: float = 15.0) -> None: + deadline = time.monotonic() + timeout + while True: + try: + with socket.create_connection(("localhost", port), timeout=1): + return + except OSError: + if time.monotonic() >= deadline: # pragma: no cover + raise + time.sleep(0.5) + + @pytest.fixture(scope="session") def report_dir(tmp_path_factory: TempPathFactory) -> Path: return tmp_path_factory.mktemp("reports") @@ -70,34 +83,28 @@ def process_xfail( @pytest.mark.autobahn def test_client(report_dir: Path, request: pytest.FixtureRequest) -> None: - client = subprocess.Popen( - ( - "wait-for-it", - "-s", - "localhost:9001", - "--", - "coverage", - "run", - "-a", - "tests/autobahn/client/client.py", - ) + autobahn_container = docker.run( + detach=True, + image="autobahn-testsuite", + name="autobahn", + remove=True, + volumes=[ + (request.path.parent / "client", "/config"), + (report_dir, "/reports"), + ], + networks=("host",), + command=( + "wstest", + "--mode", + "fuzzingserver", + "--spec", + "/config/fuzzingserver.json", + ), ) try: - autobahn_container = docker.run( - detach=True, - image="autobahn-testsuite", - name="autobahn", - publish=[(9001, 9001)], - remove=True, - volumes=[ - (request.path.parent / "client", "/config"), - (report_dir, "/reports"), - ], - ) - client.wait() + wait_for_port(9001) + subprocess.run(("coverage", "run", "-a", "tests/autobahn/client/client.py")) finally: - client.terminate() - client.wait() autobahn_container.stop() results = get_test_results(report_dir / "clients", "aiohttp") @@ -137,6 +144,7 @@ def test_server(report_dir: Path, request: pytest.FixtureRequest) -> None: ("coverage", "run", "-a", "tests/autobahn/server/server.py") ) try: + wait_for_port(9001) docker.run( image="autobahn-testsuite", name="autobahn", @@ -147,10 +155,6 @@ def test_server(report_dir: Path, request: pytest.FixtureRequest) -> None: ], networks=("host",), command=( - "wait-for-it", - "-s", - "localhost:9001", - "--", "wstest", "--mode", "fuzzingclient",