kunit: check if kernel crashed during kunit
- outputs error message with most recent log if KUnit crashes
unexpectedly or does not complete
Change-Id: Ic5677ab3a4fe215b9ba7c69e1d1e63a903a872af
Signed-off-by: Felix Guo <felixguo@google.com>
diff --git a/tools/testing/kunit/kunit_parser.py b/tools/testing/kunit/kunit_parser.py
index 6040db0..0ec2299 100644
--- a/tools/testing/kunit/kunit_parser.py
+++ b/tools/testing/kunit/kunit_parser.py
@@ -4,15 +4,21 @@
kunit_start_re = re.compile('console .* enabled')
kunit_end_re = re.compile('List of all partitions:')
+class KernelCrashException(Exception):
+ pass
+
def isolate_kunit_output(kernel_output):
started = False
for line in kernel_output:
if kunit_start_re.match(line):
started = True
elif kunit_end_re.match(line):
- break
+ return
elif started:
yield line
+ # Output ended without encountering end marker, kernel probably panicked
+ # or crashed unexpectedly.
+ raise KernelCrashException()
def raw_output(kernel_output):
for line in kernel_output:
@@ -56,56 +62,73 @@
return match.group(1) + ":" + match.group(2)
current_case_log = []
+ did_kernel_crash = False
+
def end_one_test(match, log):
log.clear()
total_tests.add(get_test_name(match))
print_with_timestamp(DIVIDER)
- for line in isolate_kunit_output(kernel_output):
- # Ignore module output:
- if (test_module_success.match(line) or
- test_module_fail.match(line)):
- print_with_timestamp(DIVIDER)
- continue
+ try:
+ for line in isolate_kunit_output(kernel_output):
+ # Ignore module output:
+ if (test_module_success.match(line) or
+ test_module_fail.match(line)):
+ print_with_timestamp(DIVIDER)
+ continue
- match = re.match(test_case_success, line)
- if match:
- print_with_timestamp(green("[PASSED] ") +
- get_test_name(match))
- end_one_test(match, current_case_log)
- continue
+ match = re.match(test_case_success, line)
+ if match:
+ print_with_timestamp(green("[PASSED] ") +
+ get_test_name(match))
+ end_one_test(match, current_case_log)
+ continue
- match = re.match(test_case_fail, line)
- # Crashed tests will report as both failed and crashed. We only
- # want to show and count it once.
- if match and get_test_name(match) not in crashed_tests:
- failed_tests.add(get_test_name(match))
- print_with_timestamp(red("[FAILED] " +
- get_test_name(match)))
- print_log(map(yellow, current_case_log))
- print_with_timestamp("")
- end_one_test(match, current_case_log)
- continue
+ match = re.match(test_case_fail, line)
+ # Crashed tests will report as both failed and crashed. We only
+ # want to show and count it once.
+ if match and get_test_name(match) not in crashed_tests:
+ failed_tests.add(get_test_name(match))
+ print_with_timestamp(red("[FAILED] " +
+ get_test_name(match)))
+ print_log(map(yellow, current_case_log))
+ print_with_timestamp("")
+ end_one_test(match, current_case_log)
+ continue
- match = re.match(test_case_crash, line)
- if match:
- crashed_tests.add(get_test_name(match))
- print_with_timestamp(yellow("[CRASH] " +
- get_test_name(match)))
- print_log(current_case_log)
- print_with_timestamp("")
- end_one_test(match, current_case_log)
- continue
+ match = re.match(test_case_crash, line)
+ if match:
+ crashed_tests.add(get_test_name(match))
+ print_with_timestamp(yellow("[CRASH] " +
+ get_test_name(match)))
+ print_log(current_case_log)
+ print_with_timestamp("")
+ end_one_test(match, current_case_log)
+ continue
- # Strip off the `kunit module-name:` prefix
- match = re.match(test_case_output, line)
- if match:
- current_case_log.append(match.group(1))
- else:
- current_case_log.append(line)
+ # Strip off the `kunit module-name:` prefix
+ match = re.match(test_case_output, line)
+ if match:
+ current_case_log.append(match.group(1))
+ else:
+ current_case_log.append(line)
+ except KernelCrashException:
+ did_kernel_crash = True
+ print_with_timestamp(
+ red("The KUnit kernel crashed unexpectedly and was " +
+ "unable to finish running tests!"))
+ print_with_timestamp(red("These are the logs from the most " +
+ "recently running test:"))
+ print_with_timestamp(DIVIDER)
+ print_log(current_case_log)
+ print_with_timestamp(DIVIDER)
- fmt = green if (len(failed_tests) + len(crashed_tests) == 0) else red
+ fmt = green if (len(failed_tests) + len(crashed_tests) == 0
+ and not did_kernel_crash) else red
+ message = ("Before the crash:" if did_kernel_crash else
+ "Testing complete.")
+
print_with_timestamp(
- fmt("Testing complete. %d tests run. %d failed. %d crashed." %
+ fmt(message + " %d tests run. %d failed. %d crashed." %
(len(total_tests), len(failed_tests), len(crashed_tests))))