Skip to content

Commit

Permalink
unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
CaseyBatten committed Dec 13, 2024
1 parent 04fb06e commit b7e2615
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 1 deletion.
6 changes: 5 additions & 1 deletion api/src/opentrons/protocol_api/core/engine/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,10 @@ def load_lid_stack(
version: Optional[int],
) -> LabwareCore:
"""Load a Stack of Lids to a given location, creating a Lid Stack."""
if quantity < 1:
raise ValueError(
"When loading a lid stack quantity cannot be less than one."
)
if isinstance(location, DeckSlotName) or isinstance(location, StagingSlotName):
load_location = self._convert_labware_location(location=location)
else:
Expand Down Expand Up @@ -733,7 +737,7 @@ def load_lid_stack(

deck_conflict.check(
engine_state=self._engine_client.state,
new_labware_id=load_result.labwareIds[0],
new_labware_id=load_result.stackLabwareId,
existing_disposal_locations=self._disposal_locations,
# TODO (spp, 2023-11-27): We've been using IDs from _labware_cores_by_id
# and _module_cores_by_id instead of getting the lists directly from engine
Expand Down
148 changes: 148 additions & 0 deletions api/tests/opentrons/protocol_api/core/engine/test_protocol_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,154 @@ def test_load_adapter_on_staging_slot(
assert subject.get_slot_item(StagingSlotName.SLOT_B4) is result


def test_load_lid(
decoy: Decoy,
mock_engine_client: EngineClient,
subject: ProtocolCore,
) -> None:
"""It should issue a LoadLid command."""
mock_labware_core = decoy.mock(cls=LabwareCore)
decoy.when(mock_labware_core.labware_id).then_return("labware-id")
decoy.when(
mock_engine_client.state.labware.find_custom_labware_load_params()
).then_return([EngineLabwareLoadParams("hello", "world", 654)])

decoy.when(
load_labware_params.resolve(
"some_labware",
"a_namespace",
456,
[EngineLabwareLoadParams("hello", "world", 654)],
)
).then_return(("some_namespace", 9001))

decoy.when(
mock_engine_client.execute_command_without_recovery(
cmd.LoadLidParams(
location=OnLabwareLocation(labwareId="labware-id"),
loadName="some_labware",
namespace="some_namespace",
version=9001,
)
)
).then_return(
commands.LoadLidResult(
labwareId="abc123",
definition=LabwareDefinition.construct(), # type: ignore[call-arg]
)
)

decoy.when(mock_engine_client.state.labware.get_definition("abc123")).then_return(
LabwareDefinition.construct(ordering=[]) # type: ignore[call-arg]
)

result = subject.load_lid(
load_name="some_labware",
location=mock_labware_core,
namespace="a_namespace",
version=456,
)

assert isinstance(result, LabwareCore)
assert result.labware_id == "abc123"
assert subject.get_labware_cores() == [result]

decoy.verify(
deck_conflict.check(
engine_state=mock_engine_client.state,
existing_labware_ids=[],
existing_module_ids=[],
existing_disposal_locations=[],
new_labware_id="abc123",
)
)

decoy.when(
mock_engine_client.state.geometry.get_slot_item(
slot_name=DeckSlotName.SLOT_5,
)
).then_return(
LoadedLabware.construct(id="abc123") # type: ignore[call-arg]
)

assert subject.get_slot_item(DeckSlotName.SLOT_5) is result


def test_load_lid_stack(
decoy: Decoy,
mock_engine_client: EngineClient,
subject: ProtocolCore,
) -> None:
"""It should issue a LoadLidStack command."""
decoy.when(
mock_engine_client.state.labware.find_custom_labware_load_params()
).then_return([EngineLabwareLoadParams("hello", "world", 654)])

decoy.when(
load_labware_params.resolve(
"some_labware",
"a_namespace",
456,
[EngineLabwareLoadParams("hello", "world", 654)],
)
).then_return(("some_namespace", 9001))

decoy.when(
mock_engine_client.execute_command_without_recovery(
cmd.LoadLidStackParams(
location=DeckSlotLocation(slotName=DeckSlotName.SLOT_5),
loadName="some_labware",
namespace="some_namespace",
version=9001,
quantity=5,
)
)
).then_return(
commands.LoadLidStackResult(
stackLabwareId="abc123",
labwareIds=["1", "2", "3", "4", "5"],
definition=LabwareDefinition.construct(), # type: ignore[call-arg]
location=DeckSlotLocation(slotName=DeckSlotName.SLOT_5),
)
)

decoy.when(mock_engine_client.state.labware.get_definition("abc123")).then_return(
LabwareDefinition.construct(ordering=[]) # type: ignore[call-arg]
)

result = subject.load_lid_stack(
load_name="some_labware",
location=DeckSlotName.SLOT_5,
namespace="a_namespace",
version=456,
quantity=5,
)

assert isinstance(result, LabwareCore)
assert result.labware_id == "abc123"
assert subject.get_labware_cores() == [result]

decoy.verify(
deck_conflict.check(
engine_state=mock_engine_client.state,
existing_labware_ids=[],
existing_module_ids=[],
existing_disposal_locations=[],
new_labware_id="abc123",
)
)

decoy.when(
mock_engine_client.state.geometry.get_slot_item(
slot_name=DeckSlotName.SLOT_5,
)
).then_return(
LoadedLabware.construct(id="abc123") # type: ignore[call-arg]
)

assert subject.get_slot_item(DeckSlotName.SLOT_5) is result


def test_load_trash_bin(
decoy: Decoy,
mock_engine_client: EngineClient,
Expand Down
109 changes: 109 additions & 0 deletions api/tests/opentrons/protocol_api/test_protocol_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,115 @@ def test_load_labware_on_adapter(
decoy.verify(mock_core_map.add(mock_labware_core, result), times=1)


@pytest.mark.parametrize("api_version", [APIVersion(2, 23)])
def test_load_labware_with_lid(
decoy: Decoy,
mock_core: ProtocolCore,
mock_core_map: LoadedCoreMap,
api_version: APIVersion,
subject: ProtocolContext,
) -> None:
"""It should create a labware with a lid on it using its execution core."""
mock_labware_core = decoy.mock(cls=LabwareCore)
mock_lid_core = decoy.mock(cls=LabwareCore)

decoy.when(mock_validation.ensure_lowercase_name("UPPERCASE_LABWARE")).then_return(
"lowercase_labware"
)

decoy.when(mock_validation.ensure_lowercase_name("UPPERCASE_LID")).then_return(
"lowercase_lid"
)
decoy.when(mock_core.robot_type).then_return("OT-3 Standard")
decoy.when(
mock_validation.ensure_and_convert_deck_slot(42, api_version, "OT-3 Standard")
).then_return(DeckSlotName.SLOT_C1)

decoy.when(
mock_core.load_labware(
load_name="lowercase_labware",
location=DeckSlotName.SLOT_C1,
label="some_display_name",
namespace="some_namespace",
version=1337,
)
).then_return(mock_labware_core)
decoy.when(mock_lid_core.get_well_columns()).then_return([])

decoy.when(
mock_core.load_lid(
load_name="lowercase_lid",
location=mock_labware_core,
namespace="some_namespace",
version=None,
)
).then_return(mock_lid_core)

decoy.when(mock_labware_core.get_name()).then_return("Full Name")
decoy.when(mock_labware_core.get_display_name()).then_return("Display Name")
decoy.when(mock_labware_core.get_well_columns()).then_return([])

result = subject.load_labware(
load_name="UPPERCASE_LABWARE",
location=42,
label="some_display_name",
namespace="some_namespace",
version=1337,
lid="UPPERCASE_LID",
)

assert isinstance(result, Labware)
assert result.name == "Full Name"

decoy.verify(mock_core_map.add(mock_labware_core, result), times=1)


@pytest.mark.parametrize("api_version", [APIVersion(2, 23)])
def test_load_lid_stack(
decoy: Decoy,
mock_core: ProtocolCore,
mock_core_map: LoadedCoreMap,
api_version: APIVersion,
subject: ProtocolContext,
) -> None:
"""It should create a labware with a lid on it using its execution core."""
mock_lid_core = decoy.mock(cls=LabwareCore)

decoy.when(mock_validation.ensure_lowercase_name("UPPERCASE_LID")).then_return(
"lowercase_lid"
)

decoy.when(mock_core.robot_type).then_return("OT-3 Standard")
decoy.when(
mock_validation.ensure_and_convert_deck_slot(42, api_version, "OT-3 Standard")
).then_return(DeckSlotName.SLOT_C1)

decoy.when(
mock_core.load_lid_stack(
load_name="lowercase_lid",
location=DeckSlotName.SLOT_C1,
quantity=5,
namespace="some_namespace",
version=1337,
)
).then_return(mock_lid_core)

decoy.when(mock_lid_core.get_name()).then_return("STACK_OBJECT")
decoy.when(mock_lid_core.get_display_name()).then_return("")
decoy.when(mock_lid_core.get_well_columns()).then_return([])

result = subject.load_lid_stack(
load_name="UPPERCASE_LID",
location=42,
quantity=5,
namespace="some_namespace",
version=1337,
)

assert isinstance(result, Labware)
assert result.name == "STACK_OBJECT"


def test_loaded_labware(
decoy: Decoy,
mock_core_map: LoadedCoreMap,
Expand Down

0 comments on commit b7e2615

Please sign in to comment.