test(alerts): wait for the alert's tasks and the run, not every task (#5063)
CI / lint (push) Successful in 2s
CI / integration (push) Successful in 46s
CI / unit (push) Successful in 1m4s
CI / publish (push) Successful in 1m25s

CI 8343: the wait-for-all-tasks loop also waited on the executor's
5-minute run-output cleanup task (_schedule_cleanup) and hit its 120s
deadline. Wait on alerts._background, then poll the run to a final status.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 13:48:50 -04:00
co-authored by Claude Opus 5.5
parent 49607a2441
commit 0ec7ce4472
+15 -5
View File
@@ -83,13 +83,23 @@ def test_firing_triggers_ansible_action(app, tmp_path):
async with s.begin():
await record_metric(s, "host_agent", "srv1", "cpu_pct", 95.0)
# Let the dispatch, the action and the run it starts finish. The run's
# task is created by the action's task, so wait until none are left.
# Let the notification and the action finish, then the run the action
# started. Not "every task": a finished run leaves a cleanup task that
# sleeps for minutes (executor._schedule_cleanup).
from steward.core import alerts
loop = asyncio.get_running_loop()
deadline = loop.time() + 120
while pending := [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]:
assert loop.time() < deadline, f"tasks still running: {pending}"
await asyncio.wait(pending, timeout=deadline - loop.time())
while alerts._background:
assert loop.time() < deadline, "the alert's tasks did not finish"
await asyncio.wait(set(alerts._background), timeout=deadline - loop.time())
while True:
async with app.db_sessionmaker() as s:
status = (await s.execute(
select(AnsibleRun.status).where(AnsibleRun.source_name == "t"))).scalar()
if status not in (None, AnsibleRunStatus.queued, AnsibleRunStatus.running):
break
assert loop.time() < deadline, f"the run is still {status}"
await asyncio.sleep(0.5)
async with app.db_sessionmaker() as s:
run = (await s.execute(