feat(k1): complete canonical control lifecycle

This commit is contained in:
DCCONSTRUCTIONS
2026-07-19 01:07:02 +03:00
parent d7a2c22faf
commit ffffee1879
42 changed files with 3577 additions and 556 deletions
+89 -1
View File
@@ -64,6 +64,23 @@ def _burst_ffmpeg(tmp_path: Path) -> Path:
return executable
def _clean_source_end_ffmpeg(tmp_path: Path) -> Path:
executable = tmp_path / "clean-source-end-ffmpeg"
executable.write_text(
f"#!{sys.executable}\n"
"import sys, time\n"
"def box(kind, payload=b''):\n"
" return (8 + len(payload)).to_bytes(4, 'big') + kind + payload\n"
"sys.stdout.buffer.write(box(b'ftyp', b'isom') + box(b'moov'))\n"
"sys.stdout.buffer.write(box(b'moof') + box(b'mdat', b'final-frame'))\n"
"sys.stdout.buffer.flush()\n"
"time.sleep(0.15)\n",
encoding="utf-8",
)
executable.chmod(0o700)
return executable
def _buffered_tail_ffmpeg(tmp_path: Path, sentinel: Path, *, fragments: int) -> Path:
executable = tmp_path / "buffered-tail-ffmpeg"
executable.write_text(
@@ -289,6 +306,76 @@ def test_acquisition_records_without_browser_and_source_switch_seals_epochs(
gateway.close()
def test_expected_camera_source_end_during_device_stop_seals_complete_epoch(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setenv(
"MISSIONCORE_FFMPEG_BINARY",
str(_clean_source_end_ffmpeg(tmp_path)),
)
gateway = XgridsK1CameraGateway(tmp_path, XGRIDS_K1_PLUGIN_ID)
session = tmp_path / "session"
session.mkdir()
try:
selected = gateway.select("sensor.camera.left", "192.168.1.20")
gateway.start_recording(session)
gateway.expect_source_end_for_device_stop()
_wait_until(
lambda: gateway.snapshot()["recording"]["completed_epochs"] == 1,
)
state = gateway.snapshot()
assert state["phase"] == "idle"
assert state["error"] is None
assert state["delivery"] is None
assert state["recording"]["active"] is True
assert state["recording"]["source_end_expected"] is False
gateway.stop_recording(status="complete")
epoch = (
session
/ "media"
/ "sensor.camera.left"
/ f"epoch-{selected['generation']}"
)
summary = json.loads((epoch / "summary.json").read_text(encoding="utf-8"))
assert summary["status"] == "complete"
assert summary["failure_code"] is None
assert summary["media_segment_count"] == 1
finally:
gateway.close()
def test_unexpected_camera_source_end_remains_a_recording_failure(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.setenv(
"MISSIONCORE_FFMPEG_BINARY",
str(_clean_source_end_ffmpeg(tmp_path)),
)
gateway = XgridsK1CameraGateway(tmp_path, XGRIDS_K1_PLUGIN_ID)
session = tmp_path / "session"
session.mkdir()
try:
selected = gateway.select("sensor.camera.left", "192.168.1.20")
gateway.start_recording(session)
_wait_until(lambda: gateway.snapshot()["phase"] == "error")
epoch = (
session
/ "media"
/ "sensor.camera.left"
/ f"epoch-{selected['generation']}"
)
summary = json.loads((epoch / "summary.json").read_text(encoding="utf-8"))
assert summary["status"] == "interrupted"
assert summary["failure_code"] == "camera-source-ended"
finally:
gateway.close()
def test_camera_storage_open_failure_is_loud_and_never_starts_ffmpeg(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
@@ -501,7 +588,8 @@ def test_service_publishes_two_dynamic_camera_rows_and_stale_stop_is_safe(
service._compatibility_attestation = {
"firmware_version": "3.0.2",
"topology": "direct-lan",
"basis": "operator-attested",
"verification": "live-device-info",
"basis": "selected-profile-live-device-info-required",
"observed_at": "2026-07-16T20:00:00Z",
}