aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/README.md26
-rwxr-xr-xtest/functional/mempool_persist.py24
-rwxr-xr-xtest/functional/rpc_blockchain.py2
-rwxr-xr-xtest/functional/rpc_net.py23
-rwxr-xr-xtest/functional/wallet_bumpfee.py28
-rw-r--r--test/lint/lint-python-dead-code-whitelist46
-rwxr-xr-xtest/lint/lint-python-dead-code.sh23
-rwxr-xr-xtest/lint/lint-whitespace.sh4
8 files changed, 72 insertions, 104 deletions
diff --git a/test/README.md b/test/README.md
index 8f08b7afe4..26fd525064 100644
--- a/test/README.md
+++ b/test/README.md
@@ -136,8 +136,10 @@ killall bitcoind
##### Test logging
-The tests contain logging at different levels (debug, info, warning, etc). By
-default:
+The tests contain logging at five different levels (DEBUG, INFO, WARNING, ERROR
+and CRITICAL). From within your functional tests you can log to these different
+levels using the logger included in the test_framework, e.g.
+`self.log.debug(object)`. By default:
- when run through the test_runner harness, *all* logs are written to
`test_framework.log` and no logs are output to the console.
@@ -182,18 +184,32 @@ call methods that interact with the bitcoind nodes-under-test.
If further introspection of the bitcoind instances themselves becomes
necessary, this can be accomplished by first setting a pdb breakpoint
at an appropriate location, running the test to that point, then using
-`gdb` to attach to the process and debug.
+`gdb` (or `lldb` on macOS) to attach to the process and debug.
-For instance, to attach to `self.node[1]` during a run:
+For instance, to attach to `self.node[1]` during a run you can get
+the pid of the node within `pdb`.
+
+```
+(pdb) self.node[1].process.pid
+```
+
+Alternatively, you can find the pid by inspecting the temp folder for the specific test
+you are running. The path to that folder is printed at the beginning of every
+test run:
```bash
2017-06-27 14:13:56.686000 TestFramework (INFO): Initializing test directory /tmp/user/1000/testo9vsdjo3
```
-use the directory path to get the pid from the pid file:
+Use the path to find the pid file in the temp folder:
```bash
cat /tmp/user/1000/testo9vsdjo3/node1/regtest/bitcoind.pid
+```
+
+Then you can use the pid to start `gdb`:
+
+```bash
gdb /home/example/bitcoind <pid>
```
diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py
index bb0169ee52..398fdeb326 100755
--- a/test/functional/mempool_persist.py
+++ b/test/functional/mempool_persist.py
@@ -37,9 +37,15 @@ Test is as follows:
"""
from decimal import Decimal
import os
+import time
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal, assert_raises_rpc_error, wait_until
+from test_framework.util import (
+ assert_equal,
+ assert_greater_than_or_equal,
+ assert_raises_rpc_error,
+ wait_until,
+)
class MempoolPersistTest(BitcoinTestFramework):
@@ -51,18 +57,13 @@ class MempoolPersistTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def run_test(self):
- chain_height = self.nodes[0].getblockcount()
- assert_equal(chain_height, 200)
-
- self.log.debug("Mine a single block to get out of IBD")
- self.nodes[0].generate(1)
- self.sync_all()
-
self.log.debug("Send 5 transactions from node2 (to its own address)")
+ tx_creation_time_lower = int(time.time())
for i in range(5):
last_txid = self.nodes[2].sendtoaddress(self.nodes[2].getnewaddress(), Decimal("10"))
node2_balance = self.nodes[2].getbalance()
self.sync_all()
+ tx_creation_time_higher = int(time.time())
self.log.debug("Verify that node0 and node1 have 5 transactions in their mempools")
assert_equal(len(self.nodes[0].getrawmempool()), 5)
@@ -75,6 +76,10 @@ class MempoolPersistTest(BitcoinTestFramework):
fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees']
assert_equal(fees['base'] + Decimal('0.00001000'), fees['modified'])
+ tx_creation_time = self.nodes[0].getmempoolentry(txid=last_txid)['time']
+ assert_greater_than_or_equal(tx_creation_time, tx_creation_time_lower)
+ assert_greater_than_or_equal(tx_creation_time_higher, tx_creation_time)
+
self.log.debug("Stop-start the nodes. Verify that node0 has the transactions in its mempool and node1 does not. Verify that node2 calculates its balance correctly after loading wallet transactions.")
self.stop_nodes()
# Give this node a head-start, so we can be "extra-sure" that it didn't load anything later
@@ -93,6 +98,9 @@ class MempoolPersistTest(BitcoinTestFramework):
fees = self.nodes[0].getmempoolentry(txid=last_txid)['fees']
assert_equal(fees['base'] + Decimal('0.00001000'), fees['modified'])
+ self.log.debug('Verify time is loaded correctly')
+ assert_equal(tx_creation_time, self.nodes[0].getmempoolentry(txid=last_txid)['time'])
+
# Verify accounting of mempool transactions after restart is correct
self.nodes[2].syncwithvalidationinterfacequeue() # Flush mempool to wallet
assert_equal(node2_balance, self.nodes[2].getbalance())
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index 266a0d6cd2..278ce6d911 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -134,7 +134,7 @@ class BlockchainTest(BitcoinTestFramework):
'bip9': {
'status': 'started',
'bit': 28,
- 'startTime': 0,
+ 'start_time': 0,
'timeout': 0x7fffffffffffffff, # testdummy does not have a timeout so is set to the max int64 value
'since': 144,
'statistics': {
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
index e24bf3111b..615f9abbe0 100755
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -20,13 +20,12 @@ from test_framework.util import (
wait_until,
)
from test_framework.mininode import P2PInterface
+import test_framework.messages
from test_framework.messages import (
CAddress,
msg_addr,
NODE_NETWORK,
NODE_WITNESS,
- NODE_GETUTXO,NODE_BLOOM,
- NODE_NETWORK_LIMITED,
)
def assert_net_servicesnames(servicesflag, servicenames):
@@ -34,18 +33,12 @@ def assert_net_servicesnames(servicesflag, servicenames):
`getpeerinfo` and `getnetworkinfo`.
:param servicesflag: The services as an integer.
- :param servicesnames: The list of decoded services names, as strings.
+ :param servicenames: The list of decoded services names, as strings.
"""
- if servicesflag & NODE_NETWORK:
- assert "NETWORK" in servicenames
- if servicesflag & NODE_GETUTXO:
- assert "GETUTXO" in servicenames
- if servicesflag & NODE_BLOOM:
- assert "BLOOM" in servicenames
- if servicesflag & NODE_WITNESS:
- assert "WITNESS" in servicenames
- if servicesflag & NODE_NETWORK_LIMITED:
- assert "NETWORK_LIMITED" in servicenames
+ servicesflag_generated = 0
+ for servicename in servicenames:
+ servicesflag_generated |= getattr(test_framework.messages, 'NODE_' + servicename)
+ assert servicesflag_generated == servicesflag
class NetTest(BitcoinTestFramework):
def set_test_params(self):
@@ -119,7 +112,7 @@ class NetTest(BitcoinTestFramework):
# check the `servicesnames` field
network_info = [node.getnetworkinfo() for node in self.nodes]
for info in network_info:
- assert_net_servicesnames(int(info["localservices"]), info["localservicesnames"])
+ assert_net_servicesnames(int(info["localservices"], 0x10), info["localservicesnames"])
def _test_getaddednodeinfo(self):
assert_equal(self.nodes[0].getaddednodeinfo(), [])
@@ -143,7 +136,7 @@ class NetTest(BitcoinTestFramework):
assert_equal(peer_info[1][0]['minfeefilter'], Decimal("0.00001000"))
# check the `servicesnames` field
for info in peer_info:
- assert_net_servicesnames(int(info[0]["services"]), info[0]["servicesnames"])
+ assert_net_servicesnames(int(info[0]["services"], 0x10), info[0]["servicesnames"])
def _test_getnodeaddresses(self):
self.nodes[0].add_p2p_connection(P2PInterface())
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index a1ec28076b..0948d47653 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -68,7 +68,9 @@ class BumpFeeTest(BitcoinTestFramework):
self.log.info("Running tests")
dest_address = peer_node.getnewaddress()
- test_simple_bumpfee_succeeds(self, rbf_node, peer_node, dest_address)
+ test_simple_bumpfee_succeeds(self, "default", rbf_node, peer_node, dest_address)
+ test_simple_bumpfee_succeeds(self, "fee_rate", rbf_node, peer_node, dest_address)
+ test_feerate_args(self, rbf_node, peer_node, dest_address)
test_segwit_bumpfee_succeeds(rbf_node, dest_address)
test_nonrbf_bumpfee_fails(peer_node, dest_address)
test_notmine_bumpfee_fails(rbf_node, peer_node, dest_address)
@@ -89,12 +91,15 @@ class BumpFeeTest(BitcoinTestFramework):
self.log.info("Success")
-def test_simple_bumpfee_succeeds(self, rbf_node, peer_node, dest_address):
+def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address):
rbfid = spend_one_input(rbf_node, dest_address)
rbftx = rbf_node.gettransaction(rbfid)
self.sync_mempools((rbf_node, peer_node))
assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool()
- bumped_tx = rbf_node.bumpfee(rbfid)
+ if mode == "fee_rate":
+ bumped_tx = rbf_node.bumpfee(rbfid, {"fee_rate":0.0015})
+ else:
+ bumped_tx = rbf_node.bumpfee(rbfid)
assert_equal(bumped_tx["errors"], [])
assert bumped_tx["fee"] - abs(rbftx["fee"]) > 0
# check that bumped_tx propagates, original tx was evicted and has a wallet conflict
@@ -110,6 +115,22 @@ def test_simple_bumpfee_succeeds(self, rbf_node, peer_node, dest_address):
assert_equal(oldwtx["replaced_by_txid"], bumped_tx["txid"])
assert_equal(bumpedwtx["replaces_txid"], rbfid)
+def test_feerate_args(self, rbf_node, peer_node, dest_address):
+ rbfid = spend_one_input(rbf_node, dest_address)
+ self.sync_mempools((rbf_node, peer_node))
+ assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool()
+
+ assert_raises_rpc_error(-8, "confTarget can't be set with totalFee or fee_rate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate.", rbf_node.bumpfee, rbfid, {"fee_rate":0.00001, "confTarget":1})
+ assert_raises_rpc_error(-8, "confTarget can't be set with totalFee or fee_rate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate.", rbf_node.bumpfee, rbfid, {"totalFee":0.00001, "confTarget":1})
+ assert_raises_rpc_error(-8, "fee_rate can't be set along with totalFee.", rbf_node.bumpfee, rbfid, {"fee_rate":0.00001, "totalFee":0.001})
+
+ # Bumping to just above minrelay should fail to increase total fee enough, at least
+ assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, rbfid, {"fee_rate":0.00001000})
+
+ assert_raises_rpc_error(-3, "Amount out of range", rbf_node.bumpfee, rbfid, {"fee_rate":-1})
+
+ assert_raises_rpc_error(-4, "is too high (cannot be higher than", rbf_node.bumpfee, rbfid, {"fee_rate":1})
+
def test_segwit_bumpfee_succeeds(rbf_node, dest_address):
# Create a transaction with segwit output, then create an RBF transaction
@@ -177,7 +198,6 @@ def test_bumpfee_with_descendant_fails(rbf_node, rbf_node_address, dest_address)
rbf_node.sendrawtransaction(tx["hex"])
assert_raises_rpc_error(-8, "Transaction has descendants in the wallet", rbf_node.bumpfee, parent_id)
-
def test_small_output_fails(rbf_node, dest_address):
# cannot bump fee with a too-small output
rbfid = spend_one_input(rbf_node, dest_address)
diff --git a/test/lint/lint-python-dead-code-whitelist b/test/lint/lint-python-dead-code-whitelist
deleted file mode 100644
index 33bb7b44fa..0000000000
--- a/test/lint/lint-python-dead-code-whitelist
+++ /dev/null
@@ -1,46 +0,0 @@
-BadInputOutpointIndex # unused class (test/functional/data/invalid_txs.py)
-_.carbon_path # unused attribute (contrib/macdeploy/custom_dsstore.py)
-connection_lost # unused function (test/functional/test_framework/mininode.py)
-connection_made # unused function (test/functional/test_framework/mininode.py)
-_.converter # unused attribute (test/functional/test_framework/test_framework.py)
-_.daemon # unused attribute (test/functional/test_framework/socks5.py)
-data_received # unused function (test/functional/test_framework/mininode.py)
-DuplicateInput # unused class (test/functional/data/invalid_txs.py)
-DisabledOpcodeTemplates # unused class (test/functional/data/invalid_txs.py)
-_.filename # unused attribute (contrib/macdeploy/custom_dsstore.py)
-InvalidOPIFConstruction # unused class (test/functional/data/invalid_txs.py)
-_.is_compressed # unused property (test/functional/test_framework/key.py)
-legacy # unused variable (test/functional/test_framework/address.py)
-msg_generic # unused class (test/functional/test_framework/messages.py)
-NonexistentInput # unused class (test/functional/data/invalid_txs.py)
-on_addr # unused function (test/functional/test_framework/mininode.py)
-on_blocktxn # unused function (test/functional/test_framework/mininode.py)
-on_block # unused function (test/functional/test_framework/mininode.py)
-on_cmpctblock # unused function (test/functional/test_framework/mininode.py)
-on_feefilter # unused function (test/functional/test_framework/mininode.py)
-on_getaddr # unused function (test/functional/test_framework/mininode.py)
-on_getblocks # unused function (test/functional/test_framework/mininode.py)
-on_getblocktxn # unused function (test/functional/test_framework/mininode.py)
-on_getdata # unused function (test/functional/test_framework/mininode.py)
-on_getheaders # unused function (test/functional/test_framework/mininode.py)
-on_headers # unused function (test/functional/test_framework/mininode.py)
-on_inv # unused function (test/functional/test_framework/mininode.py)
-on_mempool # unused function (test/functional/test_framework/mininode.py)
-on_notfound # unused function (test/functional/test_framework/mininode.py)
-on_ping # unused function (test/functional/test_framework/mininode.py)
-on_pong # unused function (test/functional/test_framework/mininode.py)
-on_reject # unused function (test/functional/test_framework/mininode.py)
-on_sendcmpct # unused function (test/functional/test_framework/mininode.py)
-on_sendheaders # unused function (test/functional/test_framework/mininode.py)
-on_tx # unused function (test/functional/test_framework/mininode.py)
-on_verack # unused function (test/functional/test_framework/mininode.py)
-on_version # unused function (test/functional/test_framework/mininode.py)
-_.optionxform # unused attribute (test/util/bitcoin-util-test.py)
-OutputMissing # unused class (test/functional/data/invalid_txs.py)
-_.posix_path # unused attribute (contrib/macdeploy/custom_dsstore.py)
-profile_with_perf # unused function (test/functional/test_framework/test_node.py)
-SizeTooSmall # unused class (test/functional/data/invalid_txs.py)
-SpendNegative # unused class (test/functional/data/invalid_txs.py)
-SpendTooMuch # unused class (test/functional/data/invalid_txs.py)
-TooManySigops # unused class (test/functional/data/invalid_txs.py)
-verify_ecdsa # unused function (test/functional/test_framework/key.py)
diff --git a/test/lint/lint-python-dead-code.sh b/test/lint/lint-python-dead-code.sh
deleted file mode 100755
index af37d393e8..0000000000
--- a/test/lint/lint-python-dead-code.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2018 The Bitcoin Core developers
-# Distributed under the MIT software license, see the accompanying
-# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#
-# Find dead Python code.
-
-export LC_ALL=C
-
-if ! command -v vulture > /dev/null; then
- echo "Skipping Python dead code linting since vulture is not installed. Install by running \"pip3 install vulture\""
- exit 0
-fi
-
-VULTURE_SUPPRESSIONS=$(dirname "${BASH_SOURCE[0]}")/lint-python-dead-code-whitelist
-if ! vulture \
- --min-confidence 60 \
- $(git rev-parse --show-toplevel) \
- "${VULTURE_SUPPRESSIONS}"; then
- echo "False positives? Suppressions can be added to ${VULTURE_SUPPRESSIONS}"
- exit 1
-fi
diff --git a/test/lint/lint-whitespace.sh b/test/lint/lint-whitespace.sh
index d5c1dee42d..861faf8516 100755
--- a/test/lint/lint-whitespace.sh
+++ b/test/lint/lint-whitespace.sh
@@ -31,14 +31,14 @@ if [ -z "${TRAVIS_COMMIT_RANGE}" ]; then
fi
showdiff() {
- if ! git diff -U0 "${TRAVIS_COMMIT_RANGE}" -- "." ":(exclude)depends/patches/" ":(exclude)src/leveldb/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" ":(exclude)doc/release-notes/"; then
+ if ! git diff -U0 "${TRAVIS_COMMIT_RANGE}" -- "." ":(exclude)depends/patches/" ":(exclude)src/leveldb/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" ":(exclude)doc/release-notes/" ":(exclude)src/qt/locale/"; then
echo "Failed to get a diff"
exit 1
fi
}
showcodediff() {
- if ! git diff -U0 "${TRAVIS_COMMIT_RANGE}" -- *.cpp *.h *.md *.py *.sh ":(exclude)src/leveldb/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" ":(exclude)doc/release-notes/"; then
+ if ! git diff -U0 "${TRAVIS_COMMIT_RANGE}" -- *.cpp *.h *.md *.py *.sh ":(exclude)src/leveldb/" ":(exclude)src/secp256k1/" ":(exclude)src/univalue/" ":(exclude)doc/release-notes/" ":(exclude)src/qt/locale/"; then
echo "Failed to get a diff"
exit 1
fi