aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/README.md3
-rw-r--r--test/functional/data/invalid_txs.py11
-rwxr-xr-xtest/functional/feature_block.py1
-rwxr-xr-xtest/functional/feature_fee_estimation.py1
-rwxr-xr-xtest/functional/interface_usdt_validation.py15
-rwxr-xr-xtest/functional/p2p_invalid_tx.py2
-rwxr-xr-xtest/functional/rpc_getorphantxs.py130
-rw-r--r--test/functional/test_framework/mempool_util.py6
-rwxr-xr-xtest/functional/test_runner.py12
-rwxr-xr-xtest/functional/wallet_backwards_compatibility.py27
-rwxr-xr-xtest/functional/wallet_upgradewallet.py1
-rwxr-xr-xtest/lint/commit-script-check.sh14
-rwxr-xr-xtest/lint/lint-format-strings.py2
-rw-r--r--test/lint/test_runner/src/main.rs18
-rwxr-xr-xtest/util/test_runner.py25
15 files changed, 206 insertions, 62 deletions
diff --git a/test/functional/README.md b/test/functional/README.md
index a4994f2e7c..a34bf1827c 100644
--- a/test/functional/README.md
+++ b/test/functional/README.md
@@ -10,7 +10,8 @@ that file and modify to fit your needs.
#### Coverage
-Running `test/functional/test_runner.py` with the `--coverage` argument tracks which RPCs are
+Assuming the build directory is `build`,
+running `build/test/functional/test_runner.py` with the `--coverage` argument tracks which RPCs are
called by the tests and prints a report of uncovered RPCs in the summary. This
can be used (along with the `--extended` argument) to find out which RPCs we
don't have test cases for.
diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py
index 2e4ca83bf0..d2d7202d86 100644
--- a/test/functional/data/invalid_txs.py
+++ b/test/functional/data/invalid_txs.py
@@ -263,6 +263,17 @@ def getDisabledOpcodeTemplate(opcode):
'valid_in_block' : True
})
+class NonStandardAndInvalid(BadTxTemplate):
+ """A non-standard transaction which is also consensus-invalid should return the consensus error."""
+ reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)"
+ expect_disconnect = True
+ valid_in_block = False
+
+ def get_tx(self):
+ return create_tx_with_script(
+ self.spend_tx, 0, script_sig=b'\x00' * 3 + b'\xab\x6a',
+ amount=(self.spend_avail // 2))
+
# Disabled opcode tx templates (CVE-2010-5137)
DisabledOpcodeTemplates = [getDisabledOpcodeTemplate(opcode) for opcode in [
OP_CAT,
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 384ca311c7..43bf61c174 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -88,6 +88,7 @@ class FullBlockTest(BitcoinTestFramework):
self.extra_args = [[
'-acceptnonstdtxn=1', # This is a consensus block test, we don't care about tx policy
'-testactivationheight=bip34@2',
+ '-par=1', # Until https://github.com/bitcoin/bitcoin/issues/30960 is fixed
]]
def run_test(self):
diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py
index 83627ff5c2..974d8268a2 100755
--- a/test/functional/feature_fee_estimation.py
+++ b/test/functional/feature_fee_estimation.py
@@ -398,6 +398,7 @@ class EstimateFeeTest(BitcoinTestFramework):
self.start_node(0)
self.connect_nodes(0, 1)
self.connect_nodes(0, 2)
+ self.sync_blocks()
assert_equal(self.nodes[0].estimatesmartfee(1)["errors"], ["Insufficient data or no feerate found"])
def broadcast_and_mine(self, broadcaster, miner, feerate, count):
diff --git a/test/functional/interface_usdt_validation.py b/test/functional/interface_usdt_validation.py
index 9a37b96ada..8a98a452de 100755
--- a/test/functional/interface_usdt_validation.py
+++ b/test/functional/interface_usdt_validation.py
@@ -8,6 +8,7 @@
"""
import ctypes
+import time
# Test will be skipped if we don't have bcc installed
try:
@@ -105,10 +106,12 @@ class ValidationTracepointTest(BitcoinTestFramework):
handle_blockconnected)
self.log.info(f"mine {BLOCKS_EXPECTED} blocks")
- block_hashes = self.generatetoaddress(
- self.nodes[0], BLOCKS_EXPECTED, ADDRESS_BCRT1_UNSPENDABLE)
- for block_hash in block_hashes:
- expected_blocks[block_hash] = self.nodes[0].getblock(block_hash, 2)
+ generatetoaddress_duration = dict()
+ for _ in range(BLOCKS_EXPECTED):
+ start = time.time()
+ hash = self.generatetoaddress(self.nodes[0], 1, ADDRESS_BCRT1_UNSPENDABLE)[0]
+ generatetoaddress_duration[hash] = (time.time() - start) * 1e9 # in nanoseconds
+ expected_blocks[hash] = self.nodes[0].getblock(hash, 2)
bpf.perf_buffer_poll(timeout=200)
@@ -123,6 +126,10 @@ class ValidationTracepointTest(BitcoinTestFramework):
assert_equal(0, event.sigops) # no sigops in coinbase tx
# only plausibility checks
assert event.duration > 0
+ # generatetoaddress (mining and connecting) takes longer than
+ # connecting the block. In case the duration unit is off, we'll
+ # detect it with this assert.
+ assert event.duration < generatetoaddress_duration[block_hash]
del expected_blocks[block_hash]
assert_equal(BLOCKS_EXPECTED, len(events))
assert_equal(0, len(expected_blocks))
diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py
index 241aefab24..ee8c6c16ca 100755
--- a/test/functional/p2p_invalid_tx.py
+++ b/test/functional/p2p_invalid_tx.py
@@ -165,7 +165,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False)
self.log.info('Test that a peer disconnection causes erase its transactions from the orphan pool')
- with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=25']):
+ with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=26']):
self.reconnect_p2p(num_connections=1)
self.log.info('Test that a transaction in the orphan pool is included in a new tip block causes erase this transaction from the orphan pool')
diff --git a/test/functional/rpc_getorphantxs.py b/test/functional/rpc_getorphantxs.py
new file mode 100755
index 0000000000..8d32ce1638
--- /dev/null
+++ b/test/functional/rpc_getorphantxs.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python3
+# Copyright (c) 2014-2024 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test the getorphantxs RPC."""
+
+from test_framework.mempool_util import tx_in_orphanage
+from test_framework.messages import msg_tx
+from test_framework.p2p import P2PInterface
+from test_framework.util import assert_equal
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.wallet import MiniWallet
+
+
+class GetOrphanTxsTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+
+ def run_test(self):
+ self.wallet = MiniWallet(self.nodes[0])
+ self.test_orphan_activity()
+ self.test_orphan_details()
+
+ def test_orphan_activity(self):
+ self.log.info("Check that orphaned transactions are returned with getorphantxs")
+ node = self.nodes[0]
+
+ self.log.info("Create two 1P1C packages, but only broadcast the children")
+ tx_parent_1 = self.wallet.create_self_transfer()
+ tx_child_1 = self.wallet.create_self_transfer(utxo_to_spend=tx_parent_1["new_utxo"])
+ tx_parent_2 = self.wallet.create_self_transfer()
+ tx_child_2 = self.wallet.create_self_transfer(utxo_to_spend=tx_parent_2["new_utxo"])
+ peer = node.add_p2p_connection(P2PInterface())
+ peer.send_and_ping(msg_tx(tx_child_1["tx"]))
+ peer.send_and_ping(msg_tx(tx_child_2["tx"]))
+
+ self.log.info("Check that neither parent is in the mempool")
+ assert_equal(node.getmempoolinfo()["size"], 0)
+
+ self.log.info("Check that both children are in the orphanage")
+
+ orphanage = node.getorphantxs(verbosity=0)
+ self.log.info("Check the size of the orphanage")
+ assert_equal(len(orphanage), 2)
+ self.log.info("Check that negative verbosity is treated as 0")
+ assert_equal(orphanage, node.getorphantxs(verbosity=-1))
+ assert tx_in_orphanage(node, tx_child_1["tx"])
+ assert tx_in_orphanage(node, tx_child_2["tx"])
+
+ self.log.info("Broadcast parent 1")
+ peer.send_and_ping(msg_tx(tx_parent_1["tx"]))
+ self.log.info("Check that parent 1 and child 1 are in the mempool")
+ raw_mempool = node.getrawmempool()
+ assert_equal(len(raw_mempool), 2)
+ assert tx_parent_1["txid"] in raw_mempool
+ assert tx_child_1["txid"] in raw_mempool
+
+ self.log.info("Check that orphanage only contains child 2")
+ orphanage = node.getorphantxs()
+ assert_equal(len(orphanage), 1)
+ assert tx_in_orphanage(node, tx_child_2["tx"])
+
+ peer.send_and_ping(msg_tx(tx_parent_2["tx"]))
+ self.log.info("Check that all parents and children are now in the mempool")
+ raw_mempool = node.getrawmempool()
+ assert_equal(len(raw_mempool), 4)
+ assert tx_parent_1["txid"] in raw_mempool
+ assert tx_child_1["txid"] in raw_mempool
+ assert tx_parent_2["txid"] in raw_mempool
+ assert tx_child_2["txid"] in raw_mempool
+ self.log.info("Check that the orphanage is empty")
+ assert_equal(len(node.getorphantxs()), 0)
+
+ self.log.info("Confirm the transactions (clears mempool)")
+ self.generate(node, 1)
+ assert_equal(node.getmempoolinfo()["size"], 0)
+
+ def test_orphan_details(self):
+ self.log.info("Check the transaction details returned from getorphantxs")
+ node = self.nodes[0]
+
+ self.log.info("Create two orphans, from different peers")
+ tx_parent_1 = self.wallet.create_self_transfer()
+ tx_child_1 = self.wallet.create_self_transfer(utxo_to_spend=tx_parent_1["new_utxo"])
+ tx_parent_2 = self.wallet.create_self_transfer()
+ tx_child_2 = self.wallet.create_self_transfer(utxo_to_spend=tx_parent_2["new_utxo"])
+ peer_1 = node.add_p2p_connection(P2PInterface())
+ peer_2 = node.add_p2p_connection(P2PInterface())
+ peer_1.send_and_ping(msg_tx(tx_child_1["tx"]))
+ peer_2.send_and_ping(msg_tx(tx_child_2["tx"]))
+
+ orphanage = node.getorphantxs(verbosity=2)
+ assert tx_in_orphanage(node, tx_child_1["tx"])
+ assert tx_in_orphanage(node, tx_child_2["tx"])
+
+ self.log.info("Check that orphan 1 and 2 were from different peers")
+ assert orphanage[0]["from"][0] != orphanage[1]["from"][0]
+
+ self.log.info("Unorphan child 2")
+ peer_2.send_and_ping(msg_tx(tx_parent_2["tx"]))
+ assert not tx_in_orphanage(node, tx_child_2["tx"])
+
+ self.log.info("Checking orphan details")
+ orphanage = node.getorphantxs(verbosity=1)
+ assert_equal(len(node.getorphantxs()), 1)
+ orphan_1 = orphanage[0]
+ self.orphan_details_match(orphan_1, tx_child_1, verbosity=1)
+
+ self.log.info("Checking orphan details (verbosity 2)")
+ orphanage = node.getorphantxs(verbosity=2)
+ orphan_1 = orphanage[0]
+ self.orphan_details_match(orphan_1, tx_child_1, verbosity=2)
+
+ def orphan_details_match(self, orphan, tx, verbosity):
+ self.log.info("Check txid/wtxid of orphan")
+ assert_equal(orphan["txid"], tx["txid"])
+ assert_equal(orphan["wtxid"], tx["wtxid"])
+
+ self.log.info("Check the sizes of orphan")
+ assert_equal(orphan["bytes"], len(tx["tx"].serialize()))
+ assert_equal(orphan["vsize"], tx["tx"].get_vsize())
+ assert_equal(orphan["weight"], tx["tx"].get_weight())
+
+ if verbosity == 2:
+ self.log.info("Check the transaction hex of orphan")
+ assert_equal(orphan["hex"], tx["hex"])
+
+
+if __name__ == '__main__':
+ GetOrphanTxsTest(__file__).main()
diff --git a/test/functional/test_framework/mempool_util.py b/test/functional/test_framework/mempool_util.py
index fe47123e13..a6a7940c60 100644
--- a/test/functional/test_framework/mempool_util.py
+++ b/test/functional/test_framework/mempool_util.py
@@ -8,6 +8,7 @@ from decimal import Decimal
from .blocktools import (
COINBASE_MATURITY,
)
+from .messages import CTransaction
from .util import (
assert_equal,
assert_greater_than,
@@ -83,3 +84,8 @@ def fill_mempool(test_framework, node, *, tx_sync_fun=None):
test_framework.log.debug("Check that mempoolminfee is larger than minrelaytxfee")
assert_equal(node.getmempoolinfo()['minrelaytxfee'], Decimal('0.00001000'))
assert_greater_than(node.getmempoolinfo()['mempoolminfee'], Decimal('0.00001000'))
+
+def tx_in_orphanage(node, tx: CTransaction) -> bool:
+ """Returns true if the transaction is in the orphanage."""
+ found = [o for o in node.getorphantxs(verbosity=1) if o["txid"] == tx.rehash() and o["wtxid"] == tx.getwtxid()]
+ return len(found) == 1
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 301f62d7b0..3d8c230066 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -160,6 +160,7 @@ BASE_SCRIPTS = [
'wallet_importmulti.py --legacy-wallet',
'mempool_limit.py',
'rpc_txoutproof.py',
+ 'rpc_getorphantxs.py',
'wallet_listreceivedby.py --legacy-wallet',
'wallet_listreceivedby.py --descriptors',
'wallet_abandonconflict.py --legacy-wallet',
@@ -446,8 +447,8 @@ def main():
help="Leave bitcoinds and test.* datadir on exit or error")
parser.add_argument('--resultsfile', '-r', help='store test results (as CSV) to the provided file')
-
args, unknown_args = parser.parse_known_args()
+ fail_on_warn = args.ci
if not args.ansi:
global DEFAULT, BOLD, GREEN, RED
DEFAULT = ("", "")
@@ -524,8 +525,12 @@ def main():
# Remove the test cases that the user has explicitly asked to exclude.
# The user can specify a test case with or without the .py extension.
if args.exclude:
+
def print_warning_missing_test(test_name):
- print("{}WARNING!{} Test '{}' not found in current test list.".format(BOLD[1], BOLD[0], test_name))
+ print("{}WARNING!{} Test '{}' not found in current test list. Check the --exclude list.".format(BOLD[1], BOLD[0], test_name))
+ if fail_on_warn:
+ sys.exit(1)
+
def remove_tests(exclude_list):
if not exclude_list:
print_warning_missing_test(exclude_test)
@@ -562,7 +567,7 @@ def main():
f"A minimum of {MIN_NO_CLEANUP_SPACE // (1024 * 1024 * 1024)} GB of free space is required.")
passon_args.append("--nocleanup")
- check_script_list(src_dir=config["environment"]["SRCDIR"], fail_on_warn=args.ci)
+ check_script_list(src_dir=config["environment"]["SRCDIR"], fail_on_warn=fail_on_warn)
check_script_prefixes()
if not args.keepcache:
@@ -871,7 +876,6 @@ def check_script_list(*, src_dir, fail_on_warn):
if len(missed_tests) != 0:
print("%sWARNING!%s The following scripts are not being run: %s. Check the test lists in test_runner.py." % (BOLD[1], BOLD[0], str(missed_tests)))
if fail_on_warn:
- # On CI this warning is an error to prevent merging incomplete commits into master
sys.exit(1)
diff --git a/test/functional/wallet_backwards_compatibility.py b/test/functional/wallet_backwards_compatibility.py
index e71283b928..775786fbb1 100755
--- a/test/functional/wallet_backwards_compatibility.py
+++ b/test/functional/wallet_backwards_compatibility.py
@@ -33,7 +33,7 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
- self.num_nodes = 12
+ self.num_nodes = 11
# Add new version after each release:
self.extra_args = [
["-addresstype=bech32", "-whitelist=noban@127.0.0.1"], # Pre-release: use to mine blocks. noban for immediate tx relay
@@ -47,7 +47,6 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
["-nowallet", "-walletrbf=1", "-addresstype=bech32", "-whitelist=noban@127.0.0.1"], # v0.19.1
["-nowallet", "-walletrbf=1", "-addresstype=bech32", "-whitelist=127.0.0.1"], # v0.18.1
["-nowallet", "-walletrbf=1", "-addresstype=bech32", "-whitelist=127.0.0.1"], # v0.17.2
- ["-nowallet", "-walletrbf=1", "-addresstype=bech32", "-whitelist=127.0.0.1", "-wallet=wallet.dat"], # v0.16.3
]
self.wallet_names = [self.default_wallet_name]
@@ -68,7 +67,6 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
190100,
180100,
170200,
- 160300,
])
self.start_nodes()
@@ -133,18 +131,17 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
def run_test(self):
node_miner = self.nodes[0]
node_master = self.nodes[1]
- node_v21 = self.nodes[self.num_nodes - 6]
- node_v17 = self.nodes[self.num_nodes - 2]
- node_v16 = self.nodes[self.num_nodes - 1]
+ node_v21 = self.nodes[self.num_nodes - 5]
+ node_v17 = self.nodes[self.num_nodes - 1]
legacy_nodes = self.nodes[2:] # Nodes that support legacy wallets
- legacy_only_nodes = self.nodes[-5:] # Nodes that only support legacy wallets
- descriptors_nodes = self.nodes[2:-5] # Nodes that support descriptor wallets
+ legacy_only_nodes = self.nodes[-4:] # Nodes that only support legacy wallets
+ descriptors_nodes = self.nodes[2:-4] # Nodes that support descriptor wallets
self.generatetoaddress(node_miner, COINBASE_MATURITY + 1, node_miner.getnewaddress())
# Sanity check the test framework:
- res = node_v16.getblockchaininfo()
+ res = node_v17.getblockchaininfo()
assert_equal(res['blocks'], COINBASE_MATURITY + 1)
self.log.info("Test wallet backwards compatibility...")
@@ -215,9 +212,6 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
# In descriptors wallet mode, run this test on the nodes that support descriptor wallets
# In legacy wallets mode, run this test on the nodes that support legacy wallets
for node in descriptors_nodes if self.options.descriptors else legacy_nodes:
- if self.major_version_less_than(node, 17):
- # loadwallet was introduced in v0.17.0
- continue
self.log.info(f"- {node.version}")
for wallet_name in ["w1", "w2", "w3"]:
if self.major_version_less_than(node, 18) and wallet_name == "w3":
@@ -290,15 +284,6 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
node_v17.assert_start_raises_init_error(["-wallet=w3"], "Error: Error loading w3: Wallet requires newer version of Bitcoin Core")
self.start_node(node_v17.index)
- # No wallet created in master can be opened in 0.16
- self.log.info("Test that wallets created in master are too new for 0.16")
- self.stop_node(node_v16.index)
- for wallet_name in ["w1", "w2", "w3"]:
- if self.options.descriptors:
- node_v16.assert_start_raises_init_error([f"-wallet={wallet_name}"], f"Error: {wallet_name} corrupt, salvage failed")
- else:
- node_v16.assert_start_raises_init_error([f"-wallet={wallet_name}"], f"Error: Error loading {wallet_name}: Wallet requires newer version of Bitcoin Core")
-
# When descriptors are enabled, w1 cannot be opened by 0.21 since it contains a taproot descriptor
if self.options.descriptors:
self.log.info("Test that 0.21 cannot open wallet containing tr() descriptors")
diff --git a/test/functional/wallet_upgradewallet.py b/test/functional/wallet_upgradewallet.py
index ef3f925ee8..c909336a25 100755
--- a/test/functional/wallet_upgradewallet.py
+++ b/test/functional/wallet_upgradewallet.py
@@ -185,6 +185,7 @@ class UpgradeWalletTest(BitcoinTestFramework):
self.restart_node(0)
copy_v16()
wallet = node_master.get_wallet_rpc(self.default_wallet_name)
+ assert_equal(wallet.getbalance(), v16_3_balance)
self.log.info("Test upgradewallet without a version argument")
self.test_upgradewallet(wallet, previous_version=159900, expected_version=169900)
# wallet should still contain the same balance
diff --git a/test/lint/commit-script-check.sh b/test/lint/commit-script-check.sh
index fe845ed19e..52ae95fbb6 100755
--- a/test/lint/commit-script-check.sh
+++ b/test/lint/commit-script-check.sh
@@ -35,20 +35,20 @@ for commit in $(git rev-list --reverse "$1"); do
git checkout --quiet "$commit"^ || exit
SCRIPT="$(git rev-list --format=%b -n1 "$commit" | sed '/^-BEGIN VERIFY SCRIPT-$/,/^-END VERIFY SCRIPT-$/{//!b};d')"
if test -z "$SCRIPT"; then
- echo "Error: missing script for: $commit"
- echo "Failed"
+ echo "Error: missing script for: $commit" >&2
+ echo "Failed" >&2
RET=1
else
- echo "Running script for: $commit"
- echo "$SCRIPT"
+ echo "Running script for: $commit" >&2
+ echo "$SCRIPT" >&2
(eval "$SCRIPT")
- git --no-pager diff --exit-code "$commit" && echo "OK" || (echo "Failed"; false) || RET=1
+ git --no-pager diff --exit-code "$commit" && echo "OK" >&2 || (echo "Failed" >&2; false) || RET=1
fi
git reset --quiet --hard HEAD
else
if git rev-list "--format=%b" -n1 "$commit" | grep -q '^-\(BEGIN\|END\)[ a-zA-Z]*-$'; then
- echo "Error: script block marker but no scripted-diff in title of commit $commit"
- echo "Failed"
+ echo "Error: script block marker but no scripted-diff in title of commit $commit" >&2
+ echo "Failed" >&2
RET=1
fi
fi
diff --git a/test/lint/lint-format-strings.py b/test/lint/lint-format-strings.py
index a809851ec6..86a17fb0f8 100755
--- a/test/lint/lint-format-strings.py
+++ b/test/lint/lint-format-strings.py
@@ -62,7 +62,7 @@ def main():
matching_files_filtered = []
for matching_file in matching_files:
- if not re.search('^src/(leveldb|secp256k1|minisketch|tinyformat|test/fuzz/strprintf.cpp)|contrib/devtools/bitcoin-tidy/example_logprintf.cpp', matching_file):
+ if not re.search('^src/(leveldb|secp256k1|minisketch|tinyformat|test/fuzz/strprintf.cpp)', matching_file):
matching_files_filtered.append(matching_file)
matching_files_filtered.sort()
diff --git a/test/lint/test_runner/src/main.rs b/test/lint/test_runner/src/main.rs
index 64a1486a4c..42c880052e 100644
--- a/test/lint/test_runner/src/main.rs
+++ b/test/lint/test_runner/src/main.rs
@@ -29,7 +29,7 @@ fn get_linter_list() -> Vec<&'static Linter> {
lint_fn: lint_doc
},
&Linter {
- description: "Check that no symbol from bitcoin-config.h is used without the header being included",
+ description: "Check that no symbol from bitcoin-build-config.h is used without the header being included",
name: "includes_build_config",
lint_fn: lint_includes_build_config
},
@@ -395,7 +395,7 @@ Please add any false positives, such as subtrees, or externally sourced files to
}
fn lint_includes_build_config() -> LintResult {
- let config_path = "./cmake/bitcoin-config.h.in";
+ let config_path = "./cmake/bitcoin-build-config.h.in";
let defines_regex = format!(
r"^\s*(?!//).*({})",
check_output(Command::new("grep").args(["define", "--", config_path]))
@@ -429,7 +429,7 @@ fn lint_includes_build_config() -> LintResult {
])
.args(get_pathspecs_exclude_subtrees())
.args([
- // These are exceptions which don't use bitcoin-config.h, rather the Makefile.am adds
+ // These are exceptions which don't use bitcoin-build-config.h, rather CMakeLists.txt adds
// these cppflags manually.
":(exclude)src/crypto/sha256_arm_shani.cpp",
":(exclude)src/crypto/sha256_avx2.cpp",
@@ -447,9 +447,9 @@ fn lint_includes_build_config() -> LintResult {
"--files-with-matches"
},
if mode {
- "^#include <config/bitcoin-config.h> // IWYU pragma: keep$"
+ "^#include <bitcoin-build-config.h> // IWYU pragma: keep$"
} else {
- "#include <config/bitcoin-config.h>" // Catch redundant includes with and without the IWYU pragma
+ "#include <bitcoin-build-config.h>" // Catch redundant includes with and without the IWYU pragma
},
"--",
])
@@ -463,11 +463,11 @@ fn lint_includes_build_config() -> LintResult {
return Err(format!(
r#"
^^^
-One or more files use a symbol declared in the bitcoin-config.h header. However, they are not
+One or more files use a symbol declared in the bitcoin-build-config.h header. However, they are not
including the header. This is problematic, because the header may or may not be indirectly
included. If the indirect include were to be intentionally or accidentally removed, the build could
still succeed, but silently be buggy. For example, a slower fallback algorithm could be picked,
-even though bitcoin-config.h indicates that a faster feature is available and should be used.
+even though bitcoin-build-config.h indicates that a faster feature is available and should be used.
If you are unsure which symbol is used, you can find it with this command:
git grep --perl-regexp '{}' -- file_name
@@ -475,7 +475,7 @@ git grep --perl-regexp '{}' -- file_name
Make sure to include it with the IWYU pragma. Otherwise, IWYU may falsely instruct to remove the
include again.
-#include <config/bitcoin-config.h> // IWYU pragma: keep
+#include <bitcoin-build-config.h> // IWYU pragma: keep
"#,
defines_regex
));
@@ -484,7 +484,7 @@ include again.
if redundant {
return Err(r#"
^^^
-None of the files use a symbol declared in the bitcoin-config.h header. However, they are including
+None of the files use a symbol declared in the bitcoin-build-config.h header. However, they are including
the header. Consider removing the unused include.
"#
.to_string());
diff --git a/test/util/test_runner.py b/test/util/test_runner.py
index e4a77d53d6..cac184ca30 100755
--- a/test/util/test_runner.py
+++ b/test/util/test_runner.py
@@ -83,13 +83,11 @@ def bctest(testDir, testObj, buildenv):
execrun = [execprog] + execargs
# Read the input data (if there is any)
- stdinCfg = None
inputData = None
if "input" in testObj:
filename = os.path.join(testDir, testObj["input"])
with open(filename, encoding="utf8") as f:
inputData = f.read()
- stdinCfg = subprocess.PIPE
# Read the expected output data (if there is any)
outputFn = None
@@ -112,9 +110,8 @@ def bctest(testDir, testObj, buildenv):
raise Exception
# Run the test
- proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
try:
- outs = proc.communicate(input=inputData)
+ res = subprocess.run(execrun, capture_output=True, text=True, input=inputData)
except OSError:
logging.error("OSError, Failed to execute " + execprog)
raise
@@ -123,9 +120,9 @@ def bctest(testDir, testObj, buildenv):
data_mismatch, formatting_mismatch = False, False
# Parse command output and expected output
try:
- a_parsed = parse_output(outs[0], outputType)
+ a_parsed = parse_output(res.stdout, outputType)
except Exception as e:
- logging.error('Error parsing command output as %s: %s' % (outputType, e))
+ logging.error(f"Error parsing command output as {outputType}: '{str(e)}'; res: {str(res)}")
raise
try:
b_parsed = parse_output(outputData, outputType)
@@ -134,13 +131,13 @@ def bctest(testDir, testObj, buildenv):
raise
# Compare data
if a_parsed != b_parsed:
- logging.error("Output data mismatch for " + outputFn + " (format " + outputType + ")")
+ logging.error(f"Output data mismatch for {outputFn} (format {outputType}); res: {str(res)}")
data_mismatch = True
# Compare formatting
- if outs[0] != outputData:
- error_message = "Output formatting mismatch for " + outputFn + ":\n"
+ if res.stdout != outputData:
+ error_message = f"Output formatting mismatch for {outputFn}:\nres: {str(res)}\n"
error_message += "".join(difflib.context_diff(outputData.splitlines(True),
- outs[0].splitlines(True),
+ res.stdout.splitlines(True),
fromfile=outputFn,
tofile="returned"))
logging.error(error_message)
@@ -152,8 +149,8 @@ def bctest(testDir, testObj, buildenv):
wantRC = 0
if "return_code" in testObj:
wantRC = testObj['return_code']
- if proc.returncode != wantRC:
- logging.error("Return code mismatch for " + outputFn)
+ if res.returncode != wantRC:
+ logging.error(f"Return code mismatch for {outputFn}; res: {str(res)}")
raise Exception
if "error_txt" in testObj:
@@ -164,8 +161,8 @@ def bctest(testDir, testObj, buildenv):
# emits DISPLAY errors when running as a windows application on
# linux through wine. Just assert that the expected error text appears
# somewhere in stderr.
- if want_error not in outs[1]:
- logging.error("Error mismatch:\n" + "Expected: " + want_error + "\nReceived: " + outs[1].rstrip())
+ if want_error not in res.stderr:
+ logging.error(f"Error mismatch:\nExpected: {want_error}\nReceived: {res.stderr.rstrip()}\nres: {str(res)}")
raise Exception
def parse_output(a, fmt):