From 3c22fea1c8afbdb05687d8437ea98c500f9abddc Mon Sep 17 00:00:00 2001 From: Naresh Kamboju Date: Wed, 19 Jun 2024 16:56:33 +0530 Subject: [PATCH] kvm-unit-tests: output test results in TAP13 format This patch introduces a new script, parse-output.py, to handle the parsing of KVM unit test outputs. The script reads input from the standard input, processes each line to determine the test result, and sanitizes test descriptions for consistent formatting. It supports parsing TAP13 output, identifying test results as pass, fail, or skip, and cleans up special characters from descriptions to ensure proper handling. By adding flag '-t|--tap13' to kvm-unit-tests run_tests.sh script, it menas that the test results output in a TAP13 format. e.g. --- .../linux/kvm-unit-tests/kvm-unit-tests.sh | 21 ++---- .../linux/kvm-unit-tests/parse-output.py | 68 +++++++++++++++++++ 2 files changed, 73 insertions(+), 16 deletions(-) create mode 100755 automated/linux/kvm-unit-tests/parse-output.py diff --git a/automated/linux/kvm-unit-tests/kvm-unit-tests.sh b/automated/linux/kvm-unit-tests/kvm-unit-tests.sh index f9c92fae4..57311d08f 100755 --- a/automated/linux/kvm-unit-tests/kvm-unit-tests.sh +++ b/automated/linux/kvm-unit-tests/kvm-unit-tests.sh @@ -27,26 +27,16 @@ while getopts "s:m:g:h" o; do done parse_output() { - # Parse each type of results - # A note on the sed line used below to strip color codes: - # busybox's sed does not implement e.g. '\x1b', and so the literal - # control code is used below. Do not copy/paste it, or it will lose - # its magic. - grep -e PASS -e SKIP -e FAIL "${RESULT_LOG}" | \ - sed 's/\[[0-9]*m//g' | \ - sed -e 's/PASS/pass/g' \ - -e 's/SKIP/skip/g' \ - -e 's/FAIL/fail/g' | \ - awk '{print $2" "$1}' >> "${RESULT_FILE}" - cat "${RESULT_FILE}" + # Parse input test names and results log to results file + ./parse-output.py < "${RESULT_LOG}" | tee -a "${RESULT_FILE}" } kvm_unit_tests_run_test() { info_msg "running kvm unit tests ..." if [ "${SMP}" = "false" ]; then - taskset -c 0 ./run_tests.sh -a -v | tee -a "${RESULT_LOG}" + taskset -c 0 ./run_tests.sh -a -t -v | tee -a "${RESULT_LOG}" else - ./run_tests.sh -a -v | tee -a "${RESULT_LOG}" + ./run_tests.sh -a -t -v | tee -a "${RESULT_LOG}" fi } @@ -84,8 +74,6 @@ install() { # Test run. ! check_root && error_msg "This script must be run as root" create_out_dir "${OUTPUT}" -# shellcheck disable=SC2164 -cd "${OUTPUT}" info_msg "About to run kvm unit tests ..." info_msg "Output directory: ${OUTPUT}" @@ -107,6 +95,7 @@ fi # Run kvm unit tests kvm_unit_tests_run_test +cd - || exit 1 # Parse and print kvm unit tests results parse_output diff --git a/automated/linux/kvm-unit-tests/parse-output.py b/automated/linux/kvm-unit-tests/parse-output.py new file mode 100755 index 000000000..5d433a664 --- /dev/null +++ b/automated/linux/kvm-unit-tests/parse-output.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +import sys +import re + + +def parse_line(line): + """ + Parses a single line of input to extract the test result and description. + + Args: + line (str): A single line of input. + + Returns: + tuple: A tuple containing the result and description. + """ + + if not line.startswith("ok") and not line.startswith("not ok"): + return None, None + + parts = re.split(r" \d+ - ", line) + if len(parts) < 2: + raise ValueError(f"Invalid line format: {line}") + + result = "pass" if parts[0] == "ok" else "fail" + description = parts[1].strip() + + if "# skip" in description.lower(): + result = "skip" + description = description.split("# skip")[0].strip() + + return result, description + + +def sanitize_description(description): + """ + Sanitizes the description by replacing spaces with dashes, removing special characters, and avoiding double dashes. + + Args: + description (str): The test description. + + Returns: + str: The sanitized description. + """ + description = description.replace(" ", "-") + description = re.sub(r"[^a-zA-Z0-9_-]+", "", description) # Slugify + description = re.sub( + r"-+", "-", description + ) # Replace multiple dashes with a single dash + return description + + +def main(): + """ + Main function to parse input, process each line, and output the results. + """ + lines = sys.stdin.readlines() + + for line in lines: + result, description = parse_line(line) + + if not result or not description: + continue + + print(f"{sanitize_description(description)} {result}") + + +if __name__ == "__main__": + main()