Skip to content

Commit 53a8ed9

Browse files
committed
chore: speed up the labware stackup tests somewhat
The labware stackup integration tests rule but were also very slow, because they were running serially and there are 8,000 of them. By making them run in parallel using concurrent.futures.ProcessPoolExecutor, we can make it take like a minute instead of 2 hours.
1 parent ac3d224 commit 53a8ed9

File tree

4 files changed

+99
-627
lines changed

4 files changed

+99
-627
lines changed

api/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ build
44
htmlcov
55

66
src/opentrons/_version.py
7+
tests/**/*.temp
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""Import to a subprocess to run the stackup test."""
2+
3+
from typing import Any, cast
4+
5+
from opentrons import protocol_api, simulate
6+
from .stackup_spec import StackupSpec
7+
8+
9+
def run_test_subprocess( # noqa: C901
10+
spec: StackupSpec,
11+
) -> tuple[float, float, float]:
12+
"""Run the stackup test in a subprocess."""
13+
context = simulate.get_protocol_api(
14+
protocol_api.MAX_SUPPORTED_VERSION, robot_type=spec.robot_type
15+
)
16+
17+
top_so_far: Any = None
18+
module_load_name = spec.module_load_name
19+
adapter_load_info = spec.adapter_load_info
20+
labware_load_info = spec.labware_load_info
21+
22+
if module_load_name:
23+
if module_load_name == "thermocyclerModuleV2":
24+
module = context.load_module(module_load_name)
25+
else:
26+
module = context.load_module(module_load_name, "D3")
27+
if module_load_name == "absorbanceReaderV1":
28+
cast(protocol_api.AbsorbanceReaderContext, module).open_lid()
29+
top_so_far = module
30+
31+
if adapter_load_info is not None:
32+
adapter_load_name, adapter_version = adapter_load_info
33+
if top_so_far is None:
34+
adapter = context.load_adapter(
35+
adapter_load_name, "D3", version=adapter_version
36+
)
37+
else:
38+
if module_load_name == "absorbanceReaderV1":
39+
adapter = context.load_labware(
40+
adapter_load_name, "A3", version=adapter_version
41+
)
42+
context.move_labware(adapter, module, use_gripper=True)
43+
else:
44+
adapter = top_so_far.load_adapter(
45+
adapter_load_name, version=adapter_version
46+
)
47+
top_so_far = adapter
48+
49+
labware_load_name, labware_version = labware_load_info
50+
if top_so_far is None:
51+
labware = context.load_labware(labware_load_name, "D3", version=labware_version)
52+
else:
53+
if module_load_name == "absorbanceReaderV1":
54+
labware = context.load_labware(
55+
labware_load_name, "A3", version=labware_version
56+
)
57+
if adapter_load_info is not None:
58+
context.move_labware(labware, adapter, use_gripper=True)
59+
else:
60+
context.move_labware(labware, module, use_gripper=True)
61+
else:
62+
labware = top_so_far.load_labware(
63+
labware_load_name, version=labware_version
64+
)
65+
top_so_far = labware
66+
67+
x, y, z = top_so_far.wells_by_name()["A1"].top().point
68+
return (x, y, z)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Stackup spec."""
2+
3+
from dataclasses import dataclass
4+
from typing import Any, Literal
5+
6+
7+
@dataclass(frozen=True)
8+
class StackupSpec:
9+
"""The test parameters of interest."""
10+
11+
robot_type: Literal["OT-2"] | Literal["Flex"]
12+
module_load_name: str | None
13+
adapter_load_info: tuple[str, int] | None
14+
labware_load_info: tuple[str, int]
15+
16+
def to_dict(self) -> dict[str, Any]:
17+
"""Convert to dictionary for JSON serialization."""
18+
return {
19+
"robot_type": self.robot_type,
20+
"module_load_name": self.module_load_name,
21+
"adapter_load_info": self.adapter_load_info,
22+
"labware_load_info": self.labware_load_info,
23+
}
24+
25+
def stackup_key(self) -> str:
26+
"""Generate a unique key for this stackup configuration."""
27+
module_name = self.module_load_name or "None"
28+
adapter_name = self.adapter_load_info[0] if self.adapter_load_info else "None"
29+
labware_name = self.labware_load_info[0]
30+
return f"{self.robot_type},{module_name},{adapter_name},{labware_name}"

0 commit comments

Comments
 (0)