Skip to content

Commit

Permalink
unseal test cleanup removal of unused pushout command and command sch…
Browse files Browse the repository at this point in the history
…ema update
  • Loading branch information
CaseyBatten committed Jan 30, 2025
1 parent 2288583 commit 9d17f2d
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 138 deletions.
11 changes: 4 additions & 7 deletions api/src/opentrons/protocol_api/core/engine/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from opentrons.protocol_api._liquid import LiquidClass

_DISPENSE_VOLUME_VALIDATION_ADDED_IN = APIVersion(2, 17)
_RESIN_TIP_DEFAULT_VOLUME = 400
_RESIN_TIP_DEFAULT_FLOW_RATE = 10.0


Expand Down Expand Up @@ -745,24 +746,20 @@ def resin_tip_dispense(
well_core: WellCore,
volume: Optional[float] = None,
flow_rate: Optional[float] = None,
push_out: Optional[float] = None,
) -> None:
"""
Args:
volume: The volume of liquid to dispense, in microliters.
volume: The volume of liquid to dispense, in microliters. Defaults to 400uL.
location: The exact location to dispense to.
well_core: The well to dispense to, if applicable.
flow_rate: The flow rate in µL/s to dispense at. Defaults to 10.0.
push_out: The amount to push the plunger below bottom position.
flow_rate: The flow rate in µL/s to dispense at. Defaults to 10.0uL/S.
"""
if isinstance(location, (TrashBin, WasteChute)):
raise ValueError("Trash Bin and Waste Chute have no Wells.")
well_name = well_core.get_name()
labware_id = well_core.labware_id
if volume is None:
volume = self._engine_client.state.pipettes.get_maximum_volume(
self._pipette_id
)
volume = _RESIN_TIP_DEFAULT_VOLUME
if flow_rate is None:
flow_rate = _RESIN_TIP_DEFAULT_FLOW_RATE

Expand Down
1 change: 0 additions & 1 deletion api/src/opentrons/protocol_api/core/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@ def resin_tip_dispense(
well_core: WellCoreType,
volume: Optional[float] = None,
flow_rate: Optional[float] = None,
push_out: Optional[float] = None,
) -> None:
...

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ def resin_tip_dispense(
well_core: WellCore,
volume: Optional[float] = None,
flow_rate: Optional[float] = None,
push_out: Optional[float] = None,
) -> None:
raise APIVersionError(api_element="Dispensing liquid from resin tips.")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ def resin_tip_dispense(
well_core: WellCore,
volume: Optional[float] = None,
flow_rate: Optional[float] = None,
push_out: Optional[float] = None,
) -> None:
raise APIVersionError(api_element="Dispensing liquid from resin tips.")

Expand Down
8 changes: 0 additions & 8 deletions api/src/opentrons/protocol_api/instrument_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -1792,7 +1792,6 @@ def resin_tip_dispense(
location: types.Location,
volume: Optional[float] = None,
rate: Optional[float] = None,
push_out: Optional[float] = None,
) -> InstrumentContext:
"""Dispense a volume from resin tips into a labware.
Expand All @@ -1814,12 +1813,6 @@ def resin_tip_dispense(
``rate`` multiplied by :py:attr:`flow_rate.dispense<flow_rate>`.
:type rate: float
:param push_out: Continue past the plunger bottom to help ensure all liquid
leaves the tip. Measured in µL. The default value is ``None``.
See :ref:`push-out-dispense` for details.
:type push_out: float
"""
well: Optional[labware.Well] = None
last_location = self._get_last_location_by_api_version()
Expand Down Expand Up @@ -1863,7 +1856,6 @@ def resin_tip_dispense(
well_core=well._core,
volume=volume,
flow_rate=rate,
push_out=push_out,
)
return self

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
from opentrons.protocol_engine.state import update_types
from opentrons.protocol_engine.state.state import StateView
from opentrons.protocol_engine.execution import MovementHandler, GantryMover, TipHandler

from opentrons.protocols.models import LabwareDefinition
import json
from opentrons_shared_data import load_shared_data

from opentrons.types import Point

Expand Down Expand Up @@ -82,13 +84,27 @@ def test_drop_tip_params_default_origin() -> None:
)


@pytest.fixture
def evotips_definition() -> LabwareDefinition:
"""A fixturee of the evotips definition."""
# TODO (chb 2025-01-29): When we migrate all labware to v3 we can clean this up
return LabwareDefinition.model_validate(
json.loads(
load_shared_data(
"labware/definitions/3/evotips_opentrons_96_labware/1.json"
)
)
)


async def test_drop_tip_implementation(
decoy: Decoy,
mock_state_view: StateView,
mock_movement_handler: MovementHandler,
mock_tip_handler: TipHandler,
mock_model_utils: ModelUtils,
gantry_mover: GantryMover,
evotips_definition: LabwareDefinition,
) -> None:
"""A DropTip command should have an execution implementation."""
subject = EvotipUnsealPipetteImplementation(
Expand All @@ -105,6 +121,9 @@ async def test_drop_tip_implementation(
wellName="A3",
wellLocation=DropTipWellLocation(offset=WellOffset(x=1, y=2, z=3)),
)
decoy.when(mock_state_view.labware.get_definition("123")).then_return(
evotips_definition
)

decoy.when(
mock_state_view.pipettes.get_is_partially_configured(pipette_id="abc")
Expand Down Expand Up @@ -154,90 +173,14 @@ async def test_drop_tip_implementation(
),
),
)

decoy.verify(
await mock_tip_handler.drop_tip(pipette_id="abc", home_after=True),
times=1,
)


async def test_drop_tip_with_alternating_locations(
decoy: Decoy,
mock_state_view: StateView,
mock_movement_handler: MovementHandler,
mock_tip_handler: TipHandler,
mock_model_utils: ModelUtils,
gantry_mover: GantryMover,
) -> None:
"""It should drop tip at random location within the labware every time."""
subject = EvotipUnsealPipetteImplementation(
state_view=mock_state_view,
movement=mock_movement_handler,
tip_handler=mock_tip_handler,
model_utils=mock_model_utils,
gantry_mover=gantry_mover,
)
params = EvotipUnsealPipetteParams(
pipetteId="abc",
labwareId="123",
wellName="A3",
wellLocation=DropTipWellLocation(offset=WellOffset(x=1, y=2, z=3)),
)
drop_location = DropTipWellLocation(
origin=DropTipWellOrigin.DEFAULT, offset=WellOffset(x=10, y=20, z=30)
)
decoy.when(
mock_state_view.geometry.get_next_tip_drop_location(
labware_id="123", well_name="A3", pipette_id="abc"
)
).then_return(drop_location)

decoy.when(
mock_state_view.pipettes.get_is_partially_configured(pipette_id="abc")
).then_return(False)

decoy.when(
mock_state_view.geometry.get_checked_tip_drop_location(
await mock_tip_handler.drop_tip(
pipette_id="abc",
labware_id="123",
well_location=drop_location,
partially_configured=False,
)
).then_return(WellLocation(offset=WellOffset(x=4, y=5, z=6)))

decoy.when(
await mock_movement_handler.move_to_well(
pipette_id="abc",
labware_id="123",
well_name="A3",
well_location=WellLocation(offset=WellOffset(x=4, y=5, z=6)),
current_well=None,
force_direct=False,
minimum_z_height=None,
speed=None,
operation_volume=None,
)
).then_return(Point(x=111, y=222, z=333))

result = await subject.execute(params)
assert result == SuccessData(
public=EvotipUnsealPipetteResult(position=DeckPoint(x=111, y=222, z=333)),
state_update=update_types.StateUpdate(
pipette_location=update_types.PipetteLocationUpdate(
pipette_id="abc",
new_location=update_types.Well(
labware_id="123",
well_name="A3",
),
new_deck_point=DeckPoint(x=111, y=222, z=333),
),
pipette_tip_state=update_types.PipetteTipStateUpdate(
pipette_id="abc", tip_geometry=None
),
pipette_aspirated_fluid=update_types.PipetteUnknownFluidUpdate(
pipette_id="abc"
),
home_after=None,
do_not_ignore_tip_presence=False,
ignore_plunger=True,
),
times=1,
)


Expand All @@ -248,6 +191,7 @@ async def test_tip_attached_error(
mock_tip_handler: TipHandler,
mock_model_utils: ModelUtils,
gantry_mover: GantryMover,
evotips_definition: LabwareDefinition,
) -> None:
"""A Evotip Unseal command should have an execution implementation."""
subject = EvotipUnsealPipetteImplementation(
Expand All @@ -264,6 +208,9 @@ async def test_tip_attached_error(
wellName="A3",
wellLocation=DropTipWellLocation(offset=WellOffset(x=1, y=2, z=3)),
)
decoy.when(mock_state_view.labware.get_definition("123")).then_return(
evotips_definition
)

decoy.when(
mock_state_view.pipettes.get_is_partially_configured(pipette_id="abc")
Expand Down Expand Up @@ -292,51 +239,21 @@ async def test_tip_attached_error(
)
).then_return(Point(x=111, y=222, z=333))
decoy.when(
await mock_tip_handler.drop_tip(pipette_id="abc", home_after=None)
await mock_tip_handler.drop_tip(
pipette_id="abc",
home_after=None,
do_not_ignore_tip_presence=False,
ignore_plunger=True,
)
).then_raise(TipAttachedError("Egads!"))

decoy.when(mock_model_utils.generate_id()).then_return("error-id")
decoy.when(mock_model_utils.get_timestamp()).then_return(
datetime(year=1, month=2, day=3)
)

result = await subject.execute(params)

assert result == DefinedErrorData(
public=StallOrCollisionError.model_construct(
id="error-id",
createdAt=datetime(year=1, month=2, day=3),
wrappedErrors=[matchers.Anything()],
errorInfo={"retryLocation": (111, 222, 333)},
),
state_update=update_types.StateUpdate(
pipette_location=update_types.PipetteLocationUpdate(
pipette_id="abc",
new_location=update_types.Well(
labware_id="123",
well_name="A3",
),
new_deck_point=DeckPoint(x=111, y=222, z=333),
),
pipette_aspirated_fluid=update_types.PipetteUnknownFluidUpdate(
pipette_id="abc"
),
),
state_update_if_false_positive=update_types.StateUpdate(
pipette_tip_state=update_types.PipetteTipStateUpdate(
pipette_id="abc",
tip_geometry=None,
),
pipette_location=update_types.PipetteLocationUpdate(
pipette_id="abc",
new_location=update_types.Well(
labware_id="123",
well_name="A3",
),
new_deck_point=DeckPoint(x=111, y=222, z=333),
),
),
)
with pytest.raises(TipAttachedError):
await subject.execute(params)


async def test_stall_error(
Expand All @@ -346,6 +263,7 @@ async def test_stall_error(
mock_tip_handler: TipHandler,
mock_model_utils: ModelUtils,
gantry_mover: GantryMover,
evotips_definition: LabwareDefinition,
) -> None:
"""A DropTip command should have an execution implementation."""
subject = EvotipUnsealPipetteImplementation(
Expand All @@ -362,6 +280,9 @@ async def test_stall_error(
wellName="A3",
wellLocation=DropTipWellLocation(offset=WellOffset(x=1, y=2, z=3)),
)
decoy.when(mock_state_view.labware.get_definition("123")).then_return(
evotips_definition
)

decoy.when(
mock_state_view.pipettes.get_is_partially_configured(pipette_id="abc")
Expand Down
Loading

0 comments on commit 9d17f2d

Please sign in to comment.