Private
Public Access
fix(mma_lifecycle): load + start + active_tickets sync for batched tests
The test_visual_sim_mma_v2 failure in tier-3 batch context was caused
by state pollution from prior live_gui tests sharing the subprocess:
1. track state file missing for leftover track:
`_cb_load_track_result` accessed `state.metadata.id` and
`state.metadata.name`, but `EMPTY_TRACK_STATE` (returned when no
state.toml exists for a track_id) had `metadata={}` (a dict, not a
TrackMetadata object). That raised `'dict' object has no attribute
'id'`. Fixed by normalizing metadata: dict -> TrackMetadata.from_dict,
TrackMetadata stays, anything else -> TrackMetadata(id=track_id,
name=track_id).
2. active_track and active_tickets never reached the App:
`_cb_load_track_result` set `self.active_track` (controller) and
`self.active_tickets = []` (via `_load_active_tickets`) but never
mirrored to `self._app.active_track` / `self._app.active_tickets`.
The /api/gui/mma_status endpoint reads `app.X` first via
`_get_app_attr`, so it returned None / [] and the test's poll
`at_id == track_id and bool(s.get('active_tickets'))` failed. Fixed
by mirroring active_track / active_tickets / active_tier to the App.
3. leftover tracks list in batched run:
Without btn_reset, `app.tracks` (App-side) accumulates tracks from
earlier tests in the session. `_get_app_attr(app, 'tracks', [])`
then returns stale leftovers, and the test's
`target_track = next((... if 'hello_world' in t.get('title') else
tracks_list[0]))` picks a leftover with no on-disk state file.
Fixed in TWO places:
(a) btn_reset now also clears `app.tracks = []` so each test starts
clean if it calls btn_reset.
(b) tests/test_visual_sim_mma_v2.py now calls `client.click('btn_reset')`
at the start. The test was the only one in its tier that did NOT
reset; with the live_gui subprocess shared across batched tests,
that's the source of the state pollution.
Also reverted the `TrackState.metadata` default change (dict -> TrackMetadata)
because it broke TrackState() construction (TrackMetadata requires `id`/`name`).
The metadata normalization in `_cb_load_track_result` is sufficient and
preserves backward compatibility with on-disk state.toml files.
Verified: tests/test_visual_sim_mma_v2.py passes in isolation (58.36s)
and tier-3 batch passes when run standalone. Other tests in tier-3
have pre-existing render-loop contention flakes in batched xdist mode
that are unrelated to this fix.
This commit is contained in:
@@ -64,6 +64,19 @@ def test_mma_complete_lifecycle(live_gui) -> None:
|
||||
client = api_hook_client.ApiHookClient()
|
||||
assert client.wait_for_server(timeout=15), "Hook server did not start"
|
||||
|
||||
# Clear any stale state from prior live_gui tests in this batched
|
||||
# subprocess. Without btn_reset, leftover tracks (created by earlier
|
||||
# tests like test_mma_concurrent_tracks_sim / test_visual_mma) sit in
|
||||
# `app.tracks` and become `tracks_list[0]`. The test's `target_track =
|
||||
# next(..., tracks_list[0])` then loads a leftover track whose on-disk
|
||||
# state file does not exist, so `_cb_load_track_result` falls back to
|
||||
# EMPTY_TRACK_STATE → `state.tasks == []` → `bool(active_tickets)` is
|
||||
# False → Stage 6 polls fail. btn_reset clears `app.tracks` / `app.active_tickets`
|
||||
# / `app.active_track` so `tracks_list` reflects only tracks accepted
|
||||
# in this test's plan_epic + accept_tracks batch.
|
||||
client.click("btn_reset")
|
||||
time.sleep(2)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Stage 1: Provider setup
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user