feature_logging.py
1 #!/usr/bin/env python3 2 # Copyright (c) 2017-present The Bitcoin Core developers 3 # Distributed under the MIT software license, see the accompanying 4 # file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 """Test debug logging.""" 6 7 import os 8 9 from test_framework.test_framework import BitcoinTestFramework 10 from test_framework.p2p import P2PInterface 11 from test_framework.test_node import ErrorMatch 12 13 14 class LoggingTest(BitcoinTestFramework): 15 def set_test_params(self): 16 self.num_nodes = 1 17 self.setup_clean_chain = True 18 19 def relative_log_path(self, name): 20 return os.path.join(self.nodes[0].chain_path, name) 21 22 def run_test(self): 23 # test default log file name 24 default_log_path = self.relative_log_path("debug.log") 25 assert os.path.isfile(default_log_path) 26 27 # test alternative log file name in datadir 28 self.restart_node(0, ["-debuglogfile=foo.log"]) 29 assert os.path.isfile(self.relative_log_path("foo.log")) 30 31 # test alternative log file name outside datadir 32 tempname = os.path.join(self.options.tmpdir, "foo.log") 33 self.restart_node(0, [f"-debuglogfile={tempname}"]) 34 assert os.path.isfile(tempname) 35 36 # check that invalid log (relative) will cause error 37 invdir = self.relative_log_path("foo") 38 invalidname = os.path.join("foo", "foo.log") 39 self.stop_node(0) 40 exp_stderr = r"Error: Could not open debug log file \S+$" 41 self.nodes[0].assert_start_raises_init_error([f"-debuglogfile={invalidname}"], exp_stderr, match=ErrorMatch.FULL_REGEX) 42 assert not os.path.isfile(os.path.join(invdir, "foo.log")) 43 44 # check that invalid log (relative) works after path exists 45 self.stop_node(0) 46 os.mkdir(invdir) 47 self.start_node(0, [f"-debuglogfile={invalidname}"]) 48 assert os.path.isfile(os.path.join(invdir, "foo.log")) 49 50 # check that invalid log (absolute) will cause error 51 self.stop_node(0) 52 invdir = os.path.join(self.options.tmpdir, "foo") 53 invalidname = os.path.join(invdir, "foo.log") 54 self.nodes[0].assert_start_raises_init_error([f"-debuglogfile={invalidname}"], exp_stderr, match=ErrorMatch.FULL_REGEX) 55 assert not os.path.isfile(os.path.join(invdir, "foo.log")) 56 57 # check that invalid log (absolute) works after path exists 58 self.stop_node(0) 59 os.mkdir(invdir) 60 self.start_node(0, [f"-debuglogfile={invalidname}"]) 61 assert os.path.isfile(os.path.join(invdir, "foo.log")) 62 63 # check that -nodebuglogfile disables logging 64 self.stop_node(0) 65 os.unlink(default_log_path) 66 assert not os.path.isfile(default_log_path) 67 self.start_node(0, ["-nodebuglogfile"]) 68 assert not os.path.isfile(default_log_path) 69 70 # just sanity check no crash here 71 self.restart_node(0, [f"-debuglogfile={os.devnull}"]) 72 73 self.log.info("Test -debug and -debugexclude raise when invalid values are passed") 74 self.stop_node(0) 75 self.nodes[0].assert_start_raises_init_error( 76 extra_args=["-debug=abc"], 77 expected_msg="Error: Unsupported logging category -debug=abc.", 78 match=ErrorMatch.FULL_REGEX, 79 ) 80 self.nodes[0].assert_start_raises_init_error( 81 extra_args=["-debugexclude=abc"], 82 expected_msg="Error: Unsupported logging category -debugexclude=abc.", 83 match=ErrorMatch.FULL_REGEX, 84 ) 85 86 self.log.info("Test -loglevel raises when invalid values are passed") 87 self.nodes[0].assert_start_raises_init_error( 88 extra_args=["-loglevel=abc"], 89 expected_msg="Error: Unsupported global logging level -loglevel=abc. Valid values: info, debug, trace.", 90 match=ErrorMatch.FULL_REGEX, 91 ) 92 self.nodes[0].assert_start_raises_init_error( 93 extra_args=["-loglevel=net:abc"], 94 expected_msg="Error: Unsupported category-specific logging level -loglevel=net:abc.", 95 match=ErrorMatch.PARTIAL_REGEX, 96 ) 97 self.nodes[0].assert_start_raises_init_error( 98 extra_args=["-loglevel=net:info:abc"], 99 expected_msg="Error: Unsupported category-specific logging level -loglevel=net:info:abc.", 100 match=ErrorMatch.PARTIAL_REGEX, 101 ) 102 103 self.log.info("Test that -nodebug,-debug=0,-debug=none clear previously specified debug options") 104 disable_debug_options = [ 105 '-debug=0', 106 '-debug=none', 107 '-nodebug' 108 ] 109 110 for disable_debug_opt in disable_debug_options: 111 # Every category before disable_debug_opt will be ignored, including the invalid 'abc' 112 self.restart_node(0, ['-debug=http', '-debug=abc', disable_debug_opt, '-debug=rpc', '-debug=net']) 113 logging = self.nodes[0].logging() 114 assert not logging['http'] 115 assert 'abc' not in logging 116 assert logging['rpc'] 117 assert logging['net'] 118 119 self.log.info("Test -logips formatting in net logs") 120 self.restart_node(0, ['-debug=net', '-logips=1']) 121 with self.nodes[0].assert_debug_log(["peer=0, peeraddr="]): 122 p2p = self.nodes[0].add_p2p_connection(P2PInterface()) 123 p2p.wait_for_verack() 124 self.nodes[0].disconnect_p2ps() 125 126 if __name__ == '__main__': 127 LoggingTest(__file__).main()