mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
merge #16115: On bitcoind startup, write config args to debug.log
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
parent
98cec64482
commit
b9efbdeab7
13
src/init.cpp
13
src/init.cpp
@ -574,7 +574,7 @@ void SetupServerArgs(NodeContext& node)
|
|||||||
argsman.AddArg("-socketevents=<mode>", "Socket events mode, which must be one of 'select', 'poll', 'epoll' or 'kqueue', depending on your system (default: Linux - 'epoll', FreeBSD/Apple - 'kqueue', Windows - 'select')", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-socketevents=<mode>", "Socket events mode, which must be one of 'select', 'poll', 'epoll' or 'kqueue', depending on your system (default: Linux - 'epoll', FreeBSD/Apple - 'kqueue', Windows - 'select')", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-timeout=<n>", strprintf("Specify connection timeout in milliseconds (minimum: 1, default: %d)", DEFAULT_CONNECT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-timeout=<n>", strprintf("Specify connection timeout in milliseconds (minimum: 1, default: %d)", DEFAULT_CONNECT_TIMEOUT), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-torcontrol=<ip>:<port>", strprintf("Tor control port to use if onion listening enabled (default: %s)", DEFAULT_TOR_CONTROL), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-torcontrol=<ip>:<port>", strprintf("Tor control port to use if onion listening enabled (default: %s)", DEFAULT_TOR_CONTROL), ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
argsman.AddArg("-torpassword=<pass>", "Tor control port password (default: empty)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-torpassword=<pass>", "Tor control port password (default: empty)", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::CONNECTION);
|
||||||
#ifdef USE_UPNP
|
#ifdef USE_UPNP
|
||||||
#if USE_UPNP
|
#if USE_UPNP
|
||||||
argsman.AddArg("-upnp", "Use UPnP to map the listening port (default: 1 when listening and no -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
argsman.AddArg("-upnp", "Use UPnP to map the listening port (default: 1 when listening and no -proxy)", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION);
|
||||||
@ -746,14 +746,14 @@ void SetupServerArgs(NodeContext& node)
|
|||||||
|
|
||||||
argsman.AddArg("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcallowip=<ip>", "Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcallowip=<ip>", "Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcauth=<userpw>", "Username and HMAC-SHA-256 hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcauth=<userpw>", "Username and HMAC-SHA-256 hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. The client then connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> pair of arguments. This option can be specified multiple times", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcbind=<addr>[:port]", "Bind to given address to listen for JSON-RPC connections. Do not expose the RPC server to untrusted networks such as the public internet! This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcbind=<addr>[:port]", "Bind to given address to listen for JSON-RPC connections. Do not expose the RPC server to untrusted networks such as the public internet! This option is ignored unless -rpcallowip is also passed. Port is optional and overrides -rpcport. Use [host]:port notation for IPv6. This option can be specified multiple times (default: 127.0.0.1 and ::1 i.e., localhost, or if -rpcallowip has been specified, 0.0.0.0 and :: i.e., all addresses)", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpccookiefile=<loc>", "Location of the auth cookie. Relative paths will be prefixed by a net-specific datadir location. (default: data dir)", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcport=<port>", strprintf("Listen for JSON-RPC connections on <port> (default: %u, testnet: %u, regtest: %u)", defaultBaseParams->RPCPort(), testnetBaseParams->RPCPort(), regtestBaseParams->RPCPort()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcthreads=<n>", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcthreads=<n>", strprintf("Set the number of threads to service RPC calls (default: %d)", DEFAULT_HTTP_THREADS), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcwhitelist=<whitelist>", "Set a whitelist to filter incoming RPC calls for a specific user. The field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc 2>,...,<rpc n>. If multiple whitelists are set for a given user, they are set-intersected. See -rpcwhitelistdefault documentation for information on default whitelist behavior.", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcwhitelist=<whitelist>", "Set a whitelist to filter incoming RPC calls for a specific user. The field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc 2>,...,<rpc n>. If multiple whitelists are set for a given user, they are set-intersected. See -rpcwhitelistdefault documentation for information on default whitelist behavior.", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcwhitelistdefault", "Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault is set to 0, if any -rpcwhitelist is set, the rpc server acts as if all rpc users are subject to empty-unless-otherwise-specified whitelists. If rpcwhitelistdefault is set to 1 and no -rpcwhitelist is set, rpc server acts as if all rpc users are subject to empty whitelists.", ArgsManager::ALLOW_BOOL, OptionsCategory::RPC);
|
argsman.AddArg("-rpcwhitelistdefault", "Sets default behavior for rpc whitelisting. Unless rpcwhitelistdefault is set to 0, if any -rpcwhitelist is set, the rpc server acts as if all rpc users are subject to empty-unless-otherwise-specified whitelists. If rpcwhitelistdefault is set to 1 and no -rpcwhitelist is set, rpc server acts as if all rpc users are subject to empty whitelists.", ArgsManager::ALLOW_BOOL, OptionsCategory::RPC);
|
||||||
argsman.AddArg("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
|
argsman.AddArg("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::RPC);
|
||||||
@ -1645,6 +1645,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
|
|||||||
LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string());
|
LogPrintf("Config file: %s (not found, skipping)\n", config_file_path.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log the config arguments to debug.log
|
||||||
|
args.LogArgs();
|
||||||
|
|
||||||
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
|
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
|
||||||
|
|
||||||
// Warn about relative -datadir path.
|
// Warn about relative -datadir path.
|
||||||
|
@ -192,4 +192,32 @@ BOOST_AUTO_TEST_CASE(boolargno)
|
|||||||
BOOST_CHECK(m_args.GetBoolArg("-foo", false));
|
BOOST_CHECK(m_args.GetBoolArg("-foo", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(logargs)
|
||||||
|
{
|
||||||
|
const auto okaylog_bool = std::make_pair("-okaylog-bool", ArgsManager::ALLOW_BOOL);
|
||||||
|
const auto okaylog_negbool = std::make_pair("-okaylog-negbool", ArgsManager::ALLOW_BOOL);
|
||||||
|
const auto okaylog = std::make_pair("-okaylog", ArgsManager::ALLOW_ANY);
|
||||||
|
const auto dontlog = std::make_pair("-dontlog", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE);
|
||||||
|
SetupArgs({okaylog_bool, okaylog_negbool, okaylog, dontlog});
|
||||||
|
ResetArgs("-okaylog-bool -nookaylog-negbool -okaylog=public -dontlog=private");
|
||||||
|
|
||||||
|
// Everything logged to debug.log will also append to str
|
||||||
|
std::string str;
|
||||||
|
auto print_connection = LogInstance().PushBackCallback(
|
||||||
|
[&str](const std::string& s) {
|
||||||
|
str += s;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Log the arguments
|
||||||
|
m_args.LogArgs();
|
||||||
|
|
||||||
|
LogInstance().DeleteCallback(print_connection);
|
||||||
|
// Check that what should appear does, and what shouldn't doesn't.
|
||||||
|
BOOST_CHECK(str.find("Command-line arg: okaylog-bool=\"\"") != std::string::npos);
|
||||||
|
BOOST_CHECK(str.find("Command-line arg: okaylog-negbool=false") != std::string::npos);
|
||||||
|
BOOST_CHECK(str.find("Command-line arg: okaylog=\"public\"") != std::string::npos);
|
||||||
|
BOOST_CHECK(str.find("dontlog=****") != std::string::npos);
|
||||||
|
BOOST_CHECK(str.find("private") == std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -935,6 +935,32 @@ std::string ArgsManager::GetDevNetName() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ArgsManager::logArgsPrefix(
|
||||||
|
const std::string& prefix,
|
||||||
|
const std::string& section,
|
||||||
|
const std::map<std::string, std::vector<util::SettingsValue>>& args) const
|
||||||
|
{
|
||||||
|
std::string section_str = section.empty() ? "" : "[" + section + "] ";
|
||||||
|
for (const auto& arg : args) {
|
||||||
|
for (const auto& value : arg.second) {
|
||||||
|
Optional<unsigned int> flags = GetArgFlags('-' + arg.first);
|
||||||
|
if (flags) {
|
||||||
|
std::string value_str = (*flags & SENSITIVE) ? "****" : value.write();
|
||||||
|
LogPrintf("%s %s%s=%s\n", prefix, section_str, arg.first, value_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArgsManager::LogArgs() const
|
||||||
|
{
|
||||||
|
LOCK(cs_args);
|
||||||
|
for (const auto& section : m_settings.ro_config) {
|
||||||
|
logArgsPrefix("Config file arg:", section.first, section.second);
|
||||||
|
}
|
||||||
|
logArgsPrefix("Command-line arg:", "", m_settings.command_line_options);
|
||||||
|
}
|
||||||
|
|
||||||
bool RenameOver(fs::path src, fs::path dest)
|
bool RenameOver(fs::path src, fs::path dest)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -172,6 +172,8 @@ public:
|
|||||||
* between mainnet and regtest/testnet won't cause problems due to these
|
* between mainnet and regtest/testnet won't cause problems due to these
|
||||||
* parameters by accident. */
|
* parameters by accident. */
|
||||||
NETWORK_ONLY = 0x200,
|
NETWORK_ONLY = 0x200,
|
||||||
|
// This argument's value is sensitive (such as a password).
|
||||||
|
SENSITIVE = 0x400,
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -340,6 +342,19 @@ public:
|
|||||||
* Return nullopt for unknown arg.
|
* Return nullopt for unknown arg.
|
||||||
*/
|
*/
|
||||||
Optional<unsigned int> GetArgFlags(const std::string& name) const;
|
Optional<unsigned int> GetArgFlags(const std::string& name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log the config file options and the command line arguments,
|
||||||
|
* useful for troubleshooting.
|
||||||
|
*/
|
||||||
|
void LogArgs() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Helper function for LogArgs().
|
||||||
|
void logArgsPrefix(
|
||||||
|
const std::string& prefix,
|
||||||
|
const std::string& section,
|
||||||
|
const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ArgsManager gArgs;
|
extern ArgsManager gArgs;
|
||||||
|
@ -76,9 +76,9 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
|
|||||||
CURRENCY_UNIT, FormatMoney(CFeeRate{DEFAULT_PAY_TX_FEE}.GetFeePerK())), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_FEE);
|
CURRENCY_UNIT, FormatMoney(CFeeRate{DEFAULT_PAY_TX_FEE}.GetFeePerK())), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_FEE);
|
||||||
argsman.AddArg("-txconfirmtarget=<n>", strprintf("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)", DEFAULT_TX_CONFIRM_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_FEE);
|
argsman.AddArg("-txconfirmtarget=<n>", strprintf("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)", DEFAULT_TX_CONFIRM_TARGET), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_FEE);
|
||||||
|
|
||||||
argsman.AddArg("-hdseed=<hex>", "User defined seed for HD wallet (should be in hex). Only has effect during wallet creation/first start (default: randomly generated)", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_HD);
|
argsman.AddArg("-hdseed=<hex>", "User defined seed for HD wallet (should be in hex). Only has effect during wallet creation/first start (default: randomly generated)", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::WALLET_HD);
|
||||||
argsman.AddArg("-mnemonic=<text>", "User defined mnemonic for HD wallet (bip39). Only has effect during wallet creation/first start (default: randomly generated)", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_HD);
|
argsman.AddArg("-mnemonic=<text>", "User defined mnemonic for HD wallet (bip39). Only has effect during wallet creation/first start (default: randomly generated)", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::WALLET_HD);
|
||||||
argsman.AddArg("-mnemonicpassphrase=<text>", "User defined mnemonic passphrase for HD wallet (BIP39). Only has effect during wallet creation/first start (default: empty string)", ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_HD);
|
argsman.AddArg("-mnemonicpassphrase=<text>", "User defined mnemonic passphrase for HD wallet (BIP39). Only has effect during wallet creation/first start (default: empty string)", ArgsManager::ALLOW_ANY | ArgsManager::SENSITIVE, OptionsCategory::WALLET_HD);
|
||||||
argsman.AddArg("-usehd", strprintf("Use hierarchical deterministic key generation (HD) after BIP39/BIP44. Only has effect during wallet creation/first start (default: %u)", DEFAULT_USE_HD_WALLET), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_HD);
|
argsman.AddArg("-usehd", strprintf("Use hierarchical deterministic key generation (HD) after BIP39/BIP44. Only has effect during wallet creation/first start (default: %u)", DEFAULT_USE_HD_WALLET), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_HD);
|
||||||
|
|
||||||
argsman.AddArg("-enablecoinjoin", strprintf("Enable use of CoinJoin for funds stored in this wallet (0-1, default: %u)", 0), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_COINJOIN);
|
argsman.AddArg("-enablecoinjoin", strprintf("Enable use of CoinJoin for funds stored in this wallet (0-1, default: %u)", 0), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET_COINJOIN);
|
||||||
|
@ -84,10 +84,40 @@ class ConfArgsTest(BitcoinTestFramework):
|
|||||||
self.start_node(0, extra_args=['-noconnect=0'])
|
self.start_node(0, extra_args=['-noconnect=0'])
|
||||||
self.stop_node(0)
|
self.stop_node(0)
|
||||||
|
|
||||||
|
def test_args_log(self):
|
||||||
|
self.log.info('Test config args logging')
|
||||||
|
with self.nodes[0].assert_debug_log(
|
||||||
|
expected_msgs=[
|
||||||
|
'Command-line arg: addnode="some.node"',
|
||||||
|
'Command-line arg: rpcauth=****',
|
||||||
|
'Command-line arg: rpcbind=****',
|
||||||
|
'Command-line arg: rpcpassword=****',
|
||||||
|
'Command-line arg: rpcuser=****',
|
||||||
|
'Command-line arg: torpassword=****',
|
||||||
|
'Config file arg: regtest="1"',
|
||||||
|
'Config file arg: [regtest] server="1"',
|
||||||
|
],
|
||||||
|
unexpected_msgs=[
|
||||||
|
'alice:f7efda5c189b999524f151318c0c86$d5b51b3beffbc0',
|
||||||
|
'127.1.1.1',
|
||||||
|
'secret-rpcuser',
|
||||||
|
'secret-torpassword',
|
||||||
|
]):
|
||||||
|
self.start_node(0, extra_args=[
|
||||||
|
'-addnode=some.node',
|
||||||
|
'-rpcauth=alice:f7efda5c189b999524f151318c0c86$d5b51b3beffbc0',
|
||||||
|
'-rpcbind=127.1.1.1',
|
||||||
|
'-rpcpassword=',
|
||||||
|
'-rpcuser=secret-rpcuser',
|
||||||
|
'-torpassword=secret-torpassword',
|
||||||
|
])
|
||||||
|
self.stop_node(0)
|
||||||
|
|
||||||
def run_test(self):
|
def run_test(self):
|
||||||
self.stop_node(0)
|
self.stop_node(0)
|
||||||
|
|
||||||
self.test_log_buffer()
|
self.test_log_buffer()
|
||||||
|
self.test_args_log()
|
||||||
|
|
||||||
|
|
||||||
self.test_config_file_parser()
|
self.test_config_file_parser()
|
||||||
|
@ -327,7 +327,9 @@ class TestNode():
|
|||||||
wait_until(self.is_node_stopped, timeout=timeout)
|
wait_until(self.is_node_stopped, timeout=timeout)
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def assert_debug_log(self, expected_msgs, timeout=2):
|
def assert_debug_log(self, expected_msgs, unexpected_msgs=None, timeout=2):
|
||||||
|
if unexpected_msgs is None:
|
||||||
|
unexpected_msgs = []
|
||||||
time_end = time.time() + timeout
|
time_end = time.time() + timeout
|
||||||
chain = get_chain_folder(self.datadir, self.chain)
|
chain = get_chain_folder(self.datadir, self.chain)
|
||||||
debug_log = os.path.join(self.datadir, chain, 'debug.log')
|
debug_log = os.path.join(self.datadir, chain, 'debug.log')
|
||||||
@ -343,6 +345,9 @@ class TestNode():
|
|||||||
dl.seek(prev_size)
|
dl.seek(prev_size)
|
||||||
log = dl.read()
|
log = dl.read()
|
||||||
print_log = " - " + "\n - ".join(log.splitlines())
|
print_log = " - " + "\n - ".join(log.splitlines())
|
||||||
|
for unexpected_msg in unexpected_msgs:
|
||||||
|
if re.search(re.escape(unexpected_msg), log, flags=re.MULTILINE):
|
||||||
|
self._raise_assertion_error('Unexpected message "{}" partially matches log:\n\n{}\n\n'.format(unexpected_msg, print_log))
|
||||||
for expected_msg in expected_msgs:
|
for expected_msg in expected_msgs:
|
||||||
if re.search(re.escape(expected_msg), log, flags=re.MULTILINE) is None:
|
if re.search(re.escape(expected_msg), log, flags=re.MULTILINE) is None:
|
||||||
found = False
|
found = False
|
||||||
|
Loading…
Reference in New Issue
Block a user