-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
scripts: twister: Add TestCase status and reason printing #78345
scripts: twister: Add TestCase status and reason printing #78345
Conversation
0795f79
to
acd4a7a
Compare
looks nice, but very busy, wonder if we should have this appear in verbosity level 2(-vv) instead of first (-v) and add a debug flag to replace level 2 now (-vv). |
acd4a7a
to
618d614
Compare
Incorporated the suggestions. Waiting for the test results. |
"verbosity.") | ||
help="Call multiple times to increase verbosity.") | ||
|
||
parser.add_argument( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change should be a separate PR as it affects current output not only for TestCase statuses.
Also something is missing in this change, like this debug output:
zephyr/scripts/pylib/twister/twisterlib/twister_main.py
Lines 139 to 157 in 23eca63
if VERBOSE > 1: | |
# if we are using command line platform filter, no need to list every | |
# other platform as excluded, we know that already. | |
# Show only the discards that apply to the selected platforms on the | |
# command line | |
for i in tplan.instances.values(): | |
if i.status == TwisterStatus.FILTER: | |
if options.platform and i.platform.name not in options.platform: | |
continue | |
logger.debug( | |
"{:<25} {:<50} {}SKIPPED{}: {}".format( | |
i.platform.name, | |
i.testsuite.name, | |
Fore.YELLOW, | |
Fore.RESET, | |
i.reason, | |
) | |
) |
IMO multi -v
command line options is more convenient way to set logging levels, whereas -d
has so many different meanings including --debug
as a special mode of program execution, not just extended log output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that at its core, coupling together debug level and verbosity while not committing to either one is hurting us in the long run.
We use both 'naked' verbosity checks and debug log levels while disallowing specifying them separately. That's not great.
We should either
- fully ditch verbosity checks in the code and replace them with custom logging levels enabled by specific verbosity levels
- add log level flag in the CLI to enable DEBUG level and still use verbosity to indicate how much information of any level one would like to have.
Given our current approach, the second option is closer to what we currently have. It should probably be in a separate PR.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't dictionary lookup simpler for this purpose ?
just thinking of something like
return status2color[status] if status in status2color else Fore.RESET
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be less concise, as I wouldn't be able to use ORs (|
) in the dictionary definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be less concise, as I wouldn't be able to use ORs (
|
) in the dictionary definition.
hmm, less concise ? I think this is more pythonic way, and you can even have another palette (grayscale), set it off assigning None, etc.
status2color = { TwisterStatus.PASS: Fore.GREEN,
TwisterStatus.SKIP: Fore.YELLOW,
TwisterStatus.FILTER: Fore.YELLOW,
TwisterStatus.BLOCK: Fore.YELLOW,
TwisterStatus.FAIL: Fore.RED,
TwisterStatus.ERROR: Fore.RED,
TwisterStatus.STARTED: Fore.MAGENTA,
TwisterStatus.NONE: Fore.MAGENTA
}
besides, no problem, just imo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe concise wasn't the right word - the Status-Colour relationship is a many-to-one relationship (many statuses can have the same colour), which is immediately apparent in match-case
structure. Dictionary is an inherently one-to-one structure (one value for one key). This necessitates repeating colours (YELLOW three times, RED two, MAGENTA two) and it's a bit harder to get information of type "Which Statuses can be yellow?"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and it's a bit harder to get information of type "Which Statuses can be yellow?"
yeah, in case of the match/case construct it is even harder: it needs to be executed for all statuses first to build status2color{} and filter it on values=='yellow'.
618d614
to
2b338c5
Compare
When at verbosity 1, we print out the status of TestInstances. This makes it harder to notice changes at TestCase level, which require perusing the logs. This adds TestCase status and reason printing if verbosity level is 2 or more. Reason printing is suppressed if the reason is empty or None. Signed-off-by: Lukasz Mrugala <[email protected]>
2b338c5
to
8a30029
Compare
@@ -19,6 +21,21 @@ def _missing_(cls, value): | |||
if value is None: | |||
return TwisterStatus.NONE | |||
|
|||
@staticmethod | |||
def get_color(status: TwisterStatus) -> str: | |||
match(status): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: If you use match
keyword, than Twister requires Python 3.10. Therefore, using from __future__ import annotations
does not have any sense (it enables some type annotations for lower versions of python)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just mentioned that, because couple days ago @golowanow added PR to still have possibility to run Twister with Python 3.8: #77077
With match
keyword it is not possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just ran into this on macOS:
❯ scripts/twister --help
ZEPHYR_BASE unset, using "/Users/johedber/src/zephyr/zephyr"
Traceback (most recent call last):
File "/Users/johedber/src/zephyr/zephyr/scripts/twister", line 207, in <module>
from twisterlib.twister_main import main
File "/Users/johedber/src/zephyr/zephyr/scripts/pylib/twister/twisterlib/twister_main.py", line 16, in <module>
from twisterlib.statuses import TwisterStatus
File "/Users/johedber/src/zephyr/zephyr/scripts/pylib/twister/twisterlib/statuses.py", line 26
match(status):
^
SyntaxError: invalid syntax
❯ which python3
/usr/bin/python3
❯ python3 --version
Python 3.9.6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: If you use
match
keyword, than Twister requires Python 3.10. Therefore, usingfrom __future__ import annotations
does not have any sense (it enables some type annotations for lower versions of python)
You are right - I've used it to change TwisterStatus
type hint into Self
- it seems I didn't upstream it. My bad.
When it comes to Python<3.10 support - Zephyr does not claim to support it since 3.7.0 LTS (Python 3.10 is listed as minimum requirement), so I do not pay older versions special consideration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When it comes to Python<3.10 support - Zephyr does not claim to support it since 3.7.0
the problem is confusing user experience to get SyntaxError just for twister --help
now.
When at verbosity 1, we print out the status of TestInstances. However, we omit the TestCases in that print-out. This makes it harder to notice changes at TestCase level, which require perusing the logs.
This PR adds TestCase status and reason printing at verbosity level 2. Reason printing is suppressed if the reason in
None
or empty.Visual example: