Repository: duckdb/duckdb
File: scripts/run_tests_one_by_one.py (Python)

Code before:
    for line in stdout.splitlines():
        if 'All tests were skipped' in line:
            return "SKIPPED"
        if line == 'assertions: - none -':
            return "0 assertions"

        # Parse assertions in format
        pos = line.find("assertion")
        if pos != -1:
            space_before_num = line.rfind(' ', 0, pos - 2)
            return line[space_before_num + 2 : pos + 10]

    return ""


for test_number, test_case in enumerate(test_cases):
    if not profile:
        print(f"[{test_number}/{test_count}]: {test_case}", end="")
    start = time.time()
    try:
        res = subprocess.run(
            [unittest_program, test_case], stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout
        )
    except subprocess.TimeoutExpired as e:
        print(" (TIMED OUT)", flush=True)
        if not no_exit:
            break
        continue

    stdout = res.stdout.decode('utf8')
    stderr = res.stderr.decode('utf8')
    end = time.time()

    additional_data = ""
    if assertions:
        additional_data += " (" + parse_assertions(stdout) + ")"
    if args.time_execution:
        additional_data += f" (Time: {end - start:.4f} seconds)"

    print(additional_data, flush=True)
    if profile:
        print(f'{test_case}	{end - start}')
    if res.returncode is not None and res.returncode != 0:
        print("FAILURE IN RUNNING TEST")
        print(
            """--------------------
RETURNCODE
--------------------
"""
        )
        print(res.returncode)

Review comment (bug):
I think here it's missing a `        return_code = 1` line to pass on information that process failed (due to timeout).

Code after:
def fail():
    global all_passed
    all_passed = False
    if not no_exit:
        exit(1)


def parse_assertions(stdout):
    for line in stdout.splitlines():
        if 'All tests were skipped' in line:
            return "SKIPPED"
        if line == 'assertions: - none -':
            return "0 assertions"

        # Parse assertions in format
        pos = line.find("assertion")
        if pos != -1:
            space_before_num = line.rfind(' ', 0, pos - 2)
            return line[space_before_num + 2 : pos + 10]

    return ""


for test_number, test_case in enumerate(test_cases):
    if not profile:
        print(f"[{test_number}/{test_count}]: {test_case}", end="")
    start = time.time()
    try:
        res = subprocess.run(
            [unittest_program, test_case], stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeout
        )
    except subprocess.TimeoutExpired as e:
        print(" (TIMED OUT)", flush=True)
        fail()
        continue

    stdout = res.stdout.decode('utf8')
    stderr = res.stderr.decode('utf8')
    end = time.time()

    additional_data = ""
    if assertions:
        additional_data += " (" + parse_assertions(stdout) + ")"
    if args.time_execution:
        additional_data += f" (Time: {end - start:.4f} seconds)"

    print(additional_data, flush=True)
    if profile:
        print(f'{test_case}	{end - start}')
    if res.returncode is None or res.returncode == 0:
        continue