rpc_misc.py
1 #!/usr/bin/env python3 2 # Copyright (c) 2019-2022 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 RPC misc output.""" 6 import xml.etree.ElementTree as ET 7 8 from test_framework.test_framework import BitcoinTestFramework 9 from test_framework.util import ( 10 assert_raises_rpc_error, 11 assert_equal, 12 assert_greater_than, 13 assert_greater_than_or_equal, 14 ) 15 16 from test_framework.authproxy import JSONRPCException 17 18 import http 19 import subprocess 20 21 22 class RpcMiscTest(BitcoinTestFramework): 23 def set_test_params(self): 24 self.num_nodes = 1 25 26 def run_test(self): 27 node = self.nodes[0] 28 29 self.log.info("test CHECK_NONFATAL") 30 msg_internal_bug = 'request.params[9].get_str() != "trigger_internal_bug"' 31 self.restart_node(0) # Required to flush the chainstate 32 try: 33 node.echo(arg9="trigger_internal_bug") 34 assert False # Must hit one of the exceptions below 35 except ( 36 subprocess.CalledProcessError, 37 http.client.CannotSendRequest, 38 http.client.RemoteDisconnected, 39 ): 40 self.log.info("Restart node after crash") 41 assert_equal(-6, node.process.wait(timeout=10)) 42 self.start_node(0) 43 except JSONRPCException as e: 44 assert_equal(e.error["code"], -1) 45 assert f"Internal bug detected: {msg_internal_bug}" in e.error["message"] 46 47 self.log.info("test max arg size") 48 ARG_SZ_COMMON = 131071 # Common limit, used previously in the test framework, serves as a regression test 49 ARG_SZ_LARGE = 8 * 1024 * 1024 # A large size, which should be rare to hit in practice 50 for arg_sz in [0, 1, 100, ARG_SZ_COMMON, ARG_SZ_LARGE]: 51 arg_string = 'a' * arg_sz 52 assert_equal([arg_string, arg_string], node.echo(arg_string, arg_string)) 53 54 self.log.info("test getmemoryinfo") 55 memory = node.getmemoryinfo()['locked'] 56 assert_greater_than(memory['used'], 0) 57 assert_greater_than(memory['free'], 0) 58 assert_greater_than(memory['total'], 0) 59 # assert_greater_than_or_equal() for locked in case locking pages failed at some point 60 assert_greater_than_or_equal(memory['locked'], 0) 61 assert_greater_than(memory['chunks_used'], 0) 62 assert_greater_than(memory['chunks_free'], 0) 63 assert_equal(memory['used'] + memory['free'], memory['total']) 64 65 self.log.info("test mallocinfo") 66 try: 67 mallocinfo = node.getmemoryinfo(mode="mallocinfo") 68 self.log.info('getmemoryinfo(mode="mallocinfo") call succeeded') 69 tree = ET.fromstring(mallocinfo) 70 assert_equal(tree.tag, 'malloc') 71 except JSONRPCException: 72 self.log.info('getmemoryinfo(mode="mallocinfo") not available') 73 assert_raises_rpc_error(-8, 'mallocinfo mode not available', node.getmemoryinfo, mode="mallocinfo") 74 75 assert_raises_rpc_error(-8, "unknown mode foobar", node.getmemoryinfo, mode="foobar") 76 77 self.log.info("test logging rpc and help") 78 79 # Test toggling a logging category on/off/on with the logging RPC. 80 assert_equal(node.logging()['qt'], True) 81 node.logging(exclude=['qt']) 82 assert_equal(node.logging()['qt'], False) 83 node.logging(include=['qt']) 84 assert_equal(node.logging()['qt'], True) 85 86 # Test logging RPC returns the logging categories in alphabetical order. 87 sorted_logging_categories = sorted(node.logging()) 88 assert_equal(list(node.logging()), sorted_logging_categories) 89 90 # Test logging help returns the logging categories string in alphabetical order. 91 categories = ', '.join(sorted_logging_categories) 92 logging_help = self.nodes[0].help('logging') 93 assert f"valid logging categories are: {categories}" in logging_help 94 95 self.log.info("test echoipc (testing spawned process in multiprocess build)") 96 assert_equal(node.echoipc("hello"), "hello") 97 98 self.log.info("test getindexinfo") 99 # Without any indices running the RPC returns an empty object 100 assert_equal(node.getindexinfo(), {}) 101 102 # Restart the node with indices and wait for them to sync 103 self.restart_node(0, ["-txindex", "-blockfilterindex", "-coinstatsindex"]) 104 self.wait_until(lambda: all(i["synced"] for i in node.getindexinfo().values())) 105 106 # Returns a list of all running indices by default 107 values = {"synced": True, "best_block_height": 200} 108 assert_equal( 109 node.getindexinfo(), 110 { 111 "txindex": values, 112 "basic block filter index": values, 113 "coinstatsindex": values, 114 } 115 ) 116 # Specifying an index by name returns only the status of that index 117 for i in {"txindex", "basic block filter index", "coinstatsindex"}: 118 assert_equal(node.getindexinfo(i), {i: values}) 119 120 # Specifying an unknown index name returns an empty result 121 assert_equal(node.getindexinfo("foo"), {}) 122 123 124 if __name__ == '__main__': 125 RpcMiscTest(__file__).main()