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

Code before:
    parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface')
    parser.add_argument('--ci', action='store_true', help='Run checks and code that are usually only enabled in a continuous integration environment')
    parser.add_argument('--exclude', '-x', help='specify a comma-separated-list of scripts to exclude.')
    parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests')
    parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit')
    parser.add_argument('--jobs', '-j', type=int, default=4, help='how many test scripts to run in parallel. Default=4.')
    parser.add_argument('--keepcache', '-k', action='store_true', help='the default behavior is to flush the cache directory on startup. --keepcache retains the cache from the previous testrun.')
    parser.add_argument('--quiet', '-q', action='store_true', help='only print dots, results summary and failure logs')
    parser.add_argument('--tmpdirprefix', '-t', default=tempfile.gettempdir(), help="Root directory for datadirs")
    parser.add_argument('--failfast', '-F', action='store_true', help='stop execution after the first test failure')
    parser.add_argument('--filter', help='filter scripts to run by regular expression')
    parser.add_argument("--nocleanup", dest="nocleanup", default=False, action="store_true",
                        help="Leave bitcoinds and test.* datadir on exit or error")
    parser.add_argument('--resultsfile', '-r', help='store test results (as CSV) to the provided file')

    args, unknown_args = parser.parse_known_args()
    fail_on_warn = args.ci
    if not args.ansi:
        global DEFAULT, BOLD, GREEN, RED
        DEFAULT = ("", "")
        BOLD = ("", "")
        GREEN = ("", "")
        RED = ("", "")

    # args to be passed on always start with two dashes; tests are the remaining unknown args
    tests = [arg for arg in unknown_args if arg[:2] != "--"]
    passon_args = [arg for arg in unknown_args if arg[:2] == "--"]

    # Read config generated by configure.
    config = configparser.ConfigParser()
    configfile = os.path.abspath(os.path.dirname(__file__)) + "/../config.ini"
    config.read_file(open(configfile, encoding="utf8"))

    passon_args.append("--configfile=%s" % configfile)

    # Set up logging
    logging_level = logging.INFO if args.quiet else logging.DEBUG
    logging.basicConfig(format='%(message)s', level=logging_level)

    # Create base test directory
    tmpdir = "%s/test_runner_₿_🏃_%s" % (args.tmpdirprefix, datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))

    os.makedirs(tmpdir)

    logging.debug("Temporary test directory at %s" % tmpdir)

    results_filepath = None
    if args.resultsfile:
        results_filepath = pathlib.Path(args.resultsfile)
        # Stop early if the parent directory doesn't exist
        assert results_filepath.parent.exists(), "Results file parent directory does not exist"

Review comment (suggestion):
I know this is meant to be mostly random, but the existing `feature` ones seem to be in alphabetic order

Code after:
    'rpc_scanblocks.py',
    'p2p_sendtxrcncl.py',
    'rpc_scantxoutset.py',
    'feature_unsupported_utxo_db.py',
    'feature_logging.py',
    'feature_anchors.py',
    'mempool_datacarrier.py',
    'feature_coinstatsindex.py',
    'wallet_orphanedreward.py',
    'wallet_timelock.py',
    'p2p_permissions.py',
    'feature_blocksdir.py',
    'wallet_startup.py',
    'feature_remove_pruned_files_on_startup.py',
    'p2p_i2p_ports.py',
    'p2p_i2p_sessions.py',
    'feature_presegwit_node_upgrade.py',
    'feature_settings.py',
    'rpc_getdescriptorinfo.py',
    'rpc_mempool_info.py',
    'rpc_help.py',
    'p2p_handshake.py',
    'p2p_handshake.py --v2transport',
    'feature_dirsymlinks.py',
    'feature_help.py',
    'feature_framework_startup_failures.py',
    'feature_shutdown.py',
    'wallet_migration.py',
    'p2p_ibd_txrelay.py',
    'p2p_seednode.py',
    # Don't append tests at the end to avoid merge conflicts
    # Put them in a random line within the section that fits their approximate run-time
]

# Place EXTENDED_SCRIPTS first since it has the 3 longest running tests
ALL_SCRIPTS = EXTENDED_SCRIPTS + BASE_SCRIPTS

NON_SCRIPTS = [
    # These are python files that live in the functional tests directory, but are not test scripts.
    "combine_logs.py",
    "create_cache.py",
    "test_runner.py",
]

def main():
    # Parse arguments and pass through unrecognised args
    parser = argparse.ArgumentParser(add_help=False,
                                     usage='%(prog)s [test_runner.py options] [script options] [scripts]',
                                     description=__doc__,
                                     epilog='''
    Help text and arguments for individual test script:''',