Skip to content

Commit

Permalink
test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
CaseyBatten committed Mar 1, 2024
1 parent c60f124 commit d91df8e
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 26 deletions.
2 changes: 1 addition & 1 deletion api/src/opentrons/protocol_engine/state/tips.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def _cluster_search_H12() -> Optional[str]:
critical_row = len(columns[critical_column]) - num_nozzle_rows
return None

if starting_tip_name is None:
if starting_tip_name is None and columns:
if self.get_pipette_channels(pipette_id) == 1:
# for a single channel pipette, always begin at A1 on the tiprack
return _cluster_search_A1()
Expand Down
19 changes: 15 additions & 4 deletions api/tests/opentrons/protocol_api/core/engine/test_labware_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest
from decoy import Decoy

from opentrons_shared_data.pipette.dev_types import PipetteNameType
from opentrons_shared_data.labware.dev_types import (
LabwareDefinition as LabwareDefDict,
LabwareParameters as LabwareParamsDict,
Expand All @@ -16,7 +17,8 @@
Metadata as LabwareDefinitionMetadata,
)

from opentrons.types import DeckSlotName, Point, Mount
from opentrons.types import DeckSlotName, Point, Mount, MountType
from opentrons.protocol_engine.types import LoadedPipette
from opentrons.protocol_engine.clients import SyncClient as EngineClient
from opentrons.protocol_engine.errors import LabwareNotOnDeckError

Expand Down Expand Up @@ -244,6 +246,17 @@ def test_get_next_tip(
decoy: Decoy, mock_engine_client: EngineClient, subject: LabwareCore
) -> None:
"""It should get the next available tip from the core."""
mount = Mount.LEFT
decoy.when(
mock_engine_client.state.pipettes.get_by_mount(MountType.from_hw_mount(mount))
).then_return(
LoadedPipette.construct(
pipetteName=PipetteNameType.P300_MULTI,
id="pipette-id",
mount=MountType.from_hw_mount(mount),
)
)

decoy.when(
mock_engine_client.state.tips.get_next_tip(
pipette_id="pipette-id",
Expand All @@ -256,9 +269,7 @@ def test_get_next_tip(
starting_tip = WellCore(
name="B1", labware_id="cool-labware", engine_client=mock_engine_client
)
result = subject.get_next_tip(
mount=Mount.LEFT, num_tips=8, starting_tip=starting_tip
)
result = subject.get_next_tip(mount=mount, num_tips=8, starting_tip=starting_tip)

assert result == "A2"

Expand Down
2 changes: 1 addition & 1 deletion api/tests/opentrons/protocol_api_old/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ def test_pick_up_tip_no_location(ctx, get_labware_def, pipette_model, tiprack_ki
if well.has_tip:
tiprack1.use_tips(well)

assert tiprack1.next_tip() is None
assert tiprack1.next_tip(mount) is None

assert tiprack2.wells()[0].has_tip
instr.pick_up_tip()
Expand Down
29 changes: 15 additions & 14 deletions api/tests/opentrons/protocol_api_old/test_labware.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,46 +375,47 @@ def test_select_next_tip(
) -> None:
tiprack = opentrons_96_tiprack_300ul
well_list = tiprack.wells()
mount = Mount.LEFT

next_one = tiprack.next_tip()
next_one = tiprack.next_tip(mount)
assert next_one == well_list[0]
next_five = tiprack.next_tip(5)
next_five = tiprack.next_tip(mount, 5)
assert next_five == well_list[0]
next_eight = tiprack.next_tip(8)
next_eight = tiprack.next_tip(mount, 8)
assert next_eight == well_list[0]
next_nine = tiprack.next_tip(9)
next_nine = tiprack.next_tip(mount, 9)
assert next_nine is None

# A1 tip only has been used
tiprack.use_tips(well_list[0])

next_one = tiprack.next_tip()
next_one = tiprack.next_tip(mount)
assert next_one == well_list[1]
next_five = tiprack.next_tip(5)
next_five = tiprack.next_tip(mount, 5)
assert next_five == well_list[1]
next_eight = tiprack.next_tip(8)
next_eight = tiprack.next_tip(mount, 8)
assert next_eight == well_list[8]

# 2nd column has also been used
tiprack.use_tips(well_list[8], num_channels=8)

next_one = tiprack.next_tip()
next_one = tiprack.next_tip(mount)
assert next_one == well_list[1]
next_five = tiprack.next_tip(5)
next_five = tiprack.next_tip(mount, 5)
assert next_five == well_list[1]
next_eight = tiprack.next_tip(8)
next_eight = tiprack.next_tip(mount, 8)
assert next_eight == well_list[16]

# Bottom 4 tips of 1rd column are also used
tiprack.use_tips(well_list[4], num_channels=4)

next_one = tiprack.next_tip()
next_one = tiprack.next_tip(mount)
assert next_one == well_list[1]
next_three = tiprack.next_tip(3)
next_three = tiprack.next_tip(mount, 3)
assert next_three == well_list[1]
next_five = tiprack.next_tip(5)
next_five = tiprack.next_tip(mount, 5)
assert next_five == well_list[16]
next_eight = tiprack.next_tip(8)
next_eight = tiprack.next_tip(mount, 8)
assert next_eight == well_list[16]

# you can reuse tips infinitely on api level 2.2
Expand Down
125 changes: 121 additions & 4 deletions api/tests/opentrons/protocol_engine/state/test_tip_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,6 @@ def test_get_next_tip_used_starting_tip(
private_result=load_pipette_private_result, command=load_pipette_command
)
)
# subject.handle_action(
# actions.UpdateCommandAction(command=pick_up_tip_command, private_result=None)
# )

result = TipView(subject.state).get_next_tip(
pipette_id="pipette-id",
Expand Down Expand Up @@ -410,11 +407,41 @@ def test_get_next_tip_skips_picked_up_tip(
def test_get_next_tip_with_starting_tip(
subject: TipStore,
load_labware_command: commands.LoadLabware,
supported_tip_fixture: pipette_definition.SupportedTipsDefinition,
) -> None:
"""It should return the starting tip, and then the following tip after that."""
subject.handle_action(
actions.UpdateCommandAction(private_result=None, command=load_labware_command)
)
load_pipette_command = commands.LoadPipette.construct( # type: ignore[call-arg]
result=commands.LoadPipetteResult(pipetteId="pipette-id")
)
load_pipette_private_result = commands.LoadPipettePrivateResult(
pipette_id="pipette-id",
serial_number="pipette-serial",
config=LoadedStaticPipetteData(
channels=1,
max_volume=15,
min_volume=3,
model="gen a",
display_name="display name",
flow_rates=FlowRates(
default_aspirate={},
default_dispense={},
default_blow_out={},
),
tip_configuration_lookup_table={15: supported_tip_fixture},
nominal_tip_overlap={},
nozzle_offset_z=1.23,
home_position=4.56,
nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2),
),
)
subject.handle_action(
actions.UpdateCommandAction(
private_result=load_pipette_private_result, command=load_pipette_command
)
)

result = TipView(subject.state).get_next_tip(
pipette_id="pipette-id",
Expand Down Expand Up @@ -453,11 +480,41 @@ def test_get_next_tip_with_starting_tip(
def test_get_next_tip_with_starting_tip_8_channel(
subject: TipStore,
load_labware_command: commands.LoadLabware,
supported_tip_fixture: pipette_definition.SupportedTipsDefinition,
) -> None:
"""It should return the starting tip, and then the following tip after that."""
subject.handle_action(
actions.UpdateCommandAction(private_result=None, command=load_labware_command)
)
load_pipette_command = commands.LoadPipette.construct( # type: ignore[call-arg]
result=commands.LoadPipetteResult(pipetteId="pipette-id")
)
load_pipette_private_result = commands.LoadPipettePrivateResult(
pipette_id="pipette-id",
serial_number="pipette-serial",
config=LoadedStaticPipetteData(
channels=8,
max_volume=15,
min_volume=3,
model="gen a",
display_name="display name",
flow_rates=FlowRates(
default_aspirate={},
default_dispense={},
default_blow_out={},
),
tip_configuration_lookup_table={15: supported_tip_fixture},
nominal_tip_overlap={},
nozzle_offset_z=1.23,
home_position=4.56,
nozzle_map=get_default_nozzle_map(PipetteNameType.P300_MULTI_GEN2),
),
)
subject.handle_action(
actions.UpdateCommandAction(
private_result=load_pipette_private_result, command=load_pipette_command
)
)

result = TipView(subject.state).get_next_tip(
pipette_id="pipette-id",
Expand Down Expand Up @@ -496,11 +553,41 @@ def test_get_next_tip_with_starting_tip_8_channel(
def test_get_next_tip_with_starting_tip_out_of_tips(
subject: TipStore,
load_labware_command: commands.LoadLabware,
supported_tip_fixture: pipette_definition.SupportedTipsDefinition,
) -> None:
"""It should return the starting tip of H12 and then None after that."""
subject.handle_action(
actions.UpdateCommandAction(private_result=None, command=load_labware_command)
)
load_pipette_command = commands.LoadPipette.construct( # type: ignore[call-arg]
result=commands.LoadPipetteResult(pipetteId="pipette-id")
)
load_pipette_private_result = commands.LoadPipettePrivateResult(
pipette_id="pipette-id",
serial_number="pipette-serial",
config=LoadedStaticPipetteData(
channels=1,
max_volume=15,
min_volume=3,
model="gen a",
display_name="display name",
flow_rates=FlowRates(
default_aspirate={},
default_dispense={},
default_blow_out={},
),
tip_configuration_lookup_table={15: supported_tip_fixture},
nominal_tip_overlap={},
nozzle_offset_z=1.23,
home_position=4.56,
nozzle_map=get_default_nozzle_map(PipetteNameType.P300_SINGLE_GEN2),
),
)
subject.handle_action(
actions.UpdateCommandAction(
private_result=load_pipette_private_result, command=load_pipette_command
)
)

result = TipView(subject.state).get_next_tip(
pipette_id="pipette-id",
Expand Down Expand Up @@ -539,11 +626,41 @@ def test_get_next_tip_with_starting_tip_out_of_tips(
def test_get_next_tip_with_column_and_starting_tip(
subject: TipStore,
load_labware_command: commands.LoadLabware,
supported_tip_fixture: pipette_definition.SupportedTipsDefinition,
) -> None:
"""It should return the first tip in a column, taking starting tip into account."""
subject.handle_action(
actions.UpdateCommandAction(private_result=None, command=load_labware_command)
)
load_pipette_command = commands.LoadPipette.construct( # type: ignore[call-arg]
result=commands.LoadPipetteResult(pipetteId="pipette-id")
)
load_pipette_private_result = commands.LoadPipettePrivateResult(
pipette_id="pipette-id",
serial_number="pipette-serial",
config=LoadedStaticPipetteData(
channels=8,
max_volume=15,
min_volume=3,
model="gen a",
display_name="display name",
flow_rates=FlowRates(
default_aspirate={},
default_dispense={},
default_blow_out={},
),
tip_configuration_lookup_table={15: supported_tip_fixture},
nominal_tip_overlap={},
nozzle_offset_z=1.23,
home_position=4.56,
nozzle_map=get_default_nozzle_map(PipetteNameType.P300_MULTI_GEN2),
),
)
subject.handle_action(
actions.UpdateCommandAction(
private_result=load_pipette_private_result, command=load_pipette_command
)
)

result = TipView(subject.state).get_next_tip(
pipette_id="pipette-id",
Expand Down Expand Up @@ -572,7 +689,7 @@ def test_reset_tips(
pipette_id="pipette-id",
serial_number="pipette-serial",
config=LoadedStaticPipetteData(
channels=8,
channels=1,
max_volume=15,
min_volume=3,
model="gen a",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ def test_new_tip_always(_instr_labware, monkeypatch):
assert xfer_plan_list == exp1
for cmd in xfer_plan_list:
getattr(i_ctx, cmd["method"])(*cmd["args"], **cmd["kwargs"])
assert tiprack.next_tip() == tiprack.columns()[0][4]
assert tiprack.next_tip(Mount.LEFT) == tiprack.columns()[0][4]


def test_transfer_w_touchtip_blowout(_instr_labware):
Expand Down
2 changes: 1 addition & 1 deletion shared-data/command/schemas/8.json
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@
"frontRightNozzle": {
"title": "Frontrightnozzle",
"description": "The front right nozzle in your configuration.",
"pattern": "[A-Z][0-100]",
"pattern": "[A-Z]\\d{1,2}",
"type": "string"
}
},
Expand Down

0 comments on commit d91df8e

Please sign in to comment.