NODEDC_MISSION_CORE/tests/test_multirate_perception_q...

76 lines
2.0 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
import pytest
from k1link.compute.multirate_perception_qualification import (
MERGED_FRAME_SCHEMA,
_validate_merged_rows,
)
from k1link.sessions import SessionIntegrityError
def _merged(index: int, semantic: dict[str, object]) -> dict[str, object]:
return {
"schema_version": MERGED_FRAME_SCHEMA,
"frame_index": index,
"source_frame_index": 1000 + index,
"session_seconds": 20.0 + index * 0.1,
"detector_result_age_ms": 80.0,
"tracks": [],
"semantic": semantic,
}
def test_merged_rows_allow_explicit_unavailable_then_fresh(tmp_path: Path) -> None:
path = tmp_path / "merged-frames.jsonl"
unavailable = {
"status": "unavailable",
"source_frame_index": None,
"source_age_ms": None,
"completion_age_ms": None,
"mask_sha256": None,
}
fresh = {
"status": "fresh",
"source_frame_index": 1000,
"source_age_ms": 200.0,
"completion_age_ms": 210.0,
"mask_sha256": "a" * 64,
}
path.write_text(
json.dumps(_merged(0, unavailable)) + "\n" + json.dumps(_merged(2, fresh)) + "\n",
encoding="utf-8",
)
_validate_merged_rows(
path,
tmp_path,
expected_indices=(0, 2),
source_start=1000,
semantic_indices={0},
)
def test_merged_rows_reject_future_semantic_binding(tmp_path: Path) -> None:
path = tmp_path / "merged-frames.jsonl"
future = {
"status": "fresh",
"source_frame_index": 1005,
"source_age_ms": 0.0,
"completion_age_ms": 200.0,
"mask_sha256": "a" * 64,
}
path.write_text(json.dumps(_merged(2, future)) + "\n", encoding="utf-8")
with pytest.raises(SessionIntegrityError, match="binding"):
_validate_merged_rows(
path,
tmp_path,
expected_indices=(2,),
source_start=1000,
semantic_indices={5},
)