From 737cf0771cb0328603ff95d817f644debb2a21e4 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sat, 8 Aug 2026 12:21:02 +0200 Subject: [PATCH] test(image): bind the fixture Flask server to an ephemeral port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The URL-image tests hard-coded port 5555 and never shut the server down, so a leftover or concurrent run left the port occupied and the readiness loop fell through silently — the tests then ran against whatever was listening, or against nothing. Use werkzeug's make_server on port 0, record the assigned port, and shut the server down in tearDownClass. The readiness loop now raises instead of falling through when the server never comes up. Co-Authored-By: Claude Opus 5 --- tests/abstract/test_abstract_blocks.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/abstract/test_abstract_blocks.py b/tests/abstract/test_abstract_blocks.py index c4770ed..795b70f 100644 --- a/tests/abstract/test_abstract_blocks.py +++ b/tests/abstract/test_abstract_blocks.py @@ -307,6 +307,8 @@ class TestImagePIL(unittest.TestCase): if FLASK_AVAILABLE and hasattr(cls, 'flask_thread'): cls.flask_server_running = False + cls.flask_server.shutdown() + cls.flask_server.server_close() cls.flask_thread.join(timeout=2) @classmethod @@ -350,10 +352,9 @@ class TestImagePIL(unittest.TestCase): """Start a Flask server for URL testing.""" import urllib.request import urllib.error + from werkzeug.serving import make_server cls.flask_app = Flask(__name__) - cls.flask_port = 5555 # Use a specific port for testing - cls.flask_server_running = True @cls.flask_app.route('/test.jpg') def serve_test_image(): @@ -363,11 +364,12 @@ class TestImagePIL(unittest.TestCase): def health_check(): return 'OK', 200 - def run_flask(): - cls.flask_app.run(host='127.0.0.1', port=cls.flask_port, debug=False, - use_reloader=False, threaded=True) + # Bind to an ephemeral port so concurrent/leftover test runs can't clash + cls.flask_server = make_server('127.0.0.1', 0, cls.flask_app, threaded=True) + cls.flask_port = cls.flask_server.server_port + cls.flask_server_running = True - cls.flask_thread = threading.Thread(target=run_flask, daemon=True) + cls.flask_thread = threading.Thread(target=cls.flask_server.serve_forever, daemon=True) cls.flask_thread.start() # Wait for server to be ready with health check @@ -379,12 +381,15 @@ class TestImagePIL(unittest.TestCase): try: with urllib.request.urlopen(f'http://127.0.0.1:{cls.flask_port}/health', timeout=1) as response: if response.status == 200: - break + return except (urllib.error.URLError, ConnectionRefusedError, OSError): pass time.sleep(wait_interval) elapsed += wait_interval + raise RuntimeError( + f"Test Flask server did not become ready on port {cls.flask_port} within {max_wait}s") + def test_image_url_detection(self): """Test URL detection functionality.""" img = Image()