diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 85b7cdb371e10..765d3d4d12cff 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -620,6 +620,13 @@ def add_parse_arguments(parser = None): environment.options object in twister.json. Default: show only non-default settings. """) + parser.add_argument( + "--report-kconfig-symbols", + action="store_true", + help="""Report Kconfig symbols applied on build (listed in `.config` file) + in twister.json as `kconfig` property of test suites selected. Default: not reported. + """) + parser.add_argument( "--retry-failed", type=int, default=0, help="Retry failing tests again, up to the number of times specified.") diff --git a/scripts/pylib/twister/twisterlib/reports.py b/scripts/pylib/twister/twisterlib/reports.py index 48c9df082c486..1e607db5ef19a 100644 --- a/scripts/pylib/twister/twisterlib/reports.py +++ b/scripts/pylib/twister/twisterlib/reports.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # vim: set syntax=python ts=4 : # -# Copyright (c) 2018 Intel Corporation +# Copyright (c) 2018-2024 Intel Corporation # SPDX-License-Identifier: Apache-2.0 import os @@ -321,6 +321,9 @@ def json_report(self, filename, version="NA", platform=None): suite["execution_time"] = f"{float(handler_time):.2f}" suite["build_time"] = f"{float(instance.build_time):.2f}" + if self.env.options.report_kconfig_symbols and instance.defconfig is not None: + suite["kconfig"] = instance.defconfig + testcases = [] if len(instance.testcases) == 1: diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index 7251f3f733ceb..9a65e6d52bcf6 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -233,7 +233,6 @@ def __init__(self, testsuite: TestSuite, platform: Platform, source_dir, build_d self.cwd = None self.capture_output = True - self.defconfig = {} self.cmake_cache = {} self.instance = None @@ -247,7 +246,8 @@ def __init__(self, testsuite: TestSuite, platform: Platform, source_dir, build_d self.jobserver = jobserver def parse_generated(self, filter_stages=[]): - self.defconfig = {} + if self.instance is not None: + self.instance.defconfig = {} return {} def run_build(self, args=[]): @@ -466,8 +466,8 @@ def parse_generated(self, filter_stages=[]): if not filter_stages or "kconfig" in filter_stages: + defconfig = {} with open(defconfig_path, "r") as fp: - defconfig = {} for line in fp.readlines(): m = self.config_re.match(line) if not m: @@ -476,7 +476,7 @@ def parse_generated(self, filter_stages=[]): continue defconfig[m.group(1)] = m.group(2).strip() - self.defconfig = defconfig + self.instance.defconfig = dict(sorted(defconfig.items())) cmake_conf = {} try: @@ -495,7 +495,7 @@ def parse_generated(self, filter_stages=[]): } filter_data.update(os.environ) if not filter_stages or "kconfig" in filter_stages: - filter_data.update(self.defconfig) + filter_data.update(self.instance.defconfig) filter_data.update(self.cmake_cache) if self.testsuite.sysbuild and self.env.options.device_testing: @@ -1116,8 +1116,8 @@ def run(self): if(self.options.seed is not None and instance.platform.name.startswith("native_")): self.parse_generated() - if('CONFIG_FAKE_ENTROPY_NATIVE_POSIX' in self.defconfig and - self.defconfig['CONFIG_FAKE_ENTROPY_NATIVE_POSIX'] == 'y'): + if('CONFIG_FAKE_ENTROPY_NATIVE_POSIX' in instance.defconfig and + instance.defconfig['CONFIG_FAKE_ENTROPY_NATIVE_POSIX'] == 'y'): instance.handler.seed = self.options.seed if self.options.extra_test_args and instance.platform.arch == "posix": diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index fb0fc1d909b48..14936f5f137b0 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -49,6 +49,7 @@ def __init__(self, testsuite, platform, outdir): self.status = None self.reason = "Unknown" self.metrics = dict() + self.defconfig = None self.handler = None self.recording = None self.outdir = outdir diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index 592d2c6304208..5da5cffda8d16 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -240,9 +240,11 @@ def test_cmake_parse_generated(mocked_jobserver): cmake = CMake(testsuite_mock, platform_mock, source_dir, build_dir, mocked_jobserver) + cmake.instance = mock.Mock() + result = cmake.parse_generated() - assert cmake.defconfig == {} + assert cmake.instance.defconfig == {} assert result == {} @@ -498,7 +500,7 @@ def mock_popen(*args, **kwargs): TESTDATA_3 = [ ('unit_testing', [], False, True, None, True, None, True, - None, None, {}, {}, None, None, [], {}), + None, None, None, {}, None, None, [], {}), ( 'other', [], True, True, ['dummy', 'west', 'options'], True, @@ -534,7 +536,7 @@ def mock_popen(*args, **kwargs): 'Dummy parse results', True, None, os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), - {}, + None, {}, {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True}, b'dummy edt pickle contents', @@ -547,7 +549,7 @@ def mock_popen(*args, **kwargs): 'Dummy parse results', True, None, None, - {}, + None, {}, {}, None, @@ -560,7 +562,7 @@ def mock_popen(*args, **kwargs): 'Dummy parse results', True, None, None, - {}, + None, {'dummy cache elem': 1}, {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, 'dummy cache elem': 1}, @@ -574,7 +576,7 @@ def mock_popen(*args, **kwargs): 'Dummy parse results', True, None, os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), - {}, + None, {'dummy cache elem': 1}, {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, 'dummy cache elem': 1}, @@ -588,7 +590,7 @@ def mock_popen(*args, **kwargs): None, True, None, os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), - {}, + None, {'dummy cache elem': 1}, {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, 'dummy cache elem': 1}, @@ -602,7 +604,7 @@ def mock_popen(*args, **kwargs): 'Dummy parse results', False, None, os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), - {}, + None, {'dummy cache elem': 1}, {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, 'dummy cache elem': 1}, @@ -617,7 +619,7 @@ def mock_popen(*args, **kwargs): SyntaxError, True, None, os.path.join('build', 'dir', 'zephyr', 'edt.pickle'), - {}, + None, {'dummy cache elem': 1}, {'ARCH': 'dummy arch', 'PLATFORM': 'other', 'env_dummy': True, 'dummy cache elem': 1}, @@ -711,6 +713,7 @@ def mock_pickle(datafile): mocked_jobserver) instance_mock = mock.Mock() fb.instance = instance_mock + fb.instance.defconfig = None fb.env = mock.Mock() fb.env.options = mock.Mock() fb.env.options.west_flash = west_flash_options @@ -738,7 +741,7 @@ def mock_pickle(datafile): assert all([log in caplog.text for log in expected_logs]) - assert fb.defconfig == expected_defconfig + assert fb.instance.defconfig == expected_defconfig assert fb.cmake_cache == expected_cmakecache @@ -2237,7 +2240,7 @@ def mock_harness(name): pb.options.extra_test_args = ['dummy_arg1', 'dummy_arg2'] pb.duts = ['another dut'] pb.options.seed = seed - pb.defconfig = defconfig + pb.instance.defconfig = defconfig pb.parse_generated = mock.Mock() with mock.patch('twisterlib.runner.HarnessImporter.get_harness',