From 7edb10e14999c6d8317de3606c50d4ff7d43ceec Mon Sep 17 00:00:00 2001 From: Dom <168790843+firestar5683@users.noreply.github.com> Date: Wed, 21 Oct 2026 15:47:55 -0500 Subject: [PATCH] Fix vision typing and projection HTTP test fixtures --- .../galaxy/test_projection_bluetooth_http.py | 3 ++ .../speed_limits/vision/tests/test_vision.py | 37 ++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/openpilot/starpilot/galaxy/test_projection_bluetooth_http.py b/openpilot/starpilot/galaxy/test_projection_bluetooth_http.py index 2fef3134fc..450025f077 100644 --- a/openpilot/starpilot/galaxy/test_projection_bluetooth_http.py +++ b/openpilot/starpilot/galaxy/test_projection_bluetooth_http.py @@ -22,6 +22,9 @@ SCREEN = {'version': 1, 'width': 1280, 'height': 720, 'margin_width': 0, class Params: def __init__(self, root): self.root, self.enabled = root, True + def get(self, key): + assert key == 'JetlinkMode' + return 0 def get_param_path(self, key): return str(self.root / key) def get_bool(self, key): assert key == 'AndroidAutoEnabled' diff --git a/openpilot/starpilot/speed_limits/vision/tests/test_vision.py b/openpilot/starpilot/speed_limits/vision/tests/test_vision.py index 117a62b777..d512c481d8 100644 --- a/openpilot/starpilot/speed_limits/vision/tests/test_vision.py +++ b/openpilot/starpilot/speed_limits/vision/tests/test_vision.py @@ -5,6 +5,7 @@ from pathlib import Path import unittest from unittest.mock import patch from types import SimpleNamespace +from typing import TypedDict import numpy as np @@ -25,6 +26,14 @@ from openpilot.starpilot.ui.feature_settings_owner import FeatureSettingsOwner from openpilot.starpilot.ui.feature_settings_state import row_change +class ObservationContext(TypedDict): + receipt_mono_ns: int + now_mono_ns: int + now_boot_ns: int + car_fingerprint: str + drive_session: str + + class TestVision(unittest.TestCase): def test_bundled_models_have_frozen_identity_and_real_synthetic_inference(self): if model.cv2 is None: @@ -65,10 +74,16 @@ class TestVision(unittest.TestCase): reads = [Detection(55, 0.60), Detection(55, 0.76), None, Detection(65, 0.99), None] with patch.object(core, 'infer', side_effect=reads): self.assertIsNone(core.observe(frame, now=1.0)) - self.assertEqual(core.observe(frame, now=1.2)[0], 55) - self.assertEqual(core.observe(frame, now=60.0)[0], 55) + observed = core.observe(frame, now=1.2) + assert observed is not None + self.assertEqual(observed[0], 55) + observed = core.observe(frame, now=60.0) + assert observed is not None + self.assertEqual(observed[0], 55) self.assertEqual(core.last_published_support_at, 1.2) - self.assertEqual(core.observe(frame, now=61.0)[0], 65) + observed = core.observe(frame, now=61.0) + assert observed is not None + self.assertEqual(observed[0], 65) self.assertEqual(core.last_published_support_at, 61.0) core.reset() self.assertIsNone(core.observe(frame, now=62.0)) @@ -118,7 +133,7 @@ class TestVision(unittest.TestCase): def test_actual_typed_wire_and_separate_camera_clock_freshness(self): msg = self._event() decoded = messaging.log_from_bytes(msg.to_bytes()).slcVisionObservation.vision - kw = {'receipt_mono_ns': 1_020_000_000, 'now_mono_ns': 1_030_000_000, + kw: ObservationContext = {'receipt_mono_ns': 1_020_000_000, 'now_mono_ns': 1_030_000_000, 'now_boot_ns': 5_050_000_000, 'car_fingerprint': 'IONIQ6', 'drive_session': 'drive-a'} valid = vision_observation(decoded, **kw) self.assertIs(valid.kind, ObservationKind.VALID) @@ -173,11 +188,12 @@ class TestVision(unittest.TestCase): event = message.slcVisionObservation.vision event.validUntilMonoTime = 3_000_000_000 decoded = messaging.log_from_bytes(message.to_bytes()).slcVisionObservation.vision - kw = {'receipt_mono_ns': 1_500_000_000, 'now_mono_ns': 1_500_000_000, + kw: ObservationContext = {'receipt_mono_ns': 1_500_000_000, 'now_mono_ns': 1_500_000_000, 'now_boot_ns': 5_500_000_000, 'car_fingerprint': 'IONIQ6', 'drive_session': 'drive-a'} self.assertIs(vision_observation(decoded, **kw).kind, ObservationKind.VALID) - self.assertIs(vision_observation(decoded, **dict(kw, now_mono_ns=3_000_000_001, - now_boot_ns=7_000_000_001)).kind, ObservationKind.STALE) + self.assertIs(vision_observation(decoded, receipt_mono_ns=kw['receipt_mono_ns'], now_mono_ns=3_000_000_001, + now_boot_ns=7_000_000_001, car_fingerprint=kw['car_fingerprint'], + drive_session=kw['drive_session']).kind, ObservationKind.STALE) def test_runtime_slow_vision_supports_display_and_control(self): message = self._event() @@ -211,12 +227,13 @@ class TestVision(unittest.TestCase): # The sign was last seen at monotonic1s. This camera heartbeat is at60s. event.cameraFrameEofBootTime = 64_000_000_000 event.validUntilMonoTime = 62_000_000_000 - kw = {'receipt_mono_ns': 60_100_000_000, 'now_mono_ns': 60_100_000_000, + kw: ObservationContext = {'receipt_mono_ns': 60_100_000_000, 'now_mono_ns': 60_100_000_000, 'now_boot_ns': 64_100_000_000, 'car_fingerprint': 'IONIQ6', 'drive_session': 'drive-a'} self.assertIs(vision_observation(event, **kw).kind, ObservationKind.VALID) self.assertEqual(event.observedMonoTime, 1_000_000_000) - self.assertIs(vision_observation(event, **dict(kw, receipt_mono_ns=59_000_000_000)).kind, - ObservationKind.STALE) + self.assertIs(vision_observation(event, receipt_mono_ns=59_000_000_000, now_mono_ns=kw['now_mono_ns'], + now_boot_ns=kw['now_boot_ns'], car_fingerprint=kw['car_fingerprint'], + drive_session=kw['drive_session']).kind, ObservationKind.STALE) event.cameraFrameEofBootTime = 61_000_000_000 self.assertIs(vision_observation(event, **kw).kind, ObservationKind.STALE) event.status = 'unavailable'