diff --git a/test/functional/abc-cmdline.py b/test/functional/abc-cmdline.py --- a/test/functional/abc-cmdline.py +++ b/test/functional/abc-cmdline.py @@ -16,7 +16,7 @@ from test_framework.util import assert_equal MAX_GENERATED_BLOCK_SIZE_ERROR = ( - r'Max generated block size \(blockmaxsize\) cannot exceed the excessive block size \(excessiveblocksize\)') + 'Max generated block size (blockmaxsize) cannot exceed the excessive block size (excessiveblocksize)') class ABC_CmdLine_Test (BitcoinTestFramework): @@ -55,7 +55,7 @@ self.stop_node(0) self.nodes[0].assert_start_raises_init_error( ["-excessiveblocksize={}".format(LEGACY_MAX_BLOCK_SIZE)], - r'Error: Excessive block size must be > 1,000,000 bytes \(1MB\)') + 'Error: Excessive block size must be > 1,000,000 bytes (1MB)') self.log.info(" Attempt to set below blockmaxsize (mining limit)") self.nodes[0].assert_start_raises_init_error( ['-blockmaxsize=1500000', '-excessiveblocksize=1300000'], 'Error: ' + MAX_GENERATED_BLOCK_SIZE_ERROR) diff --git a/test/functional/feature_blocksdir.py b/test/functional/feature_blocksdir.py --- a/test/functional/feature_blocksdir.py +++ b/test/functional/feature_blocksdir.py @@ -6,7 +6,6 @@ """ import os -import re import shutil from test_framework.test_framework import BitcoinTestFramework, initialize_datadir @@ -26,8 +25,8 @@ initialize_datadir(self.options.tmpdir, 0) self.log.info("Starting with nonexistent blocksdir ...") blocksdir_path = os.path.join(self.options.tmpdir, 'blocksdir') - self.nodes[0].assert_start_raises_init_error(["-blocksdir=" + blocksdir_path], re.escape( - 'Error: Specified blocks directory "{}" does not exist.'.format(blocksdir_path))) + self.nodes[0].assert_start_raises_init_error( + ["-blocksdir=" + blocksdir_path], 'Error: Specified blocks directory "{}" does not exist.'.format(blocksdir_path)) os.mkdir(blocksdir_path) self.log.info("Starting with existing blocksdir ...") self.start_node(0, ["-blocksdir=" + blocksdir_path]) diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py --- a/test/functional/feature_config_args.py +++ b/test/functional/feature_config_args.py @@ -4,7 +4,6 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test various command line arguments and configuration file parameters.""" import os -import re from test_framework.test_framework import BitcoinTestFramework @@ -26,8 +25,7 @@ # 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.') + ['-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, "bitcoin.conf") @@ -39,8 +37,7 @@ 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.') + ['-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 --- a/test/functional/feature_logging.py +++ b/test/functional/feature_logging.py @@ -7,6 +7,7 @@ import os from test_framework.test_framework import BitcoinTestFramework +from test_framework.test_node import ErrorMatch class LoggingTest(BitcoinTestFramework): @@ -35,7 +36,7 @@ self.stop_node(0) exp_stderr = r"Error: Could not open debug log file \S+$" self.nodes[0].assert_start_raises_init_error( - ["-debuglogfile={}".format(invalidname)], exp_stderr) + ["-debuglogfile={}".format(invalidname)], exp_stderr, match=ErrorMatch.FULL_REGEX) assert not os.path.isfile(os.path.join(invdir, "foo.log")) # check that invalid log (relative) works after path exists @@ -49,7 +50,7 @@ invdir = os.path.join(self.options.tmpdir, "foo") invalidname = os.path.join(invdir, "foo.log") self.nodes[0].assert_start_raises_init_error( - ["-debuglogfile={}".format(invalidname)], exp_stderr) + ["-debuglogfile={}".format(invalidname)], exp_stderr, match=ErrorMatch.FULL_REGEX) assert not os.path.isfile(os.path.join(invdir, "foo.log")) # check that invalid log (absolute) works after path exists diff --git a/test/functional/feature_uacomment.py b/test/functional/feature_uacomment.py --- a/test/functional/feature_uacomment.py +++ b/test/functional/feature_uacomment.py @@ -7,6 +7,7 @@ import re from test_framework.test_framework import BitcoinTestFramework +from test_framework.test_node import ErrorMatch from test_framework.util import assert_equal @@ -28,14 +29,14 @@ 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 uacomments." self.nodes[0].assert_start_raises_init_error( - ["-uacomment=" + 'a' * 256], expected) + ["-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) + ["-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 --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -6,6 +6,7 @@ import contextlib import decimal +from enum import Enum import errno import http.client import json @@ -39,6 +40,12 @@ """Raised when a node fails to start correctly.""" +class ErrorMatch(Enum): + FULL_TEXT = 1 + FULL_REGEX = 2 + PARTIAL_REGEX = 3 + + class TestNode(): """A class for representing a bitcoind node under test. @@ -262,7 +269,7 @@ self._raise_assertion_error( 'Expected message "{}" does not partially match log:\n\n{}\n\n'.format(expected_msg, print_log)) - 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 @@ -286,14 +293,18 @@ 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 = "bitcoind should have exited with an error" diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py --- a/test/functional/wallet_multiwallet.py +++ b/test/functional/wallet_multiwallet.py @@ -7,10 +7,10 @@ Verify that a bitcoind node can load multiple wallet files """ import os -import re import shutil from test_framework.test_framework import BitcoinTestFramework +from test_framework.test_node import ErrorMatch from test_framework.util import ( assert_equal, assert_raises_rpc_error, @@ -70,7 +70,7 @@ # 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) + ['-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') @@ -87,12 +87,12 @@ shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy')) exp_stderr = r"BerkeleyBatch: 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) + ['-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\'\. .*') + ['-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( @@ -101,7 +101,7 @@ 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') + ['-walletdir=' + not_a_dir], 'Error: Specified -walletdir "' + not_a_dir + '" is not a directory') # if wallets/ doesn't exist, datadir should be the default wallet dir wallet_dir2 = data_dir('walletdir') @@ -126,7 +126,7 @@ 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) + ['-walletdir=' + competing_wallet_dir], exp_stderr, match=ErrorMatch.PARTIAL_REGEX) self.restart_node(0, extra_args)