Skip to content

Commit

Permalink
add executor tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sfoster1 committed Mar 14, 2024
1 parent ed31522 commit f6b6dac
Showing 1 changed file with 242 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
)

from opentrons_shared_data.errors.exceptions import EStopActivatedError, PythonException
from opentrons.protocol_engine.notes import CommandNoteTracker
from opentrons.protocol_engine.notes import CommandNoteTracker, CommandNote


@pytest.fixture
Expand Down Expand Up @@ -445,3 +445,244 @@ def _ImplementationCls(self) -> Type[_TestCommandImpl]:
)
),
)


async def test_executor_forwards_notes_on_command_success(
decoy: Decoy,
hardware_api: HardwareControlAPI,
state_store: StateStore,
action_dispatcher: ActionDispatcher,
equipment: EquipmentHandler,
movement: MovementHandler,
mock_gantry_mover: GantryMover,
labware_movement: LabwareMovementHandler,
pipetting: PipettingHandler,
mock_tip_handler: TipHandler,
run_control: RunControlHandler,
rail_lights: RailLightsHandler,
status_bar: StatusBarHandler,
model_utils: ModelUtils,
command_note_tracker: CommandNoteTracker,
subject: CommandExecutor,
) -> None:
"""It should be able to add notes during OK execution to command updates."""
TestCommandImplCls = decoy.mock(func=_TestCommandImpl)
command_impl = decoy.mock(cls=_TestCommandImpl)

class _TestCommand(BaseCommand[_TestCommandParams, _TestCommandResult]):
commandType: str = "testCommand"
params: _TestCommandParams
result: Optional[_TestCommandResult]

@property
def _ImplementationCls(self) -> Type[_TestCommandImpl]:
return TestCommandImplCls

command_params = _TestCommandParams()
command_result = _TestCommandResult()

queued_command = cast(
Command,
_TestCommand(
id="command-id",
key="command-key",
createdAt=datetime(year=2021, month=1, day=1),
status=CommandStatus.QUEUED,
params=command_params,
),
)

command_notes = [
CommandNote(
noteKind="warning",
shortMessage="hello",
longMessage="test command note",
source="test",
)
]

running_command = cast(
Command,
_TestCommand(
id="command-id",
key="command-key",
createdAt=datetime(year=2021, month=1, day=1),
startedAt=datetime(year=2022, month=2, day=2),
status=CommandStatus.RUNNING,
params=command_params,
),
)

completed_command = cast(
Command,
_TestCommand(
id="command-id",
key="command-key",
createdAt=datetime(year=2021, month=1, day=1),
startedAt=datetime(year=2022, month=2, day=2),
completedAt=datetime(year=2023, month=3, day=3),
status=CommandStatus.SUCCEEDED,
params=command_params,
result=command_result,
notes=command_notes,
),
)

decoy.when(state_store.commands.get(command_id="command-id")).then_return(
queued_command
)

decoy.when(
queued_command._ImplementationCls(
state_view=state_store,
hardware_api=hardware_api,
equipment=equipment,
movement=movement,
gantry_mover=mock_gantry_mover,
labware_movement=labware_movement,
pipetting=pipetting,
tip_handler=mock_tip_handler,
run_control=run_control,
rail_lights=rail_lights,
status_bar=status_bar,
command_note_adder=command_note_tracker,
)
).then_return(
command_impl # type: ignore[arg-type]
)

decoy.when(await command_impl.execute(command_params)).then_return(command_result)

decoy.when(model_utils.get_timestamp()).then_return(
datetime(year=2022, month=2, day=2),
datetime(year=2023, month=3, day=3),
)
decoy.when(command_note_tracker.get_notes()).then_return(command_notes)

await subject.execute("command-id")

decoy.verify(
action_dispatcher.dispatch(
UpdateCommandAction(private_result=None, command=running_command)
),
action_dispatcher.dispatch(
UpdateCommandAction(private_result=None, command=completed_command)
),
)

async def test_executor_forwards_notes_on_command_failure(
decoy: Decoy,
hardware_api: HardwareControlAPI,
state_store: StateStore,
action_dispatcher: ActionDispatcher,
equipment: EquipmentHandler,
movement: MovementHandler,
mock_gantry_mover: GantryMover,
labware_movement: LabwareMovementHandler,
pipetting: PipettingHandler,
mock_tip_handler: TipHandler,
run_control: RunControlHandler,
rail_lights: RailLightsHandler,
status_bar: StatusBarHandler,
model_utils: ModelUtils,
subject: CommandExecutor,
command_note_tracker: CommandNoteTracker,
) -> None:
"""It should handle an error occuring during execution."""
TestCommandImplCls = decoy.mock(func=_TestCommandImpl)
command_impl = decoy.mock(cls=_TestCommandImpl)


class _TestCommand(BaseCommand[_TestCommandParams, _TestCommandResult]):
commandType: str = "testCommand"
params: _TestCommandParams
result: Optional[_TestCommandResult]

@property
def _ImplementationCls(self) -> Type[_TestCommandImpl]:
return TestCommandImplCls

command_params = _TestCommandParams()
command_notes = [
CommandNote(
noteKind="warning",
shortMessage="hello",
longMessage="test command note",
source="test",
)
]

queued_command = cast(
Command,
_TestCommand(
id="command-id",
key="command-key",
createdAt=datetime(year=2021, month=1, day=1),
status=CommandStatus.QUEUED,
params=command_params,
),
)

running_command = cast(
Command,
_TestCommand(
id="command-id",
key="command-key",
createdAt=datetime(year=2021, month=1, day=1),
startedAt=datetime(year=2022, month=2, day=2),
status=CommandStatus.RUNNING,
params=command_params,
),
)
running_command_with_notes = running_command.copy(update={'notes': command_notes})

decoy.when(state_store.commands.get(command_id="command-id")).then_return(
queued_command
)

decoy.when(
queued_command._ImplementationCls(
state_view=state_store,
hardware_api=hardware_api,
equipment=equipment,
movement=movement,
gantry_mover=mock_gantry_mover,
labware_movement=labware_movement,
pipetting=pipetting,
tip_handler=mock_tip_handler,
run_control=run_control,
rail_lights=rail_lights,
status_bar=status_bar,
command_note_adder=command_note_tracker,
)
).then_return(
command_impl # type: ignore[arg-type]
)

decoy.when(await command_impl.execute(command_params)).then_raise(RuntimeError("oh no"))

decoy.when(model_utils.generate_id()).then_return("error-id")
decoy.when(model_utils.get_timestamp()).then_return(
datetime(year=2022, month=2, day=2),
datetime(year=2023, month=3, day=3),
)
decoy.when(command_note_tracker.get_notes()).then_return(command_notes)

await subject.execute("command-id")

decoy.verify(
action_dispatcher.dispatch(
UpdateCommandAction(private_result=None, command=running_command)
),
action_dispatcher.dispatch(
UpdateCommandAction(private_result=None, command=running_command_with_notes)
),
action_dispatcher.dispatch(
FailCommandAction(
command_id="command-id",
error_id="error-id",
failed_at=datetime(year=2023, month=3, day=3),
error=matchers.ErrorMatching(PythonException, match="oh no"),
)
),
)

0 comments on commit f6b6dac

Please sign in to comment.