test: Move get_binary_paths and Binaries to util.py

Can be reviewed with the git options
--color-moved=dimmed-zebra --color-moved-ws=ignore-all-space
This commit is contained in:
MarcoFalke 2025-08-06 12:54:09 +02:00
parent 40e7d4cd0d
commit fa9f495308
No known key found for this signature in database
2 changed files with 90 additions and 87 deletions

View File

@ -14,13 +14,11 @@ import platform
import pdb
import random
import re
import shlex
import shutil
import subprocess
import sys
import tempfile
import time
import types
from .address import create_deterministic_address_bcrt1_p2tr_op_true
from .authproxy import JSONRPCException
@ -28,11 +26,13 @@ from . import coverage
from .p2p import NetworkThread
from .test_node import TestNode
from .util import (
Binaries,
MAX_NODES,
PortSeed,
assert_equal,
check_json_precision,
find_vout_for_address,
get_binary_paths,
get_datadir_path,
initialize_datadir,
p2p_port,
@ -60,63 +60,6 @@ class SkipTest(Exception):
self.message = message
class Binaries:
"""Helper class to provide information about bitcoin binaries
Attributes:
paths: Object returned from get_binary_paths() containing information
which binaries and command lines to use from environment variables and
the config file.
bin_dir: An optional string containing a directory path to look for
binaries, which takes precedence over the paths above, if specified.
This is used by tests calling binaries from previous releases.
"""
def __init__(self, paths, bin_dir):
self.paths = paths
self.bin_dir = bin_dir
def node_argv(self, **kwargs):
"Return argv array that should be used to invoke bitcoind"
return self._argv("node", self.paths.bitcoind, **kwargs)
def rpc_argv(self):
"Return argv array that should be used to invoke bitcoin-cli"
# Add -nonamed because "bitcoin rpc" enables -named by default, but bitcoin-cli doesn't
return self._argv("rpc", self.paths.bitcoincli) + ["-nonamed"]
def tx_argv(self):
"Return argv array that should be used to invoke bitcoin-tx"
return self._argv("tx", self.paths.bitcointx)
def util_argv(self):
"Return argv array that should be used to invoke bitcoin-util"
return self._argv("util", self.paths.bitcoinutil)
def wallet_argv(self):
"Return argv array that should be used to invoke bitcoin-wallet"
return self._argv("wallet", self.paths.bitcoinwallet)
def chainstate_argv(self):
"Return argv array that should be used to invoke bitcoin-chainstate"
return self._argv("chainstate", self.paths.bitcoinchainstate)
def _argv(self, command, bin_path, need_ipc=False):
"""Return argv array that should be used to invoke the command. It
either uses the bitcoin wrapper executable (if BITCOIN_CMD is set or
need_ipc is True), or the direct binary path (bitcoind, etc). When
bin_dir is set (by tests calling binaries from previous releases) it
always uses the direct path."""
if self.bin_dir is not None:
return [os.path.join(self.bin_dir, os.path.basename(bin_path))]
elif self.paths.bitcoin_cmd is not None or need_ipc:
# If the current test needs IPC functionality, use the bitcoin
# wrapper binary and append -m so it calls multiprocess binaries.
bitcoin_cmd = self.paths.bitcoin_cmd or [self.paths.bitcoin_bin]
return bitcoin_cmd + (["-m"] if need_ipc else []) + [command]
else:
return [bin_path]
class BitcoinTestMetaClass(type):
"""Metaclass for BitcoinTestFramework.
@ -270,39 +213,12 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.config = configparser.ConfigParser()
self.config.read_file(open(self.options.configfile))
self.binary_paths = self.get_binary_paths()
self.binary_paths = get_binary_paths(self.config)
if self.options.v1transport:
self.options.v2transport=False
PortSeed.n = self.options.port_seed
def get_binary_paths(self):
"""Get paths of all binaries from environment variables or their default values"""
paths = types.SimpleNamespace()
binaries = {
"bitcoin": "BITCOIN_BIN",
"bitcoind": "BITCOIND",
"bitcoin-cli": "BITCOINCLI",
"bitcoin-util": "BITCOINUTIL",
"bitcoin-tx": "BITCOINTX",
"bitcoin-chainstate": "BITCOINCHAINSTATE",
"bitcoin-wallet": "BITCOINWALLET",
}
# Set paths to bitcoin core binaries allowing overrides with environment
# variables.
for binary, env_variable_name in binaries.items():
default_filename = os.path.join(
self.config["environment"]["BUILDDIR"],
"bin",
binary + self.config["environment"]["EXEEXT"],
)
setattr(paths, env_variable_name.lower(), os.getenv(env_variable_name, default=default_filename))
# BITCOIN_CMD environment variable can be specified to invoke bitcoin
# wrapper binary instead of other executables.
paths.bitcoin_cmd = shlex.split(os.getenv("BITCOIN_CMD", "")) or None
return paths
def get_binaries(self, bin_dir=None):
return Binaries(self.binary_paths, bin_dir)

View File

@ -16,7 +16,9 @@ import pathlib
import platform
import random
import re
import shlex
import time
import types
from . import coverage
from .authproxy import AuthServiceProxy, JSONRPCException
@ -235,6 +237,91 @@ def check_json_precision():
raise RuntimeError("JSON encode/decode loses precision")
class Binaries:
"""Helper class to provide information about bitcoin binaries
Attributes:
paths: Object returned from get_binary_paths() containing information
which binaries and command lines to use from environment variables and
the config file.
bin_dir: An optional string containing a directory path to look for
binaries, which takes precedence over the paths above, if specified.
This is used by tests calling binaries from previous releases.
"""
def __init__(self, paths, bin_dir):
self.paths = paths
self.bin_dir = bin_dir
def node_argv(self, **kwargs):
"Return argv array that should be used to invoke bitcoind"
return self._argv("node", self.paths.bitcoind, **kwargs)
def rpc_argv(self):
"Return argv array that should be used to invoke bitcoin-cli"
# Add -nonamed because "bitcoin rpc" enables -named by default, but bitcoin-cli doesn't
return self._argv("rpc", self.paths.bitcoincli) + ["-nonamed"]
def tx_argv(self):
"Return argv array that should be used to invoke bitcoin-tx"
return self._argv("tx", self.paths.bitcointx)
def util_argv(self):
"Return argv array that should be used to invoke bitcoin-util"
return self._argv("util", self.paths.bitcoinutil)
def wallet_argv(self):
"Return argv array that should be used to invoke bitcoin-wallet"
return self._argv("wallet", self.paths.bitcoinwallet)
def chainstate_argv(self):
"Return argv array that should be used to invoke bitcoin-chainstate"
return self._argv("chainstate", self.paths.bitcoinchainstate)
def _argv(self, command, bin_path, need_ipc=False):
"""Return argv array that should be used to invoke the command. It
either uses the bitcoin wrapper executable (if BITCOIN_CMD is set or
need_ipc is True), or the direct binary path (bitcoind, etc). When
bin_dir is set (by tests calling binaries from previous releases) it
always uses the direct path."""
if self.bin_dir is not None:
return [os.path.join(self.bin_dir, os.path.basename(bin_path))]
elif self.paths.bitcoin_cmd is not None or need_ipc:
# If the current test needs IPC functionality, use the bitcoin
# wrapper binary and append -m so it calls multiprocess binaries.
bitcoin_cmd = self.paths.bitcoin_cmd or [self.paths.bitcoin_bin]
return bitcoin_cmd + (["-m"] if need_ipc else []) + [command]
else:
return [bin_path]
def get_binary_paths(config):
"""Get paths of all binaries from environment variables or their default values"""
paths = types.SimpleNamespace()
binaries = {
"bitcoin": "BITCOIN_BIN",
"bitcoind": "BITCOIND",
"bitcoin-cli": "BITCOINCLI",
"bitcoin-util": "BITCOINUTIL",
"bitcoin-tx": "BITCOINTX",
"bitcoin-chainstate": "BITCOINCHAINSTATE",
"bitcoin-wallet": "BITCOINWALLET",
}
# Set paths to bitcoin core binaries allowing overrides with environment
# variables.
for binary, env_variable_name in binaries.items():
default_filename = os.path.join(
config["environment"]["BUILDDIR"],
"bin",
binary + config["environment"]["EXEEXT"],
)
setattr(paths, env_variable_name.lower(), os.getenv(env_variable_name, default=default_filename))
# BITCOIN_CMD environment variable can be specified to invoke bitcoin
# wrapper binary instead of other executables.
paths.bitcoin_cmd = shlex.split(os.getenv("BITCOIN_CMD", "")) or None
return paths
def count_bytes(hex_string):
return len(bytearray.fromhex(hex_string))