Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#!/usr/bin/env python32# Copyright (c) The Bitcoin Core developers3# Distributed under the MIT software license, see the accompanying4# file COPYING or https://opensource.org/license/mit/.6import argparse7import os8import re9import shlex10import subprocess11import sys12from pathlib import Path14sys.path.append(str(Path(__file__).resolve().parent.parent / "test"))15from download_utils import download_script_assets18def run(cmd, **kwargs):19print("+ " + shlex.join(cmd), flush=True)20kwargs.setdefault("check", True)21try:22return subprocess.run(cmd, **kwargs)23except Exception as e:24sys.exit(str(e))27def print_version():28bitcoind = Path.cwd() / "bin" / "bitcoind.exe"29run([str(bitcoind), "-version"])32def check_imports():33bitcoind = Path.cwd() / "bin" / "bitcoind.exe"34output = run(35["dumpbin.exe", "/imports", str(bitcoind)],36capture_output=True,37text=True,38).stdout39dlls = re.findall(r"^\s*(\S+\.dll)\s*$", output, re.IGNORECASE | re.MULTILINE)40print("\n".join(dlls))42# Ensure the executable is linked against the expected C runtime.43dlls = {name.lower() for name in dlls}44uses_msvcrt = "msvcrt.dll" in dlls45uses_ucrt = any(name.startswith("api-ms-win-crt-") for name in dlls)46crt = os.environ["CRT"]47if crt == "msvcrt":48crt_ok = uses_msvcrt and not uses_ucrt49elif crt == "ucrt":50crt_ok = uses_ucrt and not uses_msvcrt51else:52sys.exit(f"Unexpected CRT value: {crt!r}")53if not crt_ok:54sys.exit(f"Imported DLLs do not match the expected {crt!r} C runtime.")57def check_manifests():58release_dir = Path.cwd() / "bin"59manifest_path = release_dir / "bitcoind.manifest"61cmd_bitcoind_manifest = [62"mt.exe",63"-nologo",64f"-inputresource:{release_dir / 'bitcoind.exe'}",65f"-out:{manifest_path}",66]67run(cmd_bitcoind_manifest)68print(manifest_path.read_text())70skipped = { # Skip as they currently do not have manifests71"fuzz.exe",72"bench_bitcoin.exe",73}74for entry in release_dir.iterdir():75if entry.suffix.lower() != ".exe":76continue77if entry.name in skipped:78print(f"Skipping {entry.name} (no manifest present)")79continue80print(f"Checking {entry.name}")81run(["mt.exe", "-nologo", f"-inputresource:{entry}", "-validate_manifest"])84def prepare_tests():85workspace = Path.cwd()86config_path = workspace / "test" / "config.ini"87rpcauth_path = workspace / "share" / "rpcauth" / "rpcauth.py"88replacements = {89"SRCDIR=": f"SRCDIR={workspace}",90"BUILDDIR=": f"BUILDDIR={workspace}",91"RPCAUTH=": f"RPCAUTH={rpcauth_path}",92}93lines = config_path.read_text().splitlines()94for index, line in enumerate(lines):95for prefix, new_value in replacements.items():96if line.startswith(prefix):97lines[index] = new_value98break99content = "\n".join(lines) + "\n"100config_path.write_text(content)101print(content)102cmd_download_prev_rel = [103sys.executable,104str(workspace / "test" / "get_previous_releases.py"),105]106run(cmd_download_prev_rel)107run([sys.executable, "-m", "pip", "install", "pyzmq"])109dest = workspace / "unit_test_data"110download_script_assets(dest)113def run_functional_tests():114workspace = Path.cwd()115num_procs = str(os.process_cpu_count())116test_runner_cmd = [117sys.executable,118str(workspace / "test" / "functional" / "test_runner.py"),119"--jobs",120num_procs,121"--quiet",122f"--tmpdirprefix={workspace / '_ _'}",123"--combinedlogslen=99999999",124*shlex.split(os.environ.get("TEST_RUNNER_EXTRA", "").strip()),125# Tests using ancient releases fail on Windows because of emojis in the test data directory.126"--exclude",127"feature_unsupported_utxo_db.py",128"--exclude",129"wallet_ancient_migration.py",130]131run(test_runner_cmd)133# Run ancient release tests sequentially in ASCII-only tmp dir,134# because they are excluded above due to lack of UTF-8 support in the135# ancient release.136for test_name in ["feature_unsupported_utxo_db", "wallet_ancient_migration"]:137cmd = [138sys.executable,139str(workspace / "test" / "functional" / f"{test_name}.py"),140"--previous-releases",141"--tmpdir",142str(workspace / f"test_{test_name}"),143]144run(cmd)147def run_unit_tests():148workspace = Path.cwd()149os.environ["DIR_UNIT_TEST_DATA"] = str(workspace / "unit_test_data")150# Can't use ctest here like other jobs as we don't have a CMake build tree.151commands = [152["./bin/test_bitcoin-qt.exe"],153# Intentionally run sequentially here, to catch test case failures caused by dirty global state from prior test cases:154["./bin/test_bitcoin.exe", "-l", "test_suite"],155["./src/secp256k1/bin/exhaustive_tests.exe"],156["./src/secp256k1/bin/noverify_tests.exe"],157["./src/secp256k1/bin/tests.exe"],158["./src/univalue/object.exe"],159["./src/univalue/unitester.exe"],160]161for cmd in commands:162run(cmd)165def main():166parser = argparse.ArgumentParser(description="Utility to run Windows CI steps.")167steps = list(map(lambda f: f.__name__, [168print_version,169check_imports,170check_manifests,171prepare_tests,172run_unit_tests,173run_functional_tests,174]))175parser.add_argument("step", choices=steps, help="CI step to perform.")176args = parser.parse_args()178os.environ.setdefault(179"PREVIOUS_RELEASES_DIR",180str(Path.cwd() / "previous_releases"),181)183exec(f'{args.step}()')186if __name__ == "__main__":187main()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.