aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/combine_logs.py4
-rwxr-xr-xtest/functional/feature_block.py2
-rwxr-xr-xtest/functional/feature_notifications.py54
-rwxr-xr-xtest/functional/mining_prioritisetransaction.py3
-rwxr-xr-xtest/functional/p2p_compactblocks.py2
-rwxr-xr-xtest/functional/p2p_sendheaders.py2
-rwxr-xr-xtest/functional/rpc_blockchain.py8
-rwxr-xr-xtest/functional/rpc_rawtransaction.py12
-rwxr-xr-xtest/functional/rpc_txoutproof.py8
-rw-r--r--test/functional/test_framework/authproxy.py26
-rwxr-xr-xtest/functional/test_runner.py36
-rwxr-xr-xtest/functional/wallet_basic.py8
-rwxr-xr-xtest/functional/wallet_listsinceblock.py4
-rwxr-xr-xtest/functional/wallet_multiwallet.py17
14 files changed, 119 insertions, 67 deletions
diff --git a/test/functional/combine_logs.py b/test/functional/combine_logs.py
index 3759913e44..3230d5cb6b 100755
--- a/test/functional/combine_logs.py
+++ b/test/functional/combine_logs.py
@@ -25,10 +25,6 @@ def main():
parser.add_argument('--html', dest='html', action='store_true', help='outputs the combined log as html. Requires jinja2. pip install jinja2')
args, unknown_args = parser.parse_known_args()
- if args.color and os.name != 'posix':
- print("Color output requires posix terminal colors.")
- sys.exit(1)
-
if args.html and args.color:
print("Only one out of --color or --html should be specified")
sys.exit(1)
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 71c3a396c1..628cefb76d 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -824,7 +824,7 @@ class FullBlockTest(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(b64a.vtx[1].sha256, 0)))
b64a = self.update_block("64a", [tx])
assert_equal(len(b64a.serialize()), MAX_BLOCK_BASE_SIZE + 8)
- self.sync_blocks([b64a], success=False, reject_reason='non-canonical ReadCompactSize(): iostream error')
+ self.sync_blocks([b64a], success=False, reject_reason='non-canonical ReadCompactSize():')
# bitcoind doesn't disconnect us for sending a bloated block, but if we subsequently
# resend the header message, it won't send us the getdata message again. Just
diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py
index 25a7329a0d..a93443f2db 100755
--- a/test/functional/feature_notifications.py
+++ b/test/functional/feature_notifications.py
@@ -17,17 +17,20 @@ class NotificationsTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def setup_network(self):
- self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
- self.block_filename = os.path.join(self.options.tmpdir, "blocks.txt")
- self.tx_filename = os.path.join(self.options.tmpdir, "transactions.txt")
+ self.alertnotify_dir = os.path.join(self.options.tmpdir, "alertnotify")
+ self.blocknotify_dir = os.path.join(self.options.tmpdir, "blocknotify")
+ self.walletnotify_dir = os.path.join(self.options.tmpdir, "walletnotify")
+ os.mkdir(self.alertnotify_dir)
+ os.mkdir(self.blocknotify_dir)
+ os.mkdir(self.walletnotify_dir)
# -alertnotify and -blocknotify on node0, walletnotify on node1
self.extra_args = [["-blockversion=2",
- "-alertnotify=echo %%s >> %s" % self.alert_filename,
- "-blocknotify=echo %%s >> %s" % self.block_filename],
+ "-alertnotify=echo > {}".format(os.path.join(self.alertnotify_dir, '%s')),
+ "-blocknotify=echo > {}".format(os.path.join(self.blocknotify_dir, '%s'))],
["-blockversion=211",
"-rescan",
- "-walletnotify=echo %%s >> %s" % self.tx_filename]]
+ "-walletnotify=echo > {}".format(os.path.join(self.walletnotify_dir, '%s'))]]
super().setup_network()
def run_test(self):
@@ -35,34 +38,32 @@ class NotificationsTest(BitcoinTestFramework):
block_count = 10
blocks = self.nodes[1].generate(block_count)
- # wait at most 10 seconds for expected file size before reading the content
- wait_until(lambda: os.path.isfile(self.block_filename) and os.stat(self.block_filename).st_size >= (block_count * 65), timeout=10)
+ # wait at most 10 seconds for expected number of files before reading the content
+ wait_until(lambda: len(os.listdir(self.blocknotify_dir)) == block_count, timeout=10)
- # file content should equal the generated blocks hashes
- with open(self.block_filename, 'r', encoding="utf-8") as f:
- assert_equal(sorted(blocks), sorted(l.strip() for l in f.read().splitlines()))
+ # directory content should equal the generated blocks hashes
+ assert_equal(sorted(blocks), sorted(os.listdir(self.blocknotify_dir)))
self.log.info("test -walletnotify")
- # wait at most 10 seconds for expected file size before reading the content
- wait_until(lambda: os.path.isfile(self.tx_filename) and os.stat(self.tx_filename).st_size >= (block_count * 65), timeout=10)
+ # wait at most 10 seconds for expected number of files before reading the content
+ wait_until(lambda: len(os.listdir(self.walletnotify_dir)) == block_count, timeout=10)
- # file content should equal the generated transaction hashes
+ # directory content should equal the generated transaction hashes
txids_rpc = list(map(lambda t: t['txid'], self.nodes[1].listtransactions("*", block_count)))
- with open(self.tx_filename, 'r', encoding="ascii") as f:
- assert_equal(sorted(txids_rpc), sorted(l.strip() for l in f.read().splitlines()))
- os.remove(self.tx_filename)
+ assert_equal(sorted(txids_rpc), sorted(os.listdir(self.walletnotify_dir)))
+ for tx_file in os.listdir(self.walletnotify_dir):
+ os.remove(os.path.join(self.walletnotify_dir, tx_file))
self.log.info("test -walletnotify after rescan")
# restart node to rescan to force wallet notifications
self.restart_node(1)
connect_nodes_bi(self.nodes, 0, 1)
- wait_until(lambda: os.path.isfile(self.tx_filename) and os.stat(self.tx_filename).st_size >= (block_count * 65), timeout=10)
+ wait_until(lambda: len(os.listdir(self.walletnotify_dir)) == block_count, timeout=10)
- # file content should equal the generated transaction hashes
+ # directory content should equal the generated transaction hashes
txids_rpc = list(map(lambda t: t['txid'], self.nodes[1].listtransactions("*", block_count)))
- with open(self.tx_filename, 'r', encoding="ascii") as f:
- assert_equal(sorted(txids_rpc), sorted(l.strip() for l in f.read().splitlines()))
+ assert_equal(sorted(txids_rpc), sorted(os.listdir(self.walletnotify_dir)))
# Mine another 41 up-version blocks. -alertnotify should trigger on the 51st.
self.log.info("test -alertnotify")
@@ -70,20 +71,17 @@ class NotificationsTest(BitcoinTestFramework):
self.sync_all()
# Give bitcoind 10 seconds to write the alert notification
- wait_until(lambda: os.path.isfile(self.alert_filename) and os.path.getsize(self.alert_filename), timeout=10)
+ wait_until(lambda: len(os.listdir(self.alertnotify_dir)), timeout=10)
- with open(self.alert_filename, 'r', encoding='utf8') as f:
- alert_text = f.read()
+ for notify_file in os.listdir(self.alertnotify_dir):
+ os.remove(os.path.join(self.alertnotify_dir, notify_file))
# Mine more up-version blocks, should not get more alerts:
self.nodes[1].generate(2)
self.sync_all()
- with open(self.alert_filename, 'r', encoding='utf8') as f:
- alert_text2 = f.read()
-
self.log.info("-alertnotify should not continue notifying for more unknown version blocks")
- assert_equal(alert_text, alert_text2)
+ assert_equal(len(os.listdir(self.alertnotify_dir)), 0)
if __name__ == '__main__':
NotificationsTest().main()
diff --git a/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py
index 92590717f3..c5ddee56f1 100755
--- a/test/functional/mining_prioritisetransaction.py
+++ b/test/functional/mining_prioritisetransaction.py
@@ -29,7 +29,8 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction, '', 0, 0, 0)
# Test `prioritisetransaction` invalid `txid`
- assert_raises_rpc_error(-1, "txid must be hexadecimal string", self.nodes[0].prioritisetransaction, txid='foo', fee_delta=0)
+ assert_raises_rpc_error(-8, "txid must be of length 64 (not 3, for 'foo')", self.nodes[0].prioritisetransaction, txid='foo', fee_delta=0)
+ assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'Zd1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000')", self.nodes[0].prioritisetransaction, txid='Zd1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000', fee_delta=0)
# Test `prioritisetransaction` invalid `dummy`
txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000'
diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py
index 3a5bdf806b..fafc27d16a 100755
--- a/test/functional/p2p_compactblocks.py
+++ b/test/functional/p2p_compactblocks.py
@@ -293,7 +293,7 @@ class CompactBlocksTest(BitcoinTestFramework):
block_hash = int(node.generate(1)[0], 16)
# Store the raw block in our internal format.
- block = FromHex(CBlock(), node.getblock("%02x" % block_hash, False))
+ block = FromHex(CBlock(), node.getblock("%064x" % block_hash, False))
for tx in block.vtx:
tx.calc_sha256()
block.rehash()
diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py
index d5e8dd4721..c7ae57de86 100755
--- a/test/functional/p2p_sendheaders.py
+++ b/test/functional/p2p_sendheaders.py
@@ -402,7 +402,7 @@ class SendHeadersTest(BitcoinTestFramework):
block_time += 9
- fork_point = self.nodes[0].getblock("%02x" % new_block_hashes[0])["previousblockhash"]
+ fork_point = self.nodes[0].getblock("%064x" % new_block_hashes[0])["previousblockhash"]
fork_point = int(fork_point, 16)
# Use getblocks/getdata
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index f67ecc247c..92b690176d 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -125,7 +125,9 @@ class BlockchainTest(BitcoinTestFramework):
# Test `getchaintxstats` invalid `blockhash`
assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].getchaintxstats, blockhash=0)
- assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getchaintxstats, blockhash='0')
+ assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 1, for '0')", self.nodes[0].getchaintxstats, blockhash='0')
+ assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].getchaintxstats, blockhash='ZZZ0000000000000000000000000000000000000000000000000000000000000')
+ assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getchaintxstats, blockhash='0000000000000000000000000000000000000000000000000000000000000000')
blockhash = self.nodes[0].getblockhash(200)
self.nodes[0].invalidateblock(blockhash)
assert_raises_rpc_error(-8, "Block is not in main chain", self.nodes[0].getchaintxstats, blockhash=blockhash)
@@ -203,7 +205,9 @@ class BlockchainTest(BitcoinTestFramework):
def _test_getblockheader(self):
node = self.nodes[0]
- assert_raises_rpc_error(-5, "Block not found", node.getblockheader, "nonsense")
+ assert_raises_rpc_error(-8, "hash must be of length 64 (not 8, for 'nonsense')", node.getblockheader, "nonsense")
+ assert_raises_rpc_error(-8, "hash must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')", node.getblockheader, "ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
+ assert_raises_rpc_error(-5, "Block not found", node.getblockheader, "0cf7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
besthash = node.getbestblockhash()
secondbesthash = node.getblockhash(199)
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index d86b546c7d..8ed490f552 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -80,8 +80,9 @@ class RawTransactionsTest(BitcoinTestFramework):
txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000'
assert_raises_rpc_error(-3, "Expected type array", self.nodes[0].createrawtransaction, 'foo', {})
assert_raises_rpc_error(-1, "JSON value is not an object as expected", self.nodes[0].createrawtransaction, ['foo'], {})
- assert_raises_rpc_error(-8, "txid must be hexadecimal string", self.nodes[0].createrawtransaction, [{}], {})
- assert_raises_rpc_error(-8, "txid must be hexadecimal string", self.nodes[0].createrawtransaction, [{'txid': 'foo'}], {})
+ assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].createrawtransaction, [{}], {})
+ assert_raises_rpc_error(-8, "txid must be of length 64 (not 3, for 'foo')", self.nodes[0].createrawtransaction, [{'txid': 'foo'}], {})
+ assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')", self.nodes[0].createrawtransaction, [{'txid': 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844'}], {})
assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", self.nodes[0].createrawtransaction, [{'txid': txid}], {})
assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': 'foo'}], {})
assert_raises_rpc_error(-8, "Invalid parameter, vout must be positive", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': -1}], {})
@@ -224,9 +225,10 @@ class RawTransactionsTest(BitcoinTestFramework):
# We should not get the tx if we provide an unrelated block
assert_raises_rpc_error(-5, "No such transaction found", self.nodes[0].getrawtransaction, tx, True, block2)
# An invalid block hash should raise the correct errors
- assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal", self.nodes[0].getrawtransaction, tx, True, True)
- assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal", self.nodes[0].getrawtransaction, tx, True, "foobar")
- assert_raises_rpc_error(-8, "parameter 3 must be of length 64", self.nodes[0].getrawtransaction, tx, True, "abcd1234")
+ assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].getrawtransaction, tx, True, True)
+ assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 6, for 'foobar')", self.nodes[0].getrawtransaction, tx, True, "foobar")
+ assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 8, for 'abcd1234')", self.nodes[0].getrawtransaction, tx, True, "abcd1234")
+ assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].getrawtransaction, tx, True, "ZZZ0000000000000000000000000000000000000000000000000000000000000")
assert_raises_rpc_error(-5, "Block hash not found", self.nodes[0].getrawtransaction, tx, True, "0000000000000000000000000000000000000000000000000000000000000000")
# Undo the blocks and check in_active_chain
self.nodes[0].invalidateblock(block1)
diff --git a/test/functional/rpc_txoutproof.py b/test/functional/rpc_txoutproof.py
index 867ba25022..8913b8698d 100755
--- a/test/functional/rpc_txoutproof.py
+++ b/test/functional/rpc_txoutproof.py
@@ -66,12 +66,18 @@ class MerkleBlockTest(BitcoinTestFramework):
txid_spent = txin_spent["txid"]
txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2
+ # Invalid txids
+ assert_raises_rpc_error(-8, "txid must be of length 64 (not 32, for '00000000000000000000000000000000')", self.nodes[2].gettxoutproof, ["00000000000000000000000000000000"], blockhash)
+ assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[2].gettxoutproof, ["ZZZ0000000000000000000000000000000000000000000000000000000000000"], blockhash)
+ # Invalid blockhashes
+ assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 32, for '00000000000000000000000000000000')", self.nodes[2].gettxoutproof, [txid_spent], "00000000000000000000000000000000")
+ assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[2].gettxoutproof, [txid_spent], "ZZZ0000000000000000000000000000000000000000000000000000000000000")
# We can't find the block from a fully-spent tx
assert_raises_rpc_error(-5, "Transaction not yet in block", self.nodes[2].gettxoutproof, [txid_spent])
# We can get the proof if we specify the block
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent])
# We can't get the proof if we specify a non-existent block
- assert_raises_rpc_error(-5, "Block not found", self.nodes[2].gettxoutproof, [txid_spent], "00000000000000000000000000000000")
+ assert_raises_rpc_error(-5, "Block not found", self.nodes[2].gettxoutproof, [txid_spent], "0000000000000000000000000000000000000000000000000000000000000000")
# We can get the proof if the transaction is unspent
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_unspent])), [txid_unspent])
# We can get the proof if we provide a list of transactions and one of them is unspent. The ordering of the list should not matter.
diff --git a/test/functional/test_framework/authproxy.py b/test/functional/test_framework/authproxy.py
index 900090bb66..1140fe9b3e 100644
--- a/test/functional/test_framework/authproxy.py
+++ b/test/functional/test_framework/authproxy.py
@@ -38,6 +38,7 @@ import decimal
import http.client
import json
import logging
+import os
import socket
import time
import urllib.parse
@@ -71,19 +72,12 @@ class AuthServiceProxy():
self._service_name = service_name
self.ensure_ascii = ensure_ascii # can be toggled on the fly by tests
self.__url = urllib.parse.urlparse(service_url)
- port = 80 if self.__url.port is None else self.__url.port
user = None if self.__url.username is None else self.__url.username.encode('utf8')
passwd = None if self.__url.password is None else self.__url.password.encode('utf8')
authpair = user + b':' + passwd
self.__auth_header = b'Basic ' + base64.b64encode(authpair)
-
- if connection:
- # Callables re-use the connection of the original proxy
- self.__conn = connection
- elif self.__url.scheme == 'https':
- self.__conn = http.client.HTTPSConnection(self.__url.hostname, port, timeout=timeout)
- else:
- self.__conn = http.client.HTTPConnection(self.__url.hostname, port, timeout=timeout)
+ self.timeout = timeout
+ self._set_conn(connection)
def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
@@ -102,6 +96,10 @@ class AuthServiceProxy():
'User-Agent': USER_AGENT,
'Authorization': self.__auth_header,
'Content-type': 'application/json'}
+ if os.name == 'nt':
+ # Windows somehow does not like to re-use connections
+ # TODO: Find out why the connection would disconnect occasionally and make it reusable on Windows
+ self._set_conn()
try:
self.__conn.request(method, path, postdata, headers)
return self._get_response()
@@ -178,3 +176,13 @@ class AuthServiceProxy():
def __truediv__(self, relative_uri):
return AuthServiceProxy("{}/{}".format(self.__service_url, relative_uri), self._service_name, connection=self.__conn)
+
+ def _set_conn(self, connection=None):
+ port = 80 if self.__url.port is None else self.__url.port
+ if connection:
+ self.__conn = connection
+ self.timeout = connection.timeout
+ elif self.__url.scheme == 'https':
+ self.__conn = http.client.HTTPSConnection(self.__url.hostname, port, timeout=self.timeout)
+ else:
+ self.__conn = http.client.HTTPConnection(self.__url.hostname, port, timeout=self.timeout)
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 37a3c1c602..28437f8925 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -29,7 +29,7 @@ import re
import logging
# Formatting. Default colors to empty strings.
-BOLD, BLUE, RED, GREY = ("", ""), ("", ""), ("", ""), ("", "")
+BOLD, GREEN, RED, GREY = ("", ""), ("", ""), ("", ""), ("", "")
try:
# Make sure python thinks it can write unicode to its stdout
"\u2713".encode("utf_8").decode(sys.stdout.encoding)
@@ -41,11 +41,27 @@ except UnicodeDecodeError:
CROSS = "x "
CIRCLE = "o "
-if os.name == 'posix':
+if os.name != 'nt' or sys.getwindowsversion() >= (10, 0, 14393):
+ if os.name == 'nt':
+ import ctypes
+ kernel32 = ctypes.windll.kernel32
+ ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
+ STD_OUTPUT_HANDLE = -11
+ STD_ERROR_HANDLE = -12
+ # Enable ascii color control to stdout
+ stdout = kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
+ stdout_mode = ctypes.c_int32()
+ kernel32.GetConsoleMode(stdout, ctypes.byref(stdout_mode))
+ kernel32.SetConsoleMode(stdout, stdout_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+ # Enable ascii color control to stderr
+ stderr = kernel32.GetStdHandle(STD_ERROR_HANDLE)
+ stderr_mode = ctypes.c_int32()
+ kernel32.GetConsoleMode(stderr, ctypes.byref(stderr_mode))
+ kernel32.SetConsoleMode(stderr, stderr_mode.value | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
# primitive formatting on supported
# terminal via ANSI escape sequences:
BOLD = ('\033[0m', '\033[1m')
- BLUE = ('\033[0m', '\033[0;34m')
+ GREEN = ('\033[0m', '\033[0;32m')
RED = ('\033[0m', '\033[0;31m')
GREY = ('\033[0m', '\033[1;30m')
@@ -227,6 +243,11 @@ def main():
# Create base test directory
tmpdir = "%s/test_runner_₿_🏃_%s" % (args.tmpdirprefix, datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
+
+ # If we fixed the command-line and filename encoding issue on Windows, these two lines could be removed
+ if config["environment"]["EXEEXT"] == ".exe":
+ tmpdir = "%s/test_runner_%s" % (args.tmpdirprefix, datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
+
os.makedirs(tmpdir)
logging.debug("Temporary test directory at %s" % tmpdir)
@@ -264,7 +285,7 @@ def main():
# Remove the test cases that the user has explicitly asked to exclude.
if args.exclude:
- exclude_tests = [re.sub("\.py$", "", test) + ".py" for test in args.exclude.split(',')]
+ exclude_tests = [re.sub("\.py$", "", test) + (".py" if ".py" not in test else "") for test in args.exclude.split(',')]
for exclude_test in exclude_tests:
if exclude_test in test_list:
test_list.remove(exclude_test)
@@ -359,7 +380,10 @@ def run_tests(test_list, src_dir, build_dir, tmpdir, jobs=1, enable_coverage=Fal
print('\n============')
print('{}Combined log for {}:{}'.format(BOLD[1], testdir, BOLD[0]))
print('============\n')
- combined_logs, _ = subprocess.Popen([sys.executable, os.path.join(tests_dir, 'combine_logs.py'), '-c', testdir], universal_newlines=True, stdout=subprocess.PIPE).communicate()
+ combined_logs_args = [sys.executable, os.path.join(tests_dir, 'combine_logs.py'), testdir]
+ if BOLD[0]:
+ combined_logs_args += ['--color']
+ combined_logs, _ = subprocess.Popen(combined_logs_args, universal_newlines=True, stdout=subprocess.PIPE).communicate()
print("\n".join(deque(combined_logs.splitlines(), combined_logs_len)))
if failfast:
@@ -498,7 +522,7 @@ class TestResult():
def __repr__(self):
if self.status == "Passed":
- color = BLUE
+ color = GREEN
glyph = TICK
elif self.status == "Failed":
color = RED
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 4079d05491..8bbff7f7ef 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -134,9 +134,15 @@ class WalletTest(BitcoinTestFramework):
assert_equal([unspent_0], self.nodes[2].listlockunspent())
self.nodes[2].lockunspent(True, [unspent_0])
assert_equal(len(self.nodes[2].listlockunspent()), 0)
- assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction",
+ assert_raises_rpc_error(-8, "txid must be of length 64 (not 34, for '0000000000000000000000000000000000')",
self.nodes[2].lockunspent, False,
[{"txid": "0000000000000000000000000000000000", "vout": 0}])
+ assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')",
+ self.nodes[2].lockunspent, False,
+ [{"txid": "ZZZ0000000000000000000000000000000000000000000000000000000000000", "vout": 0}])
+ assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction",
+ self.nodes[2].lockunspent, False,
+ [{"txid": "0000000000000000000000000000000000000000000000000000000000000000", "vout": 0}])
assert_raises_rpc_error(-8, "Invalid parameter, vout index out of bounds",
self.nodes[2].lockunspent, False,
[{"txid": unspent_0["txid"], "vout": 999}])
diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py
index 53e671cd3b..25ab222375 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -53,8 +53,10 @@ class ListSinceBlockTest (BitcoinTestFramework):
"42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4")
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
"0000000000000000000000000000000000000000000000000000000000000000")
- assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
+ assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 11, for 'invalid-hex')", self.nodes[0].listsinceblock,
"invalid-hex")
+ assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'Z000000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].listsinceblock,
+ "Z000000000000000000000000000000000000000000000000000000000000000")
def test_reorg(self):
'''
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 435821ec48..189bc2d50e 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -44,8 +44,9 @@ class MultiWalletTest(BitcoinTestFramework):
# create symlink to verify wallet directory path can be referenced
# through symlink
- os.mkdir(wallet_dir('w7'))
- os.symlink('w7', wallet_dir('w7_symlink'))
+ if os.name != 'nt':
+ os.mkdir(wallet_dir('w7'))
+ os.symlink('w7', wallet_dir('w7_symlink'))
# rename wallet.dat to make sure plain wallet file paths (as opposed to
# directory paths) can be loaded
@@ -66,6 +67,8 @@ class MultiWalletTest(BitcoinTestFramework):
# w8 - to verify existing wallet file is loaded correctly
# '' - to verify default wallet file is created correctly
wallet_names = ['w1', 'w2', 'w3', 'w', 'sub/w5', os.path.join(self.options.tmpdir, 'extern/w6'), 'w7_symlink', 'w8', '']
+ if os.name == 'nt':
+ wallet_names.remove('w7_symlink')
extra_args = ['-wallet={}'.format(n) for n in wallet_names]
self.start_node(0, extra_args)
assert_equal(set(node.listwallets()), set(wallet_names))
@@ -76,7 +79,7 @@ class MultiWalletTest(BitcoinTestFramework):
assert_equal(os.path.isfile(wallet_file(wallet_name)), True)
# should not initialize if wallet path can't be created
- exp_stderr = "boost::filesystem::create_directory: (The system cannot find the path specified|Not a directory):"
+ exp_stderr = "boost::filesystem::create_directory:"
self.nodes[0].assert_start_raises_init_error(['-wallet=wallet.dat/bad'], exp_stderr, match=ErrorMatch.PARTIAL_REGEX)
self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" does not exist')
@@ -92,8 +95,9 @@ class MultiWalletTest(BitcoinTestFramework):
self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr, match=ErrorMatch.PARTIAL_REGEX)
# should not initialize if wallet file is a symlink
- os.symlink('w8', wallet_dir('w8_symlink'))
- self.nodes[0].assert_start_raises_init_error(['-wallet=w8_symlink'], 'Error: Invalid -wallet path \'w8_symlink\'\. .*', match=ErrorMatch.FULL_REGEX)
+ if os.name != 'nt':
+ os.symlink('w8', wallet_dir('w8_symlink'))
+ self.nodes[0].assert_start_raises_init_error(['-wallet=w8_symlink'], 'Error: Invalid -wallet path \'w8_symlink\'\. .*', match=ErrorMatch.FULL_REGEX)
# should not initialize if the specified walletdir does not exist
self.nodes[0].assert_start_raises_init_error(['-walletdir=bad'], 'Error: Specified -walletdir "bad" does not exist')
@@ -220,7 +224,8 @@ class MultiWalletTest(BitcoinTestFramework):
assert_raises_rpc_error(-1, "BerkeleyBatch: Can't open database w8_copy (duplicates fileid", self.nodes[0].loadwallet, 'w8_copy')
# Fail to load if wallet file is a symlink
- assert_raises_rpc_error(-4, "Wallet file verification failed: Invalid -wallet path 'w8_symlink'", self.nodes[0].loadwallet, 'w8_symlink')
+ if os.name != 'nt':
+ assert_raises_rpc_error(-4, "Wallet file verification failed: Invalid -wallet path 'w8_symlink'", self.nodes[0].loadwallet, 'w8_symlink')
# Fail to load if a directory is specified that doesn't contain a wallet
os.mkdir(wallet_dir('empty_wallet_dir'))