Merge #8400: [qa]: enable rpcbind_test

9bbb414 [qa]: enable rpcbind_test (whythat)
0ff4375 [qa]: add parsing for '<host>:<port>' argument form to rpc_url() (whythat)
This commit is contained in:
MarcoFalke 2016-07-31 17:22:17 +02:00
commit cf2cecb187
No known key found for this signature in database
GPG Key ID: 2D7F2372E50FE137
3 changed files with 97 additions and 124 deletions

View File

@ -159,7 +159,7 @@ testScriptsExt = [
'txn_clone.py --mineblock', 'txn_clone.py --mineblock',
'forknotify.py', 'forknotify.py',
'invalidateblock.py', 'invalidateblock.py',
# 'rpcbind_test.py', #temporary, bug in libevent, see #6655 'rpcbind_test.py',
'smartfees.py', 'smartfees.py',
'maxblocksinflight.py', 'maxblocksinflight.py',
'p2p-acceptblock.py', 'p2p-acceptblock.py',

View File

@ -5,15 +5,27 @@
# Test for -rpcbind, as well as -rpcallowip and -rpcconnect # Test for -rpcbind, as well as -rpcallowip and -rpcconnect
# TODO extend this test from the test framework (like all other tests)
import tempfile import tempfile
import traceback import traceback
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.netutil import * from test_framework.netutil import *
def run_bind_test(tmpdir, allow_ips, connect_to, addresses, expected): class RPCBindTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.num_nodes = 1
def setup_network(self):
pass
def setup_nodes(self):
pass
def run_bind_test(self, allow_ips, connect_to, addresses, expected):
''' '''
Start a node with requested rpcallowip and rpcbind parameters, Start a node with requested rpcallowip and rpcbind parameters,
then try to connect, and check if the set of bound addresses then try to connect, and check if the set of bound addresses
@ -24,34 +36,33 @@ def run_bind_test(tmpdir, allow_ips, connect_to, addresses, expected):
if allow_ips: if allow_ips:
base_args += ['-rpcallowip=' + x for x in allow_ips] base_args += ['-rpcallowip=' + x for x in allow_ips]
binds = ['-rpcbind='+addr for addr in addresses] binds = ['-rpcbind='+addr for addr in addresses]
nodes = start_nodes(self.num_nodes, tmpdir, [base_args + binds], connect_to) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args + binds], connect_to)
try: try:
pid = bitcoind_processes[0].pid pid = bitcoind_processes[0].pid
assert_equal(set(get_bind_addrs(pid)), set(expected)) assert_equal(set(get_bind_addrs(pid)), set(expected))
finally: finally:
stop_nodes(nodes) stop_nodes(self.nodes)
wait_bitcoinds() wait_bitcoinds()
def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport): def run_allowip_test(self, allow_ips, rpchost, rpcport):
''' '''
Start a node with rpcwallow IP, and request getinfo Start a node with rpcwallow IP, and request getinfo
at a non-localhost IP. at a non-localhost IP.
''' '''
base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips]
nodes = start_nodes(self.num_nodes, tmpdir, [base_args]) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [base_args])
try: try:
# connect to node through non-loopback interface # connect to node through non-loopback interface
url = "http://rt:rt@%s:%d" % (rpchost, rpcport,) node = get_rpc_proxy(rpc_url(0, "%s:%d" % (rpchost, rpcport)), 0)
node = get_rpc_proxy(url, 1)
node.getinfo() node.getinfo()
finally: finally:
node = None # make sure connection will be garbage collected and closed node = None # make sure connection will be garbage collected and closed
stop_nodes(nodes) stop_nodes(self.nodes)
wait_bitcoinds() wait_bitcoinds()
def run_test(self):
def run_test(tmpdir): # due to OS-specific network stats queries, this test works only on Linux
assert(sys.platform.startswith('linux')) # due to OS-specific network stats queries, this test works only on Linux assert(sys.platform.startswith('linux'))
# find the first non-loopback interface for testing # find the first non-loopback interface for testing
non_loopback_ip = None non_loopback_ip = None
for name,ip in all_interfaces(): for name,ip in all_interfaces():
@ -65,83 +76,37 @@ def run_test(tmpdir):
defaultport = rpc_port(0) defaultport = rpc_port(0)
# check default without rpcallowip (IPv4 and IPv6 localhost) # check default without rpcallowip (IPv4 and IPv6 localhost)
run_bind_test(tmpdir, None, '127.0.0.1', [], self.run_bind_test(None, '127.0.0.1', [],
[('127.0.0.1', defaultport), ('::1', defaultport)]) [('127.0.0.1', defaultport), ('::1', defaultport)])
# check default with rpcallowip (IPv6 any) # check default with rpcallowip (IPv6 any)
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', [], self.run_bind_test(['127.0.0.1'], '127.0.0.1', [],
[('::0', defaultport)]) [('::0', defaultport)])
# check only IPv4 localhost (explicit) # check only IPv4 localhost (explicit)
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1'], self.run_bind_test(['127.0.0.1'], '127.0.0.1', ['127.0.0.1'],
[('127.0.0.1', defaultport)]) [('127.0.0.1', defaultport)])
# check only IPv4 localhost (explicit) with alternative port # check only IPv4 localhost (explicit) with alternative port
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171'], self.run_bind_test(['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171'],
[('127.0.0.1', 32171)]) [('127.0.0.1', 32171)])
# check only IPv4 localhost (explicit) with multiple alternative ports on same host # check only IPv4 localhost (explicit) with multiple alternative ports on same host
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171', '127.0.0.1:32172'], self.run_bind_test(['127.0.0.1'], '127.0.0.1:32171', ['127.0.0.1:32171', '127.0.0.1:32172'],
[('127.0.0.1', 32171), ('127.0.0.1', 32172)]) [('127.0.0.1', 32171), ('127.0.0.1', 32172)])
# check only IPv6 localhost (explicit) # check only IPv6 localhost (explicit)
run_bind_test(tmpdir, ['[::1]'], '[::1]', ['[::1]'], self.run_bind_test(['[::1]'], '[::1]', ['[::1]'],
[('::1', defaultport)]) [('::1', defaultport)])
# check both IPv4 and IPv6 localhost (explicit) # check both IPv4 and IPv6 localhost (explicit)
run_bind_test(tmpdir, ['127.0.0.1'], '127.0.0.1', ['127.0.0.1', '[::1]'], self.run_bind_test(['127.0.0.1'], '127.0.0.1', ['127.0.0.1', '[::1]'],
[('127.0.0.1', defaultport), ('::1', defaultport)]) [('127.0.0.1', defaultport), ('::1', defaultport)])
# check only non-loopback interface # check only non-loopback interface
run_bind_test(tmpdir, [non_loopback_ip], non_loopback_ip, [non_loopback_ip], self.run_bind_test([non_loopback_ip], non_loopback_ip, [non_loopback_ip],
[(non_loopback_ip, defaultport)]) [(non_loopback_ip, defaultport)])
# Check that with invalid rpcallowip, we are denied # Check that with invalid rpcallowip, we are denied
run_allowip_test(tmpdir, [non_loopback_ip], non_loopback_ip, defaultport) self.run_allowip_test([non_loopback_ip], non_loopback_ip, defaultport)
try: try:
run_allowip_test(tmpdir, ['1.1.1.1'], non_loopback_ip, defaultport) self.run_allowip_test(['1.1.1.1'], non_loopback_ip, defaultport)
assert(not 'Connection not denied by rpcallowip as expected') assert(not 'Connection not denied by rpcallowip as expected')
except ValueError: except JSONRPCException:
pass pass
def main():
import optparse
parser = optparse.OptionParser(usage="%prog [options]")
parser.add_option("--nocleanup", dest="nocleanup", default=False, action="store_true",
help="Leave bitcoinds and test.* datadir on exit or error")
parser.add_option("--srcdir", dest="srcdir", default="../../src",
help="Source directory containing bitcoind/bitcoin-cli (default: %default%)")
parser.add_option("--tmpdir", dest="tmpdir", default=tempfile.mkdtemp(prefix="test"),
help="Root directory for datadirs")
(options, args) = parser.parse_args()
os.environ['PATH'] = options.srcdir+":"+os.environ['PATH']
check_json_precision()
success = False
nodes = []
try:
print("Initializing test directory "+options.tmpdir)
if not os.path.isdir(options.tmpdir):
os.makedirs(options.tmpdir)
initialize_chain(options.tmpdir)
run_test(options.tmpdir)
success = True
except AssertionError as e:
print("Assertion failed: "+e.message)
except Exception as e:
print("Unexpected exception caught during testing: "+str(e))
traceback.print_tb(sys.exc_info()[2])
if not options.nocleanup:
print("Cleaning up")
wait_bitcoinds()
shutil.rmtree(options.tmpdir)
if success:
print("Tests successful")
sys.exit(0)
else:
print("Failed")
sys.exit(1)
if __name__ == '__main__': if __name__ == '__main__':
main() RPCBindTest ().main ()

View File

@ -171,7 +171,15 @@ def rpc_auth_pair(n):
def rpc_url(i, rpchost=None): def rpc_url(i, rpchost=None):
rpc_u, rpc_p = rpc_auth_pair(i) rpc_u, rpc_p = rpc_auth_pair(i)
return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, rpchost or '127.0.0.1', rpc_port(i)) host = '127.0.0.1'
port = rpc_port(i)
if rpchost:
parts = rpchost.split(':')
if len(parts) == 2:
host, port = parts
else:
host = rpchost
return "http://%s:%s@%s:%d" % (rpc_u, rpc_p, host, int(port))
def wait_for_bitcoind_start(process, url, i): def wait_for_bitcoind_start(process, url, i):
''' '''