Skip to content

Commit ca4e67c

Browse files
committed
ZTS: fail test run if test runner crashes unexpectedly
zfs-tests.sh executes test-runner.py to do the actual test work. Any exit code < 4 is interpreted as success, with the actual value describing the outcome of the tests inside. If a Python program crashes in some way (eg an uncaught exception), the process exit code is 1. Taken together, this means that test-runner.py can crash during setup, but return a "success" error code to zfs-tests.sh, which will report and exit 0. This in turn causes the CI runner to believe the test run completed successfully. This commit addresses this by making zfs-tests.sh interpret an exit code of 255 as a failure in the runner itself. Then, in test-runner.py, the "fail()" function defaults to a 255 return, and the main function gets wrapped in a generic exception handler, which prints it and calls fail(). All together, this should mean that any unexpected failure in the test runner itself will be propagated out of zfs-tests.sh for CI or any other calling program to deal with. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Signed-off-by: Rob Norris <[email protected]>
1 parent 3a55e76 commit ca4e67c

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

scripts/zfs-tests.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,10 @@ msg "${TEST_RUNNER}" \
797797
2>&1; echo $? >"$REPORT_FILE"; } | tee "$RESULTS_FILE"
798798
read -r RUNRESULT <"$REPORT_FILE"
799799

800+
if [[ "$RUNRESULT" -eq "255" ]] ; then
801+
fail "$TEST_RUNNER failed, test aborted."
802+
fi
803+
800804
#
801805
# Analyze the results.
802806
#

tests/test-runner/bin/test-runner.py.in

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import sys
2525
import ctypes
2626
import re
2727
import configparser
28+
import traceback
2829

2930
from datetime import datetime
3031
from optparse import OptionParser
@@ -1138,7 +1139,7 @@ def filter_tests(testrun, options):
11381139
testrun.filter(failed)
11391140

11401141

1141-
def fail(retstr, ret=1):
1142+
def fail(retstr, ret=255):
11421143
print('%s: %s' % (sys.argv[0], retstr))
11431144
exit(ret)
11441145

@@ -1247,23 +1248,27 @@ def parse_args():
12471248
def main():
12481249
options = parse_args()
12491250

1250-
testrun = TestRun(options)
1251+
try:
1252+
testrun = TestRun(options)
12511253

1252-
if options.runfiles:
1253-
testrun.read(options)
1254-
else:
1255-
find_tests(testrun, options)
1254+
if options.runfiles:
1255+
testrun.read(options)
1256+
else:
1257+
find_tests(testrun, options)
1258+
1259+
if options.logfile:
1260+
filter_tests(testrun, options)
12561261

1257-
if options.logfile:
1258-
filter_tests(testrun, options)
1262+
if options.template:
1263+
testrun.write(options)
1264+
exit(0)
12591265

1260-
if options.template:
1261-
testrun.write(options)
1262-
exit(0)
1266+
testrun.complete_outputdirs()
1267+
testrun.run(options)
1268+
exit(testrun.summary())
12631269

1264-
testrun.complete_outputdirs()
1265-
testrun.run(options)
1266-
exit(testrun.summary())
1270+
except Exception:
1271+
fail("Uncaught exception in test runner:\n" + traceback.format_exc())
12671272

12681273

12691274
if __name__ == '__main__':

0 commit comments

Comments
 (0)