diff options
Diffstat (limited to 'test/functional')
-rwxr-xr-x | test/functional/blockchain.py | 4 | ||||
-rwxr-xr-x | test/functional/bumpfee.py | 5 | ||||
-rwxr-xr-x | test/functional/example_test.py | 2 | ||||
-rwxr-xr-x | test/functional/fundrawtransaction.py | 3 | ||||
-rwxr-xr-x | test/functional/getblocktemplate_longpoll.py | 2 | ||||
-rwxr-xr-x | test/functional/keypool-topup.py | 2 | ||||
-rwxr-xr-x | test/functional/keypool.py | 3 | ||||
-rwxr-xr-x | test/functional/multiwallet.py | 12 | ||||
-rwxr-xr-x | test/functional/net.py | 2 | ||||
-rwxr-xr-x | test/functional/pruning.py | 4 | ||||
-rwxr-xr-x | test/functional/rawtransactions.py | 2 | ||||
-rwxr-xr-x | test/functional/rpcbind_test.py | 4 | ||||
-rwxr-xr-x | test/functional/test_framework/test_framework.py | 115 | ||||
-rwxr-xr-x | test/functional/test_framework/test_node.py | 134 | ||||
-rw-r--r-- | test/functional/test_framework/util.py | 4 | ||||
-rwxr-xr-x | test/functional/test_runner.py | 4 | ||||
-rwxr-xr-x | test/functional/wallet-dump.py | 3 | ||||
-rwxr-xr-x | test/functional/wallet-encryption.py | 3 | ||||
-rwxr-xr-x | test/functional/wallet-hd.py | 8 |
19 files changed, 206 insertions, 110 deletions
diff --git a/test/functional/blockchain.py b/test/functional/blockchain.py index a7034e6bcd..0812e1b0df 100755 --- a/test/functional/blockchain.py +++ b/test/functional/blockchain.py @@ -139,13 +139,13 @@ class BlockchainTest(BitcoinTestFramework): self.nodes[0].generate(6) assert_equal(self.nodes[0].getblockcount(), 206) self.log.debug('Node should not stop at this height') - assert_raises(subprocess.TimeoutExpired, lambda: self.bitcoind_processes[0].wait(timeout=3)) + assert_raises(subprocess.TimeoutExpired, lambda: self.nodes[0].process.wait(timeout=3)) try: self.nodes[0].generate(1) except (ConnectionError, http.client.BadStatusLine): pass # The node already shut down before response self.log.debug('Node should stop at this height...') - self.bitcoind_processes[0].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + self.nodes[0].process.wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) self.nodes[0] = self.start_node(0, self.options.tmpdir) assert_equal(self.nodes[0].getblockcount(), 207) diff --git a/test/functional/bumpfee.py b/test/functional/bumpfee.py index 9237f09240..9633ffdebb 100755 --- a/test/functional/bumpfee.py +++ b/test/functional/bumpfee.py @@ -41,8 +41,7 @@ class BumpFeeTest(BitcoinTestFramework): self.nodes = self.start_nodes(self.num_nodes, self.options.tmpdir, extra_args) # Encrypt wallet for test_locked_wallet_fails test - self.nodes[1].encryptwallet(WALLET_PASSPHRASE) - self.bitcoind_processes[1].wait() + self.nodes[1].node_encrypt_wallet(WALLET_PASSPHRASE) self.nodes[1] = self.start_node(1, self.options.tmpdir, extra_args[1]) self.nodes[1].walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) @@ -90,7 +89,7 @@ def test_simple_bumpfee_succeeds(rbf_node, peer_node, dest_address): bumped_tx = rbf_node.bumpfee(rbfid) assert_equal(bumped_tx["errors"], []) assert bumped_tx["fee"] - abs(rbftx["fee"]) > 0 - # check that bumped_tx propogates, original tx was evicted and has a wallet conflict + # check that bumped_tx propagates, original tx was evicted and has a wallet conflict sync_mempools((rbf_node, peer_node)) assert bumped_tx["txid"] in rbf_node.getrawmempool() assert bumped_tx["txid"] in peer_node.getrawmempool() diff --git a/test/functional/example_test.py b/test/functional/example_test.py index 7709524f23..79940a4264 100755 --- a/test/functional/example_test.py +++ b/test/functional/example_test.py @@ -200,7 +200,7 @@ class ExampleTest(BitcoinTestFramework): node2.add_connection(connections[1]) node2.wait_for_verack() - self.log.info("Wait for node2 reach current tip. Test that it has propogated all the blocks to us") + self.log.info("Wait for node2 reach current tip. Test that it has propagated all the blocks to us") getdata_request = msg_getdata() for block in blocks: diff --git a/test/functional/fundrawtransaction.py b/test/functional/fundrawtransaction.py index e52e773918..f2f4efcf28 100755 --- a/test/functional/fundrawtransaction.py +++ b/test/functional/fundrawtransaction.py @@ -451,8 +451,7 @@ class RawTransactionsTest(BitcoinTestFramework): self.stop_node(0) self.stop_node(2) self.stop_node(3) - self.nodes[1].encryptwallet("test") - self.bitcoind_processes[1].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + self.nodes[1].node_encrypt_wallet("test") self.nodes = self.start_nodes(self.num_nodes, self.options.tmpdir) # This test is not meant to test fee estimation and we'd like diff --git a/test/functional/getblocktemplate_longpoll.py b/test/functional/getblocktemplate_longpoll.py index bbe1dda5f7..cca30e2688 100755 --- a/test/functional/getblocktemplate_longpoll.py +++ b/test/functional/getblocktemplate_longpoll.py @@ -17,7 +17,7 @@ class LongpollThread(threading.Thread): self.longpollid = templat['longpollid'] # create a new connection to the node, we can't use the same # connection from two threads - self.node = get_rpc_proxy(node.url, 1, timeout=600) + self.node = get_rpc_proxy(node.url, 1, timeout=600, coveragedir=node.coverage_dir) def run(self): self.node.getblocktemplate({'longpollid':self.longpollid}) diff --git a/test/functional/keypool-topup.py b/test/functional/keypool-topup.py index 0e0c0ea74b..da29f697e3 100755 --- a/test/functional/keypool-topup.py +++ b/test/functional/keypool-topup.py @@ -69,7 +69,7 @@ class KeypoolRestoreTest(BitcoinTestFramework): assert_equal(self.nodes[1].listtransactions()[0]['category'], "receive") # Check that we have marked all keys up to the used keypool key as used - assert_equal(self.nodes[1].validateaddress(self.nodes[1].getnewaddress())['hdkeypath'], "m/0'/0'/111'") + assert_equal(self.nodes[1].validateaddress(self.nodes[1].getnewaddress())['hdkeypath'], "m/0'/0'/110'") if __name__ == '__main__': KeypoolRestoreTest().main() diff --git a/test/functional/keypool.py b/test/functional/keypool.py index e8be559918..3e7bb0ee07 100755 --- a/test/functional/keypool.py +++ b/test/functional/keypool.py @@ -17,8 +17,7 @@ class KeyPoolTest(BitcoinTestFramework): assert(addr_before_encrypting_data['hdmasterkeyid'] == wallet_info_old['hdmasterkeyid']) # Encrypt wallet and wait to terminate - nodes[0].encryptwallet('test') - self.bitcoind_processes[0].wait() + nodes[0].node_encrypt_wallet('test') # Restart node 0 nodes[0] = self.start_node(0, self.options.tmpdir) # Keep creating keys diff --git a/test/functional/multiwallet.py b/test/functional/multiwallet.py index 5679f40503..fc6e8e325f 100755 --- a/test/functional/multiwallet.py +++ b/test/functional/multiwallet.py @@ -35,11 +35,15 @@ class MultiWalletTest(BitcoinTestFramework): self.nodes[0] = self.start_node(0, self.options.tmpdir, self.extra_args[0]) - w1 = self.nodes[0] / "wallet/w1" + w1 = self.nodes[0].get_wallet_rpc("w1") + w2 = self.nodes[0].get_wallet_rpc("w2") + w3 = self.nodes[0].get_wallet_rpc("w3") + wallet_bad = self.nodes[0].get_wallet_rpc("bad") + w1.generate(1) # accessing invalid wallet fails - assert_raises_jsonrpc(-18, "Requested wallet does not exist or is not loaded", (self.nodes[0] / "wallet/bad").getwalletinfo) + assert_raises_jsonrpc(-18, "Requested wallet does not exist or is not loaded", wallet_bad.getwalletinfo) # accessing wallet RPC without using wallet endpoint fails assert_raises_jsonrpc(-19, "Wallet file not specified", self.nodes[0].getwalletinfo) @@ -50,14 +54,12 @@ class MultiWalletTest(BitcoinTestFramework): w1_name = w1_info['walletname'] assert_equal(w1_name, "w1") - # check w1 wallet balance - w2 = self.nodes[0] / "wallet/w2" + # check w2 wallet balance w2_info = w2.getwalletinfo() assert_equal(w2_info['immature_balance'], 0) w2_name = w2_info['walletname'] assert_equal(w2_name, "w2") - w3 = self.nodes[0] / "wallet/w3" w3_name = w3.getwalletinfo()['walletname'] assert_equal(w3_name, "w3") diff --git a/test/functional/net.py b/test/functional/net.py index 3ba3764cf9..1e63d38035 100755 --- a/test/functional/net.py +++ b/test/functional/net.py @@ -85,7 +85,7 @@ class NetTest(BitcoinTestFramework): added_nodes = self.nodes[0].getaddednodeinfo(ip_port) assert_equal(len(added_nodes), 1) assert_equal(added_nodes[0]['addednode'], ip_port) - # check that a non-existant node returns an error + # check that a non-existent node returns an error assert_raises_jsonrpc(-24, "Node has not been added", self.nodes[0].getaddednodeinfo, '1.1.1.1') diff --git a/test/functional/pruning.py b/test/functional/pruning.py index 0af91e0658..3e00a34ac4 100755 --- a/test/functional/pruning.py +++ b/test/functional/pruning.py @@ -136,7 +136,7 @@ class PruneTest(BitcoinTestFramework): self.log.info("Invalidating block %s at height %d" % (badhash,invalidheight)) self.nodes[1].invalidateblock(badhash) - # We've now switched to our previously mined-24 block fork on node 1, but thats not what we want + # We've now switched to our previously mined-24 block fork on node 1, but that's not what we want # So invalidate that fork as well, until we're on the same chain as node 0/2 (but at an ancestor 288 blocks ago) mainchainhash = self.nodes[0].getblockhash(invalidheight - 1) curhash = self.nodes[1].getblockhash(invalidheight - 1) @@ -199,7 +199,7 @@ class PruneTest(BitcoinTestFramework): goalbesthash = self.mainchainhash2 # As of 0.10 the current block download logic is not able to reorg to the original chain created in - # create_chain_with_stale_blocks because it doesn't know of any peer thats on that chain from which to + # create_chain_with_stale_blocks because it doesn't know of any peer that's on that chain from which to # redownload its missing blocks. # Invalidate the reorg_test chain in node 0 as well, it can successfully switch to the original chain # because it has all the block data. diff --git a/test/functional/rawtransactions.py b/test/functional/rawtransactions.py index 6272fc69b7..b6b90d6781 100755 --- a/test/functional/rawtransactions.py +++ b/test/functional/rawtransactions.py @@ -2,7 +2,7 @@ # Copyright (c) 2014-2016 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 rawtranscation RPCs. +"""Test the rawtransaction RPCs. Test the following RPCs: - createrawtransaction diff --git a/test/functional/rpcbind_test.py b/test/functional/rpcbind_test.py index 951685aa76..20808207b2 100755 --- a/test/functional/rpcbind_test.py +++ b/test/functional/rpcbind_test.py @@ -37,7 +37,7 @@ class RPCBindTest(BitcoinTestFramework): base_args += ['-rpcallowip=' + x for x in allow_ips] binds = ['-rpcbind='+addr for addr in addresses] self.nodes = self.start_nodes(self.num_nodes, self.options.tmpdir, [base_args + binds], connect_to) - pid = self.bitcoind_processes[0].pid + pid = self.nodes[0].process.pid assert_equal(set(get_bind_addrs(pid)), set(expected)) self.stop_nodes() @@ -49,7 +49,7 @@ class RPCBindTest(BitcoinTestFramework): base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] self.nodes = self.start_nodes(self.num_nodes, self.options.tmpdir, [base_args]) # connect to node through non-loopback interface - node = get_rpc_proxy(rpc_url(get_datadir_path(self.options.tmpdir, 0), 0, "%s:%d" % (rpchost, rpcport)), 0) + node = get_rpc_proxy(rpc_url(get_datadir_path(self.options.tmpdir, 0), 0, "%s:%d" % (rpchost, rpcport)), 0, coveragedir=self.options.coveragedir) node.getnetworkinfo() self.stop_nodes() diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index e562d11938..7903bb0045 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -5,15 +5,12 @@ """Base class for RPC testing.""" from collections import deque -import errno from enum import Enum -import http.client import logging import optparse import os import pdb import shutil -import subprocess import sys import tempfile import time @@ -21,6 +18,7 @@ import traceback from .authproxy import JSONRPCException from . import coverage +from .test_node import TestNode from .util import ( MAX_NODES, PortSeed, @@ -28,12 +26,9 @@ from .util import ( check_json_precision, connect_nodes_bi, disconnect_nodes, - get_rpc_proxy, initialize_datadir, - get_datadir_path, log_filename, p2p_port, - rpc_url, set_node_times, sync_blocks, sync_mempools, @@ -70,7 +65,6 @@ class BitcoinTestFramework(object): self.num_nodes = 4 self.setup_clean_chain = False self.nodes = [] - self.bitcoind_processes = {} self.mocktime = 0 def add_options(self, parser): @@ -213,64 +207,62 @@ class BitcoinTestFramework(object): def start_node(self, i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None, stderr=None): """Start a bitcoind and return RPC connection to it""" - datadir = os.path.join(dirname, "node" + str(i)) + if extra_args is None: + extra_args = [] if binary is None: binary = os.getenv("BITCOIND", "bitcoind") - args = [binary, "-datadir=" + datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(self.mocktime), "-uacomment=testnode%d" % i] - if extra_args is not None: - args.extend(extra_args) - self.bitcoind_processes[i] = subprocess.Popen(args, stderr=stderr) - self.log.debug("initialize_chain: bitcoind started, waiting for RPC to come up") - self._wait_for_bitcoind_start(self.bitcoind_processes[i], datadir, i, rpchost) - self.log.debug("initialize_chain: RPC successfully started") - proxy = get_rpc_proxy(rpc_url(datadir, i, rpchost), i, timeout=timewait) + node = TestNode(i, dirname, extra_args, rpchost, timewait, binary, stderr, self.mocktime, coverage_dir=self.options.coveragedir) + node.start() + node.wait_for_rpc_connection() - if self.options.coveragedir: - coverage.write_all_rpc_commands(self.options.coveragedir, proxy) + if self.options.coveragedir is not None: + coverage.write_all_rpc_commands(self.options.coveragedir, node.rpc) - return proxy + return node def start_nodes(self, num_nodes, dirname, extra_args=None, rpchost=None, timewait=None, binary=None): """Start multiple bitcoinds, return RPC connections to them""" if extra_args is None: - extra_args = [None] * num_nodes + extra_args = [[]] * num_nodes if binary is None: binary = [None] * num_nodes assert_equal(len(extra_args), num_nodes) assert_equal(len(binary), num_nodes) - rpcs = [] + nodes = [] try: for i in range(num_nodes): - rpcs.append(self.start_node(i, dirname, extra_args[i], rpchost, timewait=timewait, binary=binary[i])) + nodes.append(TestNode(i, dirname, extra_args[i], rpchost, timewait=timewait, binary=binary[i], stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir)) + nodes[i].start() + for node in nodes: + node.wait_for_rpc_connection() except: # If one node failed to start, stop the others - # TODO: abusing self.nodes in this way is a little hacky. - # Eventually we should do a better job of tracking nodes - self.nodes.extend(rpcs) self.stop_nodes() - self.nodes = [] raise - return rpcs + + if self.options.coveragedir is not None: + for node in nodes: + coverage.write_all_rpc_commands(self.options.coveragedir, node.rpc) + + return nodes def stop_node(self, i): """Stop a bitcoind test node""" - - self.log.debug("Stopping node %d" % i) - try: - self.nodes[i].stop() - except http.client.CannotSendRequest as e: - self.log.exception("Unable to stop node") - return_code = self.bitcoind_processes[i].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) - del self.bitcoind_processes[i] - assert_equal(return_code, 0) + self.nodes[i].stop_node() + while not self.nodes[i].is_node_stopped(): + time.sleep(0.1) def stop_nodes(self): """Stop multiple bitcoind test nodes""" + for node in self.nodes: + # Issue RPC to stop nodes + node.stop_node() - for i in range(len(self.nodes)): - self.stop_node(i) - assert not self.bitcoind_processes.values() # All connections must be gone now + for node in self.nodes: + # Wait for nodes to stop + while not node.is_node_stopped(): + time.sleep(0.1) def assert_start_raises_init_error(self, i, dirname, extra_args=None, expected_msg=None): with tempfile.SpooledTemporaryFile(max_size=2**16) as log_stderr: @@ -279,6 +271,8 @@ class BitcoinTestFramework(object): self.stop_node(i) except Exception as e: assert 'bitcoind exited' in str(e) # node must have shutdown + self.nodes[i].running = False + self.nodes[i].process = None if expected_msg is not None: log_stderr.seek(0) stderr = log_stderr.read().decode('utf-8') @@ -292,7 +286,7 @@ class BitcoinTestFramework(object): raise AssertionError(assert_msg) def wait_for_node_exit(self, i, timeout): - self.bitcoind_processes[i].wait(timeout) + self.nodes[i].process.wait(timeout) def split_network(self): """ @@ -389,18 +383,13 @@ class BitcoinTestFramework(object): args = [os.getenv("BITCOIND", "bitcoind"), "-server", "-keypool=1", "-datadir=" + datadir, "-discover=0"] if i > 0: args.append("-connect=127.0.0.1:" + str(p2p_port(0))) - self.bitcoind_processes[i] = subprocess.Popen(args) - self.log.debug("initialize_chain: bitcoind started, waiting for RPC to come up") - self._wait_for_bitcoind_start(self.bitcoind_processes[i], datadir, i) - self.log.debug("initialize_chain: RPC successfully started") + self.nodes.append(TestNode(i, cachedir, extra_args=[], rpchost=None, timewait=None, binary=None, stderr=None, mocktime=self.mocktime, coverage_dir=None)) + self.nodes[i].args = args + self.nodes[i].start() - self.nodes = [] - for i in range(MAX_NODES): - try: - self.nodes.append(get_rpc_proxy(rpc_url(get_datadir_path(cachedir, i), i), i)) - except: - self.log.exception("Error connecting to node %d" % i) - sys.exit(1) + # Wait for RPC connections to be ready + for node in self.nodes: + node.wait_for_rpc_connection() # Create a 200-block-long chain; each of the 4 first nodes # gets 25 mature blocks and 25 immature. @@ -444,30 +433,6 @@ class BitcoinTestFramework(object): for i in range(num_nodes): initialize_datadir(test_dir, i) - def _wait_for_bitcoind_start(self, process, datadir, i, rpchost=None): - """Wait for bitcoind to start. - - This means that RPC is accessible and fully initialized. - Raise an exception if bitcoind exits during initialization.""" - while True: - if process.poll() is not None: - raise Exception('bitcoind exited with status %i during initialization' % process.returncode) - try: - # Check if .cookie file to be created - rpc = get_rpc_proxy(rpc_url(datadir, i, rpchost), i, coveragedir=self.options.coveragedir) - rpc.getblockcount() - break # break out of loop on success - except IOError as e: - if e.errno != errno.ECONNREFUSED: # Port not yet open? - raise # unknown IO error - except JSONRPCException as e: # Initialization phase - if e.error['code'] != -28: # RPC in warmup? - raise # unknown JSON RPC exception - except ValueError as e: # cookie file not found and no rpcuser or rpcassword. bitcoind still starting - if "No RPC credentials" not in str(e): - raise - time.sleep(0.25) - class ComparisonTestFramework(BitcoinTestFramework): """Test framework for doing p2p comparison testing diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py new file mode 100755 index 0000000000..4b5dc9a792 --- /dev/null +++ b/test/functional/test_framework/test_node.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 +# Copyright (c) 2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Class for bitcoind node under test""" + +import errno +import http.client +import logging +import os +import subprocess +import time + +from .util import ( + assert_equal, + get_rpc_proxy, + rpc_url, +) +from .authproxy import JSONRPCException + +class TestNode(): + """A class for representing a bitcoind node under test. + + This class contains: + + - state about the node (whether it's running, etc) + - a Python subprocess.Popen object representing the running process + - an RPC connection to the node + + To make things easier for the test writer, a bit of magic is happening under the covers. + Any unrecognised messages will be dispatched to the RPC connection.""" + + def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mocktime, coverage_dir): + self.index = i + self.datadir = os.path.join(dirname, "node" + str(i)) + self.rpchost = rpchost + self.rpc_timeout = timewait + if binary is None: + self.binary = os.getenv("BITCOIND", "bitcoind") + else: + self.binary = binary + self.stderr = stderr + self.coverage_dir = coverage_dir + # Most callers will just need to add extra args to the standard list below. For those callers that need more flexibity, they can just set the args property directly. + self.extra_args = extra_args + self.args = [self.binary, "-datadir=" + self.datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(mocktime), "-uacomment=testnode%d" % i] + + self.running = False + self.process = None + self.rpc_connected = False + self.rpc = None + self.url = None + self.log = logging.getLogger('TestFramework.node%d' % i) + + def __getattr__(self, *args, **kwargs): + """Dispatches any unrecognised messages to the RPC connection.""" + assert self.rpc_connected and self.rpc is not None, "Error: no RPC connection" + return self.rpc.__getattr__(*args, **kwargs) + + def start(self): + """Start the node.""" + self.process = subprocess.Popen(self.args + self.extra_args, stderr=self.stderr) + self.running = True + self.log.debug("bitcoind started, waiting for RPC to come up") + + def wait_for_rpc_connection(self): + """Sets up an RPC connection to the bitcoind process. Returns False if unable to connect.""" + timeout_s = 60 # Wait for up to 60 seconds for the RPC server to respond + poll_per_s = 4 # Poll at a rate of four times per second + for _ in range(timeout_s*poll_per_s): + assert not self.process.poll(), "bitcoind exited with status %i during initialization" % self.process.returncode + try: + self.rpc = get_rpc_proxy(rpc_url(self.datadir, self.index, self.rpchost), self.index, coveragedir=self.coverage_dir) + self.rpc.getblockcount() + # If the call to getblockcount() succeeds then the RPC connection is up + self.rpc_connected = True + self.url = self.rpc.url + self.log.debug("RPC successfully started") + return + except IOError as e: + if e.errno != errno.ECONNREFUSED: # Port not yet open? + raise # unknown IO error + except JSONRPCException as e: # Initialization phase + if e.error['code'] != -28: # RPC in warmup? + raise # unknown JSON RPC exception + except ValueError as e: # cookie file not found and no rpcuser or rpcassword. bitcoind still starting + if "No RPC credentials" not in str(e): + raise + time.sleep(1.0 / poll_per_s) + raise AssertionError("Unable to connect to bitcoind") + + def get_wallet_rpc(self, wallet_name): + assert self.rpc_connected + assert self.rpc + wallet_path = "wallet/%s" % wallet_name + return self.rpc / wallet_path + + def stop_node(self): + """Stop the node.""" + if not self.running: + return + self.log.debug("Stopping node") + try: + self.stop() + except http.client.CannotSendRequest: + self.log.exception("Unable to stop node.") + + def is_node_stopped(self): + """Checks whether the node has stopped. + + Returns True if the node has stopped. False otherwise. + This method is responsible for freeing resources (self.process).""" + if not self.running: + return True + return_code = self.process.poll() + if return_code is not None: + # process has stopped. Assert that it didn't return an error code. + assert_equal(return_code, 0) + self.running = False + self.process = None + self.log.debug("Node stopped") + return True + return False + + def node_encrypt_wallet(self, passphrase): + """"Encrypts the wallet. + + This causes bitcoind to shutdown, so this method takes + care of cleaning up resources.""" + self.encryptwallet(passphrase) + while not self.is_node_stopped(): + time.sleep(0.1) + self.rpc = None + self.rpc_connected = False diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index acca72aa86..4098fd8615 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -204,7 +204,7 @@ def rpc_port(n): return PORT_MIN + PORT_RANGE + n + (MAX_NODES * PortSeed.n) % (PORT_RANGE - 1 - MAX_NODES) def rpc_url(datadir, i, rpchost=None): - rpc_u, rpc_p = get_auth_cookie(datadir, i) + rpc_u, rpc_p = get_auth_cookie(datadir) host = '127.0.0.1' port = rpc_port(i) if rpchost: @@ -232,7 +232,7 @@ def initialize_datadir(dirname, n): def get_datadir_path(dirname, n): return os.path.join(dirname, "node" + str(n)) -def get_auth_cookie(datadir, n): +def get_auth_cookie(datadir): user = None password = None if os.path.isfile(os.path.join(datadir, "bitcoin.conf")): diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index 93f180555d..d248a6c005 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -170,7 +170,7 @@ def main(): Help text and arguments for individual test script:''', formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('--coverage', action='store_true', help='generate a basic coverage report for the RPC interface') - parser.add_argument('--exclude', '-x', help='specify a comma-seperated-list of scripts to exclude.') + parser.add_argument('--exclude', '-x', help='specify a comma-separated-list of scripts to exclude.') parser.add_argument('--extended', action='store_true', help='run the extended test suite in addition to the basic tests') parser.add_argument('--force', '-f', action='store_true', help='run tests even on platforms where they are disabled by default (e.g. windows).') parser.add_argument('--help', '-h', '-?', action='store_true', help='print help text and exit') @@ -352,7 +352,7 @@ def print_results(test_results, max_len_name, runtime): class TestHandler: """ - Trigger the testscrips passed in via the list. + Trigger the test scripts passed in via the list. """ def __init__(self, num_tests_parallel, tests_dir, tmpdir, test_list=None, flags=None): diff --git a/test/functional/wallet-dump.py b/test/functional/wallet-dump.py index 569cc46e6c..61ad00330b 100755 --- a/test/functional/wallet-dump.py +++ b/test/functional/wallet-dump.py @@ -94,8 +94,7 @@ class WalletDumpTest(BitcoinTestFramework): assert_equal(found_addr_rsv, 90*2) # 90 keys plus 100% internal keys #encrypt wallet, restart, unlock and dump - self.nodes[0].encryptwallet('test') - self.bitcoind_processes[0].wait() + self.nodes[0].node_encrypt_wallet('test') self.nodes[0] = self.start_node(0, self.options.tmpdir, self.extra_args[0]) self.nodes[0].walletpassphrase('test', 10) # Should be a no-op: diff --git a/test/functional/wallet-encryption.py b/test/functional/wallet-encryption.py index ba72918fe1..8fea4140db 100755 --- a/test/functional/wallet-encryption.py +++ b/test/functional/wallet-encryption.py @@ -30,8 +30,7 @@ class WalletEncryptionTest(BitcoinTestFramework): assert_equal(len(privkey), 52) # Encrypt the wallet - self.nodes[0].encryptwallet(passphrase) - self.bitcoind_processes[0].wait(timeout=BITCOIND_PROC_WAIT_TIMEOUT) + self.nodes[0].node_encrypt_wallet(passphrase) self.nodes[0] = self.start_node(0, self.options.tmpdir) # Test that the wallet is encrypted diff --git a/test/functional/wallet-hd.py b/test/functional/wallet-hd.py index 821575ed19..751512301e 100755 --- a/test/functional/wallet-hd.py +++ b/test/functional/wallet-hd.py @@ -42,7 +42,7 @@ class WalletHDTest(BitcoinTestFramework): non_hd_add = self.nodes[0].getnewaddress() self.nodes[1].importprivkey(self.nodes[0].dumpprivkey(non_hd_add)) - # This should be enough to keep the master key and the non-HD key + # This should be enough to keep the master key and the non-HD key self.nodes[1].backupwallet(tmpdir + "/hd.bak") #self.nodes[1].dumpwallet(tmpdir + "/hd.dump") @@ -54,7 +54,7 @@ class WalletHDTest(BitcoinTestFramework): for i in range(num_hd_adds): hd_add = self.nodes[1].getnewaddress() hd_info = self.nodes[1].validateaddress(hd_add) - assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i+1)+"'") + assert_equal(hd_info["hdkeypath"], "m/0'/0'/"+str(i)+"'") assert_equal(hd_info["hdmasterkeyid"], masterkeyid) self.nodes[0].sendtoaddress(hd_add, 1) self.nodes[0].generate(1) @@ -83,7 +83,7 @@ class WalletHDTest(BitcoinTestFramework): for _ in range(num_hd_adds): hd_add_2 = self.nodes[1].getnewaddress() hd_info_2 = self.nodes[1].validateaddress(hd_add_2) - assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_+1)+"'") + assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/"+str(_)+"'") assert_equal(hd_info_2["hdmasterkeyid"], masterkeyid) assert_equal(hd_add, hd_add_2) connect_nodes_bi(self.nodes, 0, 1) @@ -101,7 +101,7 @@ class WalletHDTest(BitcoinTestFramework): for out in outs: if out['value'] != 1: keypath = self.nodes[1].validateaddress(out['scriptPubKey']['addresses'][0])['hdkeypath'] - + assert_equal(keypath[0:7], "m/0'/1'") if __name__ == '__main__': |