diff --git a/hardware-specific-tests/picamera2/cam_test_utils/__init__.py b/hardware-specific-tests/picamera2/cam_test_utils/__init__.py index 1dae1517..d5d79257 100644 --- a/hardware-specific-tests/picamera2/cam_test_utils/__init__.py +++ b/hardware-specific-tests/picamera2/cam_test_utils/__init__.py @@ -2,35 +2,40 @@ from typing import Optional import tempfile - from contextlib import contextmanager from fastapi.testclient import TestClient -from labthings_fastapi.server import ThingServer -from labthings_fastapi.client import ThingClient +import labthings_fastapi as lt from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2 @contextmanager -def camera_test_client(settings_folder: Optional[str] = None): +def camera_test_client( + cam: Optional[StreamingPiCamera2] = None, 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 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 supplies 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 - cam = StreamingPiCamera2() - server = ThingServer(settings_folder=settings_folder) + server = lt.ThingServer(settings_folder=settings_folder) server.add_thing(cam, "/camera/") with TestClient(server.app) as test_client: - client = ThingClient.from_url("/camera/", client=test_client) + client = lt.ThingClient.from_url("/camera/", client=test_client) yield client del server del cam diff --git a/hardware-specific-tests/picamera2/conftest.py b/hardware-specific-tests/picamera2/conftest.py new file mode 100644 index 00000000..f62b22a1 --- /dev/null +++ b/hardware-specific-tests/picamera2/conftest.py @@ -0,0 +1,33 @@ +"""Shared fixtures for picamera tests.""" + +import pytest + +import labthings_fastapi as lt + +from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2 + +from .cam_test_utils import camera_test_client + + +@pytest.fixture +def picamera_thing() -> StreamingPiCamera2: + """Return a 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. + """ + return StreamingPiCamera2() + + +@pytest.fixture +def picamera_client(picamera_thing) -> 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. + """ + with camera_test_client(cam=picamera_thing) as picamera_client: + yield picamera_client diff --git a/hardware-specific-tests/picamera2/test_acquisition.py b/hardware-specific-tests/picamera2/test_acquisition.py index caf8849a..7c8bd8cf 100644 --- a/hardware-specific-tests/picamera2/test_acquisition.py +++ b/hardware-specific-tests/picamera2/test_acquisition.py @@ -1,52 +1,29 @@ """Test data collection from the Raspberry Picamera.""" -from fastapi.testclient import TestClient from PIL import Image import numpy as np -import pytest - -import labthings_fastapi as lt - -from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2 -@pytest.fixture(scope="module") -def client() -> lt.ThingClient: - """Initialise a test 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. - """ - server = lt.ThingServer() - server.add_thing(StreamingPiCamera2(), "/camera/") - with TestClient(server.app) as test_client: - client = lt.ThingClient.from_url("/camera/", client=test_client) - yield client - - -def test_jpeg_and_array(client): +def test_jpeg_and_array(picamera_client): """Check that a jpeg grabbed from the stream is the same size as other captures. Compare it to an array capture and a jpeg capture. """ # Grab a jpeg from the stream - blob = client.grab_jpeg() + blob = picamera_client.grab_jpeg() mjpeg_frame = Image.open(blob.open()) # Verify throws an error if there are issues with the image mjpeg_frame.verify() assert mjpeg_frame.format == "JPEG" # Capture a jpeg - blob = client.capture_jpeg(stream_name="main") + blob = picamera_client.capture_jpeg(stream_name="main") jpeg_capture = Image.open(blob.open()) jpeg_capture.verify() assert jpeg_capture.format == "JPEG" # Capture an array - arrlist = client.capture_array(stream_name="main") + arrlist = picamera_client.capture_array(stream_name="main") array_main = np.array(arrlist) # Verify image sizes are the same diff --git a/hardware-specific-tests/picamera2/test_calibration.py b/hardware-specific-tests/picamera2/test_calibration.py index 909b533e..9be682a9 100644 --- a/hardware-specific-tests/picamera2/test_calibration.py +++ b/hardware-specific-tests/picamera2/test_calibration.py @@ -1,47 +1,16 @@ """Test data collection from the Raspberry Picamera.""" -import tempfile from copy import deepcopy -from fastapi.testclient import TestClient import pytest import labthings_fastapi as lt from openflexure_microscope_server.things.camera.picamera import ( - StreamingPiCamera2, MissingCalibrationError, ) -@pytest.fixture -def picamera_thing() -> StreamingPiCamera2: - """Return a StreamingPiCamera2 Thing. - - This is the Thing that the fixture client uses. It can be used to probe the - Thing directly to check actions had the expected response. - """ - return StreamingPiCamera2() - - -@pytest.fixture -def client(picamera_thing) -> lt.ThingClient: - """Initialise a test 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. - """ - temp_folder = tempfile.TemporaryDirectory() - server = lt.ThingServer(settings_folder=temp_folder.name) - server.add_thing(picamera_thing, "/camera/") - with TestClient(server.app) as test_client: - client = lt.ThingClient.from_url("/camera/", client=test_client) - yield client - - def test_get_tuning_algo(picamera_thing): """Test that get_tuning algorithm retrieves tuning algorithms.""" # Missing algorithm raises an error. @@ -73,7 +42,7 @@ def test_get_tuning_algo(picamera_thing): assert picamera_thing.get_tuning_algo("rpi.geq", raise_if_missing=False) is None -def test_calibration(picamera_thing, client): +def test_calibration(picamera_thing, picamera_client): """Check that full auto calibrate completes and set the expected values.""" # Check the calibration_required property used by the calibration wizard assert picamera_thing.calibration_required @@ -88,7 +57,7 @@ def test_calibration(picamera_thing, client): assert not picamera_thing.background_detector_status.ready # Run full auto calibrate - client.full_auto_calibrate() + picamera_client.full_auto_calibrate() # After calibration it should report that calibration is no longer required assert not picamera_thing.calibration_required