#!/usr/bin/env python3 # vim: set syntax=python ts=4 : # # Copyright (c) 2018 Intel Corporation # Copyright 2022 NXP # SPDX-License-Identifier: Apache-2.0 import os import pkg_resources import sys from pathlib import Path import json import logging import subprocess import shutil import re import argparse from datetime import datetime, timezone from twisterlib.coverage import supported_coverage_formats logger = logging.getLogger('twister') logger.setLevel(logging.DEBUG) from twisterlib.error import TwisterRuntimeError from twisterlib.log_helper import log_command ZEPHYR_BASE = os.getenv("ZEPHYR_BASE") if not ZEPHYR_BASE: sys.exit("$ZEPHYR_BASE environment variable undefined") sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/")) import zephyr_module # Use this for internal comparisons; that's what canonicalization is # for. Don't use it when invoking other components of the build system # to avoid confusing and hard to trace inconsistencies in error messages # and logs, generated Makefiles, etc. compared to when users invoke these # components directly. # Note "normalization" is different from canonicalization, see os.path. canonical_zephyr_base = os.path.realpath(ZEPHYR_BASE) installed_packages = [pkg.project_name for pkg in pkg_resources.working_set] # pylint: disable=not-an-iterable PYTEST_PLUGIN_INSTALLED = 'pytest-twister-harness' in installed_packages def add_parse_arguments(parser = None): if parser is None: parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) parser.fromfile_prefix_chars = "+" case_select = parser.add_argument_group("Test case selection", """ Artificially long but functional example: $ ./scripts/twister -v \\ --testsuite-root tests/ztest/base \\ --testsuite-root tests/kernel \\ --test tests/ztest/base/testing.ztest.verbose_0 \\ --test tests/kernel/fifo/fifo_api/kernel.fifo "kernel.fifo.poll" is one of the test section names in __/fifo_api/testcase.yaml """) compare_group_option = parser.add_mutually_exclusive_group() platform_group_option = parser.add_mutually_exclusive_group() run_group_option = parser.add_mutually_exclusive_group() device = parser.add_mutually_exclusive_group(required="--device-testing" in sys.argv) test_or_build = parser.add_mutually_exclusive_group() test_xor_subtest = case_select.add_mutually_exclusive_group() test_xor_generator = case_select.add_mutually_exclusive_group() valgrind_asan_group = parser.add_mutually_exclusive_group() case_select.add_argument( "-E", "--save-tests", metavar="FILENAME", action="store", help="Write a list of tests and platforms to be run to file.") case_select.add_argument( "-F", "--load-tests", metavar="FILENAME", action="store", help="Load a list of tests and platforms to be run from file.") case_select.add_argument( "-T", "--testsuite-root", action="append", default=[], help="Base directory to recursively search for test cases. All " "testcase.yaml files under here will be processed. May be " "called multiple times. Defaults to the 'samples/' and " "'tests/' directories at the base of the Zephyr tree.") case_select.add_argument( "-f", "--only-failed", action="store_true", help="Run only those tests that failed the previous twister run " "invocation.") case_select.add_argument("--list-tests", action="store_true", help="""List of all sub-test functions recursively found in all --testsuite-root arguments. Note different sub-tests can share the same section name and come from different directories. The output is flattened and reports --sub-test names only, not their directories. For instance net.socket.getaddrinfo_ok and net.socket.fd_set belong to different directories. """) case_select.add_argument("--test-tree", action="store_true", help="""Output the test plan in a tree form""") compare_group_option.add_argument("--compare-report", help="Use this report file for size comparison") compare_group_option.add_argument( "-m", "--last-metrics", action="store_true", help="Compare with the results of the previous twister " "invocation") platform_group_option.add_argument( "-G", "--integration", action="store_true", help="Run integration tests") platform_group_option.add_argument( "--emulation-only", action="store_true", help="Only build and run emulation platforms") run_group_option.add_argument( "--device-testing", action="store_true", help="Test on device directly. Specify the serial device to " "use with the --device-serial option.") run_group_option.add_argument("--generate-hardware-map", help="""Probe serial devices connected to this platform and create a hardware map file to be used with --device-testing """) device.add_argument("--device-serial", help="""Serial device for accessing the board (e.g., /dev/ttyACM0) """) device.add_argument("--device-serial-pty", help="""Script for controlling pseudoterminal. Twister believes that it interacts with a terminal when it actually interacts with the script. E.g "twister --device-testing --device-serial-pty