From ffab18ee48401e00f339d9d35d3eb78434eff01e Mon Sep 17 00:00:00 2001 From: Giacomo Vercesi Date: Tue, 21 Jun 2022 11:33:11 +0200 Subject: [PATCH] revng daemon: identify valid port This commit resolves a non-deterministic test failure in `revng daemon`. When running daemon tests, `randint` was used for selecting the listen port, this caused test failures when the same port number was used for reused. This has been replaced with the use of port 0 that guarantees the use of an unused port and psutil to find the port number once it has been bound by the daemon process. --- python/requirements.txt | 1 + share/revng/test/tests/daemon/test.py | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/python/requirements.txt b/python/requirements.txt index 9d6a59fc0..421bb5de6 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -23,3 +23,4 @@ pytest requests requests-toolbelt gql +psutil diff --git a/share/revng/test/tests/daemon/test.py b/share/revng/test/tests/daemon/test.py index 52752aeb3..6f1b5e69b 100755 --- a/share/revng/test/tests/daemon/test.py +++ b/share/revng/test/tests/daemon/test.py @@ -6,7 +6,6 @@ import io import os -from random import randint from subprocess import Popen from time import sleep from typing import Generator @@ -15,6 +14,7 @@ from urllib.request import urlopen from gql import Client, gql from gql.transport.requests import RequestsHTTPTransport +from psutil import Process from pytest import Config, fixture, mark @@ -24,6 +24,16 @@ def print_fd(fd: int): print(out_read.read()) +def get_listen_port(pid: int) -> int: + psutil_process = Process(pid) + while True: + connections = psutil_process.connections() + for connection in connections: + if connection.raddr == () and connection.status == "LISTEN": + return connection.laddr.port + sleep(0.5) + + def check_server_up(port: int): for _ in range(10): try: @@ -38,12 +48,11 @@ def check_server_up(port: int): @fixture def client(pytestconfig: Config, request) -> Generator[Client, None, None]: - port = randint(20000, 65000) - out_fd = os.memfd_create("flask_debug", 0) out = os.fdopen(out_fd, "w") - process = Popen(["revng", "daemon", "-p", str(port)], stdout=out, stderr=out, text=True) + process = Popen(["revng", "daemon", "-p", "0"], stdout=out, stderr=out, text=True) + port = get_listen_port(process.pid) try: check_server_up(port)