Merge bitcoin/bitcoin#32697: test: Turn util/test_runner into functional test

fa21631595 test: Use self.log (MarcoFalke)
fa346f7797 test: Move error string into exception (MarcoFalke)
fa1986181f test: Remove useless catch-throw (MarcoFalke)
fa2f1c55b7 move-only util data to test/functional/data/util (MarcoFalke)
faa18bf287 test: Turn util/test_runner into functional test (MarcoFalke)
fa955154c7 test: Add missing skip_if_no_bitcoin_tx (MarcoFalke)
fac9db6eb0 test: Add missing tx util to Binaries (MarcoFalke)
fa91835ec6 test: Use lowercase env var as attribute name (MarcoFalke)
fac49094cd test: Remove duplicate ConfigParser (MarcoFalke)

Pull request description:

  The `test/util/test_runner.py` has many issues:

  * The boilerplate for the test runner is duplicate or inconsistent with the other (functional) tests. For example, logging options, `ConfigParser` handling, `Binaries` handling ...
  * The cmake/ci behavior is brittle and can silently fail, as explained in https://github.com/bitcoin/bitcoin/issues/31476
  * corecheck (and likely other places that manually run the tests) completely forget to run it
  * If the test is manually called, it runs single threaded, when it could just run in parallel with the other functional tests

  Fix all issues by removing the util test_runner and moving the test logic into a new functional test file.

ACKs for top commit:
  janb84:
    re ACK fa21631595
  brunoerg:
    re-ACK fa21631595
  hebasto:
    re-ACK fa21631595, additional feedback has been addressed since my previous [review](https://github.com/bitcoin/bitcoin/pull/32697#pullrequestreview-2940350432).

Tree-SHA512: 694e647887801f002843a74011035d5ed3dfed091d3f0ae18e812a16a4680e04e60e50de0a92af7e047e8ddd6ff5a7834c690f16fd42b74ebc1674bf9989406f
This commit is contained in:
merge-script
2025-06-30 13:45:14 -04:00
68 changed files with 165 additions and 216 deletions

View File

@@ -84,6 +84,10 @@ class Binaries:
# 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)
@@ -272,9 +276,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.options.timeout_factor = self.options.timeout_factor or (4 if self.options.valgrind else 1)
self.options.previous_releases_path = previous_releases_path
config = configparser.ConfigParser()
config.read_file(open(self.options.configfile))
self.config = config
self.config = configparser.ConfigParser()
self.config.read_file(open(self.options.configfile))
self.binary_paths = self.get_binary_paths()
if self.options.v1transport:
self.options.v2transport=False
@@ -286,19 +289,20 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
paths = types.SimpleNamespace()
binaries = {
"bitcoind": ("bitcoind", "BITCOIND"),
"bitcoin-cli": ("bitcoincli", "BITCOINCLI"),
"bitcoin-util": ("bitcoinutil", "BITCOINUTIL"),
"bitcoin-chainstate": ("bitcoinchainstate", "BITCOINCHAINSTATE"),
"bitcoin-wallet": ("bitcoinwallet", "BITCOINWALLET"),
"bitcoind": "BITCOIND",
"bitcoin-cli": "BITCOINCLI",
"bitcoin-util": "BITCOINUTIL",
"bitcoin-tx": "BITCOINTX",
"bitcoin-chainstate": "BITCOINCHAINSTATE",
"bitcoin-wallet": "BITCOINWALLET",
}
for binary, [attribute_name, env_variable_name] in binaries.items():
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, attribute_name, os.getenv(env_variable_name, default=default_filename))
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
@@ -314,10 +318,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.options.cachedir = os.path.abspath(self.options.cachedir)
config = self.config
os.environ['PATH'] = os.pathsep.join([
os.path.join(config['environment']['BUILDDIR'], 'bin'),
os.path.join(self.config["environment"]["BUILDDIR"], "bin"),
os.environ['PATH']
])
@@ -1000,6 +1002,11 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
if not self.is_wallet_tool_compiled():
raise SkipTest("bitcoin-wallet has not been compiled")
def skip_if_no_bitcoin_tx(self):
"""Skip the running test if bitcoin-tx has not been compiled."""
if not self.is_bitcoin_tx_compiled():
raise SkipTest("bitcoin-tx has not been compiled")
def skip_if_no_bitcoin_util(self):
"""Skip the running test if bitcoin-util has not been compiled."""
if not self.is_bitcoin_util_compiled():
@@ -1054,6 +1061,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
"""Checks whether bitcoin-wallet was compiled."""
return self.config["components"].getboolean("ENABLE_WALLET_TOOL")
def is_bitcoin_tx_compiled(self):
"""Checks whether bitcoin-tx was compiled."""
return self.config["components"].getboolean("BUILD_BITCOIN_TX")
def is_bitcoin_util_compiled(self):
"""Checks whether bitcoin-util was compiled."""
return self.config["components"].getboolean("ENABLE_BITCOIN_UTIL")