40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
"""Consistency and cs8 layout checks for the shared RF-001A definition."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import numpy as np
|
|
import pytest
|
|
|
|
from tools.rf001a_prepare import SPEC_PATH, load_spec, quantize_cs8
|
|
|
|
|
|
def test_shared_spec_matches_existing_tx_rx_constants() -> None:
|
|
spec = load_spec()
|
|
assert spec["test_id"] == "RF001A_COMMON_CLOCK_001"
|
|
assert spec["expected_sample_count"] * 2 == 17_667_656
|
|
assert spec["rx_capture_samples"] * 2 == 320_000_000
|
|
assert spec["expected_hardware_sha256"] == (
|
|
"75f3fa39bfa4ee419f0676c54e4b9c486d7ff64bd0fe2fc06343b20c9d117ecd"
|
|
)
|
|
|
|
|
|
def test_spec_mismatch_fails_closed(tmp_path: Path) -> None:
|
|
spec = json.loads(SPEC_PATH.read_text(encoding="utf-8-sig"))
|
|
spec["digital_carrier_offset_hz"] = 0
|
|
path = tmp_path / "wrong.json"
|
|
path.write_text(json.dumps(spec), encoding="utf-8")
|
|
with pytest.raises(ValueError, match="digital_carrier_offset_hz"):
|
|
load_spec(path)
|
|
|
|
|
|
def test_cs8_signed_iq_order_and_rail_rejection() -> None:
|
|
source = np.array([0.25 - 0.125j, -0.25 + 0.125j, 0j], dtype=np.complex64)
|
|
raw = quantize_cs8(source, 256)
|
|
assert raw.dtype == np.int8
|
|
assert raw.tolist() == [64, -32, -64, 32, 0, 0]
|
|
with pytest.raises(ValueError, match="rail"):
|
|
quantize_cs8(np.array([0.5 + 0j], dtype=np.complex64), 256)
|