chore: checkpoint app work before firmware sync

This commit is contained in:
Adolfo Reyna
2026-09-07 23:01:26 -04:00
parent e42036a044
commit 59612020bb
20 changed files with 2111 additions and 1218 deletions
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""Validate MP3 Player close-and-resume evidence captured from serial."""
from __future__ import annotations
import argparse
import re
from pathlib import Path
def evaluate_resume_trace(trace: str, fixture: str, minimum_position: int = 6) -> dict[str, int]:
"""Require real playback, persisted position, and same-file relaunch evidence."""
escaped = re.escape(fixture)
initial = re.search(rf"Starting MP3 playback: {escaped} .* resume=0\b", trace)
stream_opened = re.search(r"Audio stream opened: \d+ Hz, \d+ channels", trace)
persisted = re.search(rf"History saved on hide: {escaped} pos (\d+) total \d+", trace)
resumed = re.search(rf"Resuming last play {escaped} at (\d+) sec from history", trace)
playback_matches = list(re.finditer(rf"Starting MP3 playback: {escaped} .* resume=(\d+)\b", trace))
resumed_playback = playback_matches[-1] if playback_matches else None
if "Playback task stuck, force deleting" in trace:
raise RuntimeError("forced playback task termination invalidates the device test")
if not initial or not stream_opened:
raise RuntimeError("missing verified playback evidence for the fixture")
if not persisted or not resumed or not resumed_playback:
raise RuntimeError("missing persisted or resumed playback evidence")
persisted_position = int(persisted.group(1))
resumed_position = int(resumed.group(1))
resumed_playback_position = int(resumed_playback.group(1))
if persisted_position < minimum_position:
raise RuntimeError(f"persisted position {persisted_position} is below {minimum_position}")
if resumed_position != persisted_position or resumed_playback_position != persisted_position:
raise RuntimeError("relaunch did not resume the persisted position on the same file")
return {"persisted_position": persisted_position, "resumed_position": resumed_position}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--trace", type=Path, required=True, help="Captured serial log")
parser.add_argument("--fixture", required=True, help="Absolute fixture path logged by MP3 Player")
parser.add_argument("--minimum-position", type=int, default=6)
args = parser.parse_args()
result = evaluate_resume_trace(args.trace.read_text(encoding="utf-8", errors="replace"), args.fixture, args.minimum_position)
print(f"PASS persisted_position={result['persisted_position']} resumed_position={result['resumed_position']}")
return 0
if __name__ == "__main__":
raise SystemExit(main())