Skip to content

Commit 4ae6d0f

Browse files
author
MarcoFalke
committed
Merge #10798: [tests] [utils] test bitcoin-cli
c6ec435 [tests] Add bitcoin_cli.py test script (John Newbery) b23549f [tests] add TestNodeCLI class for calling bitcoin-cli for a node (John Newbery) Pull request description: We don't test bitcoin-cli at all. That means that we can miss inconsistencies between the bitcoin-cli client and the RPC interface, such as #10698 and #10747. It also means that the various bitcoin-cli options and features are untested and regressions could be silently introduced. Let's fix that. This PR adds bitcoin-cli testing in the python functional test_framework: 1. Add a bitcoin_cli.py test script that tests bitcoin-cli. At the moment it only tests that the result of `getinfo` is the same if you run it as an RPC or through bitcoin-cli, but can easily be extended to test additional bitcoin-cli features **EDIT: `--usecli` option is moved to a separate PR. This PR now only covers the bitcoin_cli.py test.** 2. ~Add a `--usecli` option to the test framework. This changes the test to use bitcoin-cli for all RPC calls instead of using direct HTTP requests. This is somewhat experimental. It works for most tests, but there are some cases where it can't work transparently because:~ - ~the testcase is asserting on a specific error code, and bitcoin-cli returns a different error code from the direct RPC~ - ~we're sending a very large RPC request (eg `submitblock`) and it can't be serialized into a shell bitcoin-cli call.~ ~I think that even though `--usecli` doesn't work on all tests, it's still a useful experimental feature. Future potential enhancements:~ - ~enhance the framework to automatically skip tests that are known to fail with bitcoin-cli if the `--usecli` option is used.~ - ~run a subset of tests in Travis with `-usecli`~ This builds on and requires the `TestNode` PR #10711 . As an aside, this is a good demonstration of how tidy it is to add additional features/interfaces now that test node logic/state is encapsulated in a TestNode class. Addresses #10791 Tree-SHA512: a1e6be12e8e007f6f67b3d3bbcd142d835787300831eb38e6027a1ad25ca9d79c4bc99a41b19e31ee95205cba1b3b2d21a688b5909316aad70bfc2b4eb6d8a52
2 parents affe927 + c6ec435 commit 4ae6d0f

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

test/functional/bitcoin_cli.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2017 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 bitcoin-cli"""
6+
from test_framework.test_framework import BitcoinTestFramework
7+
from test_framework.util import assert_equal
8+
9+
class TestBitcoinCli(BitcoinTestFramework):
10+
11+
def __init__(self):
12+
super().__init__()
13+
self.setup_clean_chain = True
14+
self.num_nodes = 1
15+
16+
def run_test(self):
17+
"""Main test logic"""
18+
19+
self.log.info("Compare responses from getinfo RPC and `bitcoin-cli getinfo`")
20+
cli_get_info = self.nodes[0].cli.getinfo()
21+
rpc_get_info = self.nodes[0].getinfo()
22+
23+
assert_equal(cli_get_info, rpc_get_info)
24+
25+
if __name__ == '__main__':
26+
TestBitcoinCli().main()

test/functional/test_framework/test_node.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Class for bitcoind node under test"""
66

7+
import decimal
78
import errno
89
import http.client
10+
import json
911
import logging
1012
import os
1113
import subprocess
@@ -49,6 +51,8 @@ def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mo
4951
self.extra_args = extra_args
5052
self.args = [self.binary, "-datadir=" + self.datadir, "-server", "-keypool=1", "-discover=0", "-rest", "-logtimemicros", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", "-mocktime=" + str(mocktime), "-uacomment=testnode%d" % i]
5153

54+
self.cli = TestNodeCLI(os.getenv("BITCOINCLI", "bitcoin-cli"), self.datadir)
55+
5256
self.running = False
5357
self.process = None
5458
self.rpc_connected = False
@@ -136,3 +140,28 @@ def node_encrypt_wallet(self, passphrase):
136140
time.sleep(0.1)
137141
self.rpc = None
138142
self.rpc_connected = False
143+
144+
class TestNodeCLI():
145+
"""Interface to bitcoin-cli for an individual node"""
146+
147+
def __init__(self, binary, datadir):
148+
self.binary = binary
149+
self.datadir = datadir
150+
151+
def __getattr__(self, command):
152+
def dispatcher(*args, **kwargs):
153+
return self.send_cli(command, *args, **kwargs)
154+
return dispatcher
155+
156+
def send_cli(self, command, *args, **kwargs):
157+
"""Run bitcoin-cli command. Deserializes returned string as python object."""
158+
159+
pos_args = [str(arg) for arg in args]
160+
named_args = [str(key) + "=" + str(value) for (key, value) in kwargs.items()]
161+
assert not (pos_args and named_args), "Cannot use positional arguments and named arguments in the same bitcoin-cli call"
162+
p_args = [self.binary, "-datadir=" + self.datadir]
163+
if named_args:
164+
p_args += ["-named"]
165+
p_args += [command] + pos_args + named_args
166+
cli_output = subprocess.check_output(p_args, universal_newlines=True)
167+
return json.loads(cli_output, parse_float=decimal.Decimal)

test/functional/test_runner.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
# vv Tests less than 30s vv
8282
'keypool-topup.py',
8383
'zmq_test.py',
84+
'bitcoin_cli.py',
8485
'mempool_resurrect_test.py',
8586
'txn_doublespend.py --mineblock',
8687
'txn_clone.py',
@@ -279,6 +280,7 @@ def run_tests(test_list, src_dir, build_dir, exeext, tmpdir, jobs=1, enable_cove
279280
#Set env vars
280281
if "BITCOIND" not in os.environ:
281282
os.environ["BITCOIND"] = build_dir + '/src/bitcoind' + exeext
283+
os.environ["BITCOINCLI"] = build_dir + '/src/bitcoin-cli' + exeext
282284

283285
tests_dir = src_dir + '/test/functional/'
284286

0 commit comments

Comments
 (0)