Improve docs for hardware specific tests

This commit is contained in:
Julian Stirling 2025-06-24 14:07:58 +01:00
parent 11c8f47e20
commit a43a82213d
4 changed files with 61 additions and 11 deletions

View file

@ -1,11 +1,13 @@
from labthings_picamera2 import StreamingPiCamera2
from labthings_fastapi.server import ThingServer
from labthings_fastapi.client import ThingClient
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from PIL import Image from PIL import Image
import numpy as np import numpy as np
from pytest import fixture from pytest import fixture
from labthings_fastapi.server import ThingServer
from labthings_fastapi.client import ThingClient
from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2
@fixture(scope="module") @fixture(scope="module")
def client(): def client():
@ -17,10 +19,17 @@ def client():
def test_calibration(client): def test_calibration(client):
"""
Check that full auto calibrate completes without an exception
"""
client.full_auto_calibrate() client.full_auto_calibrate()
def test_jpeg_and_array(client): def test_jpeg_and_array(client):
"""
Check that grabbing a jpeg from the stream results in the same size
image as a array capture or a jpeg capture.
"""
blob = client.grab_jpeg() blob = client.grab_jpeg()
mjpeg_frame = Image.open(blob.open()) mjpeg_frame = Image.open(blob.open())
assert mjpeg_frame assert mjpeg_frame

View file

@ -5,12 +5,18 @@ from fastapi.testclient import TestClient
from labthings_fastapi.server import ThingServer from labthings_fastapi.server import ThingServer
from labthings_fastapi.client import ThingClient from labthings_fastapi.client import ThingClient
from labthings_picamera2.thing import StreamingPiCamera2
from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
def test_exposure_time_drift(): def test_exposure_time_drift():
"""
Capture 10 full resolution images and check that the exposure time remains constant
This confirms that automatic exposure time adjustment is fully turned off
"""
cam = StreamingPiCamera2() cam = StreamingPiCamera2()
server = ThingServer() server = ThingServer()
server.add_thing(cam, "/camera/") server.add_thing(cam, "/camera/")

View file

@ -5,12 +5,16 @@ import numpy as np
from labthings_fastapi.server import ThingServer from labthings_fastapi.server import ThingServer
from labthings_fastapi.client import ThingClient from labthings_fastapi.client import ThingClient
from labthings_picamera2.thing import StreamingPiCamera2
from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
def test_sensor_mode(): def test_sensor_mode():
"""
Test capturing raw arrays in two different sensor modes
"""
cam = StreamingPiCamera2() cam = StreamingPiCamera2()
server = ThingServer() server = ThingServer()
server.add_thing(cam, "/camera/") server.add_thing(cam, "/camera/")

View file

@ -1,23 +1,30 @@
"""
Tests that check that a tuning file can be reloaded
"""
import os import os
from picamera2 import Picamera2
from labthings_picamera2 import recalibrate_utils
import pytest import pytest
from picamera2 import Picamera2
from openflexure_microscope_server.things.camera import recalibrate_utils
MODEL = Picamera2.global_camera_info()[0]["Model"] MODEL = Picamera2.global_camera_info()[0]["Model"]
def check_camera_available():
assert len(Picamera2.global_camera_info()) >= 1
def load_default_tuning(): def load_default_tuning():
"""
Return the default tuning file for the connected camera.
"""
fname = f"{MODEL}.json" fname = f"{MODEL}.json"
return Picamera2.load_tuning_file(fname) return Picamera2.load_tuning_file(fname)
def generate_bad_tuning(): def generate_bad_tuning():
"""
Return a tuning file with an invalid version number to force an error when loaded.
"""
default_tuning = load_default_tuning() default_tuning = load_default_tuning()
bad_tuning = default_tuning.copy() bad_tuning = default_tuning.copy()
bad_tuning["version"] = 999 bad_tuning["version"] = 999
@ -25,6 +32,14 @@ def generate_bad_tuning():
def print_tuning(read_file=False): def print_tuning(read_file=False):
"""
Print the path of the default tuning file from the the environment variable.
:param read_file: Boolean, set true to also print the file contents.
This is useful for debuging. As PyTest suppresses the printing by default the
-s option is needed when running pylint to see this.
"""
key = "LIBCAMERA_RPI_TUNING_FILE" key = "LIBCAMERA_RPI_TUNING_FILE"
if key in os.environ: if key in os.environ:
print(f"Tuning file environment variable: {os.environ[key]}") print(f"Tuning file environment variable: {os.environ[key]}")
@ -36,6 +51,16 @@ def print_tuning(read_file=False):
def _test_bad_tuning_after_good_tuning(configure): def _test_bad_tuning_after_good_tuning(configure):
"""
Load the default tuning file into the camera, re-load with a broken tuning file,
check it errors. Finally check the default tuning file will load again afterwards.
:param configure: Boolean, set true to configure the camera on initial loading
This test checks that:
recalibrate_utils.recreate_camera_manager() is working as expected. As the default
PiCamera2 behaviour does not expect the tuning file to be reloaded.
"""
bad_tuning = generate_bad_tuning() bad_tuning = generate_bad_tuning()
default_tuning = load_default_tuning() default_tuning = load_default_tuning()
print_tuning() print_tuning()
@ -61,6 +86,12 @@ def _test_bad_tuning_after_good_tuning(configure):
del cam del cam
# Note: The tests below are marked with
# @pytest.mark.filterwarnings("ignore: Exception ignored")
# as the picamera will throw an exception ignored warning when deleting
# the picamera object. This is expected
@pytest.mark.filterwarnings("ignore: Exception ignored") @pytest.mark.filterwarnings("ignore: Exception ignored")
def test_bad_tuning_after_good_tuning_noconfigure(): def test_bad_tuning_after_good_tuning_noconfigure():
_test_bad_tuning_after_good_tuning(False) _test_bad_tuning_after_good_tuning(False)