import assert from "node:assert/strict"; import { after, before, test } from "node:test"; import { createServer } from "vite"; let server; let xgridsK1Manifest; let xgridsK1ObservationSources; let openObservationSource; let shouldRestartObservationSource; let consumeCameraLeaseRetry; let resetCameraLeaseRetryBudget; before(async () => { server = await createServer({ appType: "custom", logLevel: "silent", server: { middlewareMode: true }, }); ({ xgridsK1Manifest } = await server.ssrLoadModule( "/src/device-plugins/xgrids-k1/manifest.ts", )); ({ xgridsK1ObservationSources } = await server.ssrLoadModule( "/src/device-plugins/xgrids-k1/observationSources.ts", )); ({ openObservationSource, shouldRestartObservationSource } = await server.ssrLoadModule( "/src/core/observation/layoutPolicy.ts", )); ({ consumeCameraLeaseRetry, resetCameraLeaseRetryBudget } = await server.ssrLoadModule( "/src/components/MseFmp4WebSocketPlayer.tsx", )); }); after(async () => { await server?.close(); }); function model() { const activeModel = xgridsK1Manifest.spec.models[0]; assert.ok(activeModel, "XGRIDS plugin must declare at least one model"); return activeModel; } function cameraRow(sourceId, label) { return { stream_id: `camera.preview.${sourceId.split(".").at(-1)}`, source_id: sourceId, semantic_channel_id: "camera.preview.live", label, sensor_kind: "camera", modality: "encoded-video", availability: "available", endpoint_label: "MSE · fMP4", activation: { group_id: "camera.preview.decoder", max_active: 1, selected: false, controllable: true, }, delivery: null, }; } function declaredState(cameraRows = [ cameraRow("sensor.camera.left", "K1 · камера слева"), cameraRow("sensor.camera.right", "K1 · камера справа"), ]) { const activeModel = model(); return { phase: "connected", source_mode: "idle", k1_ip: "192.168.7.10", foxglove_ws_url: "ws://192.168.7.10:8765", foxglove_viewer_url: "http://192.168.7.10:8765/vendor-viewer", compatibility: { profile_id: "xgrids.lixelkity-k1.fw-3.0.2.direct-lan.v1", camera_preview: "rtsp://192.168.7.10:8554/vendor-preview", }, device_ref: { device_id: "device-k1-001", model_id: activeModel.id, identity_stability: "stable", identity_basis: "hardware-identifier", }, device_session: { device_session_id: "device-session-001", device_id: "device-k1-001", compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.direct-lan.v1", connectivity: "connected", }, sensor_catalog: { schema_version: "missioncore.sensor-catalog/v1alpha2", revision: "test-profile", streams: [ { stream_id: "spatial.point-cloud.live", modality: "point-cloud", availability: "observed" }, ...cameraRows, ], }, camera_preview: { phase: "idle", revision: 1, generation: 0, active_source_id: null, delivery: null, }, }; } function pointCloudStreamingState() { return { ...declaredState(), phase: "streaming", source_mode: "live", rerun_grpc_url: "rerun+http://127.0.0.1:9877/proxy", acquisition: { acquisition_id: "acquisition-001", device_id: "device-k1-001", device_session_id: "device-session-001", compatibility_profile_id: "xgrids.lixelkity-k1.fw-3.0.2.direct-lan.v1", control_mode: "operator-manual", requested_streams: ["spatial.point-cloud.live"], target_host: "127.0.0.1", duration_seconds: 0, evidence_policy: "required", state: "acquiring", state_revision: 3, }, }; } function cameraStreamingState(sourceId) { const state = pointCloudStreamingState(); const delivery = { id: `preview-generation-7:${sourceId}`, kind: "mse-fmp4-websocket", url: "/api/v1/device-plugins/xgrids-k1/camera-preview/ws?generation=7", media_type: 'video/mp4; codecs="avc1.640028"', }; state.sensor_catalog = { ...state.sensor_catalog, streams: state.sensor_catalog.streams.map((stream) => stream.source_id === sourceId ? { ...stream, availability: "streaming", activation: { ...stream.activation, selected: true }, delivery, } : stream), }; state.camera_preview = { phase: "streaming", revision: 4, generation: 7, active_source_id: sourceId, delivery, }; return state; } function collectUrlLikeStrings(value, found = []) { if (typeof value === "string") { if (value.includes("://")) found.push(value); return found; } if (Array.isArray(value)) { for (const item of value) collectUrlLikeStrings(item, found); return found; } if (value && typeof value === "object") { for (const item of Object.values(value)) collectUrlLikeStrings(item, found); } return found; } test("K1 maps zero, one or N catalog cameras without model-specific source ids", () => { const zero = xgridsK1ObservationSources(declaredState([]), model()); const one = xgridsK1ObservationSources( declaredState([cameraRow("rig.front", "Передняя камера")]), model(), ); const many = xgridsK1ObservationSources(declaredState(), model()); assert.deepEqual(zero.map(({ modality }) => modality), ["point-cloud"]); assert.deepEqual(one.map(({ sourceId }) => sourceId), ["sensor.lidar.primary", "rig.front"]); assert.deepEqual(many.map(({ sourceId }) => sourceId), [ "sensor.lidar.primary", "sensor.camera.left", "sensor.camera.right", ]); assert.equal(new Set(many.map(({ id }) => id)).size, many.length); assert.ok(many.every(({ provider }) => provider.pluginId && provider.modelId)); assert.ok(many.every(({ binding }) => binding.deviceId === "device-k1-001")); }); test("descriptor ids remain stable while point cloud and selected camera start streaming", () => { const declared = xgridsK1ObservationSources(declaredState(), model()); const streaming = xgridsK1ObservationSources( cameraStreamingState("sensor.camera.left"), model(), ); assert.deepEqual(streaming.map(({ id }) => id), declared.map(({ id }) => id)); assert.equal(declared[0].availability, "available"); assert.equal(streaming[0].availability, "streaming"); assert.equal(streaming[0].previewUrl, "rerun+http://127.0.0.1:9877/proxy"); }); test("only the authoritative selected camera receives browser delivery", () => { const sources = xgridsK1ObservationSources( cameraStreamingState("sensor.camera.left"), model(), ); const cameras = sources.filter(({ modality }) => modality === "video"); const [left, right] = cameras; assert.equal(cameras.length, 2); assert.equal(left.activation.selected, true); assert.equal(left.activation.maxActive, 1); assert.equal(left.availability, "streaming"); assert.equal(left.delivery.kind, "mse-fmp4-websocket"); assert.equal(left.transport, "websocket"); assert.equal(right.activation.selected, false); assert.equal(right.availability, "available"); assert.equal(right.delivery, null); assert.equal(left.activation.groupId, right.activation.groupId); assert.match(left.activation.groupId, /device-session-001/); }); test("switching left to right keeps ids stable and never exposes both deliveries", () => { const left = xgridsK1ObservationSources( cameraStreamingState("sensor.camera.left"), model(), ).filter(({ modality }) => modality === "video"); const right = xgridsK1ObservationSources( cameraStreamingState("sensor.camera.right"), model(), ).filter(({ modality }) => modality === "video"); assert.deepEqual(right.map(({ id }) => id), left.map(({ id }) => id)); assert.deepEqual(left.filter(({ delivery }) => delivery).map(({ sourceId }) => sourceId), [ "sensor.camera.left", ]); assert.deepEqual(right.filter(({ delivery }) => delivery).map(({ sourceId }) => sourceId), [ "sensor.camera.right", ]); }); test("camera descriptors never leak vendor RTSP endpoints or device IP addresses", () => { const sources = xgridsK1ObservationSources( cameraStreamingState("sensor.camera.left"), model(), ); const cameras = sources.filter(({ modality }) => modality === "video"); assert.ok(cameras.every(({ previewUrl }) => previewUrl === null)); assert.deepEqual(collectUrlLikeStrings(sources), [ "rerun+http://127.0.0.1:9877/proxy", ]); const serialized = JSON.stringify(cameras); assert.doesNotMatch(serialized, /rtsp:\/\//i); assert.doesNotMatch(serialized, /192\.168\.7\.10/); assert.doesNotMatch(serialized, /vendor-(?:preview|viewer)/); }); test("unattested, duplicate and unsafe camera entries fail closed", () => { const duplicate = cameraRow("sensor.camera.left", "Duplicate"); const state = cameraStreamingState("sensor.camera.left"); state.compatibility.profile_id = null; state.device_session.compatibility_profile_id = null; state.sensor_catalog.streams.push(duplicate); state.camera_preview.delivery = { ...state.camera_preview.delivery, url: "ws://192.168.7.10:9000/leak", }; const cameras = xgridsK1ObservationSources(state, model()).filter( ({ modality }) => modality === "video", ); assert.deepEqual(cameras.map(({ sourceId }) => sourceId), ["sensor.camera.right"]); assert.equal(cameras[0].availability, "unverified"); assert.equal(cameras[0].activation.controllable, false); assert.equal(cameras[0].delivery, null); }); test("camera delivery rejects literal and encoded endpoint or credential leaks", () => { const unsafeUrls = [ "/api/preview?upstream=rtsp://camera.local/live", "/api/preview?upstream=rtsp%3A%2F%2Fcamera.local%2Flive", "/api/preview?upstream=rtsp%253A%252F%252Fcamera.local%252Flive", "/api/preview?endpoint=192.168.68.52:8554", "/api/preview?endpoint=192%2E168%2E68%2E52", "/api/preview?password=not-for-the-browser", "/api/preview?%70%61%73%73%77%6f%72%64=not-for-the-browser", "/api/preview/camera:secret@device", "/%2f%2fevil.example/preview", ]; for (const url of unsafeUrls) { const state = cameraStreamingState("sensor.camera.left"); state.camera_preview.delivery = { ...state.camera_preview.delivery, url }; state.sensor_catalog.streams = state.sensor_catalog.streams.map((stream) => stream.source_id === "sensor.camera.left" ? { ...stream, delivery: { ...stream.delivery, url } } : stream, ); const left = xgridsK1ObservationSources(state, model()).find( ({ sourceId }) => sourceId === "sensor.camera.left", ); assert.ok(left, `left camera descriptor missing for ${url}`); assert.equal(left.delivery, null, `unsafe delivery escaped for ${url}`); } }); test("manual camera reconnect restores an exhausted lease retry budget", () => { let budget = resetCameraLeaseRetryBudget("delivery-7"); for (const expectedDelay of [400, 1_000, 2_000]) { const retry = consumeCameraLeaseRetry(budget, "delivery-7"); assert.equal(retry.delay, expectedDelay); budget = retry.budget; } assert.equal(consumeCameraLeaseRetry(budget, "delivery-7").delay, null); budget = resetCameraLeaseRetryBudget("delivery-7"); const retryAfterManualReset = consumeCameraLeaseRetry(budget, "delivery-7"); assert.equal(retryAfterManualReset.delay, 400); assert.equal(retryAfterManualReset.budget.count, 1); }); test("layout policy evicts only exclusive camera peers", () => { const sources = xgridsK1ObservationSources( cameraStreamingState("sensor.camera.left"), model(), ); const left = sources.find(({ sourceId }) => sourceId === "sensor.camera.left"); const right = sources.find(({ sourceId }) => sourceId === "sensor.camera.right"); const pointCloud = sources.find(({ modality }) => modality === "point-cloud"); assert.ok(left && right && pointCloud); const change = openObservationSource( [pointCloud.id, left.id], right.id, sources, ); assert.deepEqual(change.visibleIds, [pointCloud.id, right.id]); assert.deepEqual(change.removedIds, [left.id]); }); test("selected camera without delivery is explicitly restartable", () => { const state = cameraStreamingState("sensor.camera.left"); state.camera_preview = { ...state.camera_preview, phase: "error", delivery: null, }; state.sensor_catalog.streams = state.sensor_catalog.streams.map((stream) => stream.source_id === "sensor.camera.left" ? { ...stream, availability: "error", delivery: null } : stream, ); const sources = xgridsK1ObservationSources(state, model()); const left = sources.find(({ sourceId }) => sourceId === "sensor.camera.left"); const right = sources.find(({ sourceId }) => sourceId === "sensor.camera.right"); assert.ok(left && right); assert.equal(left.activation.selected, true); assert.equal(left.delivery, null); assert.equal(left.availability, "error"); assert.equal(shouldRestartObservationSource(left), true); assert.equal(shouldRestartObservationSource(right), false); });