From 69b7ab670da3b3ed161fbc5ac3777c6b73ab4d77 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 21 Jun 2026 10:38:17 -0400 Subject: [PATCH] fix(warmup_test): poll for canary records in live_gui test The live_gui subprocess spawns the desktop GUI, which creates AppController with defer_warmup=True (src/gui_2.py:318). Warmup is deferred until the first frame is painted (src/gui_2.py:1076). The previous test queried /api/warmup_canaries immediately after wait_for_server, racing against the first frame - canary list was empty until start_warmup() ran. Replace the immediate assert with a poll-with-retry loop (15s deadline, 0.5s interval) per workflow.md 'Async Setters Need Poll-For-State' rule. --- tests/test_api_hooks_warmup.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/test_api_hooks_warmup.py b/tests/test_api_hooks_warmup.py index eb46661d..fa2bddca 100644 --- a/tests/test_api_hooks_warmup.py +++ b/tests/test_api_hooks_warmup.py @@ -1,6 +1,7 @@ import pytest import sys import os +import time from unittest.mock import patch sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) @@ -108,10 +109,23 @@ def test_get_warmup_canaries_handles_empty_response() -> None: def test_live_warmup_canaries_endpoint(live_gui) -> None: - """Live: GET /api/warmup_canaries returns canary records with thread + status info.""" + """Live: GET /api/warmup_canaries returns canary records with thread + status info. + + The canary list is populated by WarmupManager.submit() which is called + from AppController.start_warmup(). For the live_gui subprocess the warmup + is deferred until the first frame is painted (src/gui_2.py:1076). This + test polls until at least one canary appears, with a 15s deadline, to + handle the race between server-ready and first-frame-painted. + """ client = ApiHookClient() assert client.wait_for_server(timeout=10) - canaries = client.get_warmup_canaries() + canaries: list = [] + deadline = time.time() + 15.0 + while time.time() < deadline: + canaries = client.get_warmup_canaries() + if canaries: + break + time.sleep(0.5) assert isinstance(canaries, list) assert len(canaries) >= 1, "expected at least one canary record from live warmup" for c in canaries: