Repository: bitcoin/bitcoin
File: test/functional/test_runner.py (Python)

Code before:

        def print_warning_missing_test(test_name):
            print("{}WARNING!{} Test '{}' not found in current test list. Check the --exclude list.".format(BOLD[1], BOLD[0], test_name))
            if fail_on_warn:
                sys.exit(1)

        def remove_tests(exclude_list):
            if not exclude_list:
                print_warning_missing_test(exclude_test)
            for exclude_item in exclude_list:
                test_list.remove(exclude_item)

        exclude_tests = [test.strip() for test in args.exclude.split(",")]
        for exclude_test in exclude_tests:
            # A space in the name indicates it has arguments such as "rpc_bind.py --ipv4"
            if ' ' in exclude_test:
                remove_tests([test for test in test_list if test.replace('.py', '') == exclude_test.replace('.py', '')])
            else:
                # Exclude all variants of a test
                remove_tests([test for test in test_list if test.split('.py')[0] == exclude_test.split('.py')[0]])

    if config["components"].getboolean("BUILD_BENCH") and TOOL_BENCH_SANITY_CHECK in test_list:
        # Remove it, and expand it for each bench in the list
        test_list.remove(TOOL_BENCH_SANITY_CHECK)
        bench_cmd = Binaries(get_binary_paths(config), bin_dir=None).bench_argv() + ["-list"]
        bench_list = subprocess.check_output(bench_cmd).decode("ascii").splitlines()
        bench_list = [f"{TOOL_BENCH_SANITY_CHECK} --bench={b}" for b in bench_list]
        # Start with special scripts (variable, unknown runtime)
        test_list.extendleft(bench_list)

    if args.filter:
        test_list = deque(filter(re.compile(args.filter).search, test_list))

    if not test_list:
        print("No valid test scripts specified. Check that your test is in one "
              "of the test lists in test_runner.py, or run test_runner.py with no arguments to run all tests")
        sys.exit(1)

    if args.help:
        # Print help for test_runner.py, then print help of the first script (with args removed) and exit.
        parser.print_help()
        subprocess.check_call([sys.executable, os.path.join(config["environment"]["SRCDIR"], 'test', 'functional', test_list[0].split()[0]), '-h'])
        sys.exit(0)

    # Warn if there is not enough space on tmpdir to run the tests with --nocleanup
    if args.nocleanup:
        if shutil.disk_usage(tmpdir).free < MIN_NO_CLEANUP_SPACE:
            print(f"{BOLD[1]}WARNING!{BOLD[0]} There may be insufficient free space in {tmpdir} to run the functional test suite with --nocleanup. "
                  f"A minimum of {MIN_NO_CLEANUP_SPACE // (1024 * 1024 * 1024)} GB of free space is required.")
        passon_args.append("--nocleanup")


Review comment (bug):
In other cases we just specify that the output is text: https://github.com/bitcoin/bitcoin/blob/fab085c15f7221986f73af7e05e799edf3eadaf0/contrib/verify-commits/verify-commits.py#L155
```suggestion
        bench_list = subprocess.check_output(bench_cmd, text=True).splitlines()
```

Note: the failure is really weird if `bitcoin_bench` isn't in the `bin` folder, we might want to give a better error message in that case.

Code after:

        def print_warning_missing_test(test_name):
            print("{}WARNING!{} Test '{}' not found in current test list. Check the --exclude list.".format(BOLD[1], BOLD[0], test_name))
            if fail_on_warn:
                sys.exit(1)

        def remove_tests(exclude_list):
            if not exclude_list:
                print_warning_missing_test(exclude_test)
            for exclude_item in exclude_list:
                test_list.remove(exclude_item)

        exclude_tests = [test.strip() for test in args.exclude.split(",")]
        for exclude_test in exclude_tests:
            # A space in the name indicates it has arguments such as "rpc_bind.py --ipv4"
            if ' ' in exclude_test:
                remove_tests([test for test in test_list if test.replace('.py', '') == exclude_test.replace('.py', '')])
            else:
                # Exclude all variants of a test
                remove_tests([test for test in test_list if test.split('.py')[0] == exclude_test.split('.py')[0]])

    if config["components"].getboolean("BUILD_BENCH") and TOOL_BENCH_SANITY_CHECK in test_list:
        # Remove it, and expand it for each bench in the list
        test_list.remove(TOOL_BENCH_SANITY_CHECK)
        bench_cmd = Binaries(get_binary_paths(config), bin_dir=None).bench_argv() + ["-list"]
        bench_list = subprocess.check_output(bench_cmd, text=True).splitlines()
        bench_list = [f"{TOOL_BENCH_SANITY_CHECK} --bench={b}" for b in bench_list]
        # Start with special scripts (variable, unknown runtime)
        test_list.extendleft(reversed(bench_list))

    if args.filter:
        test_list = deque(filter(re.compile(args.filter).search, test_list))

    if not test_list:
        print("No valid test scripts specified. Check that your test is in one "
              "of the test lists in test_runner.py, or run test_runner.py with no arguments to run all tests")
        sys.exit(1)

    if args.help:
        # Print help for test_runner.py, then print help of the first script (with args removed) and exit.
        parser.print_help()
        subprocess.check_call([sys.executable, os.path.join(config["environment"]["SRCDIR"], 'test', 'functional', test_list[0].split()[0]), '-h'])
        sys.exit(0)

    # Warn if there is not enough space on tmpdir to run the tests with --nocleanup
    if args.nocleanup:
        if shutil.disk_usage(tmpdir).free < MIN_NO_CLEANUP_SPACE:
            print(f"{BOLD[1]}WARNING!{BOLD[0]} There may be insufficient free space in {tmpdir} to run the functional test suite with --nocleanup. "
                  f"A minimum of {MIN_NO_CLEANUP_SPACE // (1024 * 1024 * 1024)} GB of free space is required.")
        passon_args.append("--nocleanup")