xref: /dpdk/dts/framework/settings.py (revision da7e701151ea8b742d4c38ace3e4fefd1b4507fc)
1# SPDX-License-Identifier: BSD-3-Clause
2# Copyright(c) 2010-2021 Intel Corporation
3# Copyright(c) 2022-2023 PANTHEON.tech s.r.o.
4# Copyright(c) 2022 University of New Hampshire
5
6import argparse
7import os
8from collections.abc import Callable, Iterable, Sequence
9from dataclasses import dataclass
10from pathlib import Path
11from typing import Any, TypeVar
12
13from .utils import DPDKGitTarball
14
15_T = TypeVar("_T")
16
17
18def _env_arg(env_var: str) -> Any:
19    class _EnvironmentArgument(argparse.Action):
20        def __init__(
21            self,
22            option_strings: Sequence[str],
23            dest: str,
24            nargs: str | int | None = None,
25            const: str | None = None,
26            default: str = None,
27            type: Callable[[str], _T | argparse.FileType | None] = None,
28            choices: Iterable[_T] | None = None,
29            required: bool = False,
30            help: str | None = None,
31            metavar: str | tuple[str, ...] | None = None,
32        ) -> None:
33            env_var_value = os.environ.get(env_var)
34            default = env_var_value or default
35            super(_EnvironmentArgument, self).__init__(
36                option_strings,
37                dest,
38                nargs=nargs,
39                const=const,
40                default=default,
41                type=type,
42                choices=choices,
43                required=required,
44                help=help,
45                metavar=metavar,
46            )
47
48        def __call__(
49            self,
50            parser: argparse.ArgumentParser,
51            namespace: argparse.Namespace,
52            values: Any,
53            option_string: str = None,
54        ) -> None:
55            setattr(namespace, self.dest, values)
56
57    return _EnvironmentArgument
58
59
60@dataclass(slots=True, frozen=True)
61class _Settings:
62    config_file_path: str
63    output_dir: str
64    timeout: float
65    verbose: bool
66    skip_setup: bool
67    dpdk_tarball_path: Path
68    compile_timeout: float
69    test_cases: list
70    re_run: int
71
72
73def _get_parser() -> argparse.ArgumentParser:
74    parser = argparse.ArgumentParser(
75        description="Run DPDK test suites. All options may be specified with "
76        "the environment variables provided in brackets. "
77        "Command line arguments have higher priority.",
78        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
79    )
80
81    parser.add_argument(
82        "--config-file",
83        action=_env_arg("DTS_CFG_FILE"),
84        default="conf.yaml",
85        help="[DTS_CFG_FILE] configuration file that describes the test cases, SUTs "
86        "and targets.",
87    )
88
89    parser.add_argument(
90        "--output-dir",
91        "--output",
92        action=_env_arg("DTS_OUTPUT_DIR"),
93        default="output",
94        help="[DTS_OUTPUT_DIR] Output directory where dts logs and results are saved.",
95    )
96
97    parser.add_argument(
98        "-t",
99        "--timeout",
100        action=_env_arg("DTS_TIMEOUT"),
101        default=15,
102        type=float,
103        help="[DTS_TIMEOUT] The default timeout for all DTS operations except for "
104        "compiling DPDK.",
105    )
106
107    parser.add_argument(
108        "-v",
109        "--verbose",
110        action=_env_arg("DTS_VERBOSE"),
111        default="N",
112        help="[DTS_VERBOSE] Set to 'Y' to enable verbose output, logging all messages "
113        "to the console.",
114    )
115
116    parser.add_argument(
117        "-s",
118        "--skip-setup",
119        action=_env_arg("DTS_SKIP_SETUP"),
120        default="N",
121        help="[DTS_SKIP_SETUP] Set to 'Y' to skip all setup steps on SUT and TG nodes.",
122    )
123
124    parser.add_argument(
125        "--tarball",
126        "--snapshot",
127        "--git-ref",
128        action=_env_arg("DTS_DPDK_TARBALL"),
129        default="dpdk.tar.xz",
130        type=Path,
131        help="[DTS_DPDK_TARBALL] Path to DPDK source code tarball or a git commit ID, "
132        "tag ID or tree ID to test. To test local changes, first commit them, "
133        "then use the commit ID with this option.",
134    )
135
136    parser.add_argument(
137        "--compile-timeout",
138        action=_env_arg("DTS_COMPILE_TIMEOUT"),
139        default=1200,
140        type=float,
141        help="[DTS_COMPILE_TIMEOUT] The timeout for compiling DPDK.",
142    )
143
144    parser.add_argument(
145        "--test-cases",
146        action=_env_arg("DTS_TESTCASES"),
147        default="",
148        help="[DTS_TESTCASES] Comma-separated list of test cases to execute. "
149        "Unknown test cases will be silently ignored.",
150    )
151
152    parser.add_argument(
153        "--re-run",
154        "--re_run",
155        action=_env_arg("DTS_RERUN"),
156        default=0,
157        type=int,
158        help="[DTS_RERUN] Re-run each test case the specified amount of times "
159        "if a test failure occurs",
160    )
161
162    return parser
163
164
165def _get_settings() -> _Settings:
166    parsed_args = _get_parser().parse_args()
167    return _Settings(
168        config_file_path=parsed_args.config_file,
169        output_dir=parsed_args.output_dir,
170        timeout=parsed_args.timeout,
171        verbose=(parsed_args.verbose == "Y"),
172        skip_setup=(parsed_args.skip_setup == "Y"),
173        dpdk_tarball_path=Path(
174            DPDKGitTarball(parsed_args.tarball, parsed_args.output_dir)
175        )
176        if not os.path.exists(parsed_args.tarball)
177        else Path(parsed_args.tarball),
178        compile_timeout=parsed_args.compile_timeout,
179        test_cases=parsed_args.test_cases.split(",") if parsed_args.test_cases else [],
180        re_run=parsed_args.re_run,
181    )
182
183
184SETTINGS: _Settings = _get_settings()
185