From 3dd5ed889eb4d60e5fe1d4aec1d974e8bb0287b2 Mon Sep 17 00:00:00 2001 From: tamarzanzouri Date: Mon, 6 May 2024 22:25:13 -0400 Subject: [PATCH] added provider and tests. not complete --- .../protocol_runner/run_orchestrator.py | 81 ++++++++++------ .../protocol_runner/test_run_orchestrator.py | 17 ++-- .../test_run_orchestrator_provider.py | 95 +++++++++++++++++++ 3 files changed, 155 insertions(+), 38 deletions(-) create mode 100644 api/tests/opentrons/protocol_runner/test_run_orchestrator_provider.py diff --git a/api/src/opentrons/protocol_runner/run_orchestrator.py b/api/src/opentrons/protocol_runner/run_orchestrator.py index 03088abde4b..089520114a9 100644 --- a/api/src/opentrons/protocol_runner/run_orchestrator.py +++ b/api/src/opentrons/protocol_runner/run_orchestrator.py @@ -1,6 +1,13 @@ +from dataclasses import dataclass from typing import Optional, Union -from .protocol_runner import create_protocol_runner, AnyRunner +from .protocol_runner import ( + create_protocol_runner, + AnyRunner, + LiveRunner, + PythonAndLegacyRunner, + JsonRunner, +) from ..hardware_control import HardwareControlAPI from ..protocol_engine import ( ProtocolEngine, @@ -22,37 +29,13 @@ class RunOrchestrator: def __init__( self, - protocol_config: Optional[Union[JsonProtocolConfig, PythonProtocolConfig]], - protocol_engine: ProtocolEngine, - hardware_api: HardwareControlAPI, - post_run_hardware_state: PostRunHardwareState = PostRunHardwareState.HOME_AND_STAY_ENGAGED, - drop_tips_after_run: bool = True, + setup_runner: LiveRunner, + fixit_runner: LiveRunner, + protocol_runner: Optional[Union[PythonAndLegacyRunner, JsonRunner]] = None, ) -> None: - self._protocol_engine = protocol_engine - self._hardware_api = hardware_api - self._post_run_hardware_state = post_run_hardware_state - self._drop_tips_after_run = drop_tips_after_run - self._setup_runner = create_protocol_runner( - protocol_engine=protocol_engine, - hardware_api=hardware_api, - post_run_hardware_state=post_run_hardware_state, - drop_tips_after_run=drop_tips_after_run, - ) - self._fixit_runner = create_protocol_runner( - protocol_engine=protocol_engine, - hardware_api=hardware_api, - post_run_hardware_state=post_run_hardware_state, - drop_tips_after_run=drop_tips_after_run, - ) - - if protocol_config: - self._protocol_runner = create_protocol_runner( - protocol_config=protocol_config, - protocol_engine=protocol_engine, - hardware_api=hardware_api, - post_run_hardware_state=post_run_hardware_state, - drop_tips_after_run=drop_tips_after_run, - ) + self._setup_runner = setup_runner + self._fixit_runner = fixit_runner + self._protocol_runner = protocol_runner def add_command( self, request: CommandCreate, failed_command_id: Optional[str] = None @@ -87,3 +70,39 @@ def add_command( self._fixit_runner.set_command_queued(request) else: self._protocol_runner.set_command_queued(request) + + +@dataclass +class RunOrchestratorProvider: + @staticmethod + def build_orchestrator( + protocol_config: Optional[Union[JsonProtocolConfig, PythonProtocolConfig]], + protocol_engine: ProtocolEngine, + hardware_api: HardwareControlAPI, + post_run_hardware_state: PostRunHardwareState = PostRunHardwareState.HOME_AND_STAY_ENGAGED, + drop_tips_after_run: bool = True, + ): + setup_runner = create_protocol_runner( + protocol_engine=protocol_engine, + hardware_api=hardware_api, + post_run_hardware_state=post_run_hardware_state, + drop_tips_after_run=drop_tips_after_run, + ) + fixit_runner = create_protocol_runner( + protocol_engine=protocol_engine, + hardware_api=hardware_api, + post_run_hardware_state=post_run_hardware_state, + drop_tips_after_run=drop_tips_after_run, + ) + protocol_runner = create_protocol_runner( + protocol_config=protocol_config, + protocol_engine=protocol_engine, + hardware_api=hardware_api, + post_run_hardware_state=post_run_hardware_state, + drop_tips_after_run=drop_tips_after_run, + ) + return RunOrchestrator( + setup_runner=setup_runner, + fixit_runner=fixit_runner, + protocol_runner=protocol_runner, + ) diff --git a/api/tests/opentrons/protocol_runner/test_run_orchestrator.py b/api/tests/opentrons/protocol_runner/test_run_orchestrator.py index ac38a18a641..e00897895f0 100644 --- a/api/tests/opentrons/protocol_runner/test_run_orchestrator.py +++ b/api/tests/opentrons/protocol_runner/test_run_orchestrator.py @@ -1,3 +1,9 @@ +@pytest.fixture +def mock_protocol_json_runner(decoy: Decoy) -> JsonRunner: + """Get a mocked out JsonRunner dependency.""" + return decoy.mock(cls=JsonRunner) + + import pytest from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] from decoy import Decoy @@ -11,7 +17,10 @@ ) from opentrons.hardware_control import API as HardwareAPI from opentrons.protocol_reader import JsonProtocolConfig, PythonProtocolConfig -from opentrons.protocol_runner.run_orchestrator import RunOrchestrator +from opentrons.protocol_runner.run_orchestrator import ( + RunOrchestrator, + RunOrchestratorProvider, +) from opentrons.protocol_runner.protocol_runner import ( JsonRunner, PythonAndLegacyRunner, @@ -20,12 +29,6 @@ ) -@pytest.fixture -def mock_protocol_json_runner(decoy: Decoy) -> JsonRunner: - """Get a mocked out JsonRunner dependency.""" - return decoy.mock(cls=JsonRunner) - - @pytest.fixture def mock_protocol_python_runner(decoy: Decoy) -> PythonAndLegacyRunner: """Get a mocked out PythonAndLegacyRunner dependency.""" diff --git a/api/tests/opentrons/protocol_runner/test_run_orchestrator_provider.py b/api/tests/opentrons/protocol_runner/test_run_orchestrator_provider.py new file mode 100644 index 00000000000..36aa5028972 --- /dev/null +++ b/api/tests/opentrons/protocol_runner/test_run_orchestrator_provider.py @@ -0,0 +1,95 @@ +import pytest +from pytest_lazyfixture import lazy_fixture # type: ignore[import-untyped] +from decoy import Decoy +from typing import Union, Optional + +from opentrons.protocols.api_support.types import APIVersion +from opentrons.protocol_engine import ( + ProtocolEngine, + commands as pe_commands, + CommandIntent, +) +from opentrons.hardware_control import API as HardwareAPI +from opentrons.protocol_reader import JsonProtocolConfig, PythonProtocolConfig +from opentrons.protocol_runner.run_orchestrator import ( + RunOrchestrator, + RunOrchestratorProvider, +) +from opentrons.protocol_runner.protocol_runner import ( + JsonRunner, + PythonAndLegacyRunner, + LiveRunner, + AnyRunner, +) + + +@pytest.fixture +def mock_protocol_python_runner(decoy: Decoy) -> PythonAndLegacyRunner: + """Get a mocked out PythonAndLegacyRunner dependency.""" + return decoy.mock(cls=PythonAndLegacyRunner) + + +@pytest.fixture +def mock_protocol_json_runner(decoy: Decoy) -> JsonRunner: + """Get a mocked out PythonAndLegacyRunner dependency.""" + return decoy.mock(cls=JsonRunner) + + +@pytest.fixture +def mock_live_runner(decoy: Decoy) -> LiveRunner: + """Get a mocked out LiveRunner dependency.""" + return decoy.mock(cls=LiveRunner) + + +@pytest.fixture +def mock_protocol_engine(decoy: Decoy) -> ProtocolEngine: + """Get a mocked out ProtocolEngine dependency.""" + return decoy.mock(cls=ProtocolEngine) + + +@pytest.fixture +def mock_hardware_api(decoy: Decoy) -> HardwareAPI: + """Get a mocked out HardwareAPI dependency.""" + return decoy.mock(cls=HardwareAPI) + + +@pytest.fixture +def subject() -> RunOrchestratorProvider: + return RunOrchestratorProvider() + + +@pytest.mark.parametrize( + "input_protocol_config, mock_protocol_runner", + [ + ( + JsonProtocolConfig(schema_version=7), + lazy_fixture("mock_protocol_json_runner"), + ), + ( + PythonProtocolConfig(api_version=APIVersion(2, 14)), + lazy_fixture("mock_protocol_python_runner"), + ), + (None, None), + ], +) +def test_build_run_orchestrator_provider( + decoy: Decoy, + subject: RunOrchestratorProvider, + mock_protocol_engine: ProtocolEngine, + mock_hardware_api: HardwareAPI, + input_protocol_config: Optional[Union[PythonProtocolConfig, JsonProtocolConfig]], + mock_live_runner: LiveRunner, + mock_protocol_runner: Optional[Union[PythonAndLegacyRunner, JsonRunner]], +) -> None: + result = subject.build_orchestrator( + protocol_config=input_protocol_config, + protocol_engine=mock_protocol_engine, + hardware_api=mock_hardware_api, + ) + + # monkey patch create_runner and stub returned value + assert result == RunOrchestrator( + setup_runner=mock_live_runner, + fixit_runner=mock_live_runner, + protocol_runner=mock_protocol_runner, + )