From 6617a996933501d02640c1228db9b6275f1efd4c Mon Sep 17 00:00:00 2001 From: random-zebra Date: Tue, 27 Jul 2021 12:46:18 +0200 Subject: [PATCH 1/7] [Tests] Move assert_start_raises_init_error method to TestNode >>> backports bitcoin@0ec08a672dce3f619e46d0c7455e95a13dc5c4e2 --- test/functional/feature_abortnode.py | 2 +- test/functional/feature_asmap.py | 4 +-- test/functional/feature_blocksdir.py | 2 +- test/functional/feature_config_args.py | 4 +-- test/functional/feature_logging.py | 6 ++-- test/functional/feature_uacomment.py | 4 +-- .../test_framework/test_framework.py | 22 ------------ test/functional/test_framework/test_node.py | 27 +++++++++++++++ test/functional/wallet_multiwallet.py | 34 +++++++++---------- 9 files changed, 55 insertions(+), 50 deletions(-) diff --git a/test/functional/feature_abortnode.py b/test/functional/feature_abortnode.py index 676600a5f7ba..5c481c9406dd 100755 --- a/test/functional/feature_abortnode.py +++ b/test/functional/feature_abortnode.py @@ -44,7 +44,7 @@ def run_test(self): self.log.info("Waiting for crash") wait_until(lambda: self.nodes[0].is_node_stopped(), timeout=60) self.log.info("Node crashed - now verifying restart fails") - self.assert_start_raises_init_error(0) + self.nodes[0].assert_start_raises_init_error() if __name__ == '__main__': AbortNodeTest().main() diff --git a/test/functional/feature_asmap.py b/test/functional/feature_asmap.py index 30f5f482270d..90b968f40d68 100755 --- a/test/functional/feature_asmap.py +++ b/test/functional/feature_asmap.py @@ -76,7 +76,7 @@ def test_default_asmap_with_missing_file(self): self.log.info('Test pivxd -asmap with missing default map file') self.stop_node(0) msg = "Error: Could not find asmap file \"{}\"".format(self.default_asmap) - self.assert_start_raises_init_error(0, extra_args=['-asmap'], expected_msg=msg) + self.nodes[0].assert_start_raises_init_error(extra_args=['-asmap'], expected_msg=msg) def test_empty_asmap(self): self.log.info('Test pivxd -asmap with empty map file') @@ -84,7 +84,7 @@ def test_empty_asmap(self): with open(self.default_asmap, "w", encoding="utf-8") as f: f.write("") msg = "Error: Could not parse asmap file \"{}\"".format(self.default_asmap) - self.assert_start_raises_init_error(0, extra_args=['-asmap'], expected_msg=msg) + self.nodes[0].assert_start_raises_init_error(extra_args=['-asmap'], expected_msg=msg) os.remove(self.default_asmap) def run_test(self): diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py index cbd327e04b79..ce5333a4fdcf 100755 --- a/test/functional/feature_blocksdir.py +++ b/test/functional/feature_blocksdir.py @@ -22,7 +22,7 @@ def run_test(self): shutil.rmtree(self.nodes[0].datadir) initialize_datadir(self.options.tmpdir, 0) self.log.info("Starting with nonexistent blocksdir ...") - self.assert_start_raises_init_error(0, ["-blocksdir="+self.options.tmpdir+ "/blocksdir"], "Specified blocks director") + self.nodes[0].assert_start_raises_init_error(["-blocksdir="+self.options.tmpdir+ "/blocksdir"], "Specified blocks director") os.mkdir(self.options.tmpdir+ "/blocksdir") self.log.info("Starting with existing blocksdir ...") self.start_node(0, ["-blocksdir="+self.options.tmpdir+ "/blocksdir"]) diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index df0b890dba88..b29177807e29 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -26,7 +26,7 @@ def run_test(self): # Check that using -datadir argument on non-existent directory fails self.nodes[0].datadir = new_data_dir - self.assert_start_raises_init_error(0, ['-datadir='+new_data_dir], 'Error: Specified data directory "' + new_data_dir + '" does not exist.') + self.nodes[0].assert_start_raises_init_error(['-datadir='+new_data_dir], 'Error: Specified data directory "' + new_data_dir + '" does not exist.') # Check that using non-existent datadir in conf file fails conf_file = os.path.join(default_data_dir, "pivx.conf") @@ -38,7 +38,7 @@ def run_test(self): f.write(conf_file_contents) # Temporarily disabled, because this test would access the user's home dir (~/.pivx) - #self.assert_start_raises_init_error(0, ['-conf=' + conf_file], 'Error reading configuration file: specified data directory "' + new_data_dir + '" does not exist.') + #self.nodes[0].assert_start_raises_init_error(['-conf=' + conf_file], 'Error reading configuration file: specified data directory "' + new_data_dir + '" does not exist.') # Create the directory and ensure the config file now works os.mkdir(new_data_dir) diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py index 4a39e31125ec..577d8e04c165 100755 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -35,7 +35,7 @@ def run_test(self): invdir = os.path.join(self.nodes[0].datadir, "regtest", "foo") invalidname = os.path.join("foo", "foo.log") self.stop_node(0) - self.assert_start_raises_init_error(0, ["-debuglogfile=%s" % (invalidname)], + self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % (invalidname)], "Error: Could not open debug log file") assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid relative filename throws") @@ -50,8 +50,8 @@ def run_test(self): self.stop_node(0) invdir = os.path.join(self.options.tmpdir, "foo") invalidname = os.path.join(invdir, "foo.log") - self.assert_start_raises_init_error(0, ["-debuglogfile=%s" % invalidname], - "Error: Could not open debug log file") + self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % invalidname], + "Error: Could not open debug log file") assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid absolute filename throws") diff --git a/test/functional/feature_uacomment.py b/test/functional/feature_uacomment.py index 567d14f828ac..78409af6f668 100755 --- a/test/functional/feature_uacomment.py +++ b/test/functional/feature_uacomment.py @@ -24,12 +24,12 @@ def run_test(self): self.log.info("test -uacomment max length") self.stop_node(0) expected = "exceeds maximum length (256). Reduce the number or size of -uacomment." - self.assert_start_raises_init_error(0, ["-uacomment=" + 'a' * 256], expected) + self.nodes[0].assert_start_raises_init_error(["-uacomment=" + 'a' * 256], expected) self.log.info("test -uacomment unsafe characters") for unsafe_char in ['/', ':', '(', ')']: expected = "User Agent comment (" + unsafe_char + ") contains unsafe characters" - self.assert_start_raises_init_error(0, ["-uacomment=" + unsafe_char], expected) + self.nodes[0].assert_start_raises_init_error(["-uacomment=" + unsafe_char], expected) if __name__ == '__main__': UacommentTest().main() diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index ceb4fa94562b..27b1532e45af 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -343,28 +343,6 @@ def restart_node(self, i, extra_args=None): self.stop_node(i) self.start_node(i, extra_args) - def assert_start_raises_init_error(self, i, extra_args=None, expected_msg=None, *args, **kwargs): - with tempfile.SpooledTemporaryFile(max_size=2**16) as log_stderr: - try: - self.start_node(i, extra_args, stderr=log_stderr, *args, **kwargs) - self.nodes[i].wait_for_rpc_connection() - self.stop_node(i) - except Exception as e: - assert 'pivxd 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') - if expected_msg not in stderr: - raise AssertionError("Expected error \"" + expected_msg + "\" not found in:\n" + stderr) - else: - if expected_msg is None: - assert_msg = "pivxd should have exited with an error" - else: - assert_msg = "pivxd should have exited with expected error " + expected_msg - raise AssertionError(assert_msg) - def wait_for_node_exit(self, i, timeout): self.nodes[i].process.wait(timeout) diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 7ac0b535eb12..f402fa285881 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -13,6 +13,7 @@ import os import re import subprocess +import tempfile import time from .authproxy import JSONRPCException @@ -209,6 +210,32 @@ def is_node_stopped(self): def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT): wait_until(self.is_node_stopped, timeout=timeout) + def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, *args, **kwargs): + """Attempt to start the node and expect it to raise an error. + Will throw if pivxd starts without an error. + Will throw if an expected_msg is provided and it does not appear in pivxd's stdout.""" + with tempfile.SpooledTemporaryFile(max_size=2**16) as log_stderr: + try: + self.start(extra_args, stderr=log_stderr, *args, **kwargs) + self.wait_for_rpc_connection() + self.stop_node() + self.wait_until_stopped() + except Exception as e: + assert 'pivxd exited' in str(e) # node must have shutdown + self.running = False + self.process = None + if expected_msg is not None: + log_stderr.seek(0) + stderr = log_stderr.read().decode('utf-8') + if expected_msg not in stderr: + raise AssertionError("Expected error \"" + expected_msg + "\" not found in:\n" + stderr) + else: + if expected_msg is None: + assert_msg = "pivxd should have exited with an error" + else: + assert_msg = "pivxd should have exited with expected error " + expected_msg + raise AssertionError(assert_msg) + @contextlib.contextmanager def assert_debug_log(self, expected_msgs): debug_log = os.path.join(self.datadir, 'regtest', 'debug.log') diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index 0f3803c08e76..b92dee0d171c 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -65,42 +65,42 @@ def wallet_file(name): assert_equal(os.path.isfile(wallet_file(wallet_name)), True) # should not initialize if wallet path can't be created - self.assert_start_raises_init_error(0, ['-wallet=wallet.dat/bad'], 'Not a directory') + self.nodes[0].assert_start_raises_init_error(['-wallet=wallet.dat/bad'], 'Not a directory') - self.assert_start_raises_init_error(0, ['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" does not exist') - self.assert_start_raises_init_error(0, ['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" is a relative path', cwd=data_dir()) - self.assert_start_raises_init_error(0, ['-walletdir=debug.log'], 'Error: Specified -walletdir "debug.log" is not a directory', cwd=data_dir()) + self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" does not exist') + self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" is a relative path', cwd=data_dir()) + self.nodes[0].assert_start_raises_init_error(['-walletdir=debug.log'], 'Error: Specified -walletdir "debug.log" is not a directory', cwd=data_dir()) # should not initialize if there are duplicate wallets - self.assert_start_raises_init_error(0, ['-wallet=w1', '-wallet=w1'], 'Error loading wallet w1. Duplicate -wallet filename specified.') + self.nodes[0].assert_start_raises_init_error(['-wallet=w1', '-wallet=w1'], 'Error loading wallet w1. Duplicate -wallet filename specified.') # should not initialize if one wallet is a copy of another shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy')) - self.assert_start_raises_init_error(0, ['-wallet=w8', '-wallet=w8_copy'], 'duplicates fileid') + self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], 'duplicates fileid') # should not initialize if wallet file is a symlink os.symlink('w8', wallet_dir('w8_symlink')) - self.assert_start_raises_init_error(0, ['-wallet=w8_symlink'], 'Invalid -wallet path') + self.nodes[0].assert_start_raises_init_error(['-wallet=w8_symlink'], 'Invalid -wallet path') # should not initialize if the specified walletdir does not exist - self.assert_start_raises_init_error(0, ['-walletdir=bad'], 'Error: Specified -walletdir "bad" does not exist') + self.nodes[0].assert_start_raises_init_error(['-walletdir=bad'], 'Error: Specified -walletdir "bad" does not exist') # should not initialize if the specified walletdir is not a directory not_a_dir = wallet_dir('notadir') open(not_a_dir, 'a', encoding="utf8").close() - self.assert_start_raises_init_error(0, ['-walletdir='+not_a_dir], 'Error: Specified -walletdir "' + not_a_dir + '" is not a directory') + self.nodes[0].assert_start_raises_init_error(['-walletdir='+not_a_dir], 'Error: Specified -walletdir "' + not_a_dir + '" is not a directory') self.log.info("Do not allow -zapwallettxes with multiwallet") - self.assert_start_raises_init_error(0, ['-zapwallettxes', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file") - self.assert_start_raises_init_error(0, ['-zapwallettxes=1', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file") - self.assert_start_raises_init_error(0, ['-zapwallettxes=2', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file") + self.nodes[0].assert_start_raises_init_error(['-zapwallettxes', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file") + self.nodes[0].assert_start_raises_init_error(['-zapwallettxes=1', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file") + self.nodes[0].assert_start_raises_init_error(['-zapwallettxes=2', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file") self.log.info("Do not allow -salvagewallet with multiwallet") - self.assert_start_raises_init_error(0, ['-salvagewallet', '-wallet=w1', '-wallet=w2'], "Error: -salvagewallet is only allowed with a single wallet file") - self.assert_start_raises_init_error(0, ['-salvagewallet=1', '-wallet=w1', '-wallet=w2'], "Error: -salvagewallet is only allowed with a single wallet file") + self.nodes[0].assert_start_raises_init_error(['-salvagewallet', '-wallet=w1', '-wallet=w2'], "Error: -salvagewallet is only allowed with a single wallet file") + self.nodes[0].assert_start_raises_init_error(['-salvagewallet=1', '-wallet=w1', '-wallet=w2'], "Error: -salvagewallet is only allowed with a single wallet file") self.log.info("Do not allow -upgradewallet with multiwallet") - self.assert_start_raises_init_error(0, ['-upgradewallet', '-wallet=w1', '-wallet=w2'], "Error: -upgradewallet is only allowed with a single wallet file") - self.assert_start_raises_init_error(0, ['-upgradewallet=1', '-wallet=w1', '-wallet=w2'], "Error: -upgradewallet is only allowed with a single wallet file") + self.nodes[0].assert_start_raises_init_error(['-upgradewallet', '-wallet=w1', '-wallet=w2'], "Error: -upgradewallet is only allowed with a single wallet file") + self.nodes[0].assert_start_raises_init_error(['-upgradewallet=1', '-wallet=w1', '-wallet=w2'], "Error: -upgradewallet is only allowed with a single wallet file") # if wallets/ doesn't exist, datadir should be the default wallet dir wallet_dir2 = data_dir('walletdir') @@ -121,7 +121,7 @@ def wallet_file(name): competing_wallet_dir = os.path.join(self.options.tmpdir, 'competing_walletdir') os.mkdir(competing_wallet_dir) self.restart_node(0, ['-walletdir='+competing_wallet_dir]) - self.assert_start_raises_init_error(1, ['-walletdir='+competing_wallet_dir], 'Error initializing wallet database environment') + self.nodes[1].assert_start_raises_init_error(['-walletdir='+competing_wallet_dir], 'Error initializing wallet database environment') self.restart_node(0, extra_args) From 496787af0482898136c9fe3ccb310b7e053c03d2 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Wed, 7 Feb 2018 10:38:25 -0500 Subject: [PATCH 2/7] [Tests] Require exact match in assert_start_raises_init_eror() --- test/functional/feature_blocksdir.py | 8 +++++--- test/functional/feature_config_args.py | 6 +++--- test/functional/feature_logging.py | 7 +++---- test/functional/feature_uacomment.py | 7 +++++-- test/functional/test_framework/test_node.py | 11 ++++++++--- test/functional/wallet_multiwallet.py | 21 +++++++++++++++------ 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py index ce5333a4fdcf..c04867e457f5 100755 --- a/test/functional/feature_blocksdir.py +++ b/test/functional/feature_blocksdir.py @@ -22,10 +22,12 @@ def run_test(self): shutil.rmtree(self.nodes[0].datadir) initialize_datadir(self.options.tmpdir, 0) self.log.info("Starting with nonexistent blocksdir ...") - self.nodes[0].assert_start_raises_init_error(["-blocksdir="+self.options.tmpdir+ "/blocksdir"], "Specified blocks director") - os.mkdir(self.options.tmpdir+ "/blocksdir") + blocksdir_path = os.path.join(self.options.tmpdir, 'blocksdir') + expected_err = "Error: Specified blocks directory \"{}\" does not exist.\n".format(blocksdir_path) + self.nodes[0].assert_start_raises_init_error(["-blocksdir=" + blocksdir_path], expected_err) + os.mkdir(blocksdir_path) self.log.info("Starting with existing blocksdir ...") - self.start_node(0, ["-blocksdir="+self.options.tmpdir+ "/blocksdir"]) + self.start_node(0, ["-blocksdir=" + blocksdir_path]) self.log.info("mining blocks..") self.nodes[0].generate(10) assert(os.path.isfile(os.path.join(self.options.tmpdir, "blocksdir", "regtest", "blocks", "blk00000.dat"))) diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index b29177807e29..3e228753d4fb 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -5,6 +5,7 @@ """Test various command line arguments and configuration file parameters.""" import os +import re from test_framework.test_framework import PivxTestFramework from test_framework.util import get_datadir_path @@ -26,7 +27,7 @@ def run_test(self): # Check that using -datadir argument on non-existent directory fails self.nodes[0].datadir = new_data_dir - self.nodes[0].assert_start_raises_init_error(['-datadir='+new_data_dir], 'Error: Specified data directory "' + new_data_dir + '" does not exist.') + self.nodes[0].assert_start_raises_init_error(['-datadir=' + new_data_dir], 'Error: Specified data directory "' + re.escape(new_data_dir) + '" does not exist.') # Check that using non-existent datadir in conf file fails conf_file = os.path.join(default_data_dir, "pivx.conf") @@ -37,8 +38,7 @@ def run_test(self): f.write("datadir=" + new_data_dir + "\n") f.write(conf_file_contents) - # Temporarily disabled, because this test would access the user's home dir (~/.pivx) - #self.nodes[0].assert_start_raises_init_error(['-conf=' + conf_file], 'Error reading configuration file: specified data directory "' + new_data_dir + '" does not exist.') + self.nodes[0].assert_start_raises_init_error(['-conf=' + conf_file], 'Error reading configuration file: specified data directory "' + re.escape(new_data_dir) + '" does not exist.') # Create the directory and ensure the config file now works os.mkdir(new_data_dir) diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py index 577d8e04c165..f9fc6e4efc1e 100755 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -35,8 +35,8 @@ def run_test(self): invdir = os.path.join(self.nodes[0].datadir, "regtest", "foo") invalidname = os.path.join("foo", "foo.log") self.stop_node(0) - self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % (invalidname)], - "Error: Could not open debug log file") + exp_stderr = "Error: Could not open debug log file \S+$" + self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % (invalidname)], exp_stderr) assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid relative filename throws") @@ -50,8 +50,7 @@ def run_test(self): self.stop_node(0) invdir = os.path.join(self.options.tmpdir, "foo") invalidname = os.path.join(invdir, "foo.log") - self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % invalidname], - "Error: Could not open debug log file") + self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % invalidname], exp_stderr) assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid absolute filename throws") diff --git a/test/functional/feature_uacomment.py b/test/functional/feature_uacomment.py index 78409af6f668..4e9011778d19 100755 --- a/test/functional/feature_uacomment.py +++ b/test/functional/feature_uacomment.py @@ -4,6 +4,8 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the -uacomment option.""" +import re + from test_framework.test_framework import PivxTestFramework from test_framework.util import assert_equal @@ -23,13 +25,14 @@ def run_test(self): self.log.info("test -uacomment max length") self.stop_node(0) - expected = "exceeds maximum length (256). Reduce the number or size of -uacomment." + expected = "Error: Total length of network version string \([0-9]+\) exceeds maximum length \(256\). Reduce the number or size of -uacomment." self.nodes[0].assert_start_raises_init_error(["-uacomment=" + 'a' * 256], expected) self.log.info("test -uacomment unsafe characters") for unsafe_char in ['/', ':', '(', ')']: - expected = "User Agent comment (" + unsafe_char + ") contains unsafe characters" + expected = "Error: User Agent comment \(" + re.escape(unsafe_char) + "\) contains unsafe characters." self.nodes[0].assert_start_raises_init_error(["-uacomment=" + unsafe_char], expected) + if __name__ == '__main__': UacommentTest().main() diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index f402fa285881..7e7b6c873ca7 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -212,8 +212,12 @@ def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT): def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, *args, **kwargs): """Attempt to start the node and expect it to raise an error. + + extra_args: extra arguments to pass through to bitcoind + expected_msg: regex that stderr should match when bitcoind fails + Will throw if pivxd starts without an error. - Will throw if an expected_msg is provided and it does not appear in pivxd's stdout.""" + Will throw if an expected_msg is provided and it does not match pivxd's stdout.""" with tempfile.SpooledTemporaryFile(max_size=2**16) as log_stderr: try: self.start(extra_args, stderr=log_stderr, *args, **kwargs) @@ -224,11 +228,12 @@ def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, *ar assert 'pivxd exited' in str(e) # node must have shutdown self.running = False self.process = None + # Check stderr for expected message if expected_msg is not None: log_stderr.seek(0) stderr = log_stderr.read().decode('utf-8') - if expected_msg not in stderr: - raise AssertionError("Expected error \"" + expected_msg + "\" not found in:\n" + stderr) + if re.fullmatch(expected_msg + '\n', stderr) is None: + raise AssertionError('Expected message "{}" does not match stderr:\n"{}"'.format(expected_msg, stderr)) else: if expected_msg is None: assert_msg = "pivxd should have exited with an error" diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index b92dee0d171c..c198bcc9462d 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -65,22 +65,30 @@ def wallet_file(name): assert_equal(os.path.isfile(wallet_file(wallet_name)), True) # should not initialize if wallet path can't be created - self.nodes[0].assert_start_raises_init_error(['-wallet=wallet.dat/bad'], 'Not a directory') + exp_stderr = "\n\n\*+\n" + \ + "EXCEPTION: .*\n" + \ + "boost::filesystem::create_directory: Not a directory:.*\n" + \ + "pivx in .*\n" + self.nodes[0].assert_start_raises_init_error(['-wallet=wallet.dat/bad'], exp_stderr) self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" does not exist') self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" is a relative path', cwd=data_dir()) self.nodes[0].assert_start_raises_init_error(['-walletdir=debug.log'], 'Error: Specified -walletdir "debug.log" is not a directory', cwd=data_dir()) # should not initialize if there are duplicate wallets - self.nodes[0].assert_start_raises_init_error(['-wallet=w1', '-wallet=w1'], 'Error loading wallet w1. Duplicate -wallet filename specified.') + self.nodes[0].assert_start_raises_init_error(['-wallet=w1', '-wallet=w1'], 'Error: Error loading wallet w1. Duplicate -wallet filename specified.') # should not initialize if one wallet is a copy of another shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy')) - self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], 'duplicates fileid') + exp_stderr = "\n\n\*+\n" + \ + "EXCEPTION: .*\n" + \ + "CDB: Can't open database w8_copy \(duplicates fileid \w+ from w8\)\s*\n" + \ + "pivx in .*\n" + self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr) # 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'], 'Invalid -wallet path') + self.nodes[0].assert_start_raises_init_error(['-wallet=w8_symlink'], 'Error: Invalid -wallet path \'w8_symlink\'\. .*') # 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') @@ -120,8 +128,9 @@ def wallet_file(name): competing_wallet_dir = os.path.join(self.options.tmpdir, 'competing_walletdir') os.mkdir(competing_wallet_dir) - self.restart_node(0, ['-walletdir='+competing_wallet_dir]) - self.nodes[1].assert_start_raises_init_error(['-walletdir='+competing_wallet_dir], 'Error initializing wallet database environment') + self.restart_node(0, ['-walletdir=' + competing_wallet_dir]) + exp_stderr = "Error: Error initializing wallet database environment \"\S+competing_walletdir\"!" + self.nodes[1].assert_start_raises_init_error(['-walletdir=' + competing_wallet_dir], exp_stderr) self.restart_node(0, extra_args) From 0318a5b9ccfc52c40251d3cd0d96a17e9f83bc58 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Tue, 27 Jul 2021 13:32:58 +0200 Subject: [PATCH 3/7] [Trivial] Remove extra newline in missing-blocksdir error --- src/init.cpp | 2 +- test/functional/feature_blocksdir.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 729eb045e3c4..59b9b33cfcd5 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1034,7 +1034,7 @@ bool AppInitParameterInteraction() // ********************************************************* Step 2: parameter interactions if (!fs::is_directory(GetBlocksDir())) { - return UIError(strprintf(_("Specified blocks directory \"%s\" does not exist.\n"), gArgs.GetArg("-blocksdir", "").c_str())); + return UIError(strprintf(_("Specified blocks directory \"%s\" does not exist."), gArgs.GetArg("-blocksdir", "").c_str())); } // Make sure enough file descriptors are available diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py index c04867e457f5..5cc5f3814cbd 100755 --- a/test/functional/feature_blocksdir.py +++ b/test/functional/feature_blocksdir.py @@ -23,7 +23,7 @@ def run_test(self): initialize_datadir(self.options.tmpdir, 0) self.log.info("Starting with nonexistent blocksdir ...") blocksdir_path = os.path.join(self.options.tmpdir, 'blocksdir') - expected_err = "Error: Specified blocks directory \"{}\" does not exist.\n".format(blocksdir_path) + expected_err = 'Error: Specified blocks directory "{}" does not exist.'.format(blocksdir_path) self.nodes[0].assert_start_raises_init_error(["-blocksdir=" + blocksdir_path], expected_err) os.mkdir(blocksdir_path) self.log.info("Starting with existing blocksdir ...") From b6d69ea82e41c705f6e3cce28f855f6158c8b9b9 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Mon, 19 Mar 2018 15:35:04 -0400 Subject: [PATCH 4/7] qa: Allow for partial_match when checking init error This allows the tests to pass on different platforms --- test/functional/test_framework/test_node.py | 12 ++++++++---- test/functional/wallet_multiwallet.py | 19 +++++++------------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 7e7b6c873ca7..cdbe0e2b90cd 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -210,7 +210,7 @@ def is_node_stopped(self): def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT): wait_until(self.is_node_stopped, timeout=timeout) - def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, *args, **kwargs): + def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, partial_match=False, *args, **kwargs): """Attempt to start the node and expect it to raise an error. extra_args: extra arguments to pass through to bitcoind @@ -231,9 +231,13 @@ def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, *ar # Check stderr for expected message if expected_msg is not None: log_stderr.seek(0) - stderr = log_stderr.read().decode('utf-8') - if re.fullmatch(expected_msg + '\n', stderr) is None: - raise AssertionError('Expected message "{}" does not match stderr:\n"{}"'.format(expected_msg, stderr)) + stderr = log_stderr.read().decode('utf-8').strip() + if partial_match: + if re.search(expected_msg, stderr, flags=re.MULTILINE) is None: + raise AssertionError('Expected message "{}" does not partially match stderr:\n"{}"'.format(expected_msg, stderr)) + else: + if re.fullmatch(expected_msg, stderr) is None: + raise AssertionError('Expected message "{}" does not fully match stderr:\n"{}"'.format(expected_msg, stderr)) else: if expected_msg is None: assert_msg = "pivxd should have exited with an error" diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index c198bcc9462d..af705e3b629d 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -9,6 +9,7 @@ """ import os +import re import shutil from test_framework.test_framework import PivxTestFramework @@ -65,11 +66,8 @@ def wallet_file(name): assert_equal(os.path.isfile(wallet_file(wallet_name)), True) # should not initialize if wallet path can't be created - exp_stderr = "\n\n\*+\n" + \ - "EXCEPTION: .*\n" + \ - "boost::filesystem::create_directory: Not a directory:.*\n" + \ - "pivx in .*\n" - self.nodes[0].assert_start_raises_init_error(['-wallet=wallet.dat/bad'], exp_stderr) + exp_stderr = "boost::filesystem::create_directory: (The system cannot find the path specified|Not a directory):" + self.nodes[0].assert_start_raises_init_error(['-wallet=wallet.dat/bad'], exp_stderr, partial_match=True) self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" does not exist') self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" is a relative path', cwd=data_dir()) @@ -80,11 +78,8 @@ def wallet_file(name): # should not initialize if one wallet is a copy of another shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy')) - exp_stderr = "\n\n\*+\n" + \ - "EXCEPTION: .*\n" + \ - "CDB: Can't open database w8_copy \(duplicates fileid \w+ from w8\)\s*\n" + \ - "pivx in .*\n" - self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr) + exp_stderr = "CDB: Can't open database w8_copy \(duplicates fileid \w+ from w8\)" + self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr, partial_match=True) # should not initialize if wallet file is a symlink os.symlink('w8', wallet_dir('w8_symlink')) @@ -95,7 +90,7 @@ def wallet_file(name): # should not initialize if the specified walletdir is not a directory not_a_dir = wallet_dir('notadir') open(not_a_dir, 'a', encoding="utf8").close() - self.nodes[0].assert_start_raises_init_error(['-walletdir='+not_a_dir], 'Error: Specified -walletdir "' + not_a_dir + '" is not a directory') + self.nodes[0].assert_start_raises_init_error(['-walletdir=' + not_a_dir], 'Error: Specified -walletdir "' + re.escape(not_a_dir) + '" is not a directory') self.log.info("Do not allow -zapwallettxes with multiwallet") self.nodes[0].assert_start_raises_init_error(['-zapwallettxes', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file") @@ -130,7 +125,7 @@ def wallet_file(name): os.mkdir(competing_wallet_dir) self.restart_node(0, ['-walletdir=' + competing_wallet_dir]) exp_stderr = "Error: Error initializing wallet database environment \"\S+competing_walletdir\"!" - self.nodes[1].assert_start_raises_init_error(['-walletdir=' + competing_wallet_dir], exp_stderr) + self.nodes[1].assert_start_raises_init_error(['-walletdir=' + competing_wallet_dir], exp_stderr, partial_match=True) self.restart_node(0, extra_args) From 92977e5139c20c9bbba39f5fe0ceb0a81138e217 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Tue, 27 Jul 2021 14:33:28 +0200 Subject: [PATCH 5/7] [Tests] Fix invalid escapes in regex strings to fix W605 >>> adapted from bitcoin@b21680baf5391a602b295b9d7d0ef66553661cb9 --- contrib/devtools/clang-format-diff.py | 4 +- contrib/devtools/copyright_header.py | 73 +++++++++++++-------------- contrib/devtools/symbol-check.py | 4 +- test/functional/combine_logs.py | 11 +++- test/functional/feature_logging.py | 2 +- test/functional/feature_uacomment.py | 4 +- test/functional/wallet_multiwallet.py | 6 +-- 7 files changed, 55 insertions(+), 49 deletions(-) diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py index f322b3a88049..98eee67f4300 100644 --- a/contrib/devtools/clang-format-diff.py +++ b/contrib/devtools/clang-format-diff.py @@ -106,7 +106,7 @@ def main(): filename = None lines_by_file = {} for line in sys.stdin: - match = re.search('^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) + match = re.search(r'^\+\+\+\ (.*?/){%s}(\S*)' % args.p, line) if match: filename = match.group(2) if filename is None: @@ -119,7 +119,7 @@ def main(): if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE): continue - match = re.search('^@@.*\+(\d+)(,(\d+))?', line) + match = re.search(r'^@@.*\+(\d+)(,(\d+))?', line) if match: start_line = int(match.group(1)) line_count = 1 diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py index 9d1a9097f686..99f554472301 100755 --- a/contrib/devtools/copyright_header.py +++ b/contrib/devtools/copyright_header.py @@ -74,7 +74,7 @@ def get_filenames_to_examine(base_directory): ################################################################################ -COPYRIGHT_WITH_C = 'Copyright \(c\)' +COPYRIGHT_WITH_C = r'Copyright \(c\)' COPYRIGHT_WITHOUT_C = 'Copyright' ANY_COPYRIGHT_STYLE = '(%s|%s)' % (COPYRIGHT_WITH_C, COPYRIGHT_WITHOUT_C) @@ -88,43 +88,42 @@ def get_filenames_to_examine(base_directory): ANY_COPYRIGHT_COMPILED = re.compile(ANY_COPYRIGHT_STYLE_OR_YEAR_STYLE) def compile_copyright_regex(copyright_style, year_style, name): - return re.compile('%s %s,? %s' % (copyright_style, year_style, name)) + return re.compile('%s %s,? %s\n' % (copyright_style, year_style, name)) EXPECTED_HOLDER_NAMES = [ - "Satoshi Nakamoto\n", - "The Bitcoin Core developers\n", - "The Bitcoin Core developers \n", - "Bitcoin Core Developers\n", - "the Bitcoin Core developers\n", - "The Bitcoin developers\n", - "The LevelDB Authors\. All rights reserved\.\n", - "BitPay Inc\.\n", - "BitPay, Inc\.\n", - "University of Illinois at Urbana-Champaign\.\n", - "MarcoFalke\n", - "Pieter Wuille\n", - "Pieter Wuille +\*\n", - "Pieter Wuille, Gregory Maxwell +\*\n", - "Pieter Wuille, Andrew Poelstra +\*\n", - "Ian Miers, Christina Garman and Matthew Green\n", - "Andrew Poelstra +\*\n", - "Wladimir J. van der Laan\n", - "Jeff Garzik\n", - "Diederik Huys, Pieter Wuille +\*\n", - "Thomas Daede, Cory Fields +\*\n", - "Jan-Klaas Kollhof\n", - "Sam Rushing\n", - "ArtForz -- public domain half-a-node\n", - " Projet RNRT SAPHIR\n", - "The Zcash developers\n", - "The Dash developers\n", - "The Dash Developers\n", - "The Dash Core developers\n", - "The PIVX developers\n", - "The PPCoin developers\n", - "The NovaCoin Developers", - "The BlackCoin Developers\n", - "The Blackcoin More developers\n", + r"Satoshi Nakamoto", + r"The Bitcoin Core developers", + r"Bitcoin Core Developers", + r"the Bitcoin Core developers", + r"The Bitcoin developers", + r"The LevelDB Authors\. All rights reserved\.", + r"BitPay Inc\.", + r"BitPay, Inc\.", + r"University of Illinois at Urbana-Champaign\.", + r"MarcoFalke", + r"Pieter Wuille", + r"Pieter Wuille +\*", + r"Pieter Wuille, Gregory Maxwell +\*", + r"Pieter Wuille, Andrew Poelstra +\*", + r"Ian Miers, Christina Garman and Matthew Green", + r"Andrew Poelstra +\*", + r"Wladimir J. van der Laan", + r"Jeff Garzik", + r"Diederik Huys, Pieter Wuille +\*", + r"Thomas Daede, Cory Fields +\*", + r"Jan-Klaas Kollhof", + r"Sam Rushing", + r"ArtForz -- public domain half-a-node", + r" Projet RNRT SAPHIR", + r"The Zcash developers", + r"The Dash developers", + r"The Dash Developers", + r"The Dash Core developers", + r"The PIVX developers", + r"The PPCoin developers", + r"The NovaCoin Developers", + r"The BlackCoin Developers", + r"The Blackcoin More developers", ] DOMINANT_STYLE_COMPILED = {} @@ -354,7 +353,7 @@ def write_file_lines(filename, file_lines): # update header years execution ################################################################################ -COPYRIGHT = 'Copyright \(c\)' +COPYRIGHT = r'Copyright \(c\)' YEAR = "20[0-9][0-9]" YEAR_RANGE = '(%s)(-%s)?' % (YEAR, YEAR) HOLDER = 'The PIVX developers' diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 11cb74ac4fd4..1bf36e224916 100755 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -142,7 +142,7 @@ def read_libraries(filename): for line in stdout.splitlines(): tokens = line.split() if len(tokens)>2 and tokens[1] == '(NEEDED)': - match = re.match('^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) + match = re.match(r'^Shared library: \[(.*)\]$', ' '.join(tokens[2:])) if match: libraries.append(match.group(1)) else: @@ -172,5 +172,3 @@ def read_libraries(filename): retval = 1 sys.exit(retval) - - diff --git a/test/functional/combine_logs.py b/test/functional/combine_logs.py index 724fc2778f6d..0de944136c72 100755 --- a/test/functional/combine_logs.py +++ b/test/functional/combine_logs.py @@ -11,6 +11,7 @@ import argparse from collections import defaultdict, namedtuple +import glob import heapq import itertools import os @@ -66,9 +67,17 @@ def read_logs(tmp_dir): Delegates to generator function get_log_events() to provide individual log events for each of the input log files.""" + # Find out what the folder is called that holds the debug.log file + chain = glob.glob("{}/node0/*/debug.log".format(tmp_dir)) + if chain: + chain = chain[0] # pick the first one if more than one chain was found (should never happen) + chain = re.search(r'node0/(.+?)/debug\.log$', chain).group(1) # extract the chain name + else: + chain = 'regtest' # fallback to regtest (should only happen when none exists) + files = [("test", "%s/test_framework.log" % tmp_dir)] for i in itertools.count(): - logfile = "{}/node{}/regtest/debug.log".format(tmp_dir, i) + logfile = "{}/node{}/{}/debug.log".format(tmp_dir, i, chain) if not os.path.isfile(logfile): break files.append(("node%d" % i, logfile)) diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py index f9fc6e4efc1e..0e6dd80e1044 100755 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -35,7 +35,7 @@ def run_test(self): invdir = os.path.join(self.nodes[0].datadir, "regtest", "foo") invalidname = os.path.join("foo", "foo.log") self.stop_node(0) - exp_stderr = "Error: Could not open debug log file \S+$" + exp_stderr = r"Error: Could not open debug log file \S+$" self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % (invalidname)], exp_stderr) assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid relative filename throws") diff --git a/test/functional/feature_uacomment.py b/test/functional/feature_uacomment.py index 4e9011778d19..77c0d61b0c72 100755 --- a/test/functional/feature_uacomment.py +++ b/test/functional/feature_uacomment.py @@ -25,12 +25,12 @@ def run_test(self): self.log.info("test -uacomment max length") self.stop_node(0) - expected = "Error: Total length of network version string \([0-9]+\) exceeds maximum length \(256\). Reduce the number or size of -uacomment." + expected = r"Error: Total length of network version string \([0-9]+\) exceeds maximum length \(256\). Reduce the number or size of -uacomment." self.nodes[0].assert_start_raises_init_error(["-uacomment=" + 'a' * 256], expected) self.log.info("test -uacomment unsafe characters") for unsafe_char in ['/', ':', '(', ')']: - expected = "Error: User Agent comment \(" + re.escape(unsafe_char) + "\) contains unsafe characters." + expected = r"Error: User Agent comment \(" + re.escape(unsafe_char) + r"\) contains unsafe characters." self.nodes[0].assert_start_raises_init_error(["-uacomment=" + unsafe_char], expected) diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index af705e3b629d..de8e22094c73 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -78,12 +78,12 @@ def wallet_file(name): # should not initialize if one wallet is a copy of another shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy')) - exp_stderr = "CDB: Can't open database w8_copy \(duplicates fileid \w+ from w8\)" + exp_stderr = r"CDB: Can't open database w8_copy \(duplicates fileid \w+ from w8\)" self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr, partial_match=True) # 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\'\. .*') + self.nodes[0].assert_start_raises_init_error(['-wallet=w8_symlink'], r'Error: Invalid -wallet path \'w8_symlink\'\. .*') # 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') @@ -124,7 +124,7 @@ def wallet_file(name): competing_wallet_dir = os.path.join(self.options.tmpdir, 'competing_walletdir') os.mkdir(competing_wallet_dir) self.restart_node(0, ['-walletdir=' + competing_wallet_dir]) - exp_stderr = "Error: Error initializing wallet database environment \"\S+competing_walletdir\"!" + exp_stderr = r"Error: Error initializing wallet database environment \"\S+competing_walletdir\"!" self.nodes[1].assert_start_raises_init_error(['-walletdir=' + competing_wallet_dir], exp_stderr, partial_match=True) self.restart_node(0, extra_args) From 38dae984e78c67cca0973cc5ca4b812892a84922 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Wed, 28 Mar 2018 09:37:09 -0400 Subject: [PATCH 6/7] qa: Match full plain text by default --- test/functional/feature_config_args.py | 5 ++--- test/functional/feature_logging.py | 5 +++-- test/functional/feature_uacomment.py | 5 +++-- test/functional/test_framework/test_node.py | 16 +++++++++++++--- test/functional/wallet_multiwallet.py | 15 +++++++-------- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py index 3e228753d4fb..f828c2bd0142 100755 --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -5,7 +5,6 @@ """Test various command line arguments and configuration file parameters.""" import os -import re from test_framework.test_framework import PivxTestFramework from test_framework.util import get_datadir_path @@ -27,7 +26,7 @@ def run_test(self): # Check that using -datadir argument on non-existent directory fails self.nodes[0].datadir = new_data_dir - self.nodes[0].assert_start_raises_init_error(['-datadir=' + new_data_dir], 'Error: Specified data directory "' + re.escape(new_data_dir) + '" does not exist.') + self.nodes[0].assert_start_raises_init_error(['-datadir=' + new_data_dir], 'Error: Specified data directory "' + new_data_dir + '" does not exist.') # Check that using non-existent datadir in conf file fails conf_file = os.path.join(default_data_dir, "pivx.conf") @@ -38,7 +37,7 @@ def run_test(self): f.write("datadir=" + new_data_dir + "\n") f.write(conf_file_contents) - self.nodes[0].assert_start_raises_init_error(['-conf=' + conf_file], 'Error reading configuration file: specified data directory "' + re.escape(new_data_dir) + '" does not exist.') + self.nodes[0].assert_start_raises_init_error(['-conf=' + conf_file], 'Error reading configuration file: specified data directory "' + new_data_dir + '" does not exist.') # Create the directory and ensure the config file now works os.mkdir(new_data_dir) diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py index 0e6dd80e1044..4bbc930f440b 100755 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -8,6 +8,7 @@ import os from test_framework.test_framework import PivxTestFramework +from test_framework.test_node import ErrorMatch class LoggingTest(PivxTestFramework): @@ -36,7 +37,7 @@ def run_test(self): invalidname = os.path.join("foo", "foo.log") self.stop_node(0) exp_stderr = r"Error: Could not open debug log file \S+$" - self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % (invalidname)], exp_stderr) + self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % (invalidname)], exp_stderr, match=ErrorMatch.FULL_REGEX) assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid relative filename throws") @@ -50,7 +51,7 @@ def run_test(self): self.stop_node(0) invdir = os.path.join(self.options.tmpdir, "foo") invalidname = os.path.join(invdir, "foo.log") - self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % invalidname], exp_stderr) + self.nodes[0].assert_start_raises_init_error(["-debuglogfile=%s" % invalidname], exp_stderr, match=ErrorMatch.FULL_REGEX) assert not os.path.isfile(os.path.join(invdir, "foo.log")) self.log.info("Invalid absolute filename throws") diff --git a/test/functional/feature_uacomment.py b/test/functional/feature_uacomment.py index 77c0d61b0c72..e825bf7dcc30 100755 --- a/test/functional/feature_uacomment.py +++ b/test/functional/feature_uacomment.py @@ -7,6 +7,7 @@ import re from test_framework.test_framework import PivxTestFramework +from test_framework.test_node import ErrorMatch from test_framework.util import assert_equal class UacommentTest(PivxTestFramework): @@ -26,12 +27,12 @@ def run_test(self): self.log.info("test -uacomment max length") self.stop_node(0) expected = r"Error: Total length of network version string \([0-9]+\) exceeds maximum length \(256\). Reduce the number or size of -uacomment." - self.nodes[0].assert_start_raises_init_error(["-uacomment=" + 'a' * 256], expected) + self.nodes[0].assert_start_raises_init_error(["-uacomment=" + 'a' * 256], expected, match=ErrorMatch.FULL_REGEX) self.log.info("test -uacomment unsafe characters") for unsafe_char in ['/', ':', '(', ')']: expected = r"Error: User Agent comment \(" + re.escape(unsafe_char) + r"\) contains unsafe characters." - self.nodes[0].assert_start_raises_init_error(["-uacomment=" + unsafe_char], expected) + self.nodes[0].assert_start_raises_init_error(["-uacomment=" + unsafe_char], expected, match=ErrorMatch.FULL_REGEX) if __name__ == '__main__': diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index cdbe0e2b90cd..78c9d499420e 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -7,6 +7,7 @@ import contextlib import decimal import errno +from enum import Enum import http.client import json import logging @@ -32,6 +33,12 @@ BITCOIND_PROC_WAIT_TIMEOUT = 600 +class ErrorMatch(Enum): + FULL_TEXT = 1 + FULL_REGEX = 2 + PARTIAL_REGEX = 3 + + class TestNode(): """A class for representing a pivxd node under test. @@ -210,7 +217,7 @@ def is_node_stopped(self): def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT): wait_until(self.is_node_stopped, timeout=timeout) - def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, partial_match=False, *args, **kwargs): + def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, match=ErrorMatch.FULL_TEXT, *args, **kwargs): """Attempt to start the node and expect it to raise an error. extra_args: extra arguments to pass through to bitcoind @@ -232,12 +239,15 @@ def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, par if expected_msg is not None: log_stderr.seek(0) stderr = log_stderr.read().decode('utf-8').strip() - if partial_match: + if match == ErrorMatch.PARTIAL_REGEX: if re.search(expected_msg, stderr, flags=re.MULTILINE) is None: raise AssertionError('Expected message "{}" does not partially match stderr:\n"{}"'.format(expected_msg, stderr)) - else: + elif match == ErrorMatch.FULL_REGEX: if re.fullmatch(expected_msg, stderr) is None: raise AssertionError('Expected message "{}" does not fully match stderr:\n"{}"'.format(expected_msg, stderr)) + elif match == ErrorMatch.FULL_TEXT: + if expected_msg != stderr: + raise AssertionError('Expected message "{}" does not fully match stderr:\n"{}"'.format(expected_msg, stderr)) else: if expected_msg is None: assert_msg = "pivxd should have exited with an error" diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py index de8e22094c73..7fcc2282b123 100755 --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -9,12 +9,11 @@ """ import os -import re import shutil from test_framework.test_framework import PivxTestFramework from test_framework.util import assert_equal, assert_raises_rpc_error - +from test_framework.test_node import ErrorMatch class MultiWalletTest(PivxTestFramework): def set_test_params(self): @@ -67,7 +66,7 @@ def wallet_file(name): # 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):" - self.nodes[0].assert_start_raises_init_error(['-wallet=wallet.dat/bad'], exp_stderr, partial_match=True) + 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') self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" is a relative path', cwd=data_dir()) @@ -79,18 +78,18 @@ def wallet_file(name): # should not initialize if one wallet is a copy of another shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy')) exp_stderr = r"CDB: Can't open database w8_copy \(duplicates fileid \w+ from w8\)" - self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr, partial_match=True) + 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'], r'Error: Invalid -wallet path \'w8_symlink\'\. .*') + self.nodes[0].assert_start_raises_init_error(['-wallet=w8_symlink'], r'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') # should not initialize if the specified walletdir is not a directory not_a_dir = wallet_dir('notadir') - open(not_a_dir, 'a', encoding="utf8").close() - self.nodes[0].assert_start_raises_init_error(['-walletdir=' + not_a_dir], 'Error: Specified -walletdir "' + re.escape(not_a_dir) + '" is not a directory') + open(not_a_dir, 'a').close() + self.nodes[0].assert_start_raises_init_error(['-walletdir=' + not_a_dir], 'Error: Specified -walletdir "' + not_a_dir + '" is not a directory') self.log.info("Do not allow -zapwallettxes with multiwallet") self.nodes[0].assert_start_raises_init_error(['-zapwallettxes', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file") @@ -125,7 +124,7 @@ def wallet_file(name): os.mkdir(competing_wallet_dir) self.restart_node(0, ['-walletdir=' + competing_wallet_dir]) exp_stderr = r"Error: Error initializing wallet database environment \"\S+competing_walletdir\"!" - self.nodes[1].assert_start_raises_init_error(['-walletdir=' + competing_wallet_dir], exp_stderr, partial_match=True) + self.nodes[1].assert_start_raises_init_error(['-walletdir=' + competing_wallet_dir], exp_stderr, match=ErrorMatch.PARTIAL_REGEX) self.restart_node(0, extra_args) From 84768b5eaff26901935056ec63041f99935f944a Mon Sep 17 00:00:00 2001 From: random-zebra Date: Tue, 27 Jul 2021 21:30:29 +0200 Subject: [PATCH 7/7] scripted-diff: bitcoind-->pivxd in tests -BEGIN VERIFY SCRIPT- sed -i 's/bitcoind/pivxd/' test/functional/*.py test/functional/*/*.py -END VERIFY SCRIPT- --- test/functional/feature_abortnode.py | 4 ++-- test/functional/feature_notifications.py | 2 +- test/functional/feature_proxy.py | 6 +++--- test/functional/feature_reindex.py | 2 +- test/functional/mempool_persist.py | 4 ++-- test/functional/p2p_leak.py | 4 ++-- test/functional/rpc_bind.py | 2 +- test/functional/test_framework/messages.py | 4 ++-- test/functional/test_framework/test_node.py | 10 +++++----- test/functional/test_runner.py | 4 ++-- 10 files changed, 21 insertions(+), 21 deletions(-) diff --git a/test/functional/feature_abortnode.py b/test/functional/feature_abortnode.py index 5c481c9406dd..9fbd831f866b 100755 --- a/test/functional/feature_abortnode.py +++ b/test/functional/feature_abortnode.py @@ -2,12 +2,12 @@ # Copyright (c) 2019 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or https://www.opensource.org/licenses/mit-license.php. -"""Test bitcoind aborts if can't disconnect a block. +"""Test pivxd aborts if can't disconnect a block. - Start a single node and generate 3 blocks. - Delete the undo data. - Mine a fork that requires disconnecting the tip. -- Verify that bitcoind AbortNode's. +- Verify that pivxd AbortNode's. """ import os diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py index 0d0ecf605a0d..ecb48b08d428 100755 --- a/test/functional/feature_notifications.py +++ b/test/functional/feature_notifications.py @@ -79,7 +79,7 @@ def run_test(self): self.nodes[1].generate(51) self.sync_all() - # Give bitcoind 10 seconds to write the alert notification + # Give pivxd 10 seconds to write the alert notification wait_until(lambda: len(os.listdir(self.alertnotify_dir)), timeout=10) for notify_file in os.listdir(self.alertnotify_dir): diff --git a/test/functional/feature_proxy.py b/test/functional/feature_proxy.py index 3d3c38ddacd5..c0a2c1da87ec 100755 --- a/test/functional/feature_proxy.py +++ b/test/functional/feature_proxy.py @@ -2,7 +2,7 @@ # Copyright (c) 2015-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. -"""Test bitcoind with different proxy configuration. +"""Test pivxd with different proxy configuration. Test plan: - Start pivxd's with different proxy configurations @@ -96,7 +96,7 @@ def node_test(self, node, proxies, auth, test_onion=True): node.addnode("15.61.23.23:1234", "onetry") cmd = proxies[0].queue.get() assert(isinstance(cmd, Socks5Command)) - # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 + # Note: pivxd's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 assert_equal(cmd.atyp, AddressType.DOMAINNAME) assert_equal(cmd.addr, b"15.61.23.23") assert_equal(cmd.port, 1234) @@ -110,7 +110,7 @@ def node_test(self, node, proxies, auth, test_onion=True): node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry") cmd = proxies[1].queue.get() assert(isinstance(cmd, Socks5Command)) - # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 + # Note: pivxd's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 assert_equal(cmd.atyp, AddressType.DOMAINNAME) assert_equal(cmd.addr, b"1233:3432:2434:2343:3234:2345:6546:4534") assert_equal(cmd.port, 5443) diff --git a/test/functional/feature_reindex.py b/test/functional/feature_reindex.py index a28bae1e0f6f..ab4e682d47ff 100755 --- a/test/functional/feature_reindex.py +++ b/test/functional/feature_reindex.py @@ -2,7 +2,7 @@ # Copyright (c) 2014-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. -"""Test running bitcoind with -reindex and -reindex-chainstate options. +"""Test running pivxd with -reindex and -reindex-chainstate options. - Start a single node and generate 3 blocks. - Stop the node and restart it with -reindex. Verify that the node has reindexed up to block 3. diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py index df13d026032e..7cfe8e3269df 100755 --- a/test/functional/mempool_persist.py +++ b/test/functional/mempool_persist.py @@ -4,7 +4,7 @@ # file COPYING or https://www.opensource.org/licenses/mit-license.php. """Test mempool persistence. -By default, bitcoind will dump mempool on shutdown and +By default, pivxd will dump mempool on shutdown and then reload it on startup. This can be overridden with the -persistmempool=false command line option. @@ -106,7 +106,7 @@ def run_test(self): assert self.nodes[0].getmempoolinfo()["loaded"] assert_equal(len(self.nodes[1].getrawmempool()), 5) - self.log.debug("Prevent bitcoind from writing mempool.dat to disk. Verify that `savemempool` fails") + self.log.debug("Prevent pivxd from writing mempool.dat to disk. Verify that `savemempool` fails") # to test the exception we are creating a tmp folder called mempool.dat.new # which is an implementation detail that could change and break this test mempooldotnew1 = mempooldat1 + '.new' diff --git a/test/functional/p2p_leak.py b/test/functional/p2p_leak.py index f7eaaaa354ef..2d70ad30b7f5 100755 --- a/test/functional/p2p_leak.py +++ b/test/functional/p2p_leak.py @@ -10,7 +10,7 @@ This test connects to a node and sends it a few messages, trying to intice it into sending us something it shouldn't. -Also test that nodes that send unsupported service bits to bitcoind are disconnected +Also test that nodes that send unsupported service bits to pivxd are disconnected and don't receive a VERACK. Unsupported service bits are currently 1 << 5 and 1 << 7 (until August 1st 2018). """ @@ -64,7 +64,7 @@ def on_blocktxn(self, message): self.bad_message(message) # anyway, and eventually get disconnected. class CNodeNoVersionBan(CLazyNode): # send a bunch of veracks without sending a message. This should get us disconnected. - # NOTE: implementation-specific check here. Remove if bitcoind ban behavior changes + # NOTE: implementation-specific check here. Remove if pivxd ban behavior changes def on_open(self): super().on_open() for i in range(banscore): diff --git a/test/functional/rpc_bind.py b/test/functional/rpc_bind.py index d54f06a6337a..31ecdf8bbd8d 100755 --- a/test/functional/rpc_bind.py +++ b/test/functional/rpc_bind.py @@ -2,7 +2,7 @@ # Copyright (c) 2014-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. -"""Test running bitcoind with the -rpcbind and -rpcallowip options.""" +"""Test running pivxd with the -rpcbind and -rpcallowip options.""" import socket import sys diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py index af151776c582..ad684d33b3b5 100644 --- a/test/functional/test_framework/messages.py +++ b/test/functional/test_framework/messages.py @@ -188,7 +188,7 @@ def FromHex(obj, hex_string): def ToHex(obj): return bytes_to_hex_str(obj.serialize()) -# Objects that map to bitcoind objects, which can be serialized/deserialized +# Objects that map to pivxd objects, which can be serialized/deserialized class CAddress(): def __init__(self): @@ -1237,7 +1237,7 @@ def __init__(self, headers=None): self.headers = headers if headers is not None else [] def deserialize(self, f): - # comment in bitcoind indicates these should be deserialized as blocks + # comment in pivxd indicates these should be deserialized as blocks blocks = deser_vector(f, CBlock) for x in blocks: self.headers.append(CBlockHeader(x)) diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py index 78c9d499420e..c7a9ec05b18e 100755 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -91,7 +91,7 @@ def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mo self.p2ps = [] def __del__(self): - # Ensure that we don't leave any bitcoind processes lying around after + # Ensure that we don't leave any pivxd processes lying around after # the test ends if self.process and self.cleanup_on_exit: # Should only happen on test failure @@ -115,7 +115,7 @@ def start(self, extra_args=None, stderr=None, *args, **kwargs): if stderr is None: stderr = self.stderr # Delete any existing cookie file -- if such a file exists (eg due to - # unclean shutdown), it will get overwritten anyway by bitcoind, and + # unclean shutdown), it will get overwritten anyway by pivxd, and # potentially interfere with our attempt to authenticate delete_cookie_file(self.datadir) self.process = subprocess.Popen(self.args + extra_args, stderr=stderr, *args, **kwargs) @@ -167,7 +167,7 @@ def wait_for_rpc_connection(self): 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 + except ValueError as e: # cookie file not found and no rpcuser or rpcassword. pivxd still starting if "No RPC credentials" not in str(e): raise time.sleep(1.0 / poll_per_s) @@ -220,8 +220,8 @@ def wait_until_stopped(self, timeout=BITCOIND_PROC_WAIT_TIMEOUT): def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, match=ErrorMatch.FULL_TEXT, *args, **kwargs): """Attempt to start the node and expect it to raise an error. - extra_args: extra arguments to pass through to bitcoind - expected_msg: regex that stderr should match when bitcoind fails + extra_args: extra arguments to pass through to pivxd + expected_msg: regex that stderr should match when pivxd fails Will throw if pivxd starts without an error. Will throw if an expected_msg is provided and it does not match pivxd's stdout.""" diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index d72f92583cfb..9dba4eff818b 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -297,7 +297,7 @@ def main(): enable_wallet = config["components"].getboolean("ENABLE_WALLET") enable_utils = config["components"].getboolean("ENABLE_UTILS") - enable_bitcoind = config["components"].getboolean("ENABLE_BITCOIND") + enable_pivxd = config["components"].getboolean("ENABLE_BITCOIND") if config["environment"]["EXEEXT"] == ".exe" and not args.force: # https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9 @@ -305,7 +305,7 @@ def main(): print("Tests currently disabled on Windows by default. Use --force option to enable") sys.exit(0) - if not (enable_wallet and enable_utils and enable_bitcoind): + if not (enable_wallet and enable_utils and enable_pivxd): print("No functional tests to run. Wallet, utils, and pivxd must all be enabled") print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") sys.exit(0)