Framework supporting the following:
- Running protocols against emulation
- Capturing called G-Codes of emulated protocols
- Parsing captured G-Codes into human-readable text or JSON format
- Diffing human-readable text or JSON format
- CLI access to all the above features
The following section is to explain why each test case inside the g-code-testing
project has either been included or
omitted. Also, it will also explain at a high-level, the different categories of tests.
Description: These tests have a Python Protocol file as an input. The framework will run the protocol and collect all G-Code output.
Tests
- protocol_2_modules - Test using 2 modules in the same protocol
- protocol_2_single_channel - Test using 2 single channel pipettes in the same protocol
- protocol_smoothie - Test an extremely simple protocol with no modules
- protocol_swift_smoke - Test the "smoke" version of the Swift Turbo protocol
- protocol_swift_turbo - Test the actual Swift Turbo protocol
Description: The tests execute the underlying function from calling an HTTP endpoint and collect all the G-Code output. Some HTTP endpoints have been skipped.
These tests cover the movement of the gantry and pipettes
- Implemented Tests
- http_move_left_pipette - Test moving the left pipette with the
robot/move
HTTP endpoint - http_move_right_pipette - Test moving the right pipette with the
robot/move
HTTP endpoint - http_move_left_mount - Test moving the left mount with the
robot/move
HTTP endpoint - http_move_right_mount - Test moving the right mount with the
robot/move
HTTP endpoint - http_home_robot - Test homing the gantry with the
robot/home
HTTP endpoint - http_home_left_pipette - Test homing the left pipette with the
robot/home
HTTP endpoint - http_home_right_pipette - Test homing the right pipette with the
robot/home
HTTP endpoint
- http_move_left_pipette - Test moving the left pipette with the
- Skipped Tests
identify
endpoint - Only goes to the Raspberry Pi, does not generate any G-Coderobot/positions
endpoint - Tests by issuing move commands which is already coveredrobot/lights
endpoint - Only goes to the Raspberry Pi, does not generate any G-Code
Module Tests: <-- Insert link here
These tests cover the functionality of all modules
- Magdeck
- Implemented Tests
- http_magdeck_calibrate - Test the
calibrate
command with the/modules/{serial}
HTTP endpoint. This command performs the automatic calibration of the magdeck. - http_magdeck_engage - Test
engage
command with the/modules/{serial}
HTTP endpoint. This command lifts the magnets. - http_magdeck_deactivate - Test
deactivate
command with the/modules/{serial}
HTTP endpoint. This command returns the magnets to home.
- http_magdeck_calibrate - Test the
- Skipped Tests
- Getters for all the properties on the magdeck because they do not generate any G-Code
bootloader
method - Because it is way too complicated to try to run this/modules/{serial}/update
endpoint - Have to inject abundled_fw
arg into the function and the return isn't worth it
- Implemented Tests
- Tempdeck
- Implemented Tests
- http_tempdeck_start_set_temp - Test
start_set_temperature
command with the/modules/{serial}
HTTP endpoint. This command sets the temperature and exits. It does not wait for the temp deck to come to temperature. - http_tempdeck_set_temp - Test
set_temperature
command with the/modules/{serial}
HTTP endpoint. This command sets the temperature and waits for the tempdeck to come up to temperature. - http_tempdeck_deactivate - Test
deactivate
command with the/modules/{serial}
HTTP endpoint. This command returns stops any heating or cooling and turns off the fan
- http_tempdeck_start_set_temp - Test
- Skipped Tests
- Getters for all the properties on the tempdeck because they do not generate any G-Code
bootloader
method - Because it is way too complicated to try to run this/modules/{serial}/update
endpoint - Have to inject abundled_fw
arg into the function and the return isn't worth itwait_next_poll
method - It is covered byhttp_tempdeck_set_temp
await_temperature
method - It does not return any unique G-Code
- Implemented Tests
- Thermocycler
- Implemented Tests
http_thermocycler_deactivate_lid
- Testdeactivate_lid
command with the/modules/{serial}
HTTP endpoint. This command turns off the heating pad on the thermocycler lid.http_thermocycler_deactivate_block
- Testdeactivate_block
command with the/modules/{serial}
HTTP endpoint. This command turns off the heating pad on the thermocycler block.http_thermocycler_deactivate
- Testdeactivate
command with the/modules/{serial}
HTTP endpoint. This command turns off the heating pad on the thermocycler block and lid.http_thermocycler_open
- Testopen
command with the/modules/{serial}
HTTP endpoint. This command opens the thermocycler lid.http_thermocycler_close
- Testclose
command with the/modules/{serial}
HTTP endpoint. This command closes the thermocycler lid.http_thermocycler_set_temp
- Testset_temperature
command with the/modules/{serial}
HTTP endpoint. This command sets the temperature of the thermocycler.http_thermocycler_cycle_temps
- Testcycle_temperatures
command with the/modules/{serial}
HTTP endpoint. This command cycles through multiple temperatures on the thermocycler.http_thermocycler_set_lid_temp
- Testset_lid_temperature
command with the/modules/{serial}
HTTP endpoint. This command sets the lid temperature of the thermocycler.
- Skipped Tests
- Getters for all the properties on the thermocycler because they do not generate any G-Code
bootloader
method - Because it is way too complicated to try to run thishold_time_probably_set
method - Because it doesn't generate any G-Code
- Implemented Tests
- Navigate into
g-code-testing
directory - Run
make setup
Using the GCodeEngine
you can run a Python protocol file against emulation.
The GCodeEngine
instance will return a GCodeProgram
instance
Example:
"""
Using default settings, run protocol at /my/absolute/path/to/my/protocol.py
against emulation.
In "Concise" format store parsed G-Code to /where/I/want/to/store/my/output.txt
"""
import os.path
from g_code_parsing.g_code_engine import HTTPGCodeEngine
from g_code_parsing.g_code_program.supported_text_modes import SupportedTextModes
from opentrons.hardware_control.emulation.settings import Settings
PROTOCOL_PATH = os.path.join('my', 'absolute', 'path', 'to', 'my', 'protocol.py')
OUTPUT_PATH = os.path.join('where', 'I', 'want', 'to', 'store', 'my', 'output.txt')
settings = Settings() # Using default settings defined in class
with HTTPGCodeEngine(settings).run_protocol(PROTOCOL_PATH) as program:
program.save_text_explanation_to_file(OUTPUT_PATH, SupportedTextModes.CONCISE)
Using the GCodeDiffer
you can compare 2 files and return the differences between
them in HTML format.
Example:
"""
Compare 2 files and save the diff to a file
"""
import os.path
from g_code_parsing.g_code_differ import GCodeDiffer
FILE_1_PATH = os.path.join('tmp', 'file_1.txt')
FILE_2_PATH = os.path.join('tmp', 'file_2.txt')
HTML_PATH = os.path.join('home', 'derek_maggio', 'Desktop', 'my_diff.html')
with open(FILE_1_PATH, 'r') as file_1, open(FILE_2_PATH, 'r') as file_2:
file_1_content = '\n'.join(file_1.readlines())
file_2_content = '\n'.join(file_2.readlines())
GCodeDiffer(file_1_content, file_2_content).save_html_diff_to_file(HTML_PATH)
Using the CLI you can access the above functionality through the command line.
run
- Execute passed filediff
- Diff passed filesconfigurations
- Print available files to run
To view available commands run:
pipenv run python -m g_code_parsing.cli -h
To view help for specific command run:
pipenv run python -m g_code_parsing.cli <your_command> -h
For example,
pipenv run python -m g_code_parsing.cli run -h
To run a protocol with the CLI use the run
command.
It has the format of
cli.py run [-h] [--text-mode Concise | Default | G-Code]
[--left-pipette left_pipette_config]
[--right-pipette right_pipette_config]
protocol_file_path
Usage Example:
pipenv run python -m g_code_parsing.cli run \
--text-mode G-Code \
--left-pipette '{"model": "p20_single_v2.0", "id": "P20SV202020070101"}' \
protocols/smoothie_protocol.py
The --text-mode
option determines the output format of running the protocol.
It has 3 choices for text modes: Default, Concise, and G-Code.
- Default - The most verbose format. Provides raw G-Code, an explanation of what the G-Code does, and an explanation of the response.
- Concise - Contains all the same information as
Default
but condenses it to a single line. Instead of headers it uses->
to delimit the G-Code, explanation, and response. - G-Code - Contains only the raw G-Code and the raw response. Delimited by
->
.
Default Output Example:
Code: M114.2
Explanation: Getting current position for all axes
Response: The current position of the robot is:
A Axis: 105.29
B Axis: -8.5
C Axis: 19.0
X Axis: 113.38
Y Axis: 11.24
Z Axis: 218.0
-----------------------------------------
Code: M400
Explanation: Waiting for motors to stop moving
Response:
-----------------------------------------
Code: M907 A0.1 B0.05 C1.0 X0.3 Y0.3 Z0.1
Explanation: Setting the current (in amps) to:
X-Axis Motor: 0.3
Y-Axis Motor: 0.3
Z-Axis Motor: 0.1
A-Axis Motor: 0.1
B-Axis Motor: 0.05
C-Axis Motor: 1.0
Response:
-----------------------------------------
Code: G4 P0.005
Explanation: Pausing movement for 0.005ms
Response:
Concise Output Example:
M114.2 -> Getting current position for all axes -> The current position of the robot is: A Axis: 105.29 B Axis: -8.5 C Axis: 19.0 X Axis: 113.38 Y Axis: 11.24 Z Axis: 218.0
M400 -> Waiting for motors to stop moving ->
M907 A0.1 B0.05 C1.0 X0.3 Y0.3 Z0.1 -> Setting the current (in amps) to: X-Axis Motor: 0.3 Y-Axis Motor: 0.3 Z-Axis Motor: 0.1 A-Axis Motor: 0.1 B-Axis Motor: 0.05 C-Axis Motor: 1.0 ->
G4 P0.005 -> Pausing movement for 0.005ms ->
G-Code Output Example:
M114.2 -> M114.2 MCS: A:105.29 B:-8.5 C:19.0 X:113.38 Y:11.24 Z:218.0
M400 ->
M907 A0.1 B0.05 C1.0 X0.3 Y0.3 Z0.1 ->
G4 P0.005 ->
Option Usage Example:
--text-mode Default
The --left-pipette
and --right-pipette
options are the way to provide the configuration
of the pipettes for the OT-2 Emulator. The expected format is JSON.
The JSON expects 2 keys id
and model
.
Option Usage Example:
--left-pipette '{"model": "p20_single_v2.0", "id": "P20SV202020070101"}'
The protocol file path can either be an absolute or relative file path to the Python protocol file that you want to run.
Argument Usage Example:
/absolute/path/to/my/file.py
OR
../relative/path/to/my/file.py
To diff 2 output files with the CLI use the diff
command.
The command will return an HTML encoded diff.
It has the format of
usage: cli.py diff [-h] file_path_1 file_path_2
Usage Example:
pipenv run python -m g_code_parsing.cli diff /file/path/one.txt /file/path/two.txt
The paths to the files you want to diff
Argument Usage Example:
/absolute/path/to/my/file.py
OR
../relative/path/to/my/file.py
When we make a change to the code that affects the Master G-Code File we have to update it in S3. To do this follow these steps.
- Switch to the branch that is failing and pull the changes
- Run
make teardown
in the root of the repo - Run
make setup
in the root of the repo - Go into
g-code-testing
and run the test that is failing- For example:
pipenv run python cli.py diff protocol/2_modules
- Once you have confirmed that it is failing, push to s3
- For example:
- For example:
pipenv run python cli.py push protocol/2_modules
- Re-run tests locally and in CI