graphql-engine/server/tests-py/ports.py
Samir Talwar 8d7c089273 server/tests-py: Start some node.js test services on random ports.
Where possible, we start the services on random ports, to avoid
port conflicts when parallelizing tests in the future.

When this isn't possible, we explicitly state the port, and wait for the
service to start. This is typically because the GraphQL Engine has already
started with knowledge of the relevant service passed in through an
environment variable.

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5542
GitOrigin-RevId: b51a095b8710e3ff20d1edb13aa576c5272a5565
2022-09-07 16:26:10 +00:00

35 lines
1.1 KiB
Python

import contextlib
import socket
import time
from typing import Optional
def find_free_port() -> int:
"""
Finds a free port.
There is no lock placed on the port, so something else could claim the port
between this function finding a port and returning.
"""
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]
def is_port_in_use(port: int) -> bool:
"""
Checks whether a local port is in use.
"""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(('localhost', port)) == 0
def wait_for_port(port: int, timeout: Optional[float] = None) -> None:
"""
Waits until a port is opened, with an optional timeout.
"""
start_time = time.monotonic()
while timeout is None or (time.monotonic() - start_time) < timeout:
if is_port_in_use(port):
return
time.sleep(0.2)
raise TimeoutError(f'Timed out waiting for port {port}.')