Skip to content

Commit

Permalink
[tests] allow tests to be run with --usecli
Browse files Browse the repository at this point in the history
test_framework accepts a new --usecli parameter. Running the test with
this parameter will cause all RPCs to be sent through bitcoin-cli rather
than directly over http. By default, individual test cases do not
support --usecli, and self.supports_cli must be set to True in the
set_test_params method.

We can make supports_cli default to True in future once we know which
tests will fail with use_cli.
  • Loading branch information
jnewbery committed Jan 8, 2018
1 parent ff9a363 commit f6ade9c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
1 change: 1 addition & 0 deletions test/functional/create_cache.py
Expand Up @@ -16,6 +16,7 @@ class CreateCache(BitcoinTestFramework):

def set_test_params(self):
self.num_nodes = 0
self.supports_cli = True

def setup_network(self):
pass
Expand Down
7 changes: 6 additions & 1 deletion test/functional/test_framework/test_framework.py
Expand Up @@ -62,6 +62,7 @@ def __init__(self):
self.setup_clean_chain = False
self.nodes = []
self.mocktime = 0
self.supports_cli = False
self.set_test_params()

assert hasattr(self, "num_nodes"), "Test must set self.num_nodes in set_test_params()"
Expand Down Expand Up @@ -91,6 +92,8 @@ def main(self):
help="Location of the test framework config file")
parser.add_option("--pdbonfailure", dest="pdbonfailure", default=False, action="store_true",
help="Attach a python debugger if test fails")
parser.add_option("--usecli", dest="usecli", default=False, action="store_true",
help="use bitcoin-cli instead of RPC for all commands")
self.add_options(parser)
(self.options, self.args) = parser.parse_args()

Expand All @@ -113,6 +116,8 @@ def main(self):
success = TestStatus.FAILED

try:
if self.options.usecli and not self.supports_cli:
raise SkipTest("--usecli specified but test does not support using CLI")
self.setup_chain()
self.setup_network()
self.run_test()
Expand Down Expand Up @@ -213,7 +218,7 @@ def add_nodes(self, num_nodes, extra_args=None, rpchost=None, timewait=None, bin
assert_equal(len(extra_args), num_nodes)
assert_equal(len(binary), num_nodes)
for i in range(num_nodes):
self.nodes.append(TestNode(i, self.options.tmpdir, extra_args[i], rpchost, timewait=timewait, binary=binary[i], stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir))
self.nodes.append(TestNode(i, self.options.tmpdir, extra_args[i], rpchost, timewait=timewait, binary=binary[i], stderr=None, mocktime=self.mocktime, coverage_dir=self.options.coveragedir, use_cli=self.options.usecli))

def start_node(self, i, extra_args=None, stderr=None):
"""Start a bitcoind"""
Expand Down
25 changes: 17 additions & 8 deletions test/functional/test_framework/test_node.py
Expand Up @@ -42,7 +42,7 @@ class TestNode():
To make things easier for the test writer, any unrecognised messages will
be dispatched to the RPC connection."""

def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mocktime, coverage_dir):
def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mocktime, coverage_dir, use_cli=False):
self.index = i
self.datadir = os.path.join(dirname, "node" + str(i))
self.rpchost = rpchost
Expand All @@ -62,6 +62,7 @@ def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mo
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]

self.cli = TestNodeCLI(os.getenv("BITCOINCLI", "bitcoin-cli"), self.datadir)
self.use_cli = use_cli

self.running = False
self.process = None
Expand All @@ -73,9 +74,12 @@ def __init__(self, i, dirname, extra_args, rpchost, timewait, binary, stderr, mo
self.p2ps = []

def __getattr__(self, name):
"""Dispatches any unrecognised messages to the RPC connection."""
assert self.rpc_connected and self.rpc is not None, "Error: no RPC connection"
return getattr(self.rpc, name)
"""Dispatches any unrecognised messages to the RPC connection or a CLI instance."""
if self.use_cli:
return getattr(self.cli, name)
else:
assert self.rpc_connected and self.rpc is not None, "Error: no RPC connection"
return getattr(self.rpc, name)

def start(self, extra_args=None, stderr=None):
"""Start the node."""
Expand Down Expand Up @@ -114,10 +118,13 @@ def wait_for_rpc_connection(self):
raise AssertionError("Unable to connect to bitcoind")

def get_wallet_rpc(self, wallet_name):
assert self.rpc_connected
assert self.rpc
wallet_path = "wallet/%s" % wallet_name
return self.rpc / wallet_path
if self.use_cli:
return self.cli("-rpcwallet={}".format(wallet_name))
else:
assert self.rpc_connected
assert self.rpc
wallet_path = "wallet/%s" % wallet_name
return self.rpc / wallet_path

def stop_node(self):
"""Stop the node."""
Expand Down Expand Up @@ -210,6 +217,7 @@ def __init__(self, binary, datadir):
self.binary = binary
self.datadir = datadir
self.input = None
self.log = logging.getLogger('TestFramework.bitcoincli')

def __call__(self, *args, input=None):
# TestNodeCLI is callable with bitcoin-cli command-line args
Expand Down Expand Up @@ -240,6 +248,7 @@ def send_cli(self, command, *args, **kwargs):
if named_args:
p_args += ["-named"]
p_args += [command] + pos_args + named_args
self.log.debug("Running bitcoin-cli command: %s" % command)
process = subprocess.Popen(p_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
cli_stdout, cli_stderr = process.communicate(input=self.input)
returncode = process.poll()
Expand Down

0 comments on commit f6ade9c

Please sign in to comment.