diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 315145b78c51b18..a88fe7534452773 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -717,8 +717,13 @@ def add_parse_arguments(parser = None): "--verbose", action="count", default=0, - help="Emit debugging information, call multiple times to increase " - "verbosity.") + help="Call multiple times to increase verbosity.") + + parser.add_argument( + "-d", + "--debug", + action="store_true", + help="Emit debugging information.") parser.add_argument("-W", "--disable-warnings-as-errors", action="store_true", help="Do not treat warning conditions as errors.") diff --git a/scripts/pylib/twister/twisterlib/runner.py b/scripts/pylib/twister/twisterlib/runner.py index d0023afdd62e184..77cec9b5670c96f 100644 --- a/scripts/pylib/twister/twisterlib/runner.py +++ b/scripts/pylib/twister/twisterlib/runner.py @@ -1110,6 +1110,13 @@ def report_out(self, results): results.done, total_tests_width, total_to_do , instance.platform.name, instance.testsuite.name, status, more_info)) + if self.options.verbose > 1: + for tc in self.instance.testcases: + color = TwisterStatus.get_color(tc.status) + logger.info(f' {" ":<{total_tests_width+25+4}} {tc.name:<75} ' + f'{color}{str.upper(tc.status.value):<12}{Fore.RESET}' + f'{" " + tc.reason if tc.reason else ""}') + if instance.status in [TwisterStatus.ERROR, TwisterStatus.FAIL]: self.log_info_file(self.options.inline_logs) else: diff --git a/scripts/pylib/twister/twisterlib/statuses.py b/scripts/pylib/twister/twisterlib/statuses.py index 7297d7615d7014b..6588a87014a2a58 100644 --- a/scripts/pylib/twister/twisterlib/statuses.py +++ b/scripts/pylib/twister/twisterlib/statuses.py @@ -5,7 +5,9 @@ """ Status classes to be used instead of str statuses. """ +from __future__ import annotations +from colorama import Fore from enum import Enum @@ -13,6 +15,21 @@ class TwisterStatus(str, Enum): def __str__(self): return str(self.value) + @staticmethod + def get_color(status: TwisterStatus) -> str: + match(status): + case TwisterStatus.PASS: + color = Fore.GREEN + case TwisterStatus.SKIP | TwisterStatus.FILTER | TwisterStatus.BLOCK: + color = Fore.YELLOW + case TwisterStatus.FAIL | TwisterStatus.ERROR: + color = Fore.RED + case TwisterStatus.STARTED | TwisterStatus.NONE: + color = Fore.MAGENTA + case _: + color = Fore.RESET + return color + # All statuses below this comment can be used for TestCase BLOCK = 'blocked' STARTED = 'started' diff --git a/scripts/pylib/twister/twisterlib/twister_main.py b/scripts/pylib/twister/twisterlib/twister_main.py index d2699ad49867e1f..b1975ba71b547fa 100644 --- a/scripts/pylib/twister/twisterlib/twister_main.py +++ b/scripts/pylib/twister/twisterlib/twister_main.py @@ -26,7 +26,7 @@ logger.setLevel(logging.DEBUG) -def setup_logging(outdir, log_file, verbose, timestamps): +def setup_logging(outdir, log_file, debug, timestamps): # create file handler which logs even debug messages if log_file: fh = logging.FileHandler(log_file) @@ -38,7 +38,7 @@ def setup_logging(outdir, log_file, verbose, timestamps): # create console handler with a higher log level ch = logging.StreamHandler() - if verbose > 1: + if debug: ch.setLevel(logging.DEBUG) else: ch.setLevel(logging.INFO) @@ -108,7 +108,7 @@ def main(options: argparse.Namespace, default_options: argparse.Namespace): fp.write(previous_results) VERBOSE = options.verbose - setup_logging(options.outdir, options.log_file, VERBOSE, options.timestamps) + setup_logging(options.outdir, options.log_file, options.debug, options.timestamps) env = TwisterEnv(options, default_options) env.discover() diff --git a/scripts/tests/twister/test_runner.py b/scripts/tests/twister/test_runner.py index 9cd4c2a8d80d1e3..8d7973f5e0554da 100644 --- a/scripts/tests/twister/test_runner.py +++ b/scripts/tests/twister/test_runner.py @@ -2008,9 +2008,13 @@ def test_projectbuilder_report_out( instance_mock.status = status instance_mock.reason = 'dummy reason' instance_mock.testsuite.name = 'dummy.testsuite.name' - instance_mock.testsuite.testcases = [mock.Mock() for _ in range(25)] - instance_mock.testcases = [mock.Mock() for _ in range(24)] + \ - [mock.Mock(status=TwisterStatus.SKIP)] + skip_mock_tc = mock.Mock(status=TwisterStatus.SKIP, reason='?') + skip_mock_tc.name = '?' + unknown_mock_tc = mock.Mock(status=mock.Mock(value='?'), reason='?') + unknown_mock_tc.name = '?' + instance_mock.testsuite.testcases = [unknown_mock_tc for _ in range(25)] + instance_mock.testcases = [unknown_mock_tc for _ in range(24)] + \ + [skip_mock_tc] env_mock = mock.Mock() pb = ProjectBuilder(instance_mock, env_mock, mocked_jobserver)