From 61531fbd4a3d0fe9fe77f542979f42cd9e4a70c1 Mon Sep 17 00:00:00 2001 From: Tomas Susanka Date: Thu, 3 Sep 2020 11:11:21 +0200 Subject: [PATCH] ci: introduce hardware tests for TT --- ci/hardware_tests/bootstrap.py | 25 +++++++++++------ ci/hardware_tests/device/device.py | 25 +++++++++++------ ci/hardware_tests/device/t1.py | 18 +++++++----- ci/hardware_tests/device/tt.py | 21 ++++++++++++++ ci/hardware_tests/get_trezor_path.sh | 9 ++++++ ci/hardware_tests/hardware.cfg | 11 +++++++- ci/test.yml | 41 +++++++++++++++++++++++++--- 7 files changed, 122 insertions(+), 28 deletions(-) create mode 100644 ci/hardware_tests/device/tt.py create mode 100755 ci/hardware_tests/get_trezor_path.sh diff --git a/ci/hardware_tests/bootstrap.py b/ci/hardware_tests/bootstrap.py index 0b5712d5f..ead7099f3 100755 --- a/ci/hardware_tests/bootstrap.py +++ b/ci/hardware_tests/bootstrap.py @@ -2,21 +2,30 @@ import configparser import sys from device.t1 import TrezorOne +from device.tt import TrezorT -def main(file: str = None): +def main(model: str, file: str = None): config = configparser.ConfigParser() config.read_file(open("hardware.cfg")) t1 = TrezorOne( - config["t1"]["location"], - config["t1"]["port"], + config["t1"]["uhub_location"], config["t1"]["arduino_serial"], + config["t1"]["port"], ) - t1.update_firmware(file) + tt = TrezorT(config["tt"]["uhub_location"], config["tt"]["port"]) + + if model == "t1": + t1.update_firmware(file) + elif model == "tt": + tt.update_firmware(file) + else: + raise ValueError("Unknown Trezor model.") if __name__ == "__main__": - file = None - if len(sys.argv) == 2: - file = sys.argv[1] - main(file) + model = sys.argv[1] + if len(sys.argv) == 3: + main(model, file=sys.argv[2]) + else: + main(model) diff --git a/ci/hardware_tests/device/device.py b/ci/hardware_tests/device/device.py index b5635f866..af3690bde 100644 --- a/ci/hardware_tests/device/device.py +++ b/ci/hardware_tests/device/device.py @@ -2,22 +2,31 @@ import datetime import os import time -import serial - class Device: - def __init__(self, uhub_location, uhub_port, arduino_serial): + def __init__(self, uhub_location, device_port): self.uhub_location = uhub_location - self.uhub_port = uhub_port - self.arduino_serial = arduino_serial - self.serial = serial.Serial(arduino_serial, 9600) + self.device_port = device_port + + def run_trezorctl(self, cmd: str): + full_cmd = "trezorctl " + full_cmd += cmd + print("[software/trezorctl] Running '{}'".format(full_cmd)) + os.system(full_cmd) + + def check_version(self): + self.run_trezorctl("get-features | grep version") + + def reboot(self): + self.power_off() + self.power_on() def power_on(self): self.now() print("[hardware/usb] Turning power on...") os.system( "uhubctl -l {} -p {} -a on > /dev/null".format( - self.uhub_location, self.uhub_port + self.uhub_location, self.device_port ) ) self.wait(3) @@ -27,7 +36,7 @@ class Device: print("[hardware/usb] Turning power off...") os.system( "uhubctl -l {} -p {} -r 100 -a off > /dev/null".format( - self.uhub_location, self.uhub_port + self.uhub_location, self.device_port ) ) self.wait(3) diff --git a/ci/hardware_tests/device/t1.py b/ci/hardware_tests/device/t1.py index 55a9e0853..49bcea1da 100644 --- a/ci/hardware_tests/device/t1.py +++ b/ci/hardware_tests/device/t1.py @@ -1,9 +1,13 @@ -import os +import serial from .device import Device class TrezorOne(Device): + def __init__(self, uhub_location, arduino_serial, device_port): + super().__init__(uhub_location, device_port) + self.serial = serial.Serial(arduino_serial, 9600) + def touch(self, location, action): self.now() print( @@ -14,17 +18,17 @@ class TrezorOne(Device): def update_firmware(self, file=None): if file: unofficial = True - trezorctlcmd = "trezorctl firmware-update -s -f {} &".format(file) - print("[software/trezorctl] Updating the firmware to {}...".format(file)) + trezorctlcmd = "firmware-update -s -f {} &".format(file) + print("[software] Updating the firmware to {}".format(file)) else: unofficial = False - trezorctlcmd = "trezorctl firmware-update &" - print("[software/trezorctl] Updating the firmware to latest...") + trezorctlcmd = "firmware-update &" + print("[software] Updating the firmware to latest") self.wait(3) self._enter_bootloader() self.wait(3) - os.system(trezorctlcmd) + self.run_trezorctl(trezorctlcmd) self.wait(3) self.touch("right", "click") self.wait(20) @@ -38,7 +42,7 @@ class TrezorOne(Device): self.wait(5) self.touch("right", "click") self.wait(5) - os.system("trezorctl get-features|grep version") + self.check_version() def _enter_bootloader(self): self.power_off() diff --git a/ci/hardware_tests/device/tt.py b/ci/hardware_tests/device/tt.py new file mode 100644 index 000000000..e78827fc4 --- /dev/null +++ b/ci/hardware_tests/device/tt.py @@ -0,0 +1,21 @@ +from .device import Device + + +class TrezorT(Device): + def update_firmware(self, file=None): + # reset to enter bootloader again + self.power_off() + self.power_on() + + if not file: + raise ValueError( + "Uploading production firmware will replace the bootloader, it is not allowed!" + ) + + self.wait(5) + print("[software] Updating the firmware to {}".format(file)) + self.run_trezorctl("firmware-update -s -f {} &".format(file)) + + # upgrading to 2.3.2 took about 80s + self.wait(80) + self.check_version() diff --git a/ci/hardware_tests/get_trezor_path.sh b/ci/hardware_tests/get_trezor_path.sh new file mode 100755 index 000000000..a47492929 --- /dev/null +++ b/ci/hardware_tests/get_trezor_path.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +if [ $# -ne 1 ] + then + echo "Usage: $0 [model]" + exit 1 +fi + +nix-shell --run "pipenv run trezorctl list | grep '$1' | cut -d' ' -f1 | tr -d '\n'" diff --git a/ci/hardware_tests/hardware.cfg b/ci/hardware_tests/hardware.cfg index 0e5eeb777..0e503fbb9 100644 --- a/ci/hardware_tests/hardware.cfg +++ b/ci/hardware_tests/hardware.cfg @@ -1,4 +1,13 @@ [t1] -location = 3-1.4 +# location of the uhub, can be found out by running `uhubctl` +uhub_location = 3-1.4 +# to which port of the uhub the device is connected port = 3 +# arduino that pushes T1 buttons arduino_serial = /dev/ttyACM0 + +[tt] +# location of the uhub, can be found out by running `uhubctl` +uhub_location = 3-3 +# to which port of the uhub the device is connected +port = 1 diff --git a/ci/test.yml b/ci/test.yml index ae4cc32a0..5d07fd74b 100644 --- a/ci/test.yml +++ b/ci/test.yml @@ -306,6 +306,31 @@ storage test: when: always # Hardware +hardware core regular device test: + stage: test + only: + - schedules # nightly build + - /^legacy\// + - /^release\// + - /^secfix\// + - /^hw\// + tags: + - tpmb + needs: ["core fw regular debug build"] + script: + - cd ci/hardware_tests + - nix-shell --run "cd ../.. && poetry install" + - nix-shell --run "poetry run trezorctl list" + - export TREZOR_PATH=$(./get_trezor_path.sh 'Trezor T') + - nix-shell --run "echo $TREZOR_PATH" + - nix-shell --run "poetry run python bootstrap.py tt ../../trezor-*.bin" + - nix-shell --run "poetry run pytest ../../tests/device_tests" + timeout: 4h + artifacts: + name: "$CI_JOB_NAME-$CI_COMMIT_SHORT_SHA" + expire_in: 2 days + when: always + hardware legacy regular device test: stage: test only: @@ -313,6 +338,7 @@ hardware legacy regular device test: - /^legacy\// - /^release\// - /^secfix\// + - /^hw\// tags: - tpmb needs: @@ -321,8 +347,11 @@ hardware legacy regular device test: - cd ci/hardware_tests - nix-shell --run "./record_video.sh ${CI_COMMIT_SHORT_SHA} start" - nix-shell --run "cd ../.. && poetry install" - - nix-shell --run "poetry run python bootstrap.py" - - nix-shell --run "poetry run python bootstrap.py ../../trezor-*.bin" + - nix-shell --run "poetry run trezorctl list" + - export TREZOR_PATH=$(./get_trezor_path.sh 'Trezor 1') + - nix-shell --run "echo $TREZOR_PATH" + - nix-shell --run "poetry run python bootstrap.py t1" + - nix-shell --run "poetry run python bootstrap.py t1 ../../trezor-*.bin" - nix-shell --run "poetry run pytest ../../tests/device_tests" - nix-shell --run "./record_video.sh ${CI_COMMIT_SHORT_SHA} stop" artifacts: @@ -341,6 +370,7 @@ hardware legacy btconly device test: - /^legacy\// - /^release\// - /^secfix\// + - /^hw\// tags: - tpmb needs: @@ -349,8 +379,11 @@ hardware legacy btconly device test: - cd ci/hardware_tests - nix-shell --run "./record_video.sh ${CI_COMMIT_SHORT_SHA} start" - nix-shell --run "cd ../.. && poetry install" - - nix-shell --run "poetry run python bootstrap.py" - - nix-shell --run "poetry run python bootstrap.py ../../trezor-*.bin" + - nix-shell --run "poetry run trezorctl list" + - export TREZOR_PATH=$(./get_trezor_path.sh 'Trezor 1') + - nix-shell --run "echo $TREZOR_PATH" + - nix-shell --run "poetry run python bootstrap.py t1" + - nix-shell --run "poetry run python bootstrap.py t1 ../../trezor-*.bin" - nix-shell --run "poetry run pytest ../../tests/device_tests" - nix-shell --run "./record_video.sh ${CI_COMMIT_SHORT_SHA} stop" artifacts: