diff --git a/src/hal/actor/commands/abort_exposures.py b/src/hal/actor/commands/abort_exposures.py index a697ed4..3233895 100644 --- a/src/hal/actor/commands/abort_exposures.py +++ b/src/hal/actor/commands/abort_exposures.py @@ -30,7 +30,7 @@ async def wait_until_idle(command: HALCommandType): """Waits until all cameras are idle.""" while True: - await asyncio.sleep(1) + await asyncio.sleep(0.5) if command.actor.helpers.apogee.is_exposing(): continue @@ -66,7 +66,7 @@ async def abort_exposures(command: HALCommandType): if isinstance(result, Exception): return command.fail(f"Failed to abort {instrument} exposure: {result!s}") elif result is not True: - return command.fail(f"Unkown error while aborting {instrument} exposure.") + return command.fail(f"Unknown error while aborting {instrument} exposure.") else: continue diff --git a/tests/actor/__init__.py b/tests/actor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_actor.py b/tests/actor/test_actor.py similarity index 100% rename from tests/test_actor.py rename to tests/actor/test_actor.py diff --git a/tests/actor/test_command_abort_exposures.py b/tests/actor/test_command_abort_exposures.py new file mode 100644 index 0000000..5dc9bb5 --- /dev/null +++ b/tests/actor/test_command_abort_exposures.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# @Author: José Sánchez-Gallego (gallegoj@uw.edu) +# @Date: 2024-05-29 +# @Filename: test_command_abort_exposures.py +# @License: BSD 3-clause (http://www.opensource.org/licenses/BSD-3-Clause) + +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +from hal.exceptions import HALError + + +if TYPE_CHECKING: + from pytest_mock import MockerFixture + + from hal.actor import HALActor + + +@pytest.mark.parametrize("observatory", ["LCO", "APO"]) +async def test_abort_exposures( + actor: HALActor, + mocker: MockerFixture, + monkeypatch: pytest.MonkeyPatch, + observatory: str, +): + apogee = actor.helpers.apogee + boss = actor.helpers.boss + + expose_macro = actor.helpers.macros["expose"] + monkeypatch.setattr(expose_macro, "_running", True) + cancel_mock = mocker.patch.object(expose_macro, "cancel") + + monkeypatch.setattr(actor, "observatory", observatory) + + mocker.patch.object(apogee, "is_exposing", side_effect=[True, False]) + mocker.patch.object(boss, "is_exposing", side_effect=[True, False]) + + cmd = actor.invoke_mock_command("abort-exposures") + await cmd + + assert cmd.status.did_succeed + cancel_mock.assert_called_once() + + +async def test_abort_exposures_abort_fails(actor: HALActor, mocker: MockerFixture): + apogee = actor.helpers.apogee + boss = actor.helpers.boss + + mocker.patch.object(apogee, "is_exposing", side_effect=[True, False]) + mocker.patch.object(boss, "is_exposing", side_effect=[True, False]) + + mocker.patch.object(apogee, "abort", side_effect=HALError("abort failed")) + + cmd = actor.invoke_mock_command("abort-exposures") + await cmd + + assert cmd.status.did_fail + error = cmd.replies[-1].message["error"] + assert "Failed to abort" in error + + +async def test_abort_exposures_abort_fails_unknown( + actor: HALActor, + mocker: MockerFixture, +): + apogee = actor.helpers.apogee + boss = actor.helpers.boss + + mocker.patch.object(apogee, "is_exposing", return_value=True) + mocker.patch.object(boss, "is_exposing", return_value=True) + + mocker.patch.object(boss, "abort", return_value=False) + + cmd = actor.invoke_mock_command("abort-exposures") + await cmd + + assert cmd.status.did_fail + error = cmd.replies[-1].message["error"] + assert "Unknown error" in error