aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/README.md13
-rw-r--r--test/config.ini.in2
-rwxr-xr-xtest/functional/feature_addrman.py87
-rwxr-xr-xtest/functional/feature_anchors.py3
-rwxr-xr-xtest/functional/feature_config_args.py26
-rwxr-xr-xtest/functional/feature_presegwit_node_upgrade.py9
-rwxr-xr-xtest/functional/feature_rbf.py11
-rwxr-xr-xtest/functional/rpc_misc.py2
-rwxr-xr-xtest/functional/rpc_signer.py8
-rwxr-xr-xtest/functional/test_runner.py1
-rwxr-xr-xtest/functional/tool_wallet.py2
-rwxr-xr-xtest/functional/wallet_basic.py2
-rwxr-xr-xtest/lint/lint-circular-dependencies.sh4
-rwxr-xr-xtest/lint/lint-locale-dependence.sh2
-rw-r--r--test/sanitizer_suppressions/ubsan2
-rwxr-xr-xtest/util/test_runner.py (renamed from test/util/bitcoin-util-test.py)0
16 files changed, 142 insertions, 32 deletions
diff --git a/test/README.md b/test/README.md
index 51e61562a4..412d5ae106 100644
--- a/test/README.md
+++ b/test/README.md
@@ -5,20 +5,24 @@ etc.
This directory contains the following sets of tests:
+- [fuzz](/test/fuzz) A runner to execute all fuzz targets from
+ [/src/test/fuzz](/src/test/fuzz).
- [functional](/test/functional) which test the functionality of
bitcoind and bitcoin-qt by interacting with them through the RPC and P2P
interfaces.
-- [util](/test/util) which tests the bitcoin utilities, currently only
-bitcoin-tx.
+- [util](/test/util) which tests the utilities (bitcoin-util, bitcoin-tx, ...).
- [lint](/test/lint/) which perform various static analysis checks.
-The util tests are run as part of `make check` target. The functional
+The util tests are run as part of `make check` target. The fuzz tests, functional
tests and lint scripts can be run as explained in the sections below.
# Running tests locally
Before tests can be run locally, Bitcoin Core must be built. See the [building instructions](/doc#building) for help.
+## Fuzz tests
+
+See [/doc/fuzzing.md](/doc/fuzzing.md)
### Functional tests
@@ -257,7 +261,7 @@ For ways to generate more granular profiles, see the README in
### Util tests
-Util tests can be run locally by running `test/util/bitcoin-util-test.py`.
+Util tests can be run locally by running `test/util/test_runner.py`.
Use the `-v` option for verbose output.
### Lint tests
@@ -269,7 +273,6 @@ Use the `-v` option for verbose output.
| [`lint-python.sh`](lint/lint-python.sh) | [flake8](https://gitlab.com/pycqa/flake8) | [3.8.3](https://github.com/bitcoin/bitcoin/pull/19348) | `pip3 install flake8==3.8.3`
| [`lint-python.sh`](lint/lint-python.sh) | [mypy](https://github.com/python/mypy) | [0.781](https://github.com/bitcoin/bitcoin/pull/19348) | `pip3 install mypy==0.781`
| [`lint-shell.sh`](lint/lint-shell.sh) | [ShellCheck](https://github.com/koalaman/shellcheck) | [0.7.2](https://github.com/bitcoin/bitcoin/pull/21749) | [details...](https://github.com/koalaman/shellcheck#installing)
-| [`lint-shell.sh`](lint/lint-shell.sh) | [yq](https://github.com/kislyuk/yq) | default | `pip3 install yq`
| [`lint-spelling.sh`](lint/lint-spelling.sh) | [codespell](https://github.com/codespell-project/codespell) | [2.0.0](https://github.com/bitcoin/bitcoin/pull/20817) | `pip3 install codespell==2.0.0`
Please be aware that on Linux distributions all dependencies are usually available as packages, but could be outdated.
diff --git a/test/config.ini.in b/test/config.ini.in
index e3872181cd..db80bba6f1 100644
--- a/test/config.ini.in
+++ b/test/config.ini.in
@@ -3,7 +3,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# These environment variables are set by the build process and read by
-# test/functional/test_runner.py and test/util/bitcoin-util-test.py
+# test/*/test_runner.py and test/util/rpcauth-test.py
[environment]
PACKAGE_NAME=@PACKAGE_NAME@
diff --git a/test/functional/feature_addrman.py b/test/functional/feature_addrman.py
new file mode 100755
index 0000000000..8ccff340f0
--- /dev/null
+++ b/test/functional/feature_addrman.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python3
+# Copyright (c) 2021 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 addrman functionality"""
+
+import os
+import struct
+
+from test_framework.messages import ser_uint256, hash256
+from test_framework.p2p import MAGIC_BYTES
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal
+
+
+def serialize_addrman(*, format=1, lowest_compatible=3):
+ new = []
+ tried = []
+ INCOMPATIBILITY_BASE = 32
+ r = MAGIC_BYTES["regtest"]
+ r += struct.pack("B", format)
+ r += struct.pack("B", INCOMPATIBILITY_BASE + lowest_compatible)
+ r += ser_uint256(1)
+ r += struct.pack("i", len(new))
+ r += struct.pack("i", len(tried))
+ ADDRMAN_NEW_BUCKET_COUNT = 1 << 10
+ r += struct.pack("i", ADDRMAN_NEW_BUCKET_COUNT ^ (1 << 30))
+ for _ in range(ADDRMAN_NEW_BUCKET_COUNT):
+ r += struct.pack("i", 0)
+ checksum = hash256(r)
+ r += checksum
+ return r
+
+
+def write_addrman(peers_dat, **kwargs):
+ with open(peers_dat, "wb") as f:
+ f.write(serialize_addrman(**kwargs))
+
+
+class AddrmanTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+
+ def run_test(self):
+ peers_dat = os.path.join(self.nodes[0].datadir, self.chain, "peers.dat")
+
+ self.log.info("Check that mocked addrman is valid")
+ self.stop_node(0)
+ write_addrman(peers_dat)
+ with self.nodes[0].assert_debug_log(["Loaded 0 addresses from peers.dat"]):
+ self.start_node(0, extra_args=["-checkaddrman=1"])
+ assert_equal(self.nodes[0].getnodeaddresses(), [])
+
+ self.log.info("Check that addrman from future cannot be read")
+ self.stop_node(0)
+ write_addrman(peers_dat, lowest_compatible=111)
+ with self.nodes[0].assert_debug_log([
+ f'ERROR: DeserializeDB: Deserialize or I/O error - Unsupported format of addrman database: 1. It is compatible with formats >=111, but the maximum supported by this version of {self.config["environment"]["PACKAGE_NAME"]} is 3.',
+ "Recreating peers.dat",
+ ]):
+ self.start_node(0)
+ assert_equal(self.nodes[0].getnodeaddresses(), [])
+
+ self.log.info("Check that corrupt addrman cannot be read")
+ self.stop_node(0)
+ with open(peers_dat, "wb") as f:
+ f.write(serialize_addrman()[:-1])
+ with self.nodes[0].assert_debug_log([
+ "ERROR: DeserializeDB: Deserialize or I/O error - CAutoFile::read: end of file",
+ "Recreating peers.dat",
+ ]):
+ self.start_node(0)
+ assert_equal(self.nodes[0].getnodeaddresses(), [])
+
+ self.log.info("Check that missing addrman is recreated")
+ self.stop_node(0)
+ os.remove(peers_dat)
+ with self.nodes[0].assert_debug_log([
+ f"Missing or invalid file {peers_dat}",
+ "Recreating peers.dat",
+ ]):
+ self.start_node(0)
+ assert_equal(self.nodes[0].getnodeaddresses(), [])
+
+
+if __name__ == "__main__":
+ AddrmanTest().main()
diff --git a/test/functional/feature_anchors.py b/test/functional/feature_anchors.py
index c39f6e6d4b..7be393a4ea 100755
--- a/test/functional/feature_anchors.py
+++ b/test/functional/feature_anchors.py
@@ -25,9 +25,6 @@ class AnchorsTest(BitcoinTestFramework):
self.num_nodes = 1
self.disable_autoconnect = False
- def setup_network(self):
- self.setup_nodes()
-
def run_test(self):
node_anchors_path = os.path.join(
self.nodes[0].datadir, "regtest", "anchors.dat"
diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py
index 0daa0ba3d8..3d9d8b7441 100755
--- a/test/functional/feature_config_args.py
+++ b/test/functional/feature_config_args.py
@@ -164,11 +164,14 @@ class ConfArgsTest(BitcoinTestFramework):
# fixed seeds
assert not os.path.exists(os.path.join(default_data_dir, "peers.dat"))
start = int(time.time())
- with self.nodes[0].assert_debug_log(expected_msgs=[
- "Loaded 0 addresses from peers.dat",
- "0 addresses found from DNS seeds",
- "opencon thread start", # Ensure ThreadOpenConnections::start time is properly set
- ]):
+ with self.nodes[0].assert_debug_log(
+ expected_msgs=[
+ "Loaded 0 addresses from peers.dat",
+ "0 addresses found from DNS seeds",
+ "opencon thread start", # Ensure ThreadOpenConnections::start time is properly set
+ ],
+ timeout=10,
+ ):
self.start_node(0, extra_args=['-dnsseed=1', '-fixedseeds=1', f'-mocktime={start}'])
with self.nodes[0].assert_debug_log(expected_msgs=[
"Adding fixed seeds as 60 seconds have passed and addrman is empty",
@@ -206,11 +209,14 @@ class ConfArgsTest(BitcoinTestFramework):
# We expect the node will allow 60 seconds prior to using fixed seeds
assert not os.path.exists(os.path.join(default_data_dir, "peers.dat"))
start = int(time.time())
- with self.nodes[0].assert_debug_log(expected_msgs=[
- "Loaded 0 addresses from peers.dat",
- "DNS seeding disabled",
- "opencon thread start", # Ensure ThreadOpenConnections::start time is properly set
- ]):
+ with self.nodes[0].assert_debug_log(
+ expected_msgs=[
+ "Loaded 0 addresses from peers.dat",
+ "DNS seeding disabled",
+ "opencon thread start", # Ensure ThreadOpenConnections::start time is properly set
+ ],
+ timeout=10,
+ ):
self.start_node(0, extra_args=['-dnsseed=0', '-fixedseeds=1', '-addnode=fakenodeaddr', f'-mocktime={start}'])
with self.nodes[0].assert_debug_log(expected_msgs=[
"Adding fixed seeds as 60 seconds have passed and addrman is empty",
diff --git a/test/functional/feature_presegwit_node_upgrade.py b/test/functional/feature_presegwit_node_upgrade.py
index f20c519082..fd6b8620d4 100755
--- a/test/functional/feature_presegwit_node_upgrade.py
+++ b/test/functional/feature_presegwit_node_upgrade.py
@@ -9,6 +9,8 @@ from test_framework.util import (
assert_equal,
softfork_active,
)
+import os
+
class SegwitUpgradeTest(BitcoinTestFramework):
def set_test_params(self):
@@ -35,8 +37,11 @@ class SegwitUpgradeTest(BitcoinTestFramework):
# Restarting the node (with segwit activation height set to 5) should result in a shutdown
# because the blockchain consists of 3 insufficiently validated blocks per segwit consensus rules.
node.assert_start_raises_init_error(
- extra_args=["-segwitheight=5"],
- expected_msg=": Witness data for blocks after height 5 requires validation. Please restart with -reindex..\nPlease restart with -reindex or -reindex-chainstate to recover.")
+ extra_args=["-segwitheight=5"],
+ expected_msg=": Witness data for blocks after height 5 requires "
+ f"validation. Please restart with -reindex..{os.linesep}"
+ "Please restart with -reindex or -reindex-chainstate to recover.",
+ )
# As directed, the user restarts the node with -reindex
self.start_node(0, extra_args=["-reindex", "-segwitheight=5"])
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index 694cca15fd..cb7556feb4 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -618,6 +618,17 @@ class ReplaceByFeeTest(BitcoinTestFramework):
assert_equal(True, self.nodes[0].getmempoolentry(optin_parent_tx['txid'])['bip125-replaceable'])
assert_raises_rpc_error(-26, 'txn-mempool-conflict', self.nodes[0].sendrawtransaction, replacement_child_tx["hex"], 0)
+ self.log.info('Check that the child tx can still be replaced (via a tx that also replaces the parent)')
+ replacement_parent_tx = self.wallet.send_self_transfer(
+ from_node=self.nodes[0],
+ utxo_to_spend=confirmed_utxo,
+ sequence=0xffffffff,
+ fee_rate=Decimal('0.03'),
+ )
+ # Check that child is removed and update wallet utxo state
+ assert_raises_rpc_error(-5, 'Transaction not in mempool', self.nodes[0].getmempoolentry, optout_child_tx['txid'])
+ self.wallet.get_utxo(txid=optout_child_tx['txid'])
+
def test_replacement_relay_fee(self):
tx = self.wallet.send_self_transfer(from_node=self.nodes[0])['tx']
diff --git a/test/functional/rpc_misc.py b/test/functional/rpc_misc.py
index 563f2ea43e..13f33c321f 100755
--- a/test/functional/rpc_misc.py
+++ b/test/functional/rpc_misc.py
@@ -57,7 +57,7 @@ class RpcMiscTest(BitcoinTestFramework):
self.log.info("test logging rpc and help")
# Test logging RPC returns the expected number of logging categories.
- assert_equal(len(node.logging()), 24)
+ assert_equal(len(node.logging()), 25)
# Test toggling a logging category on/off/on with the logging RPC.
assert_equal(node.logging()['qt'], True)
diff --git a/test/functional/rpc_signer.py b/test/functional/rpc_signer.py
index 3188763f49..9e963eba57 100755
--- a/test/functional/rpc_signer.py
+++ b/test/functional/rpc_signer.py
@@ -53,8 +53,12 @@ class RPCSignerTest(BitcoinTestFramework):
)
# Handle script missing:
- assert_raises_rpc_error(-1, 'execve failed: No such file or directory',
- self.nodes[3].enumeratesigners
+ assert_raises_rpc_error(
+ -1,
+ "CreateProcess failed: The system cannot find the file specified."
+ if platform.system() == "Windows"
+ else "execve failed: No such file or directory",
+ self.nodes[3].enumeratesigners,
)
# Handle error thrown by script
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index d6d676da1f..3792d751de 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -282,6 +282,7 @@ BASE_SCRIPTS = [
'p2p_blockfilters.py',
'p2p_message_capture.py',
'feature_includeconf.py',
+ 'feature_addrman.py',
'feature_asmap.py',
'mempool_unbroadcast.py',
'mempool_compatibility.py',
diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py
index a826fb0575..4bf3927879 100755
--- a/test/functional/tool_wallet.py
+++ b/test/functional/tool_wallet.py
@@ -344,7 +344,7 @@ class ToolWalletTest(BitcoinTestFramework):
non_exist_dump = os.path.join(self.nodes[0].datadir, "wallet.nodump")
self.assert_raises_tool_error('Unknown wallet file format "notaformat" provided. Please provide one of "bdb" or "sqlite".', '-wallet=todump', '-format=notaformat', '-dumpfile={}'.format(wallet_dump), 'createfromdump')
self.assert_raises_tool_error('Dump file {} does not exist.'.format(non_exist_dump), '-wallet=todump', '-dumpfile={}'.format(non_exist_dump), 'createfromdump')
- wallet_path = os.path.join(self.nodes[0].datadir, 'regtest/wallets/todump2')
+ wallet_path = os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'todump2')
self.assert_raises_tool_error('Failed to create database path \'{}\'. Database already exists.'.format(wallet_path), '-wallet=todump2', '-dumpfile={}'.format(wallet_dump), 'createfromdump')
self.assert_raises_tool_error("The -descriptors option can only be used with the 'create' command.", '-descriptors', '-wallet=todump2', '-dumpfile={}'.format(wallet_dump), 'createfromdump')
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index e7873a82bb..6372e1acd7 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -600,7 +600,7 @@ class WalletTest(BitcoinTestFramework):
total_txs = len(self.nodes[0].listtransactions("*", 99999))
# Try with walletrejectlongchains
- # Double chain limit but require combining inputs, so we pass SelectCoinsMinConf
+ # Double chain limit but require combining inputs, so we pass AttemptSelection
self.stop_node(0)
extra_args = ["-walletrejectlongchains", "-limitancestorcount=" + str(2 * chainlimit)]
self.start_node(0, extra_args=extra_args)
diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh
index 233381f2d9..8e74f41bb6 100755
--- a/test/lint/lint-circular-dependencies.sh
+++ b/test/lint/lint-circular-dependencies.sh
@@ -24,10 +24,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
"wallet/fees -> wallet/wallet -> wallet/fees"
"wallet/wallet -> wallet/walletdb -> wallet/wallet"
"node/coinstats -> validation -> node/coinstats"
- # Temporary circular dependencies that allow wallet.h/wallet.cpp to be
- # split up in a MOVEONLY commit. These are removed in #21206.
- "wallet/receive -> wallet/wallet -> wallet/receive"
- "wallet/spend -> wallet/wallet -> wallet/spend"
)
EXIT_CODE=0
diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh
index 737d35a397..d6312270e7 100755
--- a/test/lint/lint-locale-dependence.sh
+++ b/test/lint/lint-locale-dependence.sh
@@ -39,10 +39,8 @@ export LC_ALL=C
KNOWN_VIOLATIONS=(
"src/bitcoin-tx.cpp.*stoul"
- "src/bitcoin-tx.cpp.*trim_right"
"src/dbwrapper.cpp.*stoul"
"src/dbwrapper.cpp:.*vsnprintf"
- "src/httprpc.cpp.*trim"
"src/node/blockstorage.cpp:.*atoi"
"src/qt/rpcconsole.cpp:.*atoi"
"src/rest.cpp:.*strtol"
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index b52e105a33..63e7c57ddb 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -5,6 +5,8 @@
# names can be used.
# See https://github.com/google/sanitizers/issues/1364
signed-integer-overflow:txmempool.cpp
+# nLastSuccess read from peers.dat might cause an overflow in IsTerrible
+signed-integer-overflow:addrman.cpp
# https://github.com/bitcoin/bitcoin/pull/21798#issuecomment-829180719
signed-integer-overflow:policy/feerate.cpp
diff --git a/test/util/bitcoin-util-test.py b/test/util/test_runner.py
index aa8fd6eee5..aa8fd6eee5 100755
--- a/test/util/bitcoin-util-test.py
+++ b/test/util/test_runner.py