From 71885bdba6c076661d5bd39058f58c1fb6a51354 Mon Sep 17 00:00:00 2001 From: Wolfgang Walther Date: Sat, 11 May 2024 23:07:46 +0200 Subject: [PATCH] test: Avoid freeport() collisions in io tests It's very unlikely, but it can (and did) happen that both the server and admin ports have the same number returned from freeport(). This then leads to a situation where PostgREST will accept the same port in both cases, because the host "localhost" will allow binding to ipv4 or ipv6 respectively. This will make the IO tests fail. This change makes sure that the admin port will never be the same as the server port and thus avoids this problem. --- test/io/postgrest.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/io/postgrest.py b/test/io/postgrest.py index a91c7775e..db556cfdd 100644 --- a/test/io/postgrest.py +++ b/test/io/postgrest.py @@ -102,7 +102,7 @@ def run( env["PGRST_SERVER_UNIX_SOCKET"] = str(socketfile) baseurl = "http+unix://" + urllib.parse.quote_plus(str(socketfile)) - adminport = freeport() + adminport = freeport(port) env["PGRST_ADMIN_SERVER_PORT"] = str(adminport) adminurl = f"http://localhost:{adminport}" @@ -169,12 +169,15 @@ def metapostgrest(): yield postgrest -def freeport(): +def freeport(used_port=None): "Find a free port on localhost." - with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: - s.bind(("", 0)) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - return s.getsockname()[1] + while True: + with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: + s.bind(("", 0)) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + port = s.getsockname()[1] + if port != used_port: + return port def wait_until_exit(postgrest):