From 7a26b262a91a61fddb398299a61104e8d0bd3c31 Mon Sep 17 00:00:00 2001 From: Julian Stirling Date: Mon, 15 Dec 2025 18:28:28 +0000 Subject: [PATCH] Update the picamera tests for labthings 0.0.12 syntax --- .../picamera2/cam_test_utils/__init__.py | 50 ++++++++++++------- hardware-specific-tests/picamera2/conftest.py | 26 +++++----- .../picamera2/test_calibration.py | 4 +- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/hardware-specific-tests/picamera2/cam_test_utils/__init__.py b/hardware-specific-tests/picamera2/cam_test_utils/__init__.py index a7baeb0e..3893d583 100644 --- a/hardware-specific-tests/picamera2/cam_test_utils/__init__.py +++ b/hardware-specific-tests/picamera2/cam_test_utils/__init__.py @@ -8,13 +8,36 @@ from fastapi.testclient import TestClient import labthings_fastapi as lt -from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2 + +@contextmanager +def camera_test_client_and_server(settings_folder: Optional[str] = None): + """Yield a camera ThingClient and the associated camera server. + + This is a context manager, not a pytest fixture, as it needs to be created + multiple times in some tests. + + :param cam: The camera Thing to be used. If not supplied a new one will be created. + :param settings_folder: The settings folder for the camera, if none is supplied, new + temporary directory will be used as the settings folder. + """ + # Create a temp dir, if the setting folder is set it isn't really needed + # but doesn't add much overhead. + with tempfile.TemporaryDirectory() as tmpdir: + if settings_folder is None: + settings_folder = tmpdir + thing_conf = { + "camera": "openflexure_microscope_server.things.camera.picamera:StreamingPiCamera2", + } + server = lt.ThingServer(things=thing_conf, settings_folder=settings_folder) + + with TestClient(server.app) as test_client: + client = lt.ThingClient.from_url("/camera/", client=test_client) + yield client, server + del server @contextmanager -def camera_test_client( - cam: Optional[StreamingPiCamera2] = None, settings_folder: Optional[str] = None -): +def camera_test_client(settings_folder: Optional[str] = None): """Yield a camera ThingClient on a camera server. This is a context manager, not a pytest fixture, as it needs to be created @@ -24,18 +47,7 @@ def camera_test_client( :param settings_folder: The settings folder for the camera, if none is supplied, new temporary directory will be used as the settings folder. """ - if cam is None: - cam = StreamingPiCamera2() - # Create a temp dir, if the setting folder is set it isn't really needed - # but doesn't add much overhead. - with tempfile.TemporaryDirectory() as tmpdir: - if settings_folder is None: - settings_folder = tmpdir - server = lt.ThingServer(settings_folder=settings_folder) - server.add_thing(cam, "camera") - - with TestClient(server.app) as test_client: - client = lt.ThingClient.from_url("camera", client=test_client) - yield client - del server - del cam + with camera_test_client_and_server( + settings_folder=settings_folder + ) as client_and_server: + yield client_and_server[0] diff --git a/hardware-specific-tests/picamera2/conftest.py b/hardware-specific-tests/picamera2/conftest.py index d6f4568d..68ec8dc1 100644 --- a/hardware-specific-tests/picamera2/conftest.py +++ b/hardware-specific-tests/picamera2/conftest.py @@ -4,30 +4,32 @@ import pytest import labthings_fastapi as lt -from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2 - -from .cam_test_utils import camera_test_client +from .cam_test_utils import camera_test_client_and_server @pytest.fixture -def picamera_thing() -> StreamingPiCamera2: - """Return a StreamingPiCamera2 Thing. +def picamera_client_and_server() -> lt.ThingClient: + """Initialise a test picamera_client and server for the StreamingPiCamera2 Thing. - This is the Thing that the fixture picamera_client uses. It can be used to probe - the Thing directly to check actions had the expected response. + This fixture: + + * Sets up a ThingServer, + * Registers a StreamingPiCamera2 instance at the "camera" endpoint + * Yields a ThingClient and the server for interacting with it during tests. + * The picamera thing can be found at server.things["camera"] """ - return StreamingPiCamera2() + with camera_test_client_and_server() as client_and_server: + yield client_and_server @pytest.fixture -def picamera_client(picamera_thing) -> lt.ThingClient: +def picamera_client(picamera_client_and_server) -> lt.ThingClient: """Initialise a test picamera_client for the StreamingPiCamera2 Thing. This fixture: * Sets up a ThingServer, * Registers a StreamingPiCamera2 instance at the "camera" endpoint - * Provides a ThingClient for interacting with it during tests. + * return a ThingClient for interacting with it during tests. """ - with camera_test_client(cam=picamera_thing) as picamera_client: - yield picamera_client + return picamera_client_and_server[0] diff --git a/hardware-specific-tests/picamera2/test_calibration.py b/hardware-specific-tests/picamera2/test_calibration.py index 22d55cae..1e239344 100644 --- a/hardware-specific-tests/picamera2/test_calibration.py +++ b/hardware-specific-tests/picamera2/test_calibration.py @@ -6,8 +6,10 @@ from copy import deepcopy from .cam_test_utils import camera_test_client -def test_calibration(picamera_thing, picamera_client): +def test_calibration(picamera_client_and_server): """Check that full auto calibrate completes and set the expected values.""" + picamera_client, server = picamera_client_and_server + picamera_thing = server.things["camera"] # Check the calibration_required property used by the calibration wizard assert picamera_thing.calibration_required # Save copy of default tuning file for end of test