Update tests for not having cancel hooks
This commit is contained in:
parent
8f805c8e68
commit
f6d4b368d0
2 changed files with 68 additions and 48 deletions
|
|
@ -174,7 +174,6 @@ def _run_only_outer_scan(adjust_initial_state: Optional[Callable] = None):
|
|||
function
|
||||
"""
|
||||
# cancel handle shouldn't be used. Set to arbitrary value for checking
|
||||
cancel_mock = 1 # not called
|
||||
af_mock = MockAutoFocusThing()
|
||||
stage_mock = MockStageThing()
|
||||
cam_mock = MockCameraThing()
|
||||
|
|
@ -191,7 +190,6 @@ def _run_only_outer_scan(adjust_initial_state: Optional[Callable] = None):
|
|||
|
||||
"""Check scan vars are set up as expected"""
|
||||
assert not self._scan_lock.acquire(timeout=0.1)
|
||||
assert self._cancel is cancel_mock
|
||||
assert self._scan_logger is LOGGER
|
||||
assert self._autofocus is af_mock
|
||||
assert self._stage is stage_mock
|
||||
|
|
@ -209,7 +207,6 @@ def _run_only_outer_scan(adjust_initial_state: Optional[Callable] = None):
|
|||
exec_info = None
|
||||
try:
|
||||
mock_ss_thing.sample_scan(
|
||||
cancel=cancel_mock, # Shouldn't be used, can be checked
|
||||
logger=LOGGER,
|
||||
autofocus=af_mock,
|
||||
stage=stage_mock,
|
||||
|
|
@ -222,7 +219,6 @@ def _run_only_outer_scan(adjust_initial_state: Optional[Callable] = None):
|
|||
|
||||
assert mock_ss_thing._scan_lock.acquire(timeout=0.1)
|
||||
mock_ss_thing._scan_lock.release()
|
||||
assert mock_ss_thing._cancel is None
|
||||
assert mock_ss_thing._scan_logger is None
|
||||
assert mock_ss_thing._autofocus is None
|
||||
assert mock_ss_thing._stage is None
|
||||
|
|
@ -342,7 +338,6 @@ def scan_thing_mocked_for_run_scan(scan_thing_mocked_for_scan_data, mocker):
|
|||
"""
|
||||
scan_thing = scan_thing_mocked_for_scan_data
|
||||
scan_thing._cam = MockCameraThing()
|
||||
mocker.patch.object(scan_thing, "_cancel")
|
||||
mocker.patch.object(scan_thing, "_main_scan_loop")
|
||||
mocker.patch.object(scan_thing, "_return_to_starting_position")
|
||||
mocker.patch.object(scan_thing, "_perform_final_stitch")
|
||||
|
|
|
|||
|
|
@ -6,9 +6,8 @@ generated, and the subprocess calling works as expected.
|
|||
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import re
|
||||
import time
|
||||
import uuid
|
||||
from copy import copy
|
||||
|
||||
import pytest
|
||||
|
|
@ -23,8 +22,10 @@ from openflexure_microscope_server.stitching import (
|
|||
StitcherValidationError,
|
||||
)
|
||||
|
||||
# A global logger pretending to be an Invocation Logger
|
||||
LOGGER = logging.getLogger("mock-invocation_logger")
|
||||
from .utilities.lt_test_utils import LabThingsTestEnv
|
||||
|
||||
# A global logger pretending to the logger from a thing
|
||||
LOGGER = logging.getLogger("mock-thing_logger")
|
||||
FAKE_DIR: list[str] = os.path.join("a", "dir", "that", "is", "fake")
|
||||
THIS_DIR: str = os.path.dirname(os.path.realpath(__file__))
|
||||
MOCK_STITCHER: str = os.path.join(THIS_DIR, "mock_stitching", "mock-stitch.py")
|
||||
|
|
@ -200,7 +201,6 @@ def test_preview_stitching_command(caplog, mocker):
|
|||
mocker.patch("openflexure_microscope_server.stitching.STITCHING_CMD", mock_cmd)
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
cancel_hook = lt.deps.CancelHook(id=uuid.uuid4())
|
||||
stitcher = PreviewStitcher(FAKE_DIR, overlap=0.1, correlation_resize=0.5)
|
||||
stitcher.start()
|
||||
# Should take a second or so to run so will still be running
|
||||
|
|
@ -209,38 +209,64 @@ def test_preview_stitching_command(caplog, mocker):
|
|||
with pytest.raises(RuntimeError):
|
||||
stitcher.start()
|
||||
# Wait for it to complete
|
||||
stitcher.wait(cancel_hook)
|
||||
stitcher.wait()
|
||||
# It is now not running
|
||||
assert not stitcher.running
|
||||
assert len(caplog.records) == 0
|
||||
|
||||
|
||||
def test_preview_stitching_cancelled(caplog, mocker):
|
||||
class StitchingTestThing(lt.Thing):
|
||||
"""A Thing for running stitching in invocation threads.
|
||||
|
||||
This is needed to check cancellation behaviour.
|
||||
"""
|
||||
|
||||
@lt.action
|
||||
def run_preview(self):
|
||||
"""Run the preview stitcher."""
|
||||
stitcher = PreviewStitcher(FAKE_DIR, overlap=0.1, correlation_resize=0.5)
|
||||
# Send in the argument HANG to mock-stitch and it just hang for 10s
|
||||
stitcher._extra_args = ["HANG"]
|
||||
stitcher.start()
|
||||
stitcher.wait()
|
||||
|
||||
@lt.action
|
||||
def run_final(self):
|
||||
"""Run the final stitcher."""
|
||||
stitcher = FinalStitcher(FAKE_DIR, logger=self.logger)
|
||||
# Send in the argument HANG to mock-stitch and it just hang for 10s
|
||||
stitcher.run()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def stitching_test_env():
|
||||
"""Return a test environment for a server with just StitchingTestThing."""
|
||||
with LabThingsTestEnv(things={"stitcher": StitchingTestThing}) as env:
|
||||
yield env
|
||||
|
||||
|
||||
def test_preview_stitching_cancelled(stitching_test_env, mocker):
|
||||
"""Check that preview stitch can be cancelled."""
|
||||
mock_cmd = f"python {MOCK_STITCHER}"
|
||||
|
||||
mocker.patch("openflexure_microscope_server.stitching.STITCHING_CMD", mock_cmd)
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
stitcher = PreviewStitcher(FAKE_DIR, overlap=0.1, correlation_resize=0.5)
|
||||
# Send in the argument HANG to mock-stitch and it just hang for 10s
|
||||
stitcher._extra_args = ["HANG"]
|
||||
cancel_hook = lt.deps.CancelHook(id=uuid.uuid4())
|
||||
t_start = time.time()
|
||||
# Start stitching
|
||||
stitcher.start()
|
||||
# Run wait() in a thread.
|
||||
thread = threading.Thread(target=stitcher.wait, kwargs={"cancel": cancel_hook})
|
||||
thread.start()
|
||||
# Sleep long enough for at least 1 log.
|
||||
time.sleep(0.5)
|
||||
# use set() to cancel!
|
||||
cancel_hook.set()
|
||||
thread.join()
|
||||
# If it wasn't cancelled it would hang for 10 s. Here we check the cancel killed
|
||||
# it within 2s.
|
||||
assert t_start - time.time() < 2
|
||||
assert len(caplog.records) == 0
|
||||
t_start = time.time()
|
||||
# Start the action
|
||||
response = stitching_test_env.start_action("stitcher", "run_preview")
|
||||
# Sleep long enough for at least 1 log.
|
||||
time.sleep(0.5)
|
||||
# Cancel using a DELETE request
|
||||
stitching_test_env.cancel_action(response)
|
||||
invocation_data = stitching_test_env.poll_action(response)
|
||||
|
||||
# If it wasn't cancelled it would hang for 10 s. Here we check the cancel killed
|
||||
# it within 2s.
|
||||
assert time.time() - t_start < 2
|
||||
assert invocation_data["status"] == "cancelled"
|
||||
logs = invocation_data["log"]
|
||||
assert len(logs) == 1
|
||||
assert re.match(r"^Invocation [0-9a-f-]+ was cancelled", logs[0]["message"])
|
||||
|
||||
|
||||
def test_final_stitching_command(caplog, mocker):
|
||||
|
|
@ -255,7 +281,7 @@ def test_final_stitching_command(caplog, mocker):
|
|||
FAKE_DIR, logger=LOGGER, overlap=0.1, correlation_resize=0.5
|
||||
)
|
||||
# For the final stitcher it will always complete before returning.
|
||||
stitcher.run(cancel=lt.deps.CancelHook(id=uuid.uuid4()))
|
||||
stitcher.run()
|
||||
# The mock command logs the inputs (but not the initial command) and the
|
||||
# stitcher logs # "Stitching complete" when it ends.
|
||||
assert len(caplog.records) == len(FINAL_EXPECTED_COMMAND)
|
||||
|
|
@ -267,26 +293,25 @@ def test_final_stitching_command(caplog, mocker):
|
|||
assert msg == FINAL_EXPECTED_COMMAND[i + 1]
|
||||
|
||||
|
||||
def test_final_stitching_command_cancelled(caplog, mocker):
|
||||
def test_final_stitching_command_cancelled(stitching_test_env, mocker):
|
||||
"""Check that final stitch can be cancelled."""
|
||||
mock_cmd = f"python {MOCK_STITCHER}"
|
||||
|
||||
mocker.patch("openflexure_microscope_server.stitching.STITCHING_CMD", mock_cmd)
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
stitcher = FinalStitcher(FAKE_DIR, logger=LOGGER)
|
||||
cancel_hook = lt.deps.CancelHook(id=uuid.uuid4())
|
||||
# Start the action
|
||||
response = stitching_test_env.start_action("stitcher", "run_final")
|
||||
# Sleep long enough for at least 1 log.
|
||||
time.sleep(0.5)
|
||||
# Cancel using a DELETE request
|
||||
stitching_test_env.cancel_action(response)
|
||||
invocation_data = stitching_test_env.poll_action(response)
|
||||
|
||||
# Start stitching in a thread.
|
||||
thread = threading.Thread(target=stitcher.run, kwargs={"cancel": cancel_hook})
|
||||
thread.start()
|
||||
# Sleep long enough for at least 1 log.
|
||||
time.sleep(0.5)
|
||||
# use set() to cancel!
|
||||
cancel_hook.set()
|
||||
thread.join()
|
||||
assert len(caplog.records) < len(FINAL_EXPECTED_COMMAND) + 1
|
||||
assert caplog.records[-1].message == "Stitching cancelled by user"
|
||||
assert invocation_data["status"] == "cancelled"
|
||||
logs = invocation_data["log"]
|
||||
assert len(logs) < len(FINAL_EXPECTED_COMMAND) + 1
|
||||
assert logs[-2]["message"] == "Stitching cancelled by user"
|
||||
assert re.match(r"^Invocation [0-9a-f-]+ was cancelled", logs[-1]["message"])
|
||||
|
||||
|
||||
def test_final_stitching_command_error(caplog, mocker):
|
||||
|
|
@ -301,4 +326,4 @@ def test_final_stitching_command_error(caplog, mocker):
|
|||
# than echo.
|
||||
stitcher._extra_args = ["ERROR"]
|
||||
with pytest.raises(ChildProcessError):
|
||||
stitcher.run(cancel=lt.deps.CancelHook(id=uuid.uuid4()))
|
||||
stitcher.run()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue