Skip to content

Commit

Permalink
Added rpc help test (#392)
Browse files Browse the repository at this point in the history
* Added rpc help test

Tests the ability to generate help at runtime

* Added check for compiled wallet and zmq

* Setup clean chain to try avoid timeout on travis

* Streamline test to only check invalid help calls and help categories

* Added back removed functionality

* Updated init
  • Loading branch information
hdnsimpson authored and alex v committed Jan 29, 2019
1 parent 1990d92 commit 6707a98
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
1 change: 1 addition & 0 deletions qa/pull-tester/rpc-tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
'staticr-staking-amount.py',
'hardfork-451.py',
'staticr-tx-send.py',
'rpc-help.py',
]
#if ENABLE_ZMQ:
# testScripts.append('zmq_test.py')
Expand Down
61 changes: 61 additions & 0 deletions qa/rpc-tests/rpc-help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
# Tests RPC help output at runtime

from test_framework.test_framework import NavCoinTestFramework
from test_framework.util import *

import os


class HelpRpcTest(NavCoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.num_nodes = 1

def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
self.is_network_split = False

def run_test(self):
self.test_categories()
self.dump_help()

def test_categories(self):
node = self.nodes[0]

# wrong argument count
assert_raises_rpc_error(-1, 'help ( "command" )', node.help, 'foo', 'bar')

# invalid argument
assert_raises_rpc_error(-1, 'JSON value is not a string as expected', node.help, 0)

# help of unknown command
assert_equal(node.help('foo'), 'help: unknown command: foo')

# command titles
titles = [line[3:-3] for line in node.help().splitlines() if line.startswith('==')]

components = ['Addressindex', 'Blockchain', 'Communityfund', 'Control', 'Generating', 'Hacking', 'Mining', 'Network', 'Rawtransactions', 'Util']

# titles and components will differ depending on whether wallet and/or zmq are compiled
if 'Wallet' in titles:
components.append('Wallet')

if 'Zmq' in titles:
components.append('Zmq')

assert_equal(titles, components)

def dump_help(self):
dump_dir = os.path.join(self.options.tmpdir, 'rpc_help_dump')
os.mkdir(dump_dir)
calls = [line.split(' ', 1)[0] for line in self.nodes[0].help().splitlines() if line and not line.startswith('==')]
for call in calls:
with open(os.path.join(dump_dir, call), 'w', encoding='utf-8') as f:
# Make sure node can generate the help at runtime without crashing
f.write(self.nodes[0].help(call))


if __name__ == '__main__':
HelpRpcTest().main()
34 changes: 34 additions & 0 deletions qa/rpc-tests/test_framework/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,40 @@ def assert_array_result(object_array, to_match, expected, should_not_find = Fals
if num_matched > 0 and should_not_find == True:
raise AssertionError("Objects were found %s"%(str(to_match)))

def assert_raises_rpc_error(code, message, fun, *args, **kwds):
"""Run an RPC and verify that a specific JSONRPC exception code and message is raised.
Calls function `fun` with arguments `args` and `kwds`. Catches a JSONRPCException
and verifies that the error code and message are as expected. Throws AssertionError if
no JSONRPCException was raised or if the error code/message are not as expected.
Args:
code (int), optional: the error code returned by the RPC call (defined
in src/rpc/protocol.h). Set to None if checking the error code is not required.
message (string), optional: [a substring of] the error string returned by the
RPC call. Set to None if checking the error string is not required.
fun (function): the function to call. This should be the name of an RPC.
args*: positional arguments for the function.
kwds**: named arguments for the function.
"""
assert try_rpc(code, message, fun, *args, **kwds), "No exception raised"

def try_rpc(code, message, fun, *args, **kwds):
"""Tries to run an rpc command.
Test against error code and message if the rpc fails.
Returns whether a JSONRPCException was raised."""
try:
fun(*args, **kwds)
except JSONRPCException as e:
# JSONRPCException was thrown as expected. Check the code and message values are correct.
if (code is not None) and (code != e.error["code"]):
raise AssertionError("Unexpected JSONRPC error code %i" % e.error["code"])
if (message is not None) and (message not in e.error['message']):
raise AssertionError("Expected substring not found:" + e.error['message'])
return True
except Exception as e:
raise AssertionError("Unexpected exception raised: " + type(e).__name__)
else:
return False

def satoshi_round(amount):
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)

Expand Down

0 comments on commit 6707a98

Please sign in to comment.