rpc_misc.py raw

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