twister: Add Twister execution options to twister.json

Store Twister command line options in twister.json report as
`environment.options` object. It allows to keep the actual
execution context for test results analysis and history comparison.

A new command line option `--report-all-options` enables to report all
command line options applied, including these set as default values.

Signed-off-by: Dmitrii Golovanov <dmitrii.golovanov@intel.com>
This commit is contained in:
Dmitrii Golovanov 2024-05-07 09:11:47 +02:00 committed by Alberto Escolar
commit d45dbc26f0
4 changed files with 40 additions and 8 deletions

View file

@ -614,6 +614,12 @@ structure in the main Zephyr tree: boards/<arch>/<board_name>/""")
version or a commit ID.
""")
parser.add_argument(
"--report-all-options", action="store_true",
help="""Show all command line options applied, including defaults, as
environment.options object in twister.json. Default: show only non-default settings.
""")
parser.add_argument(
"--retry-failed", type=int, default=0,
help="Retry failing tests again, up to the number of times specified.")
@ -744,7 +750,7 @@ structure in the main Zephyr tree: boards/<arch>/<board_name>/""")
return parser
def parse_arguments(parser, args, options = None):
def parse_arguments(parser, args, options = None, on_init=True):
if options is None:
options = parser.parse_args(args)
@ -862,13 +868,13 @@ def parse_arguments(parser, args, options = None):
# Strip off the initial "--" following validation.
options.extra_test_args = options.extra_test_args[1:]
if not options.allow_installed_plugin and PYTEST_PLUGIN_INSTALLED:
if on_init and not options.allow_installed_plugin and PYTEST_PLUGIN_INSTALLED:
logger.error("By default Twister should work without pytest-twister-harness "
"plugin being installed, so please, uninstall it by "
"`pip uninstall pytest-twister-harness` and `git clean "
"-dxf scripts/pylib/pytest-twister-harness`.")
sys.exit(1)
elif options.allow_installed_plugin and PYTEST_PLUGIN_INSTALLED:
elif on_init and options.allow_installed_plugin and PYTEST_PLUGIN_INSTALLED:
logger.warning("You work with installed version of "
"pytest-twister-harness plugin.")
@ -880,12 +886,13 @@ def strip_ansi_sequences(s: str) -> str:
class TwisterEnv:
def __init__(self, options=None) -> None:
def __init__(self, options=None, default_options=None) -> None:
self.version = "Unknown"
self.toolchain = None
self.commit_date = "Unknown"
self.run_date = None
self.options = options
self.default_options = default_options
if options and options.ninja:
self.generator_cmd = "ninja"
@ -920,6 +927,18 @@ class TwisterEnv:
self.alt_config_root = options.alt_config_root if options else None
def non_default_options(self) -> dict:
"""Returns current command line options which are set to non-default values."""
diff = {}
if not self.options or not self.default_options:
return diff
dict_options = vars(self.options)
dict_default = vars(self.default_options)
for k in dict_options.keys():
if k not in dict_default or dict_options[k] != dict_default[k]:
diff[k] = dict_options[k]
return diff
def discover(self):
self.check_zephyr_version()
self.get_toolchain()

View file

@ -11,6 +11,7 @@ from colorama import Fore
import xml.etree.ElementTree as ET
import string
from datetime import datetime
from pathlib import PosixPath
logger = logging.getLogger('twister')
logger.setLevel(logging.DEBUG)
@ -235,12 +236,23 @@ class Reporting:
def json_report(self, filename, version="NA", platform=None):
logger.info(f"Writing JSON report {filename}")
if self.env.options.report_all_options:
report_options = vars(self.env.options)
else:
report_options = self.env.non_default_options()
# Resolve known JSON serialization problems.
for k,v in report_options.items():
report_options[k] = str(v) if type(v) in [PosixPath] else v
report = {}
report["environment"] = {"os": os.name,
"zephyr_version": version,
"toolchain": self.env.toolchain,
"commit_date": self.env.commit_date,
"run_date": self.env.run_date
"run_date": self.env.run_date,
"options": report_options
}
suites = []

View file

@ -62,7 +62,7 @@ def init_color(colorama_strip):
colorama.init(strip=colorama_strip)
def main(options):
def main(options, default_options):
start_time = time.time()
# Configure color output
@ -105,7 +105,7 @@ def main(options):
VERBOSE = options.verbose
setup_logging(options.outdir, options.log_file, VERBOSE, options.timestamps)
env = TwisterEnv(options)
env = TwisterEnv(options, default_options)
env.discover()
hwm = HardwareMap(env)

View file

@ -211,7 +211,8 @@ if __name__ == "__main__":
try:
parser = add_parse_arguments()
options = parse_arguments(parser, sys.argv[1:])
ret = main(options)
default_options = parse_arguments(parser, [], on_init=False)
ret = main(options, default_options)
finally:
if (os.name != "nt") and os.isatty(1):
# (OS is not Windows) and (stdout is interactive)