Skip to content

Commit

Permalink
test(analyses): 8.0.0 testing protocols into analyses battery (#16407)
Browse files Browse the repository at this point in the history
# Overview

Get these into edge ASAP!

- [x] Josh reviewed the snapshots PR making sure that protocols with
**X** had errors in the snapshot and **S** do not.

Not much else to review. We need these in so that PRs to edge are also
running against these snapshots.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: y3rsh <[email protected]>
  • Loading branch information
3 people authored Oct 4, 2024
1 parent 1b35652 commit 0484295
Show file tree
Hide file tree
Showing 86 changed files with 232,337 additions and 0 deletions.
23 changes: 23 additions & 0 deletions analyses-snapshot-testing/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,26 @@ build-opentrons-analysis:
.PHONY: generate-protocols
generate-protocols:
python -m pipenv run python -m automation.data.protocol_registry


OPENTRONS_VERSION ?= edge
export OPENTRONS_VERSION

.PHONY: build-rs
build-rs:
@echo "Building docker image for opentrons-robot-server:$(OPENTRONS_VERSION)"
@echo "Cache is always busted to ensure latest version of the code is used"
@echo "If you want to build a different version, run 'make build-rs OPENTRONS_VERSION=chore_release-8.0.0'"
docker build --build-arg OPENTRONS_VERSION=$(OPENTRONS_VERSION) --build-arg CACHEBUST=$(CACHEBUST) -t opentrons-robot-server:$(OPENTRONS_VERSION) -f citools/Dockerfile.server .

.PHONY: run-flex
run-flex:
@echo "Running opentrons-robot-server:$(OPENTRONS_VERSION)"
@echo "If you want to run a different version, run 'make run-flex OPENTRONS_VERSION=chore_release-8.0.0'"
docker run -p 31950:31950 --env-file ../robot-server/dev-flex.env opentrons-robot-server:$(OPENTRONS_VERSION)

.PHONY: run-ot2
run-ot2:
@echo "Running opentrons-robot-server:$(OPENTRONS_VERSION)"
@echo "If you want to run a different version, run 'make run-ot2 OPENTRONS_VERSION=chore_release-8.0.0'"
docker run -p 31950:31950 --env-file ../robot-server/dev.env opentrons-robot-server:$(OPENTRONS_VERSION)
20 changes: 20 additions & 0 deletions analyses-snapshot-testing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
- In CI this is the `SNAPSHOT_REF`. This is the branch or tag of the test code/snapshots that analyses generated will be compared to.
- The `ANALYSIS_REF` is the branch or tag that you want analyses generated from.

## Build the opentrons-analysis image

> This ALWAYS gets the remote code pushed to Opentrons/opentrons for the specified ANALYSIS_REF
`make build-opentrons-analysis ANALYSIS_REF=chore_release-8.0.0`

## Running the tests locally

- Compare the current branch snapshots to analyses generated from the edge branch
Expand All @@ -38,3 +44,17 @@
- `make snapshot-test PROTOCOL_NAMES=Flex_S_v2_19_Illumina_DNA_PCR_Free OVERRIDE_PROTOCOL_NAMES=none`
- `make snapshot-test PROTOCOL_NAMES=none OVERRIDE_PROTOCOL_NAMES=Flex_X_v2_18_NO_PIPETTES_Overrides_BadTypesInRTP`
- `make snapshot-test PROTOCOL_NAMES="Flex_S_v2_19_Illumina_DNA_PCR_Free,OT2_S_v2_18_P300M_P20S_HS_TC_TM_SmokeTestV3" OVERRIDE_PROTOCOL_NAMES=none`

## Running a Flex just like `make -C robot-server dev-flex`

> This ALWAYS gets the remote code pushed to Opentrons/opentrons for the specified OPENTRONS_VERSION
```shell
cd analyses-snapshot-testing \
&& make build-rs OPENTRONS_VERSION=chore_release-8.0.0 \
&& make run-rs OPENTRONS_VERSION=chore_release-8.0.0`
```

### Default OPENTRONS_VERSION=edge in the Makefile so you can omit it if you want latest edge

`cd analyses-snapshot-testing && make build-rs && make run-rs`
81 changes: 81 additions & 0 deletions analyses-snapshot-testing/automation/data/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,74 @@ class Protocols:
robot="Flex",
)

# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_8_None_PARTIAL_COLUMN_HappyPath.py
Flex_S_v2_20_8_None_PARTIAL_COLUMN_HappyPath: Protocol = Protocol(
file_stem="Flex_S_v2_20_8_None_PARTIAL_COLUMN_HappyPath",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_8_None_SINGLE_HappyPath.py
Flex_S_v2_20_8_None_SINGLE_HappyPath: Protocol = Protocol(
file_stem="Flex_S_v2_20_8_None_SINGLE_HappyPath",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_96_AllCorners.py
Flex_S_v2_20_96_AllCorners: Protocol = Protocol(
file_stem="Flex_S_v2_20_96_AllCorners",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_96_None_COLUMN_HappyPath.py
Flex_S_v2_20_96_None_COLUMN_HappyPath: Protocol = Protocol(
file_stem="Flex_S_v2_20_96_None_COLUMN_HappyPath",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_96_None_Column3_SINGLE_.py
Flex_S_v2_20_96_None_Column3_SINGLE_: Protocol = Protocol(
file_stem="Flex_S_v2_20_96_None_Column3_SINGLE_",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_96_None_ROW_HappyPath.py
Flex_S_v2_20_96_None_ROW_HappyPath: Protocol = Protocol(
file_stem="Flex_S_v2_20_96_None_ROW_HappyPath",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_96_None_SINGLE_4Corners50ul.py
Flex_S_v2_20_96_None_SINGLE_4Corners50ul: Protocol = Protocol(
file_stem="Flex_S_v2_20_96_None_SINGLE_4Corners50ul",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_96_None_SINGLE_HappyPathNorthSide.py
Flex_S_v2_20_96_None_SINGLE_HappyPathNorthSide: Protocol = Protocol(
file_stem="Flex_S_v2_20_96_None_SINGLE_HappyPathNorthSide",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_96_None_SINGLE_HappyPathSouthSide.py
Flex_S_v2_20_96_None_SINGLE_HappyPathSouthSide: Protocol = Protocol(
file_stem="Flex_S_v2_20_96_None_SINGLE_HappyPathSouthSide",
file_extension="py",
robot="Flex",
)

# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_P8X1000_P50_LLD.py
Flex_S_v2_20_P8X1000_P50_LLD: Protocol = Protocol(
file_stem="Flex_S_v2_20_P8X1000_P50_LLD",
file_extension="py",
robot="Flex",
)
# analyses-snapshot-testing/files/protocols/Flex_S_v2_20_P50_LPD.py
Flex_S_v2_20_P50_LPD: Protocol = Protocol(
file_stem="Flex_S_v2_20_P50_LPD",
file_extension="py",
robot="Flex",
)

OT2_X_v2_18_None_None_duplicateRTPVariableName: Protocol = Protocol(
file_stem="OT2_X_v2_18_None_None_duplicateRTPVariableName",
file_extension="py",
Expand Down Expand Up @@ -677,6 +745,19 @@ class Protocols:
robot="OT2",
)

# analyses-snapshot-testing/files/protocols/OT2_S_v2_20_8_None_PARTIAL_COLUMN_HappyPathMixedTipRacks.py
OT2_S_v2_20_8_None_PARTIAL_COLUMN_HappyPathMixedTipRacks: Protocol = Protocol(
file_stem="OT2_S_v2_20_8_None_PARTIAL_COLUMN_HappyPathMixedTipRacks",
file_extension="py",
robot="OT2",
)
# analyses-snapshot-testing/files/protocols/OT2_S_v2_20_8_None_SINGLE_HappyPath.py
OT2_S_v2_20_8_None_SINGLE_HappyPath: Protocol = Protocol(
file_stem="OT2_S_v2_20_8_None_SINGLE_HappyPath",
file_extension="py",
robot="OT2",
)

##########################################################################################################
# Begin Protocol Library Protocols #######################################################################
##########################################################################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,72 @@ class ProtocolsWithOverrides:
override_variable_name="type_to_test",
overrides=["str_default_no_matching_choices", "float_default_no_matching_choices", "int_default_no_matching_choices"],
)

# analyses-snapshot-testing/files/protocols/Flex_X_v2_20_96_and_8_Overrides_InvalidConfigs.py

Flex_X_v2_20_96_and_8_Overrides_InvalidConfigs: ProtocolWithOverrides = ProtocolWithOverrides(
file_stem="Flex_X_v2_20_96_and_8_Overrides_InvalidConfigs",
file_extension="py",
robot="Flex",
override_variable_name="key",
overrides=[
"ninety_six_partial_column_1",
"ninety_six_partial_column_2",
"ninety_six_partial_column_3",
"eight_partial_column_bottom_left",
"eight_partial_column_bottom_right",
"eight_partial_column_no_end",
"return_tip_error",
"drop_tip_with_location",
],
)

# analyses-snapshot-testing/files/protocols/Flex_X_v2_20_96_None_Overrides_TooTallLabware.py

Flex_X_v2_20_96_None_Overrides_TooTallLabware: ProtocolWithOverrides = ProtocolWithOverrides(
file_stem="Flex_X_v2_20_96_None_Overrides_TooTallLabware",
file_extension="py",
robot="Flex",
override_variable_name="key",
overrides=[
"transfer_source_collision",
"transfer_destination_collision",
"c3_right_edge",
"north",
"north_west",
"west",
"south_west",
"south",
"south_east",
"east",
"east_column",
"west_column",
"north_row",
"south_row",
"top_edge",
"bottom_left_edge",
"bottom_left_edge",
"bottom_right_edge",
"mix_collision",
"consolidate_source_collision",
"consolidate_destination_collision",
"distribute_source_collision",
"distribute_destination_collision",
],
)

# analyses-snapshot-testing/files/protocols/OT2_X_v2_20_8_Overrides_InvalidConfigs.py

OT2_X_v2_20_8_Overrides_InvalidConfigs: ProtocolWithOverrides = ProtocolWithOverrides(
file_stem="OT2_X_v2_20_8_Overrides_InvalidConfigs",
file_extension="py",
robot="Flex",
override_variable_name="key",
overrides=[
"eight_partial_column_bottom_left",
"eight_partial_column_bottom_right",
"eight_partial_column_no_end",
"return_tip_error",
"drop_tip_with_location",
],
)
31 changes: 31 additions & 0 deletions analyses-snapshot-testing/citools/Dockerfile.server
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Use Python 3.10 as the base image
FROM python:3.10-slim-bullseye

# Update packages and install dependencies
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y git libsystemd-dev build-essential pkg-config network-manager

# Define build arguments
ARG OPENTRONS_VERSION=edge

# Set the working directory
WORKDIR /opentrons

# Clone the Opentrons repository
ARG CACHEBUST=1
RUN git clone --branch $OPENTRONS_VERSION --depth 1 https://github.com/Opentrons/opentrons .

# Install dependencies
RUN make setup-py -j

WORKDIR /opentrons/robot-server

# Set the port via environment variable
ENV PORT=31950

# Expose the port
EXPOSE ${PORT}

# Default command
CMD ["sh", "-c", "python -m pipenv run uvicorn robot_server.app:app --host 0.0.0.0 --port ${PORT} --ws wsproto --lifespan on"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from opentrons.protocol_api import PARTIAL_COLUMN

metadata = {
"protocolName": "flex_8channel_1000 Simple",
"description": "A protocol that demonstrates safe actions with flex_8channel_1000",
"author": "Josh McVey",
}

requirements = {
"robotType": "Flex",
"apiLevel": "2.20",
}


def comment_tip_rack_status(ctx, tip_rack):
"""
Print out the tip status for each row in a tip rack.
Each row (A-H) will print the well statuses for columns 1-12 in a single comment,
with a '🟢' for present tips and a '❌' for missing tips.
"""
range_A_to_H = [chr(i) for i in range(ord("A"), ord("H") + 1)]
range_1_to_12 = range(1, 13)

ctx.comment(f"Tip rack in {tip_rack.parent}")

for row in range_A_to_H:
status_line = f"{row}: "
for col in range_1_to_12:
well = f"{row}{col}"
has_tip = tip_rack.wells_by_name()[well].has_tip
status_emoji = "🟢" if has_tip else "❌"
status_line += f"{well} {status_emoji} "

# Print the full status line for the row
ctx.comment(status_line)


def run(protocol):

trash = protocol.load_trash_bin("A3") # must load trash bin
tip_rack = protocol.load_labware(
load_name="opentrons_flex_96_tiprack_1000ul",
label="Tip Rack",
location="A1",
)

pipette = protocol.load_instrument(instrument_name="flex_8channel_1000", mount="left", tip_racks=[tip_rack])

source_labware_C2 = protocol.load_labware(
load_name="nest_1_reservoir_290ml",
label="Source Reservoir",
location="C2",
)

destination_labware_D2 = protocol.load_labware(
load_name="nest_96_wellplate_100ul_pcr_full_skirt",
label="PCR Plate",
location="2",
)

volume = 100
pipette.pick_up_tip()
comment_tip_rack_status(protocol, tip_rack)
pipette.aspirate(volume=volume, location=destination_labware_D2["H1"])
pipette.dispense(volume=volume, location=destination_labware_D2["H2"])
for i in range(1, 13):
protocol.comment(f"Touching tip to {destination_labware_D2[f'H{i}']}")
pipette.touch_tip(location=destination_labware_D2[f"H{i}"])

pipette.blow_out(location=destination_labware_D2["H1"])
pipette.mix(repetitions=3, volume=volume, location=destination_labware_D2["H1"])
pipette.drop_tip()

range_A_to_H = [chr(i) for i in range(ord("A"), ord("H") + 1)]
column1 = [destination_labware_D2[f"{row}1"] for row in range_A_to_H]
column2 = [destination_labware_D2[f"{row}2"] for row in range_A_to_H]
column3 = [destination_labware_D2[f"{row}3"] for row in range_A_to_H]
column4 = [destination_labware_D2[f"{row}4"] for row in range_A_to_H]
column5 = [destination_labware_D2[f"{row}5"] for row in range_A_to_H]
column6 = [destination_labware_D2[f"{row}6"] for row in range_A_to_H]
column7 = [destination_labware_D2[f"{row}7"] for row in range_A_to_H]

protocol.comment(f"Transferring {volume}uL from column 1 to column 2")
pipette.transfer(volume=volume, source=column1, dest=column2)
comment_tip_rack_status(protocol, tip_rack)

volume = 50
protocol.comment(f"Distribute {volume}uL from column 2 to column 3 and 4")
pipette.distribute(volume=volume, source=column2, dest=column3 + column4)
comment_tip_rack_status(protocol, tip_rack)
protocol.comment(f"Consolidate {volume}uL from column 5 and 6 to column 7")
pipette.consolidate(volume=volume, source=column5 + column6, dest=column7)
comment_tip_rack_status(protocol, tip_rack)
Loading

0 comments on commit 0484295

Please sign in to comment.