test_driver.py: Properly report exceptions

If a test fails by throwing an exception (in this case, "Too many open files")
then that exception would propagate, be uncaught, and then the remaining tests
would not be await'ed, leading to a hang.

Fix this by properly catching and reporting exceptions.
This commit is contained in:
Peter Ammon
2025-07-01 18:27:14 -07:00
parent f4ddcfa694
commit bbf7568ebd

View File

@@ -204,25 +204,31 @@ async def main():
if semaphore is not None: if semaphore is not None:
semaphore.release() semaphore.release()
tasks = [run(f, arg) for f, arg in files] tasks = [asyncio.create_task(run(f, arg), name=arg) for f, arg in files]
for task in asyncio.as_completed(tasks): while tasks:
result = await task done, tasks = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
# TODO(python>3.8): use match statement for task in done:
if isinstance(result, TestSkip): try:
arg = result.arg result = await task
skipcount += 1 except Exception as e:
print_result(arg, "SKIPPED", BLUE) arg = task.get_name()
elif isinstance(result, TestFail): result = TestFail(arg, None, f"Test '{arg}' raised an exception: {e}")
# fmt: off # TODO(python>3.8): use match statement
arg, duration_ms, error_message = result.arg, result.duration_ms, result.error_message if isinstance(result, TestSkip):
# fmt: on arg = result.arg
failcount += 1 skipcount += 1
failed += [arg] print_result(arg, "SKIPPED", BLUE)
print_result(arg, "FAILED", RED, duration_ms, error_message) elif isinstance(result, TestFail):
elif isinstance(result, TestPass): # fmt: off
arg, duration_ms = result.arg, result.duration_ms arg, duration_ms, error_message = result.arg, result.duration_ms, result.error_message
passcount += 1 # fmt: on
print_result(arg, "PASSED", GREEN, duration_ms) failcount += 1
failed += [arg]
print_result(arg, "FAILED", RED, duration_ms, error_message)
elif isinstance(result, TestPass):
arg, duration_ms = result.arg, result.duration_ms
passcount += 1
print_result(arg, "PASSED", GREEN, duration_ms)
if passcount + failcount + skipcount > 1: if passcount + failcount + skipcount > 1:
print(f"{passcount} / {passcount + failcount} passed ({skipcount} skipped)") print(f"{passcount} / {passcount + failcount} passed ({skipcount} skipped)")