Add unit tests that simulates broken frames and catches the correct error.

This commit is contained in:
Julian Stirling 2025-08-20 18:59:55 +01:00
parent 46be2c770e
commit 347247f45b
2 changed files with 63 additions and 1 deletions

58
tests/test_camera.py Normal file
View file

@ -0,0 +1,58 @@
"""Use the Simulation camera to test base camera functionality."""
import tempfile
from contextlib import contextmanager
import pytest
from fastapi.testclient import TestClient
import numpy as np
from PIL import Image
import labthings_fastapi as lt
from openflexure_microscope_server.things.camera.simulation import SimulatedCamera
@contextmanager
def camera_server(camera: SimulatedCamera) -> lt.ThingClient:
"""Add the camera to a ThingServer and start a TestClient application.
The test client application is needed for the camera to have a blocking portal.
"""
with tempfile.TemporaryDirectory() as tmpdir:
server = lt.ThingServer(settings_folder=tmpdir)
server.add_thing(camera, "/camera/")
with TestClient(server.app):
yield server
def test_handle_broken_frame():
"""Monkey patch the the mjpeg steam so 1 in 5 frames are broken, then test operation.
This simulates the very occasional broken frames that can occur when grabbing
directly from the MJPEG stream.
"""
camera = SimulatedCamera()
# Money patch the mjpeg_stream grab_frame to break 1 in 5 frames.
frame_number = 0
original_grabber = camera.mjpeg_stream.grab_frame
async def flaky_grabber():
"""Break 1 in 5 frames."""
# Use a non-local variable to know the frame count.
nonlocal frame_number
frame = await original_grabber()
if frame_number % 5 == 2:
# Make a weird broken frame
frame = frame[:2000] + frame[:2000]
frame_number += 1
return frame
camera.mjpeg_stream.grab_frame = flaky_grabber
with camera_server(camera):
portal = lt.get_blocking_portal(camera)
with pytest.raises(OSError, match="broken data stream when reading image file"):
for _i in range(15):
jpeg = camera.grab_jpeg(portal)
np.asarray(Image.open(jpeg.open()))

View file

@ -1,4 +1,8 @@
"""Generic tests for cameras, specific camera hardware reqipres hardware specific tests.""" """Tests for camera classes. These tests focus on checking the camera APIs are equivalent.
Tests for specific camera hardware are in the hardware-specific-tests directory. Tests
on camera functionality using the simulation camera are in "test_camera".
"""
import pytest import pytest