aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/README.md23
-rwxr-xr-xtest/functional/feature_bip68_sequence.py5
-rwxr-xr-xtest/functional/feature_block.py2
-rwxr-xr-xtest/functional/feature_cltv.py6
-rwxr-xr-xtest/functional/feature_config_args.py17
-rwxr-xr-xtest/functional/feature_includeconf.py6
-rwxr-xr-xtest/functional/feature_maxuploadtarget.py2
-rwxr-xr-xtest/functional/feature_rbf.py2
-rwxr-xr-xtest/functional/feature_segwit.py3
-rwxr-xr-xtest/functional/mempool_accept.py1
-rwxr-xr-xtest/functional/mempool_limit.py6
-rwxr-xr-xtest/functional/mempool_package_onemore.py86
-rwxr-xr-xtest/functional/mining_prioritisetransaction.py5
-rwxr-xr-xtest/functional/p2p_compactblocks.py3
-rwxr-xr-xtest/functional/p2p_invalid_tx.py3
-rwxr-xr-xtest/functional/p2p_node_network_limited.py6
-rwxr-xr-xtest/functional/p2p_segwit.py6
-rwxr-xr-xtest/functional/rpc_users.py182
-rwxr-xr-xtest/functional/test_framework/messages.py2
-rw-r--r--test/functional/test_framework/util.py23
-rwxr-xr-xtest/functional/test_runner.py24
-rwxr-xr-xtest/functional/wallet_basic.py3
-rwxr-xr-xtest/functional/wallet_encryption.py2
23 files changed, 240 insertions, 178 deletions
diff --git a/test/README.md b/test/README.md
index ecea3213ab..8f08b7afe4 100644
--- a/test/README.md
+++ b/test/README.md
@@ -49,6 +49,29 @@ You can run any combination (incl. duplicates) of tests by calling:
test/functional/test_runner.py <testname1> <testname2> <testname3> ...
```
+Wildcard test names can be passed, if the paths are coherent and the test runner
+is called from a `bash` shell or similar that does the globbing. For example,
+to run all the wallet tests:
+
+```
+test/functional/test_runner.py test/functional/wallet*
+functional/test_runner.py functional/wallet* (called from the test/ directory)
+test_runner.py wallet* (called from the test/functional/ directory)
+```
+
+but not
+
+```
+test/functional/test_runner.py wallet*
+```
+
+Combinations of wildcards can be passed:
+
+```
+test/functional/test_runner.py ./test/functional/tool* test/functional/mempool*
+test_runner.py tool* mempool*
+```
+
Run the regression test suite with:
```
diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py
index d38eca6cbe..f0bf09e172 100755
--- a/test/functional/feature_bip68_sequence.py
+++ b/test/functional/feature_bip68_sequence.py
@@ -29,7 +29,10 @@ NOT_FINAL_ERROR = "non-BIP68-final (code 64)"
class BIP68Test(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
- self.extra_args = [[], ["-acceptnonstdtxn=0"]]
+ self.extra_args = [
+ ["-acceptnonstdtxn=1"],
+ ["-acceptnonstdtxn=0"],
+ ]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 3ad83cd2b3..b5eac88ba7 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -78,7 +78,7 @@ class FullBlockTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
- self.extra_args = [[]]
+ self.extra_args = [['-acceptnonstdtxn=1']] # This is a consensus block test, we don't care about tx policy
def run_test(self):
node = self.nodes[0] # convenience reference to the node
diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py
index 7712e8bdf6..af34f9f0db 100755
--- a/test/functional/feature_cltv.py
+++ b/test/functional/feature_cltv.py
@@ -57,7 +57,11 @@ def cltv_validate(node, tx, height):
class BIP65Test(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
- self.extra_args = [['-whitelist=127.0.0.1', '-par=1']] # Use only one script thread to get the exact reject reason for testing
+ self.extra_args = [[
+ '-whitelist=127.0.0.1',
+ '-par=1', # Use only one script thread to get the exact reject reason for testing
+ '-acceptnonstdtxn=1', # cltv_invalidate is nonstandard
+ ]]
self.setup_clean_chain = True
self.rpc_timeout = 120
diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py
index f0d6bc21e6..aae262344d 100755
--- a/test/functional/feature_config_args.py
+++ b/test/functional/feature_config_args.py
@@ -22,7 +22,7 @@ class ConfArgsTest(BitcoinTestFramework):
conf.write('includeconf={}\n'.format(inc_conf_file_path))
self.nodes[0].assert_start_raises_init_error(
- expected_msg='Error parsing command line arguments: Invalid parameter -dash_cli',
+ expected_msg='Error: Error parsing command line arguments: Invalid parameter -dash_cli',
extra_args=['-dash_cli=1'],
)
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
@@ -33,27 +33,32 @@ class ConfArgsTest(BitcoinTestFramework):
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
conf.write('-dash=1\n')
- self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading -')
+ self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading -')
with open(inc_conf_file_path, 'w', encoding='utf8') as conf:
conf.write("wallet=foo\n")
self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Config setting for -wallet only applied on regtest network when in [regtest] section.')
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
+ conf.write('regtest=0\n') # mainnet
+ conf.write('acceptnonstdtxn=1\n')
+ self.nodes[0].assert_start_raises_init_error(expected_msg='Error: acceptnonstdtxn is not currently supported for main chain')
+
+ with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
conf.write('nono\n')
- self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 1: nono, if you intended to specify a negated option, use nono=1 instead')
+ self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 1: nono, if you intended to specify a negated option, use nono=1 instead')
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
conf.write('server=1\nrpcuser=someuser\nrpcpassword=some#pass')
- self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
+ self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
conf.write('server=1\nrpcuser=someuser\nmain.rpcpassword=some#pass')
- self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
+ self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided')
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
conf.write('server=1\nrpcuser=someuser\n[main]\nrpcpassword=some#pass')
- self.nodes[0].assert_start_raises_init_error(expected_msg='Error reading configuration file: parse error on line 4, using # in rpcpassword can be ambiguous and should be avoided')
+ self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Error reading configuration file: parse error on line 4, using # in rpcpassword can be ambiguous and should be avoided')
inc_conf_file2_path = os.path.join(self.nodes[0].datadir, 'include2.conf')
with open(os.path.join(self.nodes[0].datadir, 'bitcoin.conf'), 'a', encoding='utf-8') as conf:
diff --git a/test/functional/feature_includeconf.py b/test/functional/feature_includeconf.py
index d06f6826f0..2cd6a05d08 100755
--- a/test/functional/feature_includeconf.py
+++ b/test/functional/feature_includeconf.py
@@ -43,7 +43,7 @@ class IncludeConfTest(BitcoinTestFramework):
self.log.info("-includeconf cannot be used as command-line arg")
self.stop_node(0)
- self.nodes[0].assert_start_raises_init_error(extra_args=["-includeconf=relative2.conf"], expected_msg="Error parsing command line arguments: -includeconf cannot be used from commandline; -includeconf=relative2.conf")
+ self.nodes[0].assert_start_raises_init_error(extra_args=["-includeconf=relative2.conf"], expected_msg="Error: Error parsing command line arguments: -includeconf cannot be used from commandline; -includeconf=relative2.conf")
self.log.info("-includeconf cannot be used recursively. subversion should end with 'main; relative)/'")
with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "a", encoding="utf8") as f:
@@ -59,11 +59,11 @@ class IncludeConfTest(BitcoinTestFramework):
# Commented out as long as we ignore invalid arguments in configuration files
#with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "w", encoding="utf8") as f:
# f.write("foo=bar\n")
- #self.nodes[0].assert_start_raises_init_error(expected_msg="Error reading configuration file: Invalid configuration value foo")
+ #self.nodes[0].assert_start_raises_init_error(expected_msg="Error: Error reading configuration file: Invalid configuration value foo")
self.log.info("-includeconf cannot be invalid path")
os.remove(os.path.join(self.options.tmpdir, "node0", "relative.conf"))
- self.nodes[0].assert_start_raises_init_error(expected_msg="Error reading configuration file: Failed to include configuration file relative.conf")
+ self.nodes[0].assert_start_raises_init_error(expected_msg="Error: Error reading configuration file: Failed to include configuration file relative.conf")
self.log.info("multiple -includeconf args can be used from the base config file. subversion should end with 'main; relative; relative2)/'")
with open(os.path.join(self.options.tmpdir, "node0", "relative.conf"), "w", encoding="utf8") as f:
diff --git a/test/functional/feature_maxuploadtarget.py b/test/functional/feature_maxuploadtarget.py
index 87c318de9a..180ea0e51d 100755
--- a/test/functional/feature_maxuploadtarget.py
+++ b/test/functional/feature_maxuploadtarget.py
@@ -35,7 +35,7 @@ class MaxUploadTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
- self.extra_args = [["-maxuploadtarget=800"]]
+ self.extra_args = [["-maxuploadtarget=800", "-acceptnonstdtxn=1"]]
# Cache for utxos, as the listunspent may take a long time later in the test
self.utxo_cache = []
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index 1496c5d958..fd79df0b07 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -67,8 +67,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
self.num_nodes = 1
self.extra_args = [
[
+ "-acceptnonstdtxn=1",
"-maxorphantx=1000",
- "-whitelist=127.0.0.1",
"-limitancestorcount=50",
"-limitancestorsize=101",
"-limitdescendantcount=200",
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index 2d4dd96a1d..a71d4071d5 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -53,17 +53,20 @@ class SegWitTest(BitcoinTestFramework):
# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.
self.extra_args = [
[
+ "-acceptnonstdtxn=1",
"-rpcserialversion=0",
"-vbparams=segwit:0:999999999999",
"-addresstype=legacy",
],
[
+ "-acceptnonstdtxn=1",
"-blockversion=4",
"-rpcserialversion=1",
"-vbparams=segwit:0:999999999999",
"-addresstype=legacy",
],
[
+ "-acceptnonstdtxn=1",
"-blockversion=536870915",
"-vbparams=segwit:0:999999999999",
"-addresstype=legacy",
diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
index 2bb5d8ab7d..209a222004 100755
--- a/test/functional/mempool_accept.py
+++ b/test/functional/mempool_accept.py
@@ -36,7 +36,6 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
self.num_nodes = 1
self.extra_args = [[
'-txindex',
- '-acceptnonstdtxn=0', # Try to mimic main-net
]] * self.num_nodes
def skip_test_if_missing_module(self):
diff --git a/test/functional/mempool_limit.py b/test/functional/mempool_limit.py
index 351b27e94a..edf2069933 100755
--- a/test/functional/mempool_limit.py
+++ b/test/functional/mempool_limit.py
@@ -13,7 +13,11 @@ class MempoolLimitTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
- self.extra_args = [["-maxmempool=5", "-spendzeroconfchange=0"]]
+ self.extra_args = [[
+ "-acceptnonstdtxn=1",
+ "-maxmempool=5",
+ "-spendzeroconfchange=0",
+ ]]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/mempool_package_onemore.py b/test/functional/mempool_package_onemore.py
new file mode 100755
index 0000000000..f955c1a77f
--- /dev/null
+++ b/test/functional/mempool_package_onemore.py
@@ -0,0 +1,86 @@
+#!/usr/bin/env python3
+# Copyright (c) 2014-2019 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 descendant package tracking carve-out allowing one final transaction in
+ an otherwise-full package as long as it has only one parent and is <= 10k in
+ size.
+"""
+
+from decimal import Decimal
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal, assert_raises_rpc_error, satoshi_round
+
+MAX_ANCESTORS = 25
+MAX_DESCENDANTS = 25
+
+class MempoolPackagesTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+ self.extra_args = [["-maxorphantx=1000"]]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
+ # Build a transaction that spends parent_txid:vout
+ # Return amount sent
+ def chain_transaction(self, node, parent_txids, vouts, value, fee, num_outputs):
+ send_value = satoshi_round((value - fee)/num_outputs)
+ inputs = []
+ for (txid, vout) in zip(parent_txids, vouts):
+ inputs.append({'txid' : txid, 'vout' : vout})
+ outputs = {}
+ for i in range(num_outputs):
+ outputs[node.getnewaddress()] = send_value
+ rawtx = node.createrawtransaction(inputs, outputs)
+ signedtx = node.signrawtransactionwithwallet(rawtx)
+ txid = node.sendrawtransaction(signedtx['hex'])
+ fulltx = node.getrawtransaction(txid, 1)
+ assert len(fulltx['vout']) == num_outputs # make sure we didn't generate a change output
+ return (txid, send_value)
+
+ def run_test(self):
+ # Mine some blocks and have them mature.
+ self.nodes[0].generate(101)
+ utxo = self.nodes[0].listunspent(10)
+ txid = utxo[0]['txid']
+ vout = utxo[0]['vout']
+ value = utxo[0]['amount']
+
+ fee = Decimal("0.0002")
+ # MAX_ANCESTORS transactions off a confirmed tx should be fine
+ chain = []
+ for _ in range(4):
+ (txid, sent_value) = self.chain_transaction(self.nodes[0], [txid], [vout], value, fee, 2)
+ vout = 0
+ value = sent_value
+ chain.append([txid, value])
+ for _ in range(MAX_ANCESTORS - 4):
+ (txid, sent_value) = self.chain_transaction(self.nodes[0], [txid], [0], value, fee, 1)
+ value = sent_value
+ chain.append([txid, value])
+ (second_chain, second_chain_value) = self.chain_transaction(self.nodes[0], [utxo[1]['txid']], [utxo[1]['vout']], utxo[1]['amount'], fee, 1)
+
+ # Check mempool has MAX_ANCESTORS + 1 transactions in it
+ assert_equal(len(self.nodes[0].getrawmempool(True)), MAX_ANCESTORS + 1)
+
+ # Adding one more transaction on to the chain should fail.
+ assert_raises_rpc_error(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], [txid], [0], value, fee, 1)
+ # ...even if it chains on from some point in the middle of the chain.
+ assert_raises_rpc_error(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], [chain[2][0]], [1], chain[2][1], fee, 1)
+ assert_raises_rpc_error(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], [chain[1][0]], [1], chain[1][1], fee, 1)
+ # ...even if it chains on to two parent transactions with one in the chain.
+ assert_raises_rpc_error(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], [chain[0][0], second_chain], [1, 0], chain[0][1] + second_chain_value, fee, 1)
+ # ...especially if its > 40k weight
+ assert_raises_rpc_error(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], [chain[0][0]], [1], chain[0][1], fee, 350)
+ # But not if it chains directly off the first transaction
+ self.chain_transaction(self.nodes[0], [chain[0][0]], [1], chain[0][1], fee, 1)
+ # and the second chain should work just fine
+ self.chain_transaction(self.nodes[0], [second_chain], [0], second_chain_value, fee, 1)
+
+ # Finally, check that we added two transactions
+ assert_equal(len(self.nodes[0].getrawmempool(True)), MAX_ANCESTORS + 3)
+
+if __name__ == '__main__':
+ MempoolPackagesTest().main()
diff --git a/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py
index b0a069be81..7e05a8e6c8 100755
--- a/test/functional/mining_prioritisetransaction.py
+++ b/test/functional/mining_prioritisetransaction.py
@@ -14,7 +14,10 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
- self.extra_args = [["-printpriority=1"], ["-printpriority=1"]]
+ self.extra_args = [[
+ "-printpriority=1",
+ "-acceptnonstdtxn=1",
+ ]] * self.num_nodes
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py
index 0994857912..eb3336bd3b 100755
--- a/test/functional/p2p_compactblocks.py
+++ b/test/functional/p2p_compactblocks.py
@@ -95,6 +95,9 @@ class CompactBlocksTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
+ self.extra_args = [[
+ "-acceptnonstdtxn=1",
+ ]]
self.utxos = []
def skip_test_if_missing_module(self):
diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py
index 1b18dd3e58..3cca2d78db 100755
--- a/test/functional/p2p_invalid_tx.py
+++ b/test/functional/p2p_invalid_tx.py
@@ -25,6 +25,9 @@ from data import invalid_txs
class InvalidTxRequestTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
+ self.extra_args = [[
+ "-acceptnonstdtxn=1",
+ ]]
self.setup_clean_chain = True
def bootstrap_p2p(self, *, num_connections=1):
diff --git a/test/functional/p2p_node_network_limited.py b/test/functional/p2p_node_network_limited.py
index 573d5f5a5f..a4650df8ee 100755
--- a/test/functional/p2p_node_network_limited.py
+++ b/test/functional/p2p_node_network_limited.py
@@ -8,7 +8,7 @@ Tests that a node configured with -prune=550 signals NODE_NETWORK_LIMITED correc
and that it responds to getdata requests for blocks correctly:
- send a block within 288 + 2 of the tip
- disconnect peers who request blocks older than that."""
-from test_framework.messages import CInv, msg_getdata, msg_verack, NODE_BLOOM, NODE_NETWORK_LIMITED, NODE_WITNESS
+from test_framework.messages import CInv, msg_getdata, msg_verack, NODE_NETWORK_LIMITED, NODE_WITNESS
from test_framework.mininode import P2PInterface, mininode_lock
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
@@ -55,7 +55,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
def run_test(self):
node = self.nodes[0].add_p2p_connection(P2PIgnoreInv())
- expected_services = NODE_BLOOM | NODE_WITNESS | NODE_NETWORK_LIMITED
+ expected_services = NODE_WITNESS | NODE_NETWORK_LIMITED
self.log.info("Check that node has signalled expected services.")
assert_equal(node.nServices, expected_services)
@@ -83,7 +83,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
node1.wait_for_addr()
#must relay address with NODE_NETWORK_LIMITED
- assert_equal(node1.firstAddrnServices, 1036)
+ assert_equal(node1.firstAddrnServices, expected_services)
self.nodes[0].disconnect_p2ps()
node1.wait_for_disconnect()
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index b7fa42f593..dca71aec43 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -184,7 +184,11 @@ class SegWitTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 3
# This test tests SegWit both pre and post-activation, so use the normal BIP9 activation.
- self.extra_args = [["-whitelist=127.0.0.1", "-vbparams=segwit:0:999999999999"], ["-whitelist=127.0.0.1", "-acceptnonstdtxn=0", "-vbparams=segwit:0:999999999999"], ["-whitelist=127.0.0.1", "-vbparams=segwit:0:0"]]
+ self.extra_args = [
+ ["-whitelist=127.0.0.1", "-acceptnonstdtxn=1", "-vbparams=segwit:0:999999999999"],
+ ["-whitelist=127.0.0.1", "-acceptnonstdtxn=0", "-vbparams=segwit:0:999999999999"],
+ ["-whitelist=127.0.0.1", "-acceptnonstdtxn=1", "-vbparams=segwit:0:0"],
+ ]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/rpc_users.py b/test/functional/rpc_users.py
index 102dd22594..8bbb3c04fa 100755
--- a/test/functional/rpc_users.py
+++ b/test/functional/rpc_users.py
@@ -20,6 +20,17 @@ import string
import configparser
import sys
+def call_with_auth(node, user, password):
+ url = urllib.parse.urlparse(node.url)
+ headers = {"Authorization": "Basic " + str_to_b64str('{}:{}'.format(user, password))}
+
+ conn = http.client.HTTPConnection(url.hostname, url.port)
+ conn.connect()
+ conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
+ resp = conn.getresponse()
+ conn.close()
+ return resp
+
class HTTPBasicsTest(BitcoinTestFramework):
def set_test_params(self):
@@ -28,15 +39,24 @@ class HTTPBasicsTest(BitcoinTestFramework):
def setup_chain(self):
super().setup_chain()
#Append rpcauth to bitcoin.conf before initialization
+ self.rtpassword = "cA773lm788buwYe4g4WT+05pKyNruVKjQ25x3n0DQcM="
rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144"
- rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e"
- rpcuser = "rpcuser=rpcuser💻"
- rpcpassword = "rpcpassword=rpcpassword🔑"
- self.user = ''.join(SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(10))
+ self.rpcuser = "rpcuser💻"
+ self.rpcpassword = "rpcpassword🔑"
+
config = configparser.ConfigParser()
config.read_file(open(self.options.configfile))
gen_rpcauth = config['environment']['RPCAUTH']
+
+ # Generate RPCAUTH with specified password
+ self.rt2password = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI="
+ p = subprocess.Popen([sys.executable, gen_rpcauth, 'rt2', self.rt2password], stdout=subprocess.PIPE, universal_newlines=True)
+ lines = p.stdout.read().splitlines()
+ rpcauth2 = lines[1]
+
+ # Generate RPCAUTH without specifying password
+ self.user = ''.join(SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(10))
p = subprocess.Popen([sys.executable, gen_rpcauth, self.user], stdout=subprocess.PIPE, universal_newlines=True)
lines = p.stdout.read().splitlines()
rpcauth3 = lines[1]
@@ -47,160 +67,40 @@ class HTTPBasicsTest(BitcoinTestFramework):
f.write(rpcauth2+"\n")
f.write(rpcauth3+"\n")
with open(os.path.join(get_datadir_path(self.options.tmpdir, 1), "bitcoin.conf"), 'a', encoding='utf8') as f:
- f.write(rpcuser+"\n")
- f.write(rpcpassword+"\n")
-
- def run_test(self):
-
- ##################################################
- # Check correctness of the rpcauth config option #
- ##################################################
- url = urllib.parse.urlparse(self.nodes[0].url)
-
- #Old authpair
- authpair = url.username + ':' + url.password
-
- #New authpair generated via share/rpcauth tool
- password = "cA773lm788buwYe4g4WT+05pKyNruVKjQ25x3n0DQcM="
-
- #Second authpair with different username
- password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI="
- authpairnew = "rt:"+password
+ f.write("rpcuser={}\n".format(self.rpcuser))
+ f.write("rpcpassword={}\n".format(self.rpcpassword))
+ def test_auth(self, node, user, password):
self.log.info('Correct...')
- headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
+ assert_equal(200, call_with_auth(node, user, password).status)
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 200)
- conn.close()
-
- #Use new authpair to confirm both work
- self.log.info('Correct...')
- headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
-
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 200)
- conn.close()
-
- #Wrong login name with rt's password
self.log.info('Wrong...')
- authpairnew = "rtwrong:"+password
- headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
-
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 401)
- conn.close()
+ assert_equal(401, call_with_auth(node, user, password+'wrong').status)
- #Wrong password for rt
self.log.info('Wrong...')
- authpairnew = "rt:"+password+"wrong"
- headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
+ assert_equal(401, call_with_auth(node, user+'wrong', password).status)
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 401)
- conn.close()
-
- #Correct for rt2
- self.log.info('Correct...')
- authpairnew = "rt2:"+password2
- headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
-
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 200)
- conn.close()
-
- #Wrong password for rt2
self.log.info('Wrong...')
- authpairnew = "rt2:"+password2+"wrong"
- headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
-
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 401)
- conn.close()
+ assert_equal(401, call_with_auth(node, user+'wrong', password+'wrong').status)
- #Correct for randomly generated user
- self.log.info('Correct...')
- authpairnew = self.user+":"+self.password
- headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
-
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 200)
- conn.close()
+ def run_test(self):
- #Wrong password for randomly generated user
- self.log.info('Wrong...')
- authpairnew = self.user+":"+self.password+"Wrong"
- headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
+ ##################################################
+ # Check correctness of the rpcauth config option #
+ ##################################################
+ url = urllib.parse.urlparse(self.nodes[0].url)
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 401)
- conn.close()
+ self.test_auth(self.nodes[0], url.username, url.password)
+ self.test_auth(self.nodes[0], 'rt', self.rtpassword)
+ self.test_auth(self.nodes[0], 'rt2', self.rt2password)
+ self.test_auth(self.nodes[0], self.user, self.password)
###############################################################
# Check correctness of the rpcuser/rpcpassword config options #
###############################################################
url = urllib.parse.urlparse(self.nodes[1].url)
- # rpcuser and rpcpassword authpair
- self.log.info('Correct...')
- rpcuserauthpair = "rpcuser💻:rpcpassword🔑"
-
- headers = {"Authorization": "Basic " + str_to_b64str(rpcuserauthpair)}
-
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 200)
- conn.close()
-
- #Wrong login name with rpcuser's password
- rpcuserauthpair = "rpcuserwrong:rpcpassword"
- headers = {"Authorization": "Basic " + str_to_b64str(rpcuserauthpair)}
-
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 401)
- conn.close()
-
- #Wrong password for rpcuser
- self.log.info('Wrong...')
- rpcuserauthpair = "rpcuser:rpcpasswordwrong"
- headers = {"Authorization": "Basic " + str_to_b64str(rpcuserauthpair)}
-
- conn = http.client.HTTPConnection(url.hostname, url.port)
- conn.connect()
- conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
- resp = conn.getresponse()
- assert_equal(resp.status, 401)
- conn.close()
-
+ self.test_auth(self.nodes[1], self.rpcuser, self.rpcpassword)
if __name__ == '__main__':
HTTPBasicsTest ().main ()
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index e454ed5987..89a5a65e64 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -44,7 +44,7 @@ BIP125_SEQUENCE_NUMBER = 0xfffffffd # Sequence number that is BIP 125 opt-in an
NODE_NETWORK = (1 << 0)
# NODE_GETUTXO = (1 << 1)
-NODE_BLOOM = (1 << 2)
+# NODE_BLOOM = (1 << 2)
NODE_WITNESS = (1 << 3)
NODE_NETWORK_LIMITED = (1 << 10)
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 26215083fb..efd962ea93 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -19,6 +19,7 @@ import time
from . import coverage
from .authproxy import AuthServiceProxy, JSONRPCException
+from io import BytesIO
logger = logging.getLogger("TestFramework.utils")
@@ -515,14 +516,13 @@ def gen_return_txouts():
for i in range(512):
script_pubkey = script_pubkey + "01"
# concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
- txouts = "81"
+ txouts = []
+ from .messages import CTxOut
+ txout = CTxOut()
+ txout.nValue = 0
+ txout.scriptPubKey = hex_str_to_bytes(script_pubkey)
for k in range(128):
- # add txout value
- txouts = txouts + "0000000000000000"
- # add length of script_pubkey
- txouts = txouts + "fd0402"
- # add script_pubkey
- txouts = txouts + script_pubkey
+ txouts.append(txout)
return txouts
# Create a spend of each passed-in utxo, splicing in "txouts" to each raw
@@ -530,6 +530,7 @@ def gen_return_txouts():
def create_lots_of_big_transactions(node, txouts, utxos, num, fee):
addr = node.getnewaddress()
txids = []
+ from .messages import CTransaction
for _ in range(num):
t = utxos.pop()
inputs = [{"txid": t["txid"], "vout": t["vout"]}]
@@ -537,9 +538,11 @@ def create_lots_of_big_transactions(node, txouts, utxos, num, fee):
change = t['amount'] - fee
outputs[addr] = satoshi_round(change)
rawtx = node.createrawtransaction(inputs, outputs)
- newtx = rawtx[0:92]
- newtx = newtx + txouts
- newtx = newtx + rawtx[94:]
+ tx = CTransaction()
+ tx.deserialize(BytesIO(hex_str_to_bytes(rawtx)))
+ for txout in txouts:
+ tx.vout.append(txout)
+ newtx = tx.serialize().hex()
signresult = node.signrawtransactionwithwallet(newtx, None, "NONE")
txid = node.sendrawtransaction(signresult["hex"], 0)
txids.append(txid)
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 462547f44f..6fc48f2649 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -157,6 +157,7 @@ BASE_SCRIPTS = [
'rpc_invalidateblock.py',
'feature_rbf.py',
'mempool_packages.py',
+ 'mempool_package_onemore.py',
'rpc_createmultisig.py',
'feature_versionbits_warning.py',
'rpc_preciousblock.py',
@@ -234,6 +235,7 @@ def main():
parser.add_argument('--quiet', '-q', action='store_true', help='only print dots, results summary and failure logs')
parser.add_argument('--tmpdirprefix', '-t', default=tempfile.gettempdir(), help="Root directory for datadirs")
parser.add_argument('--failfast', action='store_true', help='stop execution after the first test failure')
+ parser.add_argument('--filter', help='filter scripts to run by regular expression')
args, unknown_args = parser.parse_known_args()
# args to be passed on always start with two dashes; tests are the remaining unknown args
@@ -269,11 +271,22 @@ def main():
test_list = []
if tests:
# Individual tests have been specified. Run specified tests that exist
- # in the ALL_SCRIPTS list. Accept the name with or without .py extension.
- tests = [test + ".py" if ".py" not in test else test for test in tests]
+ # in the ALL_SCRIPTS list. Accept names with or without a .py extension.
+ # Specified tests can contain wildcards, but in that case the supplied
+ # paths should be coherent, e.g. the same path as that provided to call
+ # test_runner.py. Examples:
+ # `test/functional/test_runner.py test/functional/wallet*`
+ # `test/functional/test_runner.py ./test/functional/wallet*`
+ # `test_runner.py wallet*`
+ # but not:
+ # `test/functional/test_runner.py wallet*`
+ # Multiple wildcards can be passed:
+ # `test_runner.py tool* mempool*`
for test in tests:
- if test in ALL_SCRIPTS:
- test_list.append(test)
+ script = test.split("/")[-1]
+ script = script + ".py" if ".py" not in script else script
+ if script in ALL_SCRIPTS:
+ test_list.append(script)
else:
print("{}WARNING!{} Test '{}' not found in full test list.".format(BOLD[1], BOLD[0], test))
elif args.extended:
@@ -294,6 +307,9 @@ def main():
if not exclude_list:
print("{}WARNING!{} Test '{}' not found in current test list.".format(BOLD[1], BOLD[0], exclude_test))
+ if args.filter:
+ test_list = list(filter(re.compile(args.filter).search, test_list))
+
if not test_list:
print("No valid test scripts specified. Check that your test is in one "
"of the test lists in test_runner.py, or run test_runner.py with no arguments to run all tests")
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index daa834b5b8..34e84fcf55 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -20,6 +20,9 @@ from test_framework.util import (
class WalletTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
+ self.extra_args = [[
+ "-acceptnonstdtxn=1",
+ ]] * self.num_nodes
self.setup_clean_chain = True
def skip_test_if_missing_module(self):
diff --git a/test/functional/wallet_encryption.py b/test/functional/wallet_encryption.py
index c514b7e0b4..fbcb4e75ba 100755
--- a/test/functional/wallet_encryption.py
+++ b/test/functional/wallet_encryption.py
@@ -49,7 +49,7 @@ class WalletEncryptionTest(BitcoinTestFramework):
assert_equal(privkey, self.nodes[0].dumpprivkey(address))
# Check that the timeout is right
- time.sleep(2)
+ time.sleep(3)
assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", self.nodes[0].dumpprivkey, address)
# Test wrong passphrase