Update tests for new camera streaming modes

This commit is contained in:
Julian Stirling 2026-05-26 22:28:51 +01:00
parent aff860a086
commit 7dd715da88
8 changed files with 27 additions and 35 deletions

View file

@ -6,7 +6,6 @@ on camera functionality using the simulation camera are in "test_camera".
from labthings_fastapi.testing import create_thing_without_server
from openflexure_microscope_server.things.camera import BaseCamera
from openflexure_microscope_server.things.camera.opencv import OpenCVCamera
from openflexure_microscope_server.things.camera.simulation import SimulatedCamera
@ -57,11 +56,9 @@ def test_thing_description_equivalence(mock_picam_thing):
camera child classes. Any addition of actions must be accompanied by an update
to this test, prompting discussion of whether the action belongs in the subclass
or the base camera class.
"""
base_td = create_thing_without_server(BaseCamera).thing_description()
base_actions = set(base_td.actions.keys())
base_props = set(base_td.properties.keys())
The base camera class is not instantiated as it is an Abstract Base Class
"""
sim_camera = create_thing_without_server(SimulatedCamera)
sim_description = _get_clean_camera_description(sim_camera)
opencv_camera = create_thing_without_server(OpenCVCamera)
@ -82,8 +79,8 @@ def test_thing_description_equivalence(mock_picam_thing):
# Camera actions and properties should generally be equivalent except for exposed
# manual settings and calibration actions.
assert opencv_actions == sim_actions == base_actions
assert opencv_props == sim_props == base_props
assert opencv_actions == sim_actions
assert opencv_props == sim_props
# For now PiCamera has a number of extra actions and properties. These should be
# reduced over time by creating a way to use the functionality in a way as clearly
@ -92,7 +89,6 @@ def test_thing_description_equivalence(mock_picam_thing):
picamera_extra_actions = {
"set_static_green_equalisation",
"set_ce_enable_to_off",
"stop_streaming",
"reset_ccm",
}
picamera_extra_props = {
@ -103,15 +99,12 @@ def test_thing_description_equivalence(mock_picam_thing):
"sensor_resolution",
"capture_metadata",
"camera_configuration",
"stream_resolution",
"tuning",
"sensor_modes",
"sensor_mode",
}
# Note these are only the action not exposed as calibration actions.
for action in picamera_extra_actions:
assert action in picamera_actions
for props in picamera_extra_props:
assert props in picamera_props
assert picamera_actions - base_actions == picamera_extra_actions
assert picamera_props - base_props == picamera_extra_props
assert picamera_actions - sim_actions == picamera_extra_actions
assert picamera_props - sim_props == picamera_extra_props

View file

@ -12,7 +12,6 @@ import labthings_fastapi as lt
from labthings_fastapi.testing import create_thing_without_server
from openflexure_microscope_server.things.background_detect import ChannelDeviationLUV
from openflexure_microscope_server.things.camera import BaseCamera
from openflexure_microscope_server.things.camera import (
picamera_tuning_file_utils as tf_utils,
)
@ -32,8 +31,8 @@ def temp_jpeg(tmp_path: Path) -> Path:
def test_add_metadata_to_capture(temp_jpeg):
"""Use a BaseCamera to add metadata to a tmp capture and test fields."""
base_cam = create_thing_without_server(BaseCamera)
"""Use a SimulatedCamerato add metadata to a tmp capture and test fields."""
cam = create_thing_without_server(SimulatedCamera)
metadata = {
"Dummy1": 1,
"Dummy2": "two",
@ -48,7 +47,7 @@ def test_add_metadata_to_capture(temp_jpeg):
"things_states": metadata,
}
base_cam._add_metadata_to_capture(str(temp_jpeg), capture_metadata)
cam._add_metadata_to_capture(str(temp_jpeg), capture_metadata)
# Reload EXIF
exif_dict = piexif.load(str(temp_jpeg))
@ -177,7 +176,7 @@ def test_picamera_metadata_written_to_exif(mock_picam_thing, temp_jpeg, mocker):
exif_dict = piexif.load(str(temp_jpeg))
user_comment = json.loads(exif_dict["Exif"][piexif.ExifIFD.UserComment].decode())
assert user_comment["camera"] == "StreamingPiCamera2"
assert user_comment["camera"] == "PiCameraV2"
assert user_comment["camera_board"] == "imx219"
# gamma_correction keys are cast to strings
assert user_comment["tuning"] == {

View file

@ -492,7 +492,7 @@ def check_run_scan(scan_thing, caplog, expected_exception=None):
final_scan_data = scan_thing._ongoing_scan.save_scan_data.call_args[0][0]
calls = {
"cam_start_streaming_calls": scan_thing._cam.start_streaming.call_count,
"cam_change_streaming_mode_calls": scan_thing._cam.change_streaming_mode.call_count,
"main_scan_loop_calls": scan_thing._main_scan_loop.call_count,
"return_to_start_calls": scan_thing._return_to_starting_position.call_count,
"perform_final_stitch_calls": scan_thing._perform_final_stitch.call_count,
@ -509,7 +509,7 @@ def test_run_scan(scan_thing_mocked_for_run_scan, caplog):
assert len(logs) == 0
expected_calls_numbers = {
"cam_start_streaming_calls": 2,
"cam_change_streaming_mode_calls": 2,
"main_scan_loop_calls": 1,
"return_to_start_calls": 1,
"perform_final_stitch_calls": 1,
@ -534,7 +534,7 @@ def test_run_scan_err_in_main_loop(scan_thing_mocked_for_run_scan, caplog, mocke
# Main loop not run, nor are return to start, final stitch, or purging of empty
# scans. Save scan data is still called twice
expected_calls_numbers = {
"cam_start_streaming_calls": 2,
"cam_change_streaming_mode_calls": 2,
"main_scan_loop_calls": 1,
"return_to_start_calls": 0,
"perform_final_stitch_calls": 0,
@ -559,7 +559,7 @@ def test_run_scan_cancelled(scan_thing_mocked_for_run_scan, caplog, mocker):
# Main loop not run, nor are return to start, final stitch, or purging of empty
# scans. Save scan data is still called twice
expected_calls_numbers = {
"cam_start_streaming_calls": 2,
"cam_change_streaming_mode_calls": 2,
"main_scan_loop_calls": 1,
"return_to_start_calls": 1,
"perform_final_stitch_calls": 1,
@ -584,7 +584,7 @@ def test_run_scan_fill_disk(scan_thing_mocked_for_run_scan, caplog, mocker):
# Main loop not run, nor are return to start, final stitch, or purging of empty
# scans. Save scan data is still called twice
expected_calls_numbers = {
"cam_start_streaming_calls": 2,
"cam_change_streaming_mode_calls": 2,
"main_scan_loop_calls": 1,
"return_to_start_calls": 0,
"perform_final_stitch_calls": 0,