From bf6153a7e0bcf247e3ae76de317e0f9d3d2fe263 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 26 Feb 2025 14:54:01 +0100 Subject: [PATCH 1/5] docker: virtme: switch to v1.33 The latest version, we don't need anything in particular from it. Link: https://github.com/arighi/virtme-ng/releases/tag/v1.33 Signed-off-by: Matthieu Baerts (NGI0) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 75a3b0b..98080ea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -87,7 +87,7 @@ RUN cd /opt && \ make install # Virtme NG -ARG VIRTME_NG_VERSION="1.32" +ARG VIRTME_NG_VERSION="1.33" RUN pip3 install --break-system-packages virtme-ng=="${VIRTME_NG_VERSION}" # to quickly shutdown the VM and more From be8fa1a2db3e2cd51beb676058b4369d44a9d87c Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Wed, 26 Feb 2025 14:57:16 +0100 Subject: [PATCH 2/5] kconfig: mute override errors When updating the config, 'virtme-configkernel' will launch 'make olddefconfig', which will produce a lot of warnings like this one: .config::warning: override: reassigning to symbol Mute stderr. There should not be other issues. If there are, they will continue to be caught, but not detailed. Signed-off-by: Matthieu Baerts (NGI0) --- entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.sh b/entrypoint.sh index 7d0da92..d3e58a8 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -687,7 +687,7 @@ gen_kconfig() { local mode kconfig=() vck rc=0 fi # KBUILD_OUTPUT is used by virtme - "${VIRTME_CONFIGKERNEL}" "${vck[@]}" "${MAKE_ARGS_O[@]}" || rc=${?} + "${VIRTME_CONFIGKERNEL}" "${vck[@]}" "${MAKE_ARGS_O[@]}" 2>/dev/null || rc=${?} ./scripts/config --file "${VIRTME_KCONFIG}" "${kconfig[@]}" || rc=${?} From 285b6a49f657d7d67f699398a047a59411a19dbf Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Tue, 4 Mar 2025 17:41:07 +0100 Subject: [PATCH 3/5] tap2json: switch to 4 spaces for the indentation Apparently preferred with Python scripts. Link: https://peps.python.org/pep-0008/#tabs-or-spaces Signed-off-by: Matthieu Baerts (NGI0) --- tap2json.py | 202 ++++++++++++++++++++++++++-------------------------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/tap2json.py b/tap2json.py index aa85413..582c5aa 100755 --- a/tap2json.py +++ b/tap2json.py @@ -14,138 +14,138 @@ def get_args_parser(): - parser = argparse.ArgumentParser( - description="(Simple) TAP to JSON converter" - ) - - parser.add_argument( - "--output", - "-o", - action="store", - help="Output JSON file" - ) - - parser.add_argument( - "--info", - "-I", - action="append", - metavar="key:value", - help="Add extra info in the JSON, can be used multiple times" - ) - - parser.add_argument( - "--only-fails", - "-f", - action="store_true", - help="Only keep failed tests" - ) - - parser.add_argument( - "tapfiles", - metavar="tapfiles", - type=str, - nargs="*", - help="Input TAP file(s)" - ) - - return parser + parser = argparse.ArgumentParser( + description="(Simple) TAP to JSON converter" + ) + + parser.add_argument( + "--output", + "-o", + action="store", + help="Output JSON file" + ) + + parser.add_argument( + "--info", + "-I", + action="append", + metavar="key:value", + help="Add extra info in the JSON, can be used multiple times" + ) + + parser.add_argument( + "--only-fails", + "-f", + action="store_true", + help="Only keep failed tests" + ) + + parser.add_argument( + "tapfiles", + metavar="tapfiles", + type=str, + nargs="*", + help="Input TAP file(s)" + ) + + return parser # Same as in NIPA TAP_RE = re.compile(r"(not )?ok (\d+)( -)? ([^#]*[^ ])( +# +)?([^ ].*)?$") TIME_RE = re.compile(r"time=([0-9.]+)ms") def parse_tap(tap, name, only_fails): - results = {} - has_results = False + results = {} + has_results = False - for line in tap: - try: - r = TAP_RE.match(line.rstrip()).groups() - except AttributeError: - continue + for line in tap: + try: + r = TAP_RE.match(line.rstrip()).groups() + except AttributeError: + continue - has_results = True + has_results = True - success = r[0] is None + success = r[0] is None - result = { - 'result': "pass" if success else "fail", - 'name': r[3] - } + result = { + 'result': "pass" if success else "fail", + 'name': r[3] + } - if r[4] and r[5]: - result['comment'] = r[5] - if success: - if r[5].lower().startswith('skip'): - result['result'] = "skip" - elif r[5].lower().startswith('ignore flaky'): - result['result'] = "flaky" + if r[4] and r[5]: + result['comment'] = r[5] + if success: + if r[5].lower().startswith('skip'): + result['result'] = "skip" + elif r[5].lower().startswith('ignore flaky'): + result['result'] = "flaky" - t = TIME_RE.findall(r[5].lower()) - if t: - result['time_ms'] = t[-1] # take the last one - result['comment'] = result['comment'].replace("time=" + result['time_ms'] + "ms", "").replace(" ", " ").strip() - if not result['comment']: - del result['comment'] + t = TIME_RE.findall(r[5].lower()) + if t: + result['time_ms'] = t[-1] # take the last one + result['comment'] = result['comment'].replace("time=" + result['time_ms'] + "ms", "").replace(" ", " ").strip() + if not result['comment']: + del result['comment'] - if only_fails and result['result'] == "pass": - continue + if only_fails and result['result'] == "pass": + continue - results[r[1]] = result + results[r[1]] = result - # just in case, to catch errors - if not has_results: - results[0] = {'result': "fail", 'name': name} + # just in case, to catch errors + if not has_results: + results[0] = {'result': "fail", 'name': name} - return results + return results def parse_all_tap(tap_files, only_fails): - results = {} + results = {} - for tap in tap_files: - name = os.path.splitext(os.path.basename(tap))[0] - with open(tap, "r", encoding="utf-8") as fd: - result = parse_tap(fd.readlines(), name, only_fails) - if result: - results[name] = result + for tap in tap_files: + name = os.path.splitext(os.path.basename(tap))[0] + with open(tap, "r", encoding="utf-8") as fd: + result = parse_tap(fd.readlines(), name, only_fails) + if result: + results[name] = result - return results + return results def add_info(results, infos): - results = { - "results": results - } + results = { + "results": results + } - for info in infos: - info = info.split(':', 1) - if len(info) != 2: - print("Skip info: " + info[0], file=sys.stderr) - continue + for info in infos: + info = info.split(':', 1) + if len(info) != 2: + print("Skip info: " + info[0], file=sys.stderr) + continue - results[info[0]] = info[1] + results[info[0]] = info[1] - return results + return results def write_json(out_file, results): - out = json.dumps(results) - if out_file: - with open(out_file, "w") as fd: - fd.write(out) - else: - print(out) + out = json.dumps(results) + if out_file: + with open(out_file, "w") as fd: + fd.write(out) + else: + print(out) if __name__ == "__main__": - arg_parser = get_args_parser() - args = arg_parser.parse_args() + arg_parser = get_args_parser() + args = arg_parser.parse_args() - if not args.tapfiles: - arg_parser.print_usage() - sys.exit(1) + if not args.tapfiles: + arg_parser.print_usage() + sys.exit(1) - results = parse_all_tap(args.tapfiles, args.only_fails) + results = parse_all_tap(args.tapfiles, args.only_fails) - if args.info: - results = add_info(results, args.info) + if args.info: + results = add_info(results, args.info) - write_json(args.output, results) + write_json(args.output, results) From 94db6604063a9bd04c7dbd1e422b3f9e13d939bd Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Tue, 4 Mar 2025 17:51:57 +0100 Subject: [PATCH 4/5] tap2json: fix style issues Found by Pylint and Flake8, e.g. - 2 blank lines after function definition - 2 spaces before inline comment - line too long - missing module docstring - redefining name 'results' from outer scope - force the output file encoding to the default utf-8 one. The "missing method or function docstring" has been ignored for the moment, their name is quite explicit and the script is small. Signed-off-by: Matthieu Baerts (NGI0) --- tap2json.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/tap2json.py b/tap2json.py index 582c5aa..a7cc68b 100755 --- a/tap2json.py +++ b/tap2json.py @@ -1,10 +1,14 @@ #! /usr/bin/python3 # SPDX-License-Identifier: GPL-2.0 -# -# Very simple TAP to JSON parser -# -# JQ can be used to filter tests later, e.g.abs -# $ jq '.results.[] | select(.[].result == "fail")' results.json + +""" +Very simple TAP to JSON parser + +JQ can be used to filter tests later, e.g.abs + $ jq '.results.[] | select(.[].result == "fail")' results.json +""" + +# pylint: disable=missing-function-docstring import argparse import json @@ -50,10 +54,12 @@ def get_args_parser(): return parser + # Same as in NIPA TAP_RE = re.compile(r"(not )?ok (\d+)( -)? ([^#]*[^ ])( +# +)?([^ ].*)?$") TIME_RE = re.compile(r"time=([0-9.]+)ms") + def parse_tap(tap, name, only_fails): results = {} has_results = False @@ -83,8 +89,10 @@ def parse_tap(tap, name, only_fails): t = TIME_RE.findall(r[5].lower()) if t: - result['time_ms'] = t[-1] # take the last one - result['comment'] = result['comment'].replace("time=" + result['time_ms'] + "ms", "").replace(" ", " ").strip() + result['time_ms'] = t[-1] # take the last one + result['comment'] = result['comment'] \ + .replace("time=" + result['time_ms'] + "ms", "") \ + .replace(" ", " ").strip() if not result['comment']: del result['comment'] @@ -112,6 +120,7 @@ def parse_all_tap(tap_files, only_fails): return results + def add_info(results, infos): results = { "results": results @@ -127,14 +136,16 @@ def add_info(results, infos): return results + def write_json(out_file, results): out = json.dumps(results) if out_file: - with open(out_file, "w") as fd: + with open(out_file, "w", encoding="utf-8") as fd: fd.write(out) else: print(out) + if __name__ == "__main__": arg_parser = get_args_parser() args = arg_parser.parse_args() @@ -143,9 +154,9 @@ def write_json(out_file, results): arg_parser.print_usage() sys.exit(1) - results = parse_all_tap(args.tapfiles, args.only_fails) + main_results = parse_all_tap(args.tapfiles, args.only_fails) if args.info: - results = add_info(results, args.info) + main_results = add_info(main_results, args.info) - write_json(args.output, results) + write_json(args.output, main_results) From 882fe60615fe18c44e8894432b44648378dab0d4 Mon Sep 17 00:00:00 2001 From: "Matthieu Baerts (NGI0)" Date: Tue, 4 Mar 2025 18:11:38 +0100 Subject: [PATCH 5/5] tap2json: do not fail when reading binary content Such content can be ignored (removed), it is not useful. Because of that, some errors were not reported. Signed-off-by: Matthieu Baerts (NGI0) --- tap2json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tap2json.py b/tap2json.py index a7cc68b..e5a8279 100755 --- a/tap2json.py +++ b/tap2json.py @@ -113,7 +113,7 @@ def parse_all_tap(tap_files, only_fails): for tap in tap_files: name = os.path.splitext(os.path.basename(tap))[0] - with open(tap, "r", encoding="utf-8") as fd: + with open(tap, "r", encoding="utf-8", errors='ignore') as fd: result = parse_tap(fd.readlines(), name, only_fails) if result: results[name] = result