NODEDC_MISSION_CORE/apps/control-station/test/groundQualification.test.mjs

256 lines
7.6 KiB
JavaScript

import assert from "node:assert/strict";
import { after, before, test } from "node:test";
import { createServer } from "vite";
let server;
let decodeGroundQualification;
let decodeGroundFailurePreview;
let decodeGroundReview;
let decodeGroundReviewFrame;
let fetchGroundQualification;
let GroundQualificationContractError;
let parseGooseFrameId;
let groupGooseReviewFrames;
const aggregate = {
micro: {
ground_iou: 0.75,
natural_ground_recall: 0.8,
obstacle_non_ground_recall: 0.92,
},
latency_ms: { p50: 12, p95: 18, maximum: 25 },
assigned_fraction: 1,
source_coverage: 1,
frame_count: 961,
};
const qualification = {
schema_version: "missioncore.polygon-ground-qualification/v1",
access: "read-only",
run_id: "goose-ground-abc",
identity_sha256: "a".repeat(64),
source_id: "goose-3d/v2025-08-22",
split: "validation",
frame_count: 961,
aggregates: {
current: { ...aggregate, micro: { ...aggregate.micro, ground_iou: 0.5 } },
patchworkpp: aggregate,
},
degradations: { "range-20m": { ...aggregate, source_coverage: 0.6 } },
checks: [{
check_id: "ground-iou-gain",
observed: 0.25,
operator: ">=",
threshold: 0.07,
passed: true,
}],
worst_frames: [{
frame_id: "2022-07-22_flight__0071_0001",
current_ground_iou: 0.6,
patchwork_ground_iou: 0.55,
ground_iou_delta: -0.05,
patchwork_natural_ground_recall: 0.7,
}],
decision: {
status: "shadow-candidate",
passed: true,
promoted_to_navigation_or_safety: false,
reason: "all gates passed",
},
safety: {
qualification_only: true,
actuator_authority: false,
navigation_or_safety_accepted: false,
},
};
before(async () => {
server = await createServer({
appType: "custom",
logLevel: "silent",
server: { middlewareMode: true },
});
({
decodeGroundQualification,
decodeGroundFailurePreview,
decodeGroundReview,
decodeGroundReviewFrame,
fetchGroundQualification,
GroundQualificationContractError,
parseGooseFrameId,
} = await server.ssrLoadModule("/src/core/polygon/groundQualification.ts"));
({
groupGooseReviewFrames,
} = await server.ssrLoadModule("/src/workspaces/GooseDatasetReview.tsx"));
});
after(async () => {
await server?.close();
});
test("decodes a bounded shadow-only qualification", () => {
const decoded = decodeGroundQualification(qualification);
assert.equal(decoded.frameCount, 961);
assert.equal(decoded.patchwork.micro.groundIou, 0.75);
assert.equal(decoded.degradations["range-20m"].sourceCoverage, 0.6);
assert.equal(decoded.decision.promotedToNavigationOrSafety, false);
});
test("rejects navigation or safety promotion", () => {
assert.throws(
() => decodeGroundQualification({
...qualification,
decision: {
...qualification.decision,
promoted_to_navigation_or_safety: true,
},
}),
GroundQualificationContractError,
);
});
test("decodes point-aligned failure preview", () => {
const decoded = decodeGroundFailurePreview({
schema_version: "missioncore.polygon-ground-failure-preview/v1",
access: "read-only",
run_id: "goose-ground-abc",
source_id: "goose-3d/v2025-08-22",
frame_id: "2022-07-22_flight__0071_0001",
source_point_count: 2,
point_count: 2,
sampling: "deterministic-even-index",
points_xyz_m: [[0, 0, 0], [1, 1, 1]],
ground_truth_ground: [1, 0],
evaluated: [1, 1],
current_ground: [0, 0],
patchwork_ground: [1, 0],
current_disagreement: [1, 0],
patchwork_disagreement: [0, 0],
safety: { navigation_or_safety_accepted: false },
});
assert.equal(decoded.pointCount, 2);
assert.deepEqual(decoded.patchworkGround, [1, 0]);
});
test("treats missing qualification as a generic run", async () => {
const result = await fetchGroundQualification("goose-ground-abc", {
fetcher: async () => new Response(
JSON.stringify({ detail: "not found" }),
{ status: 404, headers: { "content-type": "application/json" } },
),
});
assert.equal(result, null);
});
test("decodes a complete ordered frame review", () => {
const decoded = decodeGroundReview({
schema_version: "missioncore.polygon-ground-review/v2",
access: "read-only",
run_id: "goose-ground-abc",
identity_sha256: "b".repeat(64),
source_id: "goose-3d/v2025-08-22",
frame_count: 2,
preview_points: 12_000,
frames: [0, 1].map((sequence) => ({
sequence,
frame_id: `2022-07-22_flight__007${sequence + 1}_165849423${sequence}334310308`,
dataset_sequence_id: "2022-07-22_flight",
dataset_frame_number: sequence + 71,
sensor_timestamp_ns: `165849423${sequence}334310308`,
source_point_count: 100_000,
point_count: 12_000,
current: {
ground_iou: 0.5,
natural_ground_recall: 0.55,
obstacle_non_ground_recall: 0.91,
latency_ms: 3_000,
},
patchworkpp: {
ground_iou: 0.7,
natural_ground_recall: 0.75,
obstacle_non_ground_recall: 0.94,
latency_ms: 20,
},
ground_iou_delta: 0.2,
})),
});
assert.equal(decoded.frames.length, 2);
assert.equal(decoded.frames[1].sequence, 1);
assert.equal(decoded.frames[1].datasetSequenceId, "2022-07-22_flight");
assert.equal(decoded.frames[1].datasetFrameNumber, 72);
assert.equal(decoded.frames[0].patchwork.groundIou, 0.7);
});
test("parses GOOSE sequence, source frame and nanosecond timestamp", () => {
assert.deepEqual(
parseGooseFrameId("2023-05-17_neubiberg_sunny__0459_1684330012686564560"),
{
datasetSequenceId: "2023-05-17_neubiberg_sunny",
datasetFrameNumber: 459,
sensorTimestampNs: "1684330012686564560",
},
);
});
test("keeps independent GOOSE recordings in separate playback sequences", () => {
const metric = {
groundIou: 0.5,
naturalGroundRecall: 0.6,
obstacleNonGroundRecall: 0.9,
latencyMs: 20,
};
const frames = [
["2022-07-22_flight", 71, "1658494234334310308"],
["2022-07-22_flight", 72, "1658494235988100385"],
["2023-05-17_neubiberg_sunny", 459, "1684330012686564560"],
].map(([datasetSequenceId, datasetFrameNumber, sensorTimestampNs], sequence) => ({
sequence,
frameId: `${datasetSequenceId}__${String(datasetFrameNumber).padStart(4, "0")}_${sensorTimestampNs}`,
datasetSequenceId,
datasetFrameNumber,
sensorTimestampNs,
sourcePointCount: 100_000,
pointCount: 12_000,
current: metric,
patchwork: metric,
groundIouDelta: 0,
}));
const groups = groupGooseReviewFrames({
runId: "goose-ground-abc",
identitySha256: "b".repeat(64),
sourceId: "goose-3d/v2025-08-22",
frameCount: frames.length,
previewPoints: 12_000,
frames,
});
assert.equal(groups.length, 2);
assert.equal(groups[0].frames.length, 2);
assert.equal(groups[1].frames.length, 1);
assert.ok(groups[0].durationSeconds > 1.6);
});
test("decodes a point-aligned review frame with intensity", () => {
const decoded = decodeGroundReviewFrame({
schema_version: "missioncore.polygon-ground-review-frame/v1",
access: "read-only",
run_id: "goose-ground-abc",
source_id: "goose-3d/v2025-08-22",
frame_id: "2022-07-22_flight__0071_0001",
source_point_count: 2,
point_count: 2,
sampling: "deterministic-even-index",
points_xyz_m: [[0, 0, 0], [1, 1, 1]],
intensity_0_255: [12, 255],
ground_truth_ground: [1, 0],
evaluated: [1, 1],
current_ground: [0, 0],
patchwork_ground: [1, 0],
current_disagreement: [1, 0],
patchwork_disagreement: [0, 0],
safety: { navigation_or_safety_accepted: false },
});
assert.deepEqual(decoded.intensity0To255, [12, 255]);
assert.equal(decoded.frameId, "2022-07-22_flight__0071_0001");
});