Skip to content

Commit ecc6433

Browse files
multiple test file fixes. <400 left
1 parent f4ab776 commit ecc6433

File tree

9 files changed

+81
-48
lines changed

9 files changed

+81
-48
lines changed

api/src/opentrons/hardware_control/backends/controller.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,21 @@ class Controller:
5757
"""
5858

5959
@classmethod
60-
async def build(cls, config: RobotConfig) -> Controller:
60+
async def build(cls, config: Optional[RobotConfig]) -> Controller:
6161
"""Build a Controller instance.
6262
6363
Use this factory method rather than the initializer to handle proper
6464
GPIO initialization.
6565
6666
:param config: A loaded robot config.
6767
"""
68+
6869
gpio = build_gpio_chardev("gpiochip0")
6970
gpio.config_by_board_rev()
7071
await gpio.setup()
7172
return cls(config, gpio)
7273

73-
def __init__(self, config: RobotConfig, gpio: GPIODriverLike):
74+
def __init__(self, config: Optional[RobotConfig], gpio: GPIODriverLike):
7475
"""Build a Controller instance.
7576
7677
Always prefer using :py:meth:`.build` to create an instance of this class. For

api/src/opentrons/protocols/advanced_control/mix.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import typing
1+
from typing import Any, Dict, Tuple
22

33
from opentrons.protocols.advanced_control.transfers import MixStrategy, Mix
44

55

6-
def mix_from_kwargs(
7-
top_kwargs: typing.Dict[str, typing.Any]
8-
) -> typing.Tuple[MixStrategy, Mix]:
6+
def mix_from_kwargs(top_kwargs: Dict[str, Any]) -> Tuple[MixStrategy, Mix]:
97
"""A utility function to determine mix strategy from key word arguments
108
to InstrumentContext.mix"""
119

12-
def _mix_requested(kwargs, opt):
10+
def _mix_requested(kwargs: Dict[str, Any], opt: str) -> bool:
1311
"""
1412
Helper for determining mix options from :py:meth:`transfer` kwargs
1513
Mixes can be ignored in kwargs by either

api/tests/opentrons/hardware_control/integration/test_controller.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
from typing import Iterator
2-
1+
from typing import AsyncGenerator, Iterator
32
import pytest
3+
4+
from opentrons.config.types import RobotConfig
45
from opentrons import _find_smoothie_file
56
from opentrons.config.robot_configs import build_config
67
from opentrons.hardware_control import Controller
@@ -12,31 +13,36 @@
1213
async def subject(
1314
emulation_app: Iterator[None],
1415
emulator_settings: Settings,
15-
) -> Controller:
16+
) -> AsyncGenerator[Controller, None]:
1617
conf = build_config({})
1718
port = f"socket://127.0.0.1:{emulator_settings.smoothie.port}"
19+
assert isinstance(conf, RobotConfig)
1820
hc = await Controller.build(config=conf)
1921
await hc.connect(port=port)
2022
yield hc
2123
await hc._smoothie_driver.disconnect()
2224

2325

24-
async def test_get_fw_version(subject: Controller):
26+
async def test_get_fw_version(subject: Controller) -> None:
2527
"""It should be set."""
2628
_, fw_version = _find_smoothie_file()
2729
assert subject._cached_fw_version == fw_version
2830

2931

30-
async def test_get_attached_instruments(subject: Controller):
32+
async def test_get_attached_instruments(subject: Controller) -> None:
3133
"""It should get the attached instruments."""
3234
instruments = await subject.get_attached_instruments({})
3335
assert instruments[Mount.RIGHT]["id"] == "P20SV202020070101"
34-
assert instruments[Mount.RIGHT]["config"].display_name == "P20 Single-Channel GEN2"
36+
right_config = instruments[Mount.RIGHT]["config"]
37+
assert right_config is not None
38+
assert right_config.display_name == "P20 Single-Channel GEN2"
3539
assert instruments[Mount.LEFT]["id"] == "P3HMV202020041605"
36-
assert instruments[Mount.LEFT]["config"].display_name == "P20 8-Channel GEN2"
40+
left_config = instruments[Mount.LEFT]["config"]
41+
assert left_config is not None
42+
assert left_config.display_name == "P20 8-Channel GEN2"
3743

3844

39-
async def test_move(subject: Controller):
45+
async def test_move(subject: Controller) -> None:
4046
"""It should move."""
4147
new_position = {"X": 1.0, "Z": 2.0, "Y": 3.0, "A": 4.0, "B": 5.0, "C": 6.0}
4248

api/tests/opentrons/hardware_control/test_gpio.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
from unittest.mock import MagicMock
22
import pytest
3+
import pdb
34

45
from opentrons import hardware_control as hc
6+
from opentrons.drivers import rpi_drivers
57
from opentrons.drivers.rpi_drivers.gpio_simulator import SimulatingGPIOCharDev
8+
from opentrons.hardware_control.types import BoardRevision
69

710

8-
async def test_gpio_setup(monkeypatch):
11+
async def test_gpio_setup() -> None:
912
# Test without DTOVERLAY path
1013
# Board revision should be defaulted to 2.1
14+
pdb.set_trace()
1115
backend = await hc.Controller.build(config=None)
1216
assert str(backend.board_revision) == "2.1"
1317

@@ -21,17 +25,17 @@ async def test_gpio_setup(monkeypatch):
2125
(hc.types.BoardRevision.C, 0.5),
2226
],
2327
)
24-
async def test_current_setting(monkeypatch, revision, a_current):
28+
async def test_current_setting(
29+
monkeypatch: pytest.MonkeyPatch, revision: BoardRevision, a_current: float
30+
) -> None:
2531
mock_gpio = MagicMock(spec=SimulatingGPIOCharDev)
2632

27-
async def fake_side_effect():
33+
async def fake_side_effect() -> None:
2834
pass
2935

3036
mock_gpio.setup.side_effect = fake_side_effect
3137
mock_gpio.board_rev = revision
32-
mock_build = MagicMock(
33-
spec=hc.backends.controller.build_gpio_chardev, return_value=mock_gpio
34-
)
38+
mock_build = MagicMock(spec=rpi_drivers, return_value=mock_gpio)
3539
monkeypatch.setattr(hc.backends.controller, "build_gpio_chardev", mock_build)
3640
backend = await hc.Controller.build(config=None)
3741
assert backend.board_revision == revision

api/tests/opentrons/hardware_control/test_gripper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,14 @@ def test_reload_instrument_cal_ot3_conf_changed(
121121

122122
@pytest.mark.ot3_only
123123
def test_jaw_calibration_error_checking() -> None:
124-
subject = gripper.Gripper(fake_gripper_conf, fake_offset, "fakeid123")
124+
subject = gripper.Gripper(fake_gripper_conf, fake_offset, "fakeid123") # type: ignore[arg-type]
125125
with pytest.raises(MotionFailedError):
126126
subject.update_jaw_open_position_from_closed_position(0)
127127

128128

129129
@pytest.mark.ot3_only
130130
def test_jaw_calibration() -> None:
131-
subject = gripper.Gripper(fake_gripper_conf, fake_offset, "fakeid123")
131+
subject = gripper.Gripper(fake_gripper_conf, fake_offset, "fakeid123") # type: ignore[arg-type]
132132
subject.update_jaw_open_position_from_closed_position(
133133
(
134134
fake_gripper_conf.geometry.jaw_width["max"]

api/tests/opentrons/hardware_control/test_pipette_handler.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"""Tests for the HardwareApi class."""
2+
from _pytest.fixtures import FixtureRequest
23
import pytest
3-
44
from decoy import Decoy
55
from typing import Optional, Tuple, Dict, List
66

77
from opentrons import types
88
from opentrons.hardware_control.types import OT3Mount, Axis
99
from opentrons.hardware_control.instruments.ot2.pipette import Pipette
10+
from opentrons_shared_data.pipette.types import PipetteChannelType
1011
from opentrons.hardware_control.instruments.ot2.pipette_handler import (
1112
PipetteHandlerProvider,
1213
)
@@ -39,7 +40,7 @@ def mock_pipettes_ot3(decoy: Decoy) -> Tuple[OT3Pipette, OT3Pipette]:
3940

4041

4142
@pytest.fixture
42-
def subject(decoy: Decoy, mock_pipette: Pipette) -> PipetteHandlerProvider:
43+
def subject(decoy: Decoy, mock_pipette: Pipette) -> PipetteHandlerProvider[types.Mount]:
4344
inst_by_mount = {types.Mount.LEFT: mock_pipette, types.Mount.RIGHT: None}
4445
subject = PipetteHandlerProvider(attached_instruments=inst_by_mount)
4546
return subject
@@ -99,7 +100,7 @@ def mock_pickup_list() -> List[TipActionMoveSpec]:
99100
)
100101
def test_plan_check_pick_up_tip_with_presses_argument(
101102
decoy: Decoy,
102-
subject: PipetteHandlerProvider,
103+
subject: PipetteHandlerProvider[types.Mount],
103104
mock_pipette: Pipette,
104105
presses_input: int,
105106
expected_array_length: int,
@@ -153,13 +154,13 @@ def test_plan_check_pick_up_tip_with_presses_argument(
153154
)
154155
def test_plan_check_pick_up_tip_with_presses_argument_ot3(
155156
decoy: Decoy,
156-
subject_ot3: PipetteHandlerProvider,
157+
subject_ot3: PipetteHandlerProvider[types.Mount],
157158
mock_pipette_ot3: OT3Pipette,
158159
presses_input: int,
159160
expected_array_length: int,
160161
channels: int,
161162
expected_pick_up_motor_actions: Optional[List[TipActionMoveSpec]],
162-
request,
163+
request: FixtureRequest,
163164
) -> None:
164165
"""Should return an array with expected length."""
165166
mount = OT3Mount.LEFT
@@ -201,11 +202,13 @@ def test_plan_check_pick_up_tip_with_presses_argument_ot3(
201202
).then_return(1.0)
202203
decoy.when(mock_pipette_ot3.plunger_motor_current.run).then_return(1)
203204
decoy.when(mock_pipette_ot3.config.quirks).then_return([])
204-
decoy.when(mock_pipette_ot3.channels).then_return(channels)
205+
decoy.when(mock_pipette_ot3.channels).then_return(PipetteChannelType(channels))
205206
decoy.when(mock_pipette_ot3.config.end_tip_action_retract_distance_mm).then_return(
206207
2
207208
)
208209

210+
assert isinstance(subject_ot3, OT3PipetteHandler)
211+
209212
if channels == 96:
210213
spec = subject_ot3.plan_ht_pick_up_tip(96)
211214
else:
@@ -216,7 +219,9 @@ def test_plan_check_pick_up_tip_with_presses_argument_ot3(
216219
)
217220

218221

219-
def test_get_pipette_fails(decoy: Decoy, subject: PipetteHandlerProvider):
222+
def test_get_pipette_fails(
223+
decoy: Decoy, subject: PipetteHandlerProvider[types.Mount]
224+
) -> None:
220225
with pytest.raises(types.PipetteNotAttachedError):
221226
subject.get_pipette(types.Mount.RIGHT)
222227

@@ -233,12 +238,12 @@ def test_ot3_pipette_handler_gives_checks_with_different_pipettes(
233238
left_offset: Optional[types.Point],
234239
right_offset: Optional[types.Point],
235240
ok: bool,
236-
mock_pipettes_ot3: Tuple[OT3Pipette],
241+
mock_pipettes_ot3: Tuple[OT3Pipette, OT3Pipette],
237242
decoy: Decoy,
238243
) -> None:
239244
"""Should give you reasonable results with one or two pipettes attached."""
240245
# with a left and not right pipette, we should be able to pass our checks
241-
inst_by_mount: Dict[OT3Mount, OT3Pipette] = {}
246+
inst_by_mount: Dict[OT3Mount, OT3Pipette | None] = {}
242247
if left_offset is not None:
243248
inst_by_mount[OT3Mount.LEFT] = mock_pipettes_ot3[0]
244249
decoy.when(mock_pipettes_ot3[0].pipette_offset.offset).then_return(left_offset)
@@ -248,13 +253,15 @@ def test_ot3_pipette_handler_gives_checks_with_different_pipettes(
248253
subject = OT3PipetteHandler(attached_instruments=inst_by_mount)
249254
if left_offset is not None:
250255
left_result = subject.get_instrument_offset(OT3Mount.LEFT)
256+
assert left_result is not None
251257
assert left_result.offset == left_offset
252258
if ok:
253259
assert left_result.reasonability_check_failures == []
254260
else:
255261
assert len(left_result.reasonability_check_failures) == 1
256262
if right_offset is not None:
257263
right_result = subject.get_instrument_offset(OT3Mount.RIGHT)
264+
assert right_result is not None
258265
assert right_result.offset == right_offset
259266
if ok:
260267
assert right_result.reasonability_check_failures == []

api/tests/opentrons/hardware_control/test_types.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
import enum
2+
from typing import List, cast
23
from opentrons.hardware_control import types
34

45

5-
def test_create_aionotify_event():
6+
def test_create_aionotify_event() -> None:
67
class FakeEnum(enum.Enum):
78
CREATE = enum.auto()
89
DELETE = enum.auto()
910
MODIFY = enum.auto()
1011

11-
enum_list = [FakeEnum.CREATE, FakeEnum.DELETE, FakeEnum.MODIFY]
12+
enum_list: List[enum.Enum] = cast(
13+
List[enum.Enum], [FakeEnum.CREATE, FakeEnum.DELETE, FakeEnum.MODIFY]
14+
)
15+
16+
# enum_list = [FakeEnum.CREATE, FakeEnum.DELETE, FakeEnum.MODIFY]
1217

1318
new_event = types.AionotifyEvent.build("fake event", enum_list)
1419

20+
assert hasattr(new_event.flags, "CREATE")
21+
assert hasattr(new_event.flags, "DELETE")
22+
assert hasattr(new_event.flags, "MODIFY")
1523
assert new_event.flags.CREATE
1624
assert new_event.flags.DELETE
1725
assert new_event.flags.MODIFY

api/tests/opentrons/hardware_control/test_util.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
from typing import List
1+
from typing import List, Mapping, Tuple
22

3-
from opentrons.hardware_control.util import plan_arc, check_motion_bounds
3+
from opentrons.hardware_control.util import AxisType, plan_arc, check_motion_bounds
44
from opentrons.hardware_control.types import (
55
CriticalPoint,
66
MotionChecks,
@@ -13,7 +13,7 @@
1313
import pytest
1414

1515

16-
def check_arc_basic(arc: List[Point], from_pt: Point, to_pt: Point):
16+
def check_arc_basic(arc: List[Point], from_pt: Point, to_pt: Point) -> None:
1717
"""Check the tests that should always be true for different-well moves
1818
- we should always go only up, then only xy, then only down
1919
- we should have three moves
@@ -42,11 +42,11 @@ def check_arc_basic(arc: List[Point], from_pt: Point, to_pt: Point):
4242
[Point(10, 20, 30), Point(10, 30, 40), 40],
4343
],
4444
)
45-
def test_basic_arcs(from_pt, to_pt, z_height):
45+
def test_basic_arcs(from_pt: Point, to_pt: Point, z_height: float) -> None:
4646
check_arc_basic([a[0] for a in plan_arc(from_pt, to_pt, z_height)], from_pt, to_pt)
4747

4848

49-
def test_arc_with_waypoint():
49+
def test_arc_with_waypoint() -> None:
5050
from_pt = Point(20, 20, 40)
5151
to_pt = Point(0, 0, 10)
5252
arc = plan_arc(from_pt, to_pt, 50, extra_waypoints=[(5, 10), (20, 30)])
@@ -59,7 +59,7 @@ def test_arc_with_waypoint():
5959
assert arc[2][0].z == 50
6060

6161

62-
def test_cp_blending():
62+
def test_cp_blending() -> None:
6363
from_pt = Point(10, 10, 10)
6464
to_pt = Point(0, 0, 10)
6565
arc = plan_arc(from_pt, to_pt, 50, None, CriticalPoint.XY_CENTER)
@@ -95,7 +95,14 @@ def test_cp_blending():
9595
({Axis.Z: 5}, {Axis.Z: 3}, {Axis.Z: (2, 4)}, MotionChecks.BOTH, True, "high"),
9696
],
9797
)
98-
def test_check_motion_bounds(xformed, deck, bounds, check, catch, phrase):
98+
def test_check_motion_bounds(
99+
xformed: Mapping[AxisType, float],
100+
deck: Mapping[AxisType, float],
101+
bounds: Mapping[AxisType, Tuple[float, float]],
102+
check: MotionChecks,
103+
catch: bool,
104+
phrase: str,
105+
) -> None:
99106
if catch:
100107
with pytest.raises(OutOfBoundsMove, match=phrase):
101108
check_motion_bounds(xformed, deck, bounds, check)

0 commit comments

Comments
 (0)