1995fb337SOwen Hilyard# SPDX-License-Identifier: BSD-3-Clause 2995fb337SOwen Hilyard# Copyright(c) 2010-2021 Intel Corporation 378534506SJuraj Linkeš# Copyright(c) 2022-2023 PANTHEON.tech s.r.o. 4995fb337SOwen Hilyard# Copyright(c) 2022 University of New Hampshire 5995fb337SOwen Hilyard 66ef07151SJuraj Linkeš"""Environment variables and command line arguments parsing. 76ef07151SJuraj Linkeš 86ef07151SJuraj LinkešThis is a simple module utilizing the built-in argparse module to parse command line arguments, 96ef07151SJuraj Linkešaugment them with values from environment variables and make them available across the framework. 106ef07151SJuraj Linkeš 116ef07151SJuraj LinkešThe command line value takes precedence, followed by the environment variable value, 126ef07151SJuraj Linkešfollowed by the default value defined in this module. 136ef07151SJuraj Linkeš 146ef07151SJuraj LinkešThe command line arguments along with the supported environment variables are: 156ef07151SJuraj Linkeš 166ef07151SJuraj Linkeš.. option:: --config-file 176ef07151SJuraj Linkeš.. envvar:: DTS_CFG_FILE 186ef07151SJuraj Linkeš 196ef07151SJuraj Linkeš The path to the YAML test run configuration file. 206ef07151SJuraj Linkeš 216ef07151SJuraj Linkeš.. option:: --output-dir, --output 226ef07151SJuraj Linkeš.. envvar:: DTS_OUTPUT_DIR 236ef07151SJuraj Linkeš 246ef07151SJuraj Linkeš The directory where DTS logs and results are saved. 256ef07151SJuraj Linkeš 266ef07151SJuraj Linkeš.. option:: --compile-timeout 276ef07151SJuraj Linkeš.. envvar:: DTS_COMPILE_TIMEOUT 286ef07151SJuraj Linkeš 296ef07151SJuraj Linkeš The timeout for compiling DPDK. 306ef07151SJuraj Linkeš 316ef07151SJuraj Linkeš.. option:: -t, --timeout 326ef07151SJuraj Linkeš.. envvar:: DTS_TIMEOUT 336ef07151SJuraj Linkeš 346ef07151SJuraj Linkeš The timeout for all DTS operation except for compiling DPDK. 356ef07151SJuraj Linkeš 366ef07151SJuraj Linkeš.. option:: -v, --verbose 376ef07151SJuraj Linkeš.. envvar:: DTS_VERBOSE 386ef07151SJuraj Linkeš 396ef07151SJuraj Linkeš Set to any value to enable logging everything to the console. 406ef07151SJuraj Linkeš 416ef07151SJuraj Linkeš.. option:: -s, --skip-setup 426ef07151SJuraj Linkeš.. envvar:: DTS_SKIP_SETUP 436ef07151SJuraj Linkeš 446ef07151SJuraj Linkeš Set to any value to skip building DPDK. 456ef07151SJuraj Linkeš 466ef07151SJuraj Linkeš.. option:: --tarball, --snapshot, --git-ref 476ef07151SJuraj Linkeš.. envvar:: DTS_DPDK_TARBALL 486ef07151SJuraj Linkeš 496ef07151SJuraj Linkeš The path to a DPDK tarball, git commit ID, tag ID or tree ID to test. 506ef07151SJuraj Linkeš 51*4a4678c7SJuraj Linkeš.. option:: --test-suite 52*4a4678c7SJuraj Linkeš.. envvar:: DTS_TEST_SUITES 536ef07151SJuraj Linkeš 54*4a4678c7SJuraj Linkeš A test suite with test cases which may be specified multiple times. 55*4a4678c7SJuraj Linkeš In the environment variable, the suites are joined with a comma. 566ef07151SJuraj Linkeš 576ef07151SJuraj Linkeš.. option:: --re-run, --re_run 586ef07151SJuraj Linkeš.. envvar:: DTS_RERUN 596ef07151SJuraj Linkeš 606ef07151SJuraj Linkeš Re-run each test case this many times in case of a failure. 616ef07151SJuraj Linkeš 626ef07151SJuraj LinkešThe module provides one key module-level variable: 636ef07151SJuraj Linkeš 646ef07151SJuraj LinkešAttributes: 656ef07151SJuraj Linkeš SETTINGS: The module level variable storing framework-wide DTS settings. 666ef07151SJuraj Linkeš 676ef07151SJuraj LinkešTypical usage example:: 686ef07151SJuraj Linkeš 696ef07151SJuraj Linkeš from framework.settings import SETTINGS 706ef07151SJuraj Linkeš foo = SETTINGS.foo 716ef07151SJuraj Linkeš""" 726ef07151SJuraj Linkeš 73995fb337SOwen Hilyardimport argparse 74995fb337SOwen Hilyardimport os 75840b1e01SJuraj Linkešfrom dataclasses import dataclass, field 76680d8a24SJuraj Linkešfrom pathlib import Path 77*4a4678c7SJuraj Linkešfrom typing import Any 78995fb337SOwen Hilyard 79*4a4678c7SJuraj Linkešfrom .config import TestSuiteConfig 80c9d31a7eSJuraj Linkešfrom .utils import DPDKGitTarball 81680d8a24SJuraj Linkeš 82995fb337SOwen Hilyard 83840b1e01SJuraj Linkeš@dataclass(slots=True) 84840b1e01SJuraj Linkešclass Settings: 856ef07151SJuraj Linkeš """Default framework-wide user settings. 866ef07151SJuraj Linkeš 876ef07151SJuraj Linkeš The defaults may be modified at the start of the run. 886ef07151SJuraj Linkeš """ 896ef07151SJuraj Linkeš 906ef07151SJuraj Linkeš #: 91840b1e01SJuraj Linkeš config_file_path: Path = Path(__file__).parent.parent.joinpath("conf.yaml") 926ef07151SJuraj Linkeš #: 93840b1e01SJuraj Linkeš output_dir: str = "output" 946ef07151SJuraj Linkeš #: 95840b1e01SJuraj Linkeš timeout: float = 15 966ef07151SJuraj Linkeš #: 97840b1e01SJuraj Linkeš verbose: bool = False 986ef07151SJuraj Linkeš #: 99840b1e01SJuraj Linkeš skip_setup: bool = False 1006ef07151SJuraj Linkeš #: 101840b1e01SJuraj Linkeš dpdk_tarball_path: Path | str = "dpdk.tar.xz" 1026ef07151SJuraj Linkeš #: 103840b1e01SJuraj Linkeš compile_timeout: float = 1200 1046ef07151SJuraj Linkeš #: 105*4a4678c7SJuraj Linkeš test_suites: list[TestSuiteConfig] = field(default_factory=list) 1066ef07151SJuraj Linkeš #: 107840b1e01SJuraj Linkeš re_run: int = 0 108840b1e01SJuraj Linkeš 109840b1e01SJuraj Linkeš 110840b1e01SJuraj LinkešSETTINGS: Settings = Settings() 111995fb337SOwen Hilyard 112995fb337SOwen Hilyard 113995fb337SOwen Hilyarddef _get_parser() -> argparse.ArgumentParser: 114*4a4678c7SJuraj Linkeš """Create the argument parser for DTS. 115*4a4678c7SJuraj Linkeš 116*4a4678c7SJuraj Linkeš Command line options take precedence over environment variables, which in turn take precedence 117*4a4678c7SJuraj Linkeš over default values. 118*4a4678c7SJuraj Linkeš 119*4a4678c7SJuraj Linkeš Returns: 120*4a4678c7SJuraj Linkeš argparse.ArgumentParser: The configured argument parser with defined options. 121*4a4678c7SJuraj Linkeš """ 122*4a4678c7SJuraj Linkeš 123*4a4678c7SJuraj Linkeš def env_arg(env_var: str, default: Any) -> Any: 124*4a4678c7SJuraj Linkeš """A helper function augmenting the argparse with environment variables. 125*4a4678c7SJuraj Linkeš 126*4a4678c7SJuraj Linkeš If the supplied environment variable is defined, then the default value 127*4a4678c7SJuraj Linkeš of the argument is modified. This satisfies the priority order of 128*4a4678c7SJuraj Linkeš command line argument > environment variable > default value. 129*4a4678c7SJuraj Linkeš 130*4a4678c7SJuraj Linkeš Args: 131*4a4678c7SJuraj Linkeš env_var: Environment variable name. 132*4a4678c7SJuraj Linkeš default: Default value. 133*4a4678c7SJuraj Linkeš 134*4a4678c7SJuraj Linkeš Returns: 135*4a4678c7SJuraj Linkeš Environment variable or default value. 136*4a4678c7SJuraj Linkeš """ 137*4a4678c7SJuraj Linkeš return os.environ.get(env_var) or default 138*4a4678c7SJuraj Linkeš 13978534506SJuraj Linkeš parser = argparse.ArgumentParser( 140517b4b26SJuraj Linkeš description="Run DPDK test suites. All options may be specified with the environment " 141517b4b26SJuraj Linkeš "variables provided in brackets. Command line arguments have higher priority.", 14278534506SJuraj Linkeš formatter_class=argparse.ArgumentDefaultsHelpFormatter, 14378534506SJuraj Linkeš ) 144995fb337SOwen Hilyard 145995fb337SOwen Hilyard parser.add_argument( 146995fb337SOwen Hilyard "--config-file", 147*4a4678c7SJuraj Linkeš default=env_arg("DTS_CFG_FILE", SETTINGS.config_file_path), 148840b1e01SJuraj Linkeš type=Path, 149*4a4678c7SJuraj Linkeš help="[DTS_CFG_FILE] The configuration file that describes the test cases, " 150*4a4678c7SJuraj Linkeš "SUTs and targets.", 151995fb337SOwen Hilyard ) 152995fb337SOwen Hilyard 153179d7059SJuraj Linkeš parser.add_argument( 154179d7059SJuraj Linkeš "--output-dir", 155179d7059SJuraj Linkeš "--output", 156*4a4678c7SJuraj Linkeš default=env_arg("DTS_OUTPUT_DIR", SETTINGS.output_dir), 15755442c14SLuca Vizzarro help="[DTS_OUTPUT_DIR] Output directory where DTS logs and results are saved.", 158179d7059SJuraj Linkeš ) 159179d7059SJuraj Linkeš 160179d7059SJuraj Linkeš parser.add_argument( 16134dfd265SJuraj Linkeš "-t", 16234dfd265SJuraj Linkeš "--timeout", 163*4a4678c7SJuraj Linkeš default=env_arg("DTS_TIMEOUT", SETTINGS.timeout), 164680d8a24SJuraj Linkeš type=float, 165517b4b26SJuraj Linkeš help="[DTS_TIMEOUT] The default timeout for all DTS operations except for compiling DPDK.", 16634dfd265SJuraj Linkeš ) 16734dfd265SJuraj Linkeš 16834dfd265SJuraj Linkeš parser.add_argument( 169179d7059SJuraj Linkeš "-v", 170179d7059SJuraj Linkeš "--verbose", 171*4a4678c7SJuraj Linkeš action="store_true", 172*4a4678c7SJuraj Linkeš default=env_arg("DTS_VERBOSE", SETTINGS.verbose), 173840b1e01SJuraj Linkeš help="[DTS_VERBOSE] Specify to enable verbose output, logging all messages " 174179d7059SJuraj Linkeš "to the console.", 175179d7059SJuraj Linkeš ) 176179d7059SJuraj Linkeš 177680d8a24SJuraj Linkeš parser.add_argument( 178680d8a24SJuraj Linkeš "-s", 179680d8a24SJuraj Linkeš "--skip-setup", 180*4a4678c7SJuraj Linkeš action="store_true", 181*4a4678c7SJuraj Linkeš default=env_arg("DTS_SKIP_SETUP", SETTINGS.skip_setup), 182840b1e01SJuraj Linkeš help="[DTS_SKIP_SETUP] Specify to skip all setup steps on SUT and TG nodes.", 183680d8a24SJuraj Linkeš ) 184680d8a24SJuraj Linkeš 185680d8a24SJuraj Linkeš parser.add_argument( 186680d8a24SJuraj Linkeš "--tarball", 187680d8a24SJuraj Linkeš "--snapshot", 188c9d31a7eSJuraj Linkeš "--git-ref", 189*4a4678c7SJuraj Linkeš default=env_arg("DTS_DPDK_TARBALL", SETTINGS.dpdk_tarball_path), 190680d8a24SJuraj Linkeš type=Path, 191c9d31a7eSJuraj Linkeš help="[DTS_DPDK_TARBALL] Path to DPDK source code tarball or a git commit ID, " 192c9d31a7eSJuraj Linkeš "tag ID or tree ID to test. To test local changes, first commit them, " 193c9d31a7eSJuraj Linkeš "then use the commit ID with this option.", 194680d8a24SJuraj Linkeš ) 195680d8a24SJuraj Linkeš 196680d8a24SJuraj Linkeš parser.add_argument( 197680d8a24SJuraj Linkeš "--compile-timeout", 198*4a4678c7SJuraj Linkeš default=env_arg("DTS_COMPILE_TIMEOUT", SETTINGS.compile_timeout), 199680d8a24SJuraj Linkeš type=float, 200680d8a24SJuraj Linkeš help="[DTS_COMPILE_TIMEOUT] The timeout for compiling DPDK.", 201680d8a24SJuraj Linkeš ) 202680d8a24SJuraj Linkeš 2036fc05ca7SJuraj Linkeš parser.add_argument( 204*4a4678c7SJuraj Linkeš "--test-suite", 205*4a4678c7SJuraj Linkeš action="append", 206*4a4678c7SJuraj Linkeš nargs="+", 207*4a4678c7SJuraj Linkeš metavar=("TEST_SUITE", "TEST_CASES"), 208*4a4678c7SJuraj Linkeš default=env_arg("DTS_TEST_SUITES", SETTINGS.test_suites), 209*4a4678c7SJuraj Linkeš help="[DTS_TEST_SUITES] A list containing a test suite with test cases. " 210*4a4678c7SJuraj Linkeš "The first parameter is the test suite name, and the rest are test case names, " 211*4a4678c7SJuraj Linkeš "which are optional. May be specified multiple times. To specify multiple test suites in " 212*4a4678c7SJuraj Linkeš "the environment variable, join the lists with a comma. " 213*4a4678c7SJuraj Linkeš "Examples: " 214*4a4678c7SJuraj Linkeš "--test-suite suite case case --test-suite suite case ... | " 215*4a4678c7SJuraj Linkeš "DTS_TEST_SUITES='suite case case, suite case, ...' | " 216*4a4678c7SJuraj Linkeš "--test-suite suite --test-suite suite case ... | " 217*4a4678c7SJuraj Linkeš "DTS_TEST_SUITES='suite, suite case, ...'", 2186fc05ca7SJuraj Linkeš ) 2196fc05ca7SJuraj Linkeš 2206fc05ca7SJuraj Linkeš parser.add_argument( 2216fc05ca7SJuraj Linkeš "--re-run", 2226fc05ca7SJuraj Linkeš "--re_run", 223*4a4678c7SJuraj Linkeš default=env_arg("DTS_RERUN", SETTINGS.re_run), 2246fc05ca7SJuraj Linkeš type=int, 2256ef07151SJuraj Linkeš help="[DTS_RERUN] Re-run each test case the specified number of times " 226*4a4678c7SJuraj Linkeš "if a test failure occurs.", 2276fc05ca7SJuraj Linkeš ) 2286fc05ca7SJuraj Linkeš 229995fb337SOwen Hilyard return parser 230995fb337SOwen Hilyard 231995fb337SOwen Hilyard 232*4a4678c7SJuraj Linkešdef _process_test_suites(args: str | list[list[str]]) -> list[TestSuiteConfig]: 233*4a4678c7SJuraj Linkeš """Process the given argument to a list of :class:`TestSuiteConfig` to execute. 234*4a4678c7SJuraj Linkeš 235*4a4678c7SJuraj Linkeš Args: 236*4a4678c7SJuraj Linkeš args: The arguments to process. The args is a string from an environment variable 237*4a4678c7SJuraj Linkeš or a list of from the user input containing tests suites with tests cases, 238*4a4678c7SJuraj Linkeš each of which is a list of [test_suite, test_case, test_case, ...]. 239*4a4678c7SJuraj Linkeš 240*4a4678c7SJuraj Linkeš Returns: 241*4a4678c7SJuraj Linkeš A list of test suite configurations to execute. 242*4a4678c7SJuraj Linkeš """ 243*4a4678c7SJuraj Linkeš if isinstance(args, str): 244*4a4678c7SJuraj Linkeš # Environment variable in the form of "suite case case, suite case, suite, ..." 245*4a4678c7SJuraj Linkeš args = [suite_with_cases.split() for suite_with_cases in args.split(",")] 246*4a4678c7SJuraj Linkeš 247*4a4678c7SJuraj Linkeš test_suites_to_run = [] 248*4a4678c7SJuraj Linkeš for suite_with_cases in args: 249*4a4678c7SJuraj Linkeš test_suites_to_run.append( 250*4a4678c7SJuraj Linkeš TestSuiteConfig(test_suite=suite_with_cases[0], test_cases=suite_with_cases[1:]) 251*4a4678c7SJuraj Linkeš ) 252*4a4678c7SJuraj Linkeš 253*4a4678c7SJuraj Linkeš return test_suites_to_run 254*4a4678c7SJuraj Linkeš 255*4a4678c7SJuraj Linkeš 256840b1e01SJuraj Linkešdef get_settings() -> Settings: 2576ef07151SJuraj Linkeš """Create new settings with inputs from the user. 2586ef07151SJuraj Linkeš 2596ef07151SJuraj Linkeš The inputs are taken from the command line and from environment variables. 260*4a4678c7SJuraj Linkeš 261*4a4678c7SJuraj Linkeš Returns: 262*4a4678c7SJuraj Linkeš The new settings object. 2636ef07151SJuraj Linkeš """ 264995fb337SOwen Hilyard parsed_args = _get_parser().parse_args() 265840b1e01SJuraj Linkeš return Settings( 266995fb337SOwen Hilyard config_file_path=parsed_args.config_file, 267179d7059SJuraj Linkeš output_dir=parsed_args.output_dir, 268680d8a24SJuraj Linkeš timeout=parsed_args.timeout, 269840b1e01SJuraj Linkeš verbose=parsed_args.verbose, 270840b1e01SJuraj Linkeš skip_setup=parsed_args.skip_setup, 271840b1e01SJuraj Linkeš dpdk_tarball_path=Path( 272840b1e01SJuraj Linkeš Path(DPDKGitTarball(parsed_args.tarball, parsed_args.output_dir)) 273c9d31a7eSJuraj Linkeš if not os.path.exists(parsed_args.tarball) 274840b1e01SJuraj Linkeš else Path(parsed_args.tarball) 275840b1e01SJuraj Linkeš ), 276680d8a24SJuraj Linkeš compile_timeout=parsed_args.compile_timeout, 277*4a4678c7SJuraj Linkeš test_suites=_process_test_suites(parsed_args.test_suite), 2786fc05ca7SJuraj Linkeš re_run=parsed_args.re_run, 279995fb337SOwen Hilyard ) 280