feat(plugins): isolate device integrations
This commit is contained in:
+21
-20
@@ -16,7 +16,8 @@ from fastapi import APIRouter, HTTPException, Response
|
||||
from fastapi.routing import APIRoute
|
||||
|
||||
import k1link.sessions.media as recorded_media_module
|
||||
from k1link.mqtt.capture import FRAME_HEADER, RAW_MAGIC
|
||||
from k1link.device_plugins.xgrids_k1 import xgrids_k1_archive_source
|
||||
from k1link.device_plugins.xgrids_k1.mqtt.capture import FRAME_HEADER, RAW_MAGIC
|
||||
from k1link.sessions import (
|
||||
MaterializedRecording,
|
||||
RecordedMediaInspector,
|
||||
@@ -27,8 +28,8 @@ from k1link.sessions import (
|
||||
SessionStore,
|
||||
)
|
||||
from k1link.sessions.media import _manifest_generation_sha256
|
||||
from k1link.viewer.recorded import recorded_blueprint_rrd
|
||||
from k1link.viewer.rerun_bridge import RerunSceneSettings
|
||||
from k1link.viewer.rrd_export import recorded_blueprint_rrd
|
||||
from k1link.web.camera_archive import CameraArchiveWriter
|
||||
from k1link.web.session_api import (
|
||||
LayoutPutRequest,
|
||||
@@ -195,7 +196,7 @@ def test_session_router_lists_details_and_dispatches_opaque_replay(tmp_path: Pat
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
observed: list[ReplayCommand] = []
|
||||
|
||||
async def launch(command: ReplayCommand) -> dict[str, Any]:
|
||||
@@ -238,7 +239,7 @@ def test_session_router_lists_details_and_dispatches_opaque_replay(tmp_path: Pat
|
||||
"dispatched": True,
|
||||
}
|
||||
assert replay["runtime_state"]["source_mode"] == "replay"
|
||||
assert observed[0].source_path.name == "mqtt.raw.k1mqtt"
|
||||
assert observed[0].primary_artifact.path.name == "mqtt.raw.k1mqtt"
|
||||
for value in (listing, detail, replay):
|
||||
assert_no_local_paths(value, repository)
|
||||
|
||||
@@ -250,7 +251,7 @@ def test_session_router_returns_seekable_recording_and_serves_byte_ranges(
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
payload = b"RRD-seekable-recording"
|
||||
export_calls = 0
|
||||
|
||||
@@ -354,7 +355,7 @@ def test_cold_replay_returns_quick_202_then_status_returns_ready_launch(
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
started = threading.Event()
|
||||
release = threading.Event()
|
||||
calls = 0
|
||||
@@ -579,7 +580,7 @@ def test_recording_response_releases_pin_once_when_asgi_send_fails(
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
recording_path = tmp_path / "pinned.rrd"
|
||||
payload = b"RRD-pinned-response"
|
||||
recording_path.write_bytes(payload)
|
||||
@@ -663,7 +664,7 @@ def test_preparation_status_and_cancel_are_bound_to_exact_job_etag(tmp_path: Pat
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
started = threading.Event()
|
||||
release = threading.Event()
|
||||
|
||||
@@ -740,7 +741,7 @@ def test_stale_status_poll_does_not_create_a_replacement_job(tmp_path: Path) ->
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
calls = 0
|
||||
|
||||
def exporter(_source: Path, _destination: Path) -> dict[str, object]:
|
||||
@@ -782,7 +783,7 @@ def test_ready_post_uses_each_callers_playback_without_mutating_shared_job(
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
calls = 0
|
||||
|
||||
def exporter(source: Path, destination: Path) -> dict[str, object]:
|
||||
@@ -849,7 +850,7 @@ def test_production_router_never_materializes_recording_inline(tmp_path: Path) -
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
calls = 0
|
||||
|
||||
def exporter(_source: Path, _destination: Path) -> dict[str, object]:
|
||||
@@ -887,7 +888,7 @@ def test_recorded_blueprint_endpoint_is_small_strict_and_session_scoped(
|
||||
sessions = repository / "sessions"
|
||||
session = make_legacy_session(sessions, "20260716T205632Z_viewer_live")
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
observed_settings: list[RerunSceneSettings] = []
|
||||
|
||||
def capture_settings(settings: RerunSceneSettings, **kwargs: Any) -> bytes:
|
||||
@@ -977,7 +978,7 @@ def test_session_router_exposes_opaque_recorded_media_manifest_and_ranges(
|
||||
writer.close()
|
||||
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
payload = b"recording"
|
||||
|
||||
def export_recording(source: Path, destination: Path) -> dict[str, object]:
|
||||
@@ -1189,7 +1190,7 @@ def test_ready_launch_uses_background_prepared_camera_manifest_without_rescan(
|
||||
)
|
||||
writer.close()
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
|
||||
def exporter(source: Path, destination: Path) -> dict[str, object]:
|
||||
payload = b"prepared-recording"
|
||||
@@ -1300,7 +1301,7 @@ def test_recorded_media_epoch_ends_are_monotonic_generation_bound_and_not_rrd_pa
|
||||
)
|
||||
second.close()
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
command = store.prepare_replay(session.name)
|
||||
artifact = store.list_recorded_media(session.name)[0]
|
||||
manifest = RecordedMediaInspector().inspect(artifact, command)
|
||||
@@ -1353,7 +1354,7 @@ def test_recorded_media_rejects_non_monotonic_segments_and_overlapping_epochs(
|
||||
)
|
||||
writer.close()
|
||||
store = SessionStore(non_monotonic_root, data_dir=tmp_path / "non-monotonic-data")
|
||||
store.import_legacy_viewer_live(non_monotonic_root / "sessions")
|
||||
store.reconcile_archive(xgrids_k1_archive_source(non_monotonic_root / "sessions"))
|
||||
with pytest.raises(SessionIntegrityError, match="strictly monotonic"):
|
||||
RecordedMediaInspector().inspect(
|
||||
store.list_recorded_media(non_monotonic_session.name)[0],
|
||||
@@ -1384,7 +1385,7 @@ def test_recorded_media_rejects_non_monotonic_segments_and_overlapping_epochs(
|
||||
)
|
||||
second.close()
|
||||
store = SessionStore(overlap_root, data_dir=tmp_path / "overlap-data")
|
||||
store.import_legacy_viewer_live(overlap_root / "sessions")
|
||||
store.reconcile_archive(xgrids_k1_archive_source(overlap_root / "sessions"))
|
||||
with pytest.raises(SessionIntegrityError, match="overlap"):
|
||||
RecordedMediaInspector().inspect(
|
||||
store.list_recorded_media(overlap_session.name)[0],
|
||||
@@ -1403,7 +1404,7 @@ def test_background_preparation_fails_closed_on_unparseable_recorded_media(
|
||||
writer.append("media", b"not-an-iso-bmff-fragment")
|
||||
writer.close()
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
|
||||
def exporter(source: Path, destination: Path) -> dict[str, object]:
|
||||
return {
|
||||
@@ -1463,7 +1464,7 @@ def test_background_preparation_rejects_camera_outside_rrd_timeline(
|
||||
)
|
||||
writer.close()
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
|
||||
def exporter(source: Path, destination: Path) -> dict[str, object]:
|
||||
payload = b"short-spatial-recording"
|
||||
@@ -1526,7 +1527,7 @@ def test_recorded_media_preparation_sidecar_reuses_and_rebuilds_generation(
|
||||
)
|
||||
writer.close()
|
||||
store = SessionStore(repository, data_dir=tmp_path / "data")
|
||||
store.import_legacy_viewer_live(sessions)
|
||||
store.reconcile_archive(xgrids_k1_archive_source(sessions))
|
||||
command = store.prepare_replay(session.name)
|
||||
artifact = store.list_recorded_media(session.name)[0]
|
||||
cache_root = tmp_path / "prepared-media"
|
||||
|
||||
Reference in New Issue
Block a user