Rework radar system
This commit is contained in:
@@ -41,6 +41,26 @@ def _valid_payload() -> dict:
|
||||
class StrictNumericTypingTest(unittest.TestCase):
|
||||
"""Every config integer reads strictly; null falls back to the default."""
|
||||
|
||||
def test_switch_driver_is_only_a_guard_for_old_h7992_profiles(self) -> None:
|
||||
payload = _valid_payload()
|
||||
for port in ("port1", "port2"):
|
||||
switch = payload["switches"][port]
|
||||
self.assertNotIn("driver", switch)
|
||||
switch["driver"] = "h7992"
|
||||
self.assertNotIn("driver", RunConfigModel.from_dict(payload).to_dict()["switches"][port])
|
||||
for unsupported in ("hmc349a", "unknown", "", None, 1, {}, []):
|
||||
switch["driver"] = unsupported
|
||||
with self.subTest(port=port, driver=unsupported), self.assertRaisesRegex(ValueError, "driver"):
|
||||
RunConfigModel.from_dict(payload)
|
||||
switch.pop("driver")
|
||||
switch["invert_logic"] = False
|
||||
self.assertNotIn("invert_logic", RunConfigModel.from_dict(payload).to_dict()["switches"][port])
|
||||
for unsupported in (True, None, 0, "false", {}, []):
|
||||
switch["invert_logic"] = unsupported
|
||||
with self.subTest(port=port, invert_logic=unsupported), self.assertRaisesRegex(ValueError, "invert_logic"):
|
||||
RunConfigModel.from_dict(payload)
|
||||
switch.pop("invert_logic")
|
||||
|
||||
def _reject_int(self, section: list[str], key: str, value: object) -> None:
|
||||
payload = _valid_payload()
|
||||
node = payload
|
||||
@@ -109,7 +129,6 @@ class AcquisitionValidationTest(unittest.TestCase):
|
||||
config.radar.sweep.points = 32
|
||||
for port, switch in enumerate((config.output_switch, config.input_switch), 1):
|
||||
switch.radar_port = port
|
||||
switch.driver = "h7992"
|
||||
switch.gpio_chip = "/dev/gpiochip0"
|
||||
switch.pin_a, switch.pin_b = 17, 27
|
||||
for name in ("raw", "preprocessed", "raw_tap", "preprocessed_tap"):
|
||||
@@ -123,7 +142,8 @@ class AcquisitionValidationTest(unittest.TestCase):
|
||||
ring = getattr(config.rings, name)
|
||||
ring.name = "/test"
|
||||
original = ring.slot_size_bytes
|
||||
ring.slot_size_bytes = 4096
|
||||
minimum_frame = 44 + len(config.combos) * (28 + 12 * config.radar.sweep.points)
|
||||
ring.slot_size_bytes = (minimum_frame - 1) // 8 * 8
|
||||
with self.subTest(ring=name), self.assertRaisesRegex(ValueError, f"rings.{name}"):
|
||||
validate_acquisition_config(config)
|
||||
ring.slot_size_bytes = original
|
||||
@@ -154,7 +174,7 @@ class AcquisitionValidationTest(unittest.TestCase):
|
||||
|
||||
def test_bad_switch_settings_are_reported_before_hardware_open(self) -> None:
|
||||
for field, value in (
|
||||
("driver_mode", "typo"), ("driver", "typo"), ("default_position", 1),
|
||||
("driver_mode", "typo"), ("default_position", 1),
|
||||
("radar_port", 0), ("pin_a", -1), ("pin_b", 17), ("gpio_chip", ""),
|
||||
):
|
||||
config = self.config()
|
||||
@@ -207,7 +227,9 @@ class ComboValidationTest(unittest.TestCase):
|
||||
def test_direct_model_positions_cannot_be_silently_truncated(self) -> None:
|
||||
for value in (0.5, True, '0'):
|
||||
with self.subTest(value=value), self.assertRaisesRegex(ValueError, 'integer'):
|
||||
validate_combos([ComboModel(value, 0)], input_positions=2, output_positions=2)
|
||||
combo = ComboModel(0, 0)
|
||||
setattr(combo, 'input', value)
|
||||
validate_combos([combo], input_positions=2, output_positions=2)
|
||||
def test_within_bounds_passes(self) -> None:
|
||||
validate_combos(
|
||||
[ComboModel(input=0, output=0), ComboModel(input=3, output=1)],
|
||||
@@ -266,9 +288,10 @@ class RingValidationTest(unittest.TestCase):
|
||||
class GprValidationTest(unittest.TestCase):
|
||||
@staticmethod
|
||||
def _gpr(**overrides: object) -> GprModel:
|
||||
base = {"relative_permittivity": 4.0, "tx_geometry": [], "rx_geometry": []}
|
||||
base.update(overrides)
|
||||
return GprModel(**base) # type: ignore[arg-type]
|
||||
model = GprModel(relative_permittivity=4.0)
|
||||
for key, value in overrides.items():
|
||||
setattr(model, key, value)
|
||||
return model
|
||||
|
||||
def _validate(self, gpr: GprModel) -> None:
|
||||
validate_gpr_model(gpr, input_switch_positions=4, output_switch_positions=2)
|
||||
@@ -298,10 +321,14 @@ class GprValidationTest(unittest.TestCase):
|
||||
rx_geometry=[GprRxGeometryModel(input_pos=0, x_m=0.0, y_m=0.0, z_m=0.0)],
|
||||
))
|
||||
|
||||
def test_direct_geometry_positions_cannot_be_silently_truncated(self) -> None:
|
||||
for value in (0.5, True, '0'):
|
||||
with self.subTest(value=value), self.assertRaisesRegex(ValueError, 'integer'):
|
||||
self._validate(self._gpr(tx_geometry=[GprTxGeometryModel(output_pos=value)]))
|
||||
def test_direct_geometry_values_cannot_be_silently_coerced(self) -> None:
|
||||
for field, values, message in (("output_pos", (0.5, True, "0"), "integer"),
|
||||
("x_m", (True, "0", None, float("nan"), float("inf"), 3.5e38, 10**400), "number")):
|
||||
for value in values:
|
||||
with self.subTest(field=field, value=value), self.assertRaisesRegex(ValueError, message):
|
||||
entry = GprTxGeometryModel()
|
||||
setattr(entry, field, value)
|
||||
self._validate(self._gpr(tx_geometry=[entry]))
|
||||
|
||||
|
||||
class ParseCombosFromTextTest(unittest.TestCase):
|
||||
|
||||
Reference in New Issue
Block a user