aboutsummaryrefslogtreecommitdiff
path: root/test/functional/test_framework/test_framework.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/test_framework/test_framework.py')
-rwxr-xr-xtest/functional/test_framework/test_framework.py111
1 files changed, 69 insertions, 42 deletions
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 921f12d9fb..c4b10af16c 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -18,6 +18,7 @@ import subprocess
import sys
import tempfile
import time
+import types
from .address import create_deterministic_address_bcrt1_p2tr_op_true
from .authproxy import JSONRPCException
@@ -56,6 +57,48 @@ 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 daemon_argv(self):
+ "Return argv array that should be used to invoke bitcoind"
+ return self._argv(self.paths.bitcoind)
+
+ def rpc_argv(self):
+ "Return argv array that should be used to invoke bitcoin-cli"
+ return self._argv(self.paths.bitcoincli)
+
+ def util_argv(self):
+ "Return argv array that should be used to invoke bitcoin-util"
+ return self._argv(self.paths.bitcoinutil)
+
+ def wallet_argv(self):
+ "Return argv array that should be used to invoke bitcoin-wallet"
+ return self._argv(self.paths.bitcoinwallet)
+
+ def _argv(self, bin_path):
+ """Return argv array that should be used to invoke the command.
+ Normally this will return binary paths directly from the paths object,
+ but when bin_dir is set (by tests calling binaries from previous
+ releases) it will return paths relative to bin_dir instead."""
+ if self.bin_dir is not None:
+ return [os.path.join(self.bin_dir, os.path.basename(bin_path))]
+ else:
+ return [bin_path]
+
+
class BitcoinTestMetaClass(type):
"""Metaclass for BitcoinTestFramework.
@@ -220,6 +263,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
config = configparser.ConfigParser()
config.read_file(open(self.options.configfile))
self.config = config
+ self.binary_paths = self.get_binary_paths()
if self.options.v1transport:
self.options.v2transport=False
@@ -229,23 +273,20 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# So set it to None to force -disablewallet, because the wallet is not needed.
self.options.descriptors = None
elif self.options.descriptors is None:
- # Some wallet is either required or optionally used by the test.
- # Prefer SQLite unless it isn't available
- if self.is_sqlite_compiled():
+ if self.is_wallet_compiled():
self.options.descriptors = True
- elif self.is_bdb_compiled():
- self.options.descriptors = False
else:
- # If neither are compiled, tests requiring a wallet will be skipped and the value of self.options.descriptors won't matter
+ # Tests requiring a wallet will be skipped and the value of self.options.descriptors won't matter
# It still needs to exist and be None in order for tests to work however.
# So set it to None, which will also set -disablewallet.
self.options.descriptors = None
PortSeed.n = self.options.port_seed
- def set_binary_paths(self):
- """Update self.options with the paths of all binaries from environment variables or their default values"""
+ def get_binary_paths(self):
+ """Get paths of all binaries from environment variables or their default values"""
+ paths = types.SimpleNamespace()
binaries = {
"bitcoind": ("bitcoind", "BITCOIND"),
"bitcoin-cli": ("bitcoincli", "BITCOINCLI"),
@@ -255,10 +296,14 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
for binary, [attribute_name, env_variable_name] in binaries.items():
default_filename = os.path.join(
self.config["environment"]["BUILDDIR"],
- "src",
+ "bin",
binary + self.config["environment"]["EXEEXT"],
)
- setattr(self.options, attribute_name, os.getenv(env_variable_name, default=default_filename))
+ setattr(paths, attribute_name, os.getenv(env_variable_name, default=default_filename))
+ return paths
+
+ def get_binaries(self, bin_dir=None):
+ return Binaries(self.binary_paths, bin_dir)
def setup(self):
"""Call this method to start up the test framework object with options set."""
@@ -269,11 +314,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
config = self.config
- self.set_binary_paths()
-
os.environ['PATH'] = os.pathsep.join([
- os.path.join(config['environment']['BUILDDIR'], 'src'),
- os.path.join(config['environment']['BUILDDIR'], 'src', 'qt'), os.environ['PATH']
+ os.path.join(config['environment']['BUILDDIR'], 'bin'),
+ os.environ['PATH']
])
# Set up temp directory and start logging
@@ -477,14 +520,14 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
group.add_argument("--legacy-wallet", action='store_const', const=False, **kwargs,
help="Run test using legacy wallets", dest='descriptors')
- def add_nodes(self, num_nodes: int, extra_args=None, *, rpchost=None, binary=None, binary_cli=None, versions=None):
+ def add_nodes(self, num_nodes: int, extra_args=None, *, rpchost=None, versions=None):
"""Instantiate TestNode objects.
Should only be called once after the nodes have been specified in
set_test_params()."""
- def get_bin_from_version(version, bin_name, bin_default):
+ def bin_dir_from_version(version):
if not version:
- return bin_default
+ return None
if version > 219999:
# Starting at client version 220000 the first two digits represent
# the major version, e.g. v22.0 instead of v0.22.0.
@@ -502,7 +545,6 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
),
),
'bin',
- bin_name,
)
if self.bind_to_localhost_only:
@@ -517,13 +559,12 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
extra_args[i] = extra_args[i] + ["-whitelist=noban,in,out@127.0.0.1"]
if versions is None:
versions = [None] * num_nodes
- if binary is None:
- binary = [get_bin_from_version(v, 'bitcoind', self.options.bitcoind) for v in versions]
- if binary_cli is None:
- binary_cli = [get_bin_from_version(v, 'bitcoin-cli', self.options.bitcoincli) for v in versions]
+ bin_dirs = [bin_dir_from_version(v) for v in versions]
# Fail test if any of the needed release binaries is missing
bins_missing = False
- for bin_path in binary + binary_cli:
+ for bin_path in (argv[0] for bin_dir in bin_dirs
+ for binaries in (self.get_binaries(bin_dir),)
+ for argv in (binaries.daemon_argv(), binaries.rpc_argv())):
if shutil.which(bin_path) is None:
self.log.error(f"Binary not found: {bin_path}")
bins_missing = True
@@ -533,8 +574,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
assert_equal(len(extra_confs), num_nodes)
assert_equal(len(extra_args), num_nodes)
assert_equal(len(versions), num_nodes)
- assert_equal(len(binary), num_nodes)
- assert_equal(len(binary_cli), num_nodes)
+ assert_equal(len(bin_dirs), num_nodes)
for i in range(num_nodes):
args = list(extra_args[i])
test_node_i = TestNode(
@@ -544,8 +584,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
rpchost=rpchost,
timewait=self.rpc_timeout,
timeout_factor=self.options.timeout_factor,
- bitcoind=binary[i],
- bitcoin_cli=binary_cli[i],
+ binaries=self.get_binaries(bin_dirs[i]),
version=versions[i],
coverage_dir=self.options.coveragedir,
cwd=self.options.tmpdir,
@@ -856,8 +895,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
rpchost=None,
timewait=self.rpc_timeout,
timeout_factor=self.options.timeout_factor,
- bitcoind=self.options.bitcoind,
- bitcoin_cli=self.options.bitcoincli,
+ binaries=self.get_binaries(),
coverage_dir=None,
cwd=self.options.tmpdir,
descriptors=self.options.descriptors,
@@ -966,16 +1004,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self._requires_wallet = True
if not self.is_wallet_compiled():
raise SkipTest("wallet has not been compiled.")
- if self.options.descriptors:
- self.skip_if_no_sqlite()
- else:
+ if not self.options.descriptors:
self.skip_if_no_bdb()
- def skip_if_no_sqlite(self):
- """Skip the running test if sqlite has not been compiled."""
- if not self.is_sqlite_compiled():
- raise SkipTest("sqlite has not been compiled.")
-
def skip_if_no_bdb(self):
"""Skip the running test if BDB has not been compiled."""
if not self.is_bdb_compiled():
@@ -1030,7 +1061,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
"""Checks whether wallet support for the specified type
(legacy or descriptor wallet) was compiled."""
if self.options.descriptors:
- return self.is_sqlite_compiled()
+ return self.is_wallet_compiled()
else:
return self.is_bdb_compiled()
@@ -1050,10 +1081,6 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
"""Checks whether the USDT tracepoints were compiled."""
return self.config["components"].getboolean("ENABLE_USDT_TRACEPOINTS")
- def is_sqlite_compiled(self):
- """Checks whether the wallet module was compiled with Sqlite support."""
- return self.config["components"].getboolean("USE_SQLITE")
-
def is_bdb_compiled(self):
"""Checks whether the wallet module was compiled with BDB support."""
return self.config["components"].getboolean("USE_BDB")