Commit bae4c0c3 authored by Vincent Stehlé's avatar Vincent Stehlé
Browse files

Merge branch 'vincent/for-merge' into 'main'

Colors and plurals

See merge request !8
parents b9839848 432ad305
...@@ -36,8 +36,8 @@ command. The parsed report can be found in `result.md`. ...@@ -36,8 +36,8 @@ command. The parsed report can be found in `result.md`.
$ ./parser.py \ $ ./parser.py \
</path/to/sct_results/Overall/Summary.ekl> \ </path/to/sct_results/Overall/Summary.ekl> \
contrib/v21.07_0.9_BETA/EBBR.seq contrib/v21.07_0.9_BETA/EBBR.seq
INFO apply_rules: Updated 200 test(s) out of 12206 after applying 124 rule(s) INFO apply_rules: Updated 200 tests out of 12206 after applying 124 rules
INFO main: 0 dropped(s), 1 failure(s), 93 ignored(s), 106 known u-boot limitation(s), 12006 pass(s), 0 warning(s) INFO main: 0 dropped, 1 failure, 93 ignored, 106 known u-boot limitations, 12006 pass, 0 warning
``` ```
(The `EBBR.yaml' configuration file is used to process results by default.) (The `EBBR.yaml' configuration file is used to process results by default.)
......
...@@ -10,6 +10,7 @@ import json ...@@ -10,6 +10,7 @@ import json
import re import re
import hashlib import hashlib
import os import os
import curses
try: try:
from packaging import version from packaging import version
...@@ -36,6 +37,34 @@ if 'packaging.version' in sys.modules and \ ...@@ -36,6 +37,34 @@ if 'packaging.version' in sys.modules and \
else: else:
yaml_load_args = {} yaml_load_args = {}
# Colors
normal = ''
red = ''
yellow = ''
green = ''
if os.isatty(sys.stdout.fileno()):
curses.setupterm()
setafb = curses.tigetstr('setaf') or ''
setaf = setafb.decode()
normal = curses.tigetstr('sgr0').decode() or ''
red = curses.tparm(setafb, curses.COLOR_RED).decode() or ''
yellow = curses.tparm(setafb, curses.COLOR_YELLOW).decode() or ''
green = curses.tparm(setafb, curses.COLOR_GREEN).decode() or ''
# Compute the plural of a word.
def maybe_plural(n, word):
if n < 2:
return word
ll = word[len(word) - 1].lower()
if ll == 'd' or ll == 's':
return word
else:
return f'{word}s'
# based loosley on https://stackoverflow.com/a/4391978 # based loosley on https://stackoverflow.com/a/4391978
# returns a filtered dict of dicts that meet some Key-value pair. # returns a filtered dict of dicts that meet some Key-value pair.
...@@ -145,8 +174,9 @@ def ekl_parser(file): ...@@ -145,8 +174,9 @@ def ekl_parser(file):
temp_list.append(tmp_dict) temp_list.append(tmp_dict)
n += 1 n += 1
except Exception: except Exception:
print(f"Line {i+1}:", split_line) logging.error(f"Line {i+1}: {split_line}")
sys.exit("your log may be corrupted") logging.error("your log may be corrupted")
sys.exit(1)
else: else:
logging.error(f"Unparsed line {i} `{line}'") logging.error(f"Unparsed line {i} `{line}'")
...@@ -163,7 +193,8 @@ def seq_parser(file): ...@@ -163,7 +193,8 @@ def seq_parser(file):
magic = 7 magic = 7
# a test in a seq file is 7 lines, if not mod7, something wrong.. # a test in a seq file is 7 lines, if not mod7, something wrong..
if len(lines) % magic != 0: if len(lines) % magic != 0:
sys.exit("seqfile cut short, should be mod7") logging.error("seqfile cut short, should be mod7")
sys.exit(1)
# the utf-16 char makes this looping a bit harder, so we use x+(i) where i # the utf-16 char makes this looping a bit harder, so we use x+(i) where i
# is next 0-6th # is next 0-6th
# loop ever "7 lines" # loop ever "7 lines"
...@@ -322,7 +353,8 @@ def apply_rules(cross_check, conf): ...@@ -322,7 +353,8 @@ def apply_rules(cross_check, conf):
if n: if n:
r = len(conf) r = len(conf)
logging.info( logging.info(
f'Updated {n} test(s) out of {s} after applying {r} rule(s)') f"Updated {n} {maybe_plural(n, 'test')} out of {s}"
f" after applying {r} {maybe_plural(r, 'rule')}")
# Use YAML configuration file and perform all the transformations described in # Use YAML configuration file and perform all the transformations described in
...@@ -357,7 +389,8 @@ def filter_data(cross_check, Filter): ...@@ -357,7 +389,8 @@ def filter_data(cross_check, Filter):
r = list(filter(function, cross_check)) r = list(filter(function, cross_check))
after = len(r) after = len(r)
logging.info(f"Filtered out {before - after} test(s), kept {after}") n = before - after
logging.info(f"Filtered out {n} {maybe_plural(n, 'test')}, kept {after}")
return r return r
...@@ -764,6 +797,29 @@ def read_md(input_md): ...@@ -764,6 +797,29 @@ def read_md(input_md):
return cross_check return cross_check
# Print a one-line summary
# We know how to colorize some categories when they are non-zero.
def print_summary(bins, res_keys):
colors = {
'DROPPED': red,
'FAILURE': red,
'PASS': green,
'SKIPPED': yellow,
'WARNING': yellow,
}
d = {}
for k in res_keys:
n = len(bins[k])
d[k] = f'{n} {maybe_plural(n, k.lower())}'
if n > 0 and k in colors:
d[k] = f'{colors[k]}{d[k]}{normal}'
logging.info(', '.join(map(lambda k: d[k], sorted(res_keys))))
if __name__ == '__main__': if __name__ == '__main__':
me = os.path.realpath(__file__) me = os.path.realpath(__file__)
here = os.path.dirname(me) here = os.path.dirname(me)
...@@ -817,6 +873,11 @@ if __name__ == '__main__': ...@@ -817,6 +873,11 @@ if __name__ == '__main__':
format='%(levelname)s %(funcName)s: %(message)s', format='%(levelname)s %(funcName)s: %(message)s',
level=logging.DEBUG if args.debug else logging.INFO) level=logging.DEBUG if args.debug else logging.INFO)
ln = logging.getLevelName(logging.WARNING)
logging.addLevelName(logging.WARNING, f"{yellow}{ln}{normal}")
ln = logging.getLevelName(logging.ERROR)
logging.addLevelName(logging.ERROR, f"{red}{ln}{normal}")
if args.input_md is not None: if args.input_md is not None:
cross_check = read_md(args.input_md) cross_check = read_md(args.input_md)
else: else:
...@@ -860,11 +921,7 @@ if __name__ == '__main__': ...@@ -860,11 +921,7 @@ if __name__ == '__main__':
bins[k] = key_value_find(cross_check, "result", k) bins[k] = key_value_find(cross_check, "result", k)
# Print a one-line summary # Print a one-line summary
s = map( print_summary(bins, res_keys)
lambda k: '{} {}(s)'.format(len(bins[k]), k.lower()),
sorted(res_keys))
logging.info(', '.join(s))
# generate MD summary # generate MD summary
# As a special case, we skip generation when we are reading from a markdown # As a special case, we skip generation when we are reading from a markdown
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment