Merge bitcoin/bitcoin#33633: test: [move-only] binary utils to utils.py
fa75ef4328test: Move export_env_build_path to util.py (MarcoFalke)fa9f495308test: Move get_binary_paths and Binaries to util.py (MarcoFalke) Pull request description: Having the binary related utils sit in the test_framework.py is fine. However, they are mostly stand-alone utils, which may be used externally. So move them to utils.py, to allow easier external use. The diff is trivial and can be reviewed via the git options `--color-moved=dimmed-zebra --color-moved-ws=ignore-all-space`. ACKs for top commit: kevkevinpal: ACK [fa75ef4](https://github.com/bitcoin/bitcoin/pull/33633/commits/fa75ef4328f638221bcf85fcbefa885122084622) Sjors: lgtm ACKfa75ef4328yuvicc: Code review ACKfa75ef4328janb84: ACKfa75ef4328musaHaruna: Code Review ACK [fa75ef4](https://github.com/bitcoin/bitcoin/pull/33633/commits/fa75ef4328f638221bcf85fcbefa885122084622) enirox001: ACK [fa75ef4](https://github.com/bitcoin/bitcoin/commit/fa75ef4328f638221bcf85fcbefa885122084622) Tree-SHA512: f382118484cb5495e8888214437e72c81727d54f97b3c09dfd996faab6cb6643c4c2d816b89ab82de73fc091c36ed7b8744c7d34a443b6adc415eb06697ef6ea
This commit is contained in:
2 files changed
+99
-92
No files matched your search
@@ -14,13 +14,11 @@ import platform
|
|||||||
import pdb
|
import pdb
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import shlex
|
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
import types
|
|
||||||
|
|
||||||
from .address import create_deterministic_address_bcrt1_p2tr_op_true
|
from .address import create_deterministic_address_bcrt1_p2tr_op_true
|
||||||
from .authproxy import JSONRPCException
|
from .authproxy import JSONRPCException
|
||||||
@@ -28,11 +26,14 @@ from . import coverage
|
|||||||
from .p2p import NetworkThread
|
from .p2p import NetworkThread
|
||||||
from .test_node import TestNode
|
from .test_node import TestNode
|
||||||
from .util import (
|
from .util import (
|
||||||
|
Binaries,
|
||||||
MAX_NODES,
|
MAX_NODES,
|
||||||
PortSeed,
|
PortSeed,
|
||||||
assert_equal,
|
assert_equal,
|
||||||
check_json_precision,
|
check_json_precision,
|
||||||
|
export_env_build_path,
|
||||||
find_vout_for_address,
|
find_vout_for_address,
|
||||||
|
get_binary_paths,
|
||||||
get_datadir_path,
|
get_datadir_path,
|
||||||
initialize_datadir,
|
initialize_datadir,
|
||||||
p2p_port,
|
p2p_port,
|
||||||
@@ -60,63 +61,6 @@ class SkipTest(Exception):
|
|||||||
self.message = message
|
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):
|
class BitcoinTestMetaClass(type):
|
||||||
"""Metaclass for BitcoinTestFramework.
|
"""Metaclass for BitcoinTestFramework.
|
||||||
|
|
||||||
@@ -270,39 +214,12 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
|||||||
|
|
||||||
self.config = configparser.ConfigParser()
|
self.config = configparser.ConfigParser()
|
||||||
self.config.read_file(open(self.options.configfile))
|
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:
|
if self.options.v1transport:
|
||||||
self.options.v2transport=False
|
self.options.v2transport=False
|
||||||
|
|
||||||
PortSeed.n = self.options.port_seed
|
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):
|
def get_binaries(self, bin_dir=None):
|
||||||
return Binaries(self.binary_paths, bin_dir)
|
return Binaries(self.binary_paths, bin_dir)
|
||||||
|
|
||||||
@@ -310,14 +227,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
|||||||
"""Call this method to start up the test framework object with options set."""
|
"""Call this method to start up the test framework object with options set."""
|
||||||
|
|
||||||
check_json_precision()
|
check_json_precision()
|
||||||
|
export_env_build_path(self.config)
|
||||||
|
|
||||||
self.options.cachedir = os.path.abspath(self.options.cachedir)
|
self.options.cachedir = os.path.abspath(self.options.cachedir)
|
||||||
|
|
||||||
os.environ['PATH'] = os.pathsep.join([
|
|
||||||
os.path.join(self.config["environment"]["BUILDDIR"], "bin"),
|
|
||||||
os.environ['PATH']
|
|
||||||
])
|
|
||||||
|
|
||||||
# Set up temp directory and start logging
|
# Set up temp directory and start logging
|
||||||
if self.options.tmpdir:
|
if self.options.tmpdir:
|
||||||
self.options.tmpdir = os.path.abspath(self.options.tmpdir)
|
self.options.tmpdir = os.path.abspath(self.options.tmpdir)
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import pathlib
|
|||||||
import platform
|
import platform
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
|
import shlex
|
||||||
import time
|
import time
|
||||||
|
import types
|
||||||
|
|
||||||
from . import coverage
|
from . import coverage
|
||||||
from .authproxy import AuthServiceProxy, JSONRPCException
|
from .authproxy import AuthServiceProxy, JSONRPCException
|
||||||
@@ -235,6 +237,98 @@ def check_json_precision():
|
|||||||
raise RuntimeError("JSON encode/decode loses 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 export_env_build_path(config):
|
||||||
|
os.environ["PATH"] = os.pathsep.join([
|
||||||
|
os.path.join(config["environment"]["BUILDDIR"], "bin"),
|
||||||
|
os.environ["PATH"],
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def count_bytes(hex_string):
|
def count_bytes(hex_string):
|
||||||
return len(bytearray.fromhex(hex_string))
|
return len(bytearray.fromhex(hex_string))
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user