diff options
Diffstat (limited to 'test/run_device_tests.py')
-rwxr-xr-x | test/run_device_tests.py | 98 |
1 files changed, 73 insertions, 25 deletions
diff --git a/test/run_device_tests.py b/test/run_device_tests.py index a2277afd4f..4661d57b74 100755 --- a/test/run_device_tests.py +++ b/test/run_device_tests.py @@ -18,7 +18,7 @@ machine against a board connected to a local machine. For example: Start servod and JLink locally: (local chroot) $ sudo servod --board dragonclaw -(local chroot) $ JLinkRemoteServerCLExe -select USB +(local chroot) $ sudo JLinkRemoteServerCLExe -select USB Forward the FPMCU console on a TCP port: @@ -37,27 +37,31 @@ Run the script on the remote machine: --jlink_port 19020 --console_port 10000 """ # pylint: enable=line-too-long +# TODO(b/267800058): refactor into multiple modules +# pylint: disable=too-many-lines import argparse import concurrent +from concurrent.futures.thread import ThreadPoolExecutor +from dataclasses import dataclass +from dataclasses import field +from enum import Enum import io import logging import os +from pathlib import Path import re import socket import subprocess import sys import time -from concurrent.futures.thread import ThreadPoolExecutor -from dataclasses import dataclass, field -from enum import Enum -from pathlib import Path from typing import BinaryIO, Dict, List, Optional, Tuple # pylint: disable=import-error import colorama # type: ignore[import] -import fmap from contextlib2 import ExitStack +import fmap + # pylint: enable=import-error @@ -71,6 +75,8 @@ ALL_TESTS_FAILED_REGEX = re.compile(r"Fail! \(\d+ tests\)\r\n") SINGLE_CHECK_PASSED_REGEX = re.compile(r"Pass: .*") SINGLE_CHECK_FAILED_REGEX = re.compile(r".*failed:.*") +RW_IMAGE_BOOTED_REGEX = re.compile(r"^\[Image: RW.*") + ASSERTION_FAILURE_REGEX = re.compile(r"ASSERTION FAILURE.*") DATA_ACCESS_VIOLATION_8020000_REGEX = re.compile( @@ -131,6 +137,15 @@ class ImageType(Enum): RW = 2 +class ApplicationType(Enum): + """ + Select the application type to use (test or production) + """ + + TEST = 1 + PRODUCTION = 2 + + @dataclass class BoardConfig: """Board-specific configuration.""" @@ -150,7 +165,8 @@ class TestConfig: # pylint: disable=too-many-instance-attributes test_name: str - image_to_use: ImageType = ImageType.RW + imagetype_to_use: ImageType = ImageType.RW + apptype_to_use: ApplicationType = ApplicationType.TEST finish_regexes: List = None fail_regexes: List = None toggle_power: bool = False @@ -204,6 +220,12 @@ class AllTests: def get_public_tests(board_config: BoardConfig) -> List[TestConfig]: """Return public test configs for the specified board.""" tests = [ + TestConfig( + test_name="production_app_test", + finish_regexes=[RW_IMAGE_BOOTED_REGEX], + imagetype_to_use=ImageType.RW, + apptype_to_use=ApplicationType.PRODUCTION, + ), TestConfig(test_name="abort"), TestConfig(test_name="aes"), TestConfig(test_name="always_memset"), @@ -214,12 +236,12 @@ class AllTests: TestConfig(test_name="exception"), TestConfig( test_name="flash_physical", - image_to_use=ImageType.RO, + imagetype_to_use=ImageType.RO, toggle_power=True, ), TestConfig( test_name="flash_write_protect", - image_to_use=ImageType.RO, + imagetype_to_use=ImageType.RO, toggle_power=True, enable_hw_write_protect=True, ), @@ -227,7 +249,7 @@ class AllTests: TestConfig( config_name="fpsensor_spi_ro", test_name="fpsensor", - image_to_use=ImageType.RO, + imagetype_to_use=ImageType.RO, test_args=["spi"], ), TestConfig( @@ -238,7 +260,7 @@ class AllTests: TestConfig( config_name="fpsensor_uart_ro", test_name="fpsensor", - image_to_use=ImageType.RO, + imagetype_to_use=ImageType.RO, test_args=["uart"], ), TestConfig( @@ -256,7 +278,7 @@ class AllTests: TestConfig( config_name="mpu_ro", test_name="mpu", - image_to_use=ImageType.RO, + imagetype_to_use=ImageType.RO, finish_regexes=[board_config.mpu_regex], ), TestConfig( @@ -282,7 +304,9 @@ class AllTests: finish_regexes=[board_config.rollback_region1_regex], test_args=["region1"], ), - TestConfig(test_name="rollback_entropy", image_to_use=ImageType.RO), + TestConfig( + test_name="rollback_entropy", imagetype_to_use=ImageType.RO + ), TestConfig(test_name="rtc"), TestConfig(test_name="sha256"), TestConfig(test_name="sha256_unrolled"), @@ -305,6 +329,7 @@ class AllTests: ), TestConfig(test_name="timer"), TestConfig(test_name="timer_dos"), + TestConfig(test_name="tpm_seed_clear"), TestConfig(test_name="utils", timeout_secs=20), TestConfig(test_name="utils_str"), ] @@ -501,6 +526,14 @@ def power(board_config: BoardConfig, power_on: bool) -> None: subprocess.run(cmd, check=False).check_returncode() +def power_cycle(board_config: BoardConfig) -> None: + """power_cycle the boards.""" + logging.debug("power_cycling board") + power(board_config, power_on=False) + time.sleep(1) + power(board_config, power_on=True) + + def hw_write_protect(enable: bool) -> None: """Enable/disable hardware write protect.""" if enable: @@ -516,7 +549,9 @@ def hw_write_protect(enable: bool) -> None: subprocess.run(cmd, check=False).check_returncode() -def build(test_name: str, board_name: str, compiler: str) -> None: +def build( + test_name: str, board_name: str, compiler: str, app_type: ApplicationType +) -> None: """Build specified test for specified board.""" cmd = ["make"] @@ -525,10 +560,15 @@ def build(test_name: str, board_name: str, compiler: str) -> None: cmd = cmd + [ "BOARD=" + board_name, - "test-" + test_name, "-j", ] + # If the image type is a test image, then apply test- prefix to the target name + if app_type == ApplicationType.TEST: + cmd = cmd + [ + "test-" + test_name, + ] + logging.debug('Running command: "%s"', " ".join(cmd)) subprocess.run(cmd, check=False).check_returncode() @@ -626,12 +666,14 @@ def run_test( # Wait for boot to finish time.sleep(1) console.write("\n".encode()) - if test.image_to_use == ImageType.RO: + if test.imagetype_to_use == ImageType.RO: console.write("reboot ro\n".encode()) time.sleep(1) - test_cmd = "runtest " + " ".join(test.test_args) + "\n" - console.write(test_cmd.encode()) + # Skip runtest if using standard app type + if test.apptype_to_use != ApplicationType.PRODUCTION: + test_cmd = "runtest " + " ".join(test.test_args) + "\n" + console.write(test_cmd.encode()) while True: console.flush() @@ -706,11 +748,19 @@ def flash_and_run_test( build_board = test.build_board # build test binary - build(test.test_name, build_board, args.compiler) + build(test.test_name, build_board, args.compiler, test.apptype_to_use) - image_path = os.path.join( - EC_DIR, "build", build_board, test.test_name, test.test_name + ".bin" - ) + if test.apptype_to_use == ApplicationType.PRODUCTION: + image_path = os.path.join(EC_DIR, "build", build_board, "ec.bin") + else: + image_path = os.path.join( + EC_DIR, + "build", + build_board, + test.test_name, + test.test_name + ".bin", + ) + logging.debug("image_path: %s", image_path) if test.ro_image is not None: try: @@ -741,9 +791,7 @@ def flash_and_run_test( return False if test.toggle_power: - power(board_config, power_on=False) - time.sleep(1) - power(board_config, power_on=True) + power_cycle(board_config) hw_write_protect(test.enable_hw_write_protect) |