diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/README.md | 26 | ||||
-rwxr-xr-x | test/functional/mempool_persist.py | 24 | ||||
-rwxr-xr-x | test/functional/rpc_blockchain.py | 2 | ||||
-rwxr-xr-x | test/functional/rpc_net.py | 23 | ||||
-rwxr-xr-x | test/functional/wallet_bumpfee.py | 28 | ||||
-rw-r--r-- | test/lint/lint-python-dead-code-whitelist | 46 | ||||
-rwxr-xr-x | test/lint/lint-python-dead-code.sh | 23 | ||||
-rwxr-xr-x | test/lint/lint-whitespace.sh | 4 |
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 |