import importlib.util from pathlib import Path RUNNER_PATH = Path(__file__).parents[1] / "scripts" / "mp3_player_device_runner.py" def load_runner(): spec = importlib.util.spec_from_file_location("mp3_player_device_runner", RUNNER_PATH) module = importlib.util.module_from_spec(spec) assert spec.loader is not None spec.loader.exec_module(module) return module def test_resume_trace_requires_playback_persistence_and_same_path_resume(): runner = load_runner() fixture = "/sdcard/download/test.mp3" trace = "\n".join( [ "I Mp3Player: Starting MP3 playback: /sdcard/download/test.mp3 (size: 480000 bytes) resume=0", "I Mp3Player: Audio stream opened: 16000 Hz, 1 channels", "I Mp3Player: History saved on hide: /sdcard/download/test.mp3 pos 9 total 30", "I Mp3Player: Resuming last play /sdcard/download/test.mp3 at 9 sec from history", "I Mp3Player: Starting MP3 playback: /sdcard/download/test.mp3 (size: 480000 bytes) resume=9", ] ) result = runner.evaluate_resume_trace(trace, fixture, minimum_position=6) assert result == {"persisted_position": 9, "resumed_position": 9} def test_resume_trace_rejects_a_different_file_or_no_playback_evidence(): runner = load_runner() fixture = "/sdcard/download/test.mp3" try: runner.evaluate_resume_trace( "I Mp3Player: Starting MP3 playback: /sdcard/other.mp3 (size: 1 bytes) resume=0", fixture, minimum_position=6, ) except RuntimeError as exc: assert "playback" in str(exc).lower() else: raise AssertionError("missing playback evidence must fail") def test_resume_trace_rejects_forced_playback_task_termination(): runner = load_runner() fixture = "/sdcard/download/test.mp3" trace = "\n".join( [ f"I Mp3Player: Starting MP3 playback: {fixture} (size: 480000 bytes) resume=0", "I Mp3Player: Audio stream opened: 16000 Hz, 1 channels", f"I Mp3Player: History saved on hide: {fixture} pos 9 total 180", "W Mp3Player: Playback task stuck, force deleting", f"I Mp3Player: Resuming last play {fixture} at 9 sec from history", f"I Mp3Player: Starting MP3 playback: {fixture} (size: 480000 bytes) resume=9", ] ) try: runner.evaluate_resume_trace(trace, fixture, minimum_position=6) except RuntimeError as exc: assert "forced" in str(exc).lower() else: raise AssertionError("forced task termination must fail the device test")