From 4dbffb89fc8ae2711ccb62dec67f982d43e6a5f6 Mon Sep 17 00:00:00 2001 From: Ken Sedgwick Date: Fri, 10 Jul 2026 15:36:23 -0700 Subject: [PATCH] tests: fix flaky reckless tests by waiting for the canned github server The canned_github_server fixture Popens a Flask server and never waits for it to start listening; the git repository setup between the Popen and the yield usually gives it enough time. Under CI load it can lose that race: a valgrind-shard failure shows test_search's first reckless invocation getting connection refused within a second of the test starting, while Flask's "Running on http://127.0.0.1:..." banner only appears in the log after the test had already failed. Wait for the port to accept connections before yielding, and fail loudly if the server process dies instead of coming up. Changelog-None --- tests/test_reckless.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/test_reckless.py b/tests/test_reckless.py index d294b79a50ef..c7c7f426bccc 100644 --- a/tests/test_reckless.py +++ b/tests/test_reckless.py @@ -2,7 +2,7 @@ import subprocess from pathlib import PosixPath, Path import socket -from pyln.testing.utils import VALGRIND +from pyln.testing.utils import TIMEOUT, VALGRIND import pytest import os import re @@ -85,6 +85,21 @@ def canned_github_server(directory): del my_env['GIT_INDEX_FILE'] # We also need the github api data for the repo which will be served via http shutil.copyfile(str(FILE_PATH / 'data/recklessrepo/rkls_api_lightningd_plugins.json'), os.path.join(directory, 'rkls_api_lightningd_plugins.json')) + + # Flask can be slow to start listening under CI load; make sure the + # first reckless invocation doesn't race it and get connection refused. + start = time.time() + while True: + assert server.poll() is None, "canned github server died" + try: + with socket.create_connection(('127.0.0.1', int(free_port)), + timeout=5): + break + except OSError: + if time.time() >= start + TIMEOUT: + server.terminate() + raise RuntimeError("canned github server never started listening") + time.sleep(0.2) yield # Delete requirements.txt from the testplugpass directory with open(requirements_file_path, 'w') as f: