diff --git a/openpilot/starpilot/ui/tests/test_big_camera_pending_switch.py b/openpilot/starpilot/ui/tests/test_big_camera_pending_switch.py index 6e708288cc..412b43e78d 100644 --- a/openpilot/starpilot/ui/tests/test_big_camera_pending_switch.py +++ b/openpilot/starpilot/ui/tests/test_big_camera_pending_switch.py @@ -29,6 +29,7 @@ def test_big_cancelled_wide_switch_never_consumes_unwanted_target_frame(experime pending = Mock() pending.recv.side_effect = AssertionError('Obsolete wide stream must not be consumed') sm = {'selfdriveState': NS(experimentalMode=True), 'carState': NS(vEgo=1.)} + view._clients = {road.NARROW_ROAD_CAM: view.client, road.WIDE_CAM: pending} with patch.object(cameraview, 'VisionIpcClient', return_value=pending): view._switch_stream_if_needed(sm) assert view._switching and view._target_stream_type == road.WIDE_CAM diff --git a/openpilot/starpilot/ui/tests/test_camera_client_cache.py b/openpilot/starpilot/ui/tests/test_camera_client_cache.py new file mode 100644 index 0000000000..e15f110b8e --- /dev/null +++ b/openpilot/starpilot/ui/tests/test_camera_client_cache.py @@ -0,0 +1,35 @@ +from unittest.mock import Mock,patch +from openpilot.selfdrive.ui.onroad import cameraview as camera + +class ViewWithoutResources(camera.CameraView): + def close(self):pass + + +def test_constructor_caches_once_across_repeated_switches(): + with patch.object(camera,'COMMA_HARDWARE',False), \ + patch.object(camera,'VisionIpcClient',side_effect=lambda *a,**k:Mock()) as factory, \ + patch.object(camera.rl,'load_shader_from_memory',return_value=Mock(id=0)), \ + patch.object(camera.rl,'get_shader_location',return_value=1), \ + patch.object(camera.ui_state,'add_offroad_transition_callback'): + view=ViewWithoutResources('camera-cache-test',camera.VisionStreamType.VISION_STREAM_NARROW_ROAD) + expected=len(list(camera.VisionStreamType)) + assert factory.call_count==expected + identities=dict(view._clients) + with patch.object(view,'_initialize_textures'): + for _ in range(50): + for stream in camera.VisionStreamType: + view.switch_stream(stream) + if view._switching:view._complete_switch() + assert view.client is identities[stream] + assert factory.call_count==expected + + +def test_new_drive_drains_cached_clients_and_cancels_pending_switch(): + view=ViewWithoutResources.__new__(ViewWithoutResources) + view._clients={stream:Mock() for stream in camera.VisionStreamType} + view.client=view._clients[camera.VisionStreamType.VISION_STREAM_NARROW_ROAD] + view.frame=Mock();view._target_client=Mock();view._target_stream_type=Mock();view._switching=True + with patch.object(camera.ui_state,'is_onroad',return_value=True):view._offroad_transition() + assert view.frame is None and view._target_client is None + assert view._target_stream_type is None and not view._switching + for client in view._clients.values():client.recv.assert_called_once_with(timeout_ms=0) diff --git a/openpilot/starpilot/ui/tests/test_camera_resources.py b/openpilot/starpilot/ui/tests/test_camera_resources.py index 0700887895..9cca7a4e5d 100644 --- a/openpilot/starpilot/ui/tests/test_camera_resources.py +++ b/openpilot/starpilot/ui/tests/test_camera_resources.py @@ -29,6 +29,7 @@ for path in ("openpilot.selfdrive.ui.onroad.cameraview", "openpilot.selfdrive.ui view.egl_texture = SimpleNamespace(id=13) if hardware else None view.egl_images = {1: "owned-image"} if hardware else {} view.frame, view.client, view.available_streams = None, None, set() + view._clients = {} textures, shaders, images = [], [], [] with patch.object(module, "COMMA_HARDWARE", hardware), \\ patch.object(module.rl, "unload_texture", side_effect=lambda texture: textures.append(texture.id)), \\