tests: Make proxy_test work on travis servers without IPv6

Github-Pull: #7489
Rebased-From: 7539f1aae3b41279dc5d49e09f448a78a071e114
Cherry-picked-From: 9ca957bcd401de69c4c03904b9ee8b8b41052905
This commit is contained in:
Wladimir J. van der Laan 2016-02-09 12:37:05 +01:00 committed by Simon
parent a4b8b3fdd4
commit 0713229fc9
2 changed files with 58 additions and 31 deletions

View File

@ -6,6 +6,7 @@
from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, start_nodes from test_framework.util import assert_equal, start_nodes
from test_framework.netutil import test_ipv6_local
import socket import socket
import os import os
@ -36,6 +37,7 @@ addnode connect to generic DNS name
class ProxyTest(BitcoinTestFramework): class ProxyTest(BitcoinTestFramework):
def __init__(self): def __init__(self):
self.have_ipv6 = test_ipv6_local()
# Create two proxies on different ports # Create two proxies on different ports
# ... one unauthenticated # ... one unauthenticated
self.conf1 = Socks5Configuration() self.conf1 = Socks5Configuration()
@ -47,29 +49,36 @@ class ProxyTest(BitcoinTestFramework):
self.conf2.addr = ('127.0.0.1', 14000 + (os.getpid() % 1000)) self.conf2.addr = ('127.0.0.1', 14000 + (os.getpid() % 1000))
self.conf2.unauth = True self.conf2.unauth = True
self.conf2.auth = True self.conf2.auth = True
# ... one on IPv6 with similar configuration if self.have_ipv6:
self.conf3 = Socks5Configuration() # ... one on IPv6 with similar configuration
self.conf3.af = socket.AF_INET6 self.conf3 = Socks5Configuration()
self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000)) self.conf3.af = socket.AF_INET6
self.conf3.unauth = True self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000))
self.conf3.auth = True self.conf3.unauth = True
self.conf3.auth = True
else:
print "Warning: testing without local IPv6 support"
self.serv1 = Socks5Server(self.conf1) self.serv1 = Socks5Server(self.conf1)
self.serv1.start() self.serv1.start()
self.serv2 = Socks5Server(self.conf2) self.serv2 = Socks5Server(self.conf2)
self.serv2.start() self.serv2.start()
self.serv3 = Socks5Server(self.conf3) if self.have_ipv6:
self.serv3.start() self.serv3 = Socks5Server(self.conf3)
self.serv3.start()
def setup_nodes(self): def setup_nodes(self):
# Note: proxies are not used to connect to local nodes # Note: proxies are not used to connect to local nodes
# this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost # this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost
return start_nodes(4, self.options.tmpdir, extra_args=[ args = [
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'], ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'],
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'], ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'],
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'], ['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'],
['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion'] []
]) ]
if self.have_ipv6:
args[3] = ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion']
return start_nodes(4, self.options.tmpdir, extra_args=args)
def node_test(self, node, proxies, auth, test_onion=True): def node_test(self, node, proxies, auth, test_onion=True):
rv = [] rv = []
@ -86,18 +95,19 @@ class ProxyTest(BitcoinTestFramework):
assert_equal(cmd.password, None) assert_equal(cmd.password, None)
rv.append(cmd) rv.append(cmd)
# Test: outgoing IPv6 connection through node if self.have_ipv6:
node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry") # Test: outgoing IPv6 connection through node
cmd = proxies[1].queue.get() node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry")
assert(isinstance(cmd, Socks5Command)) cmd = proxies[1].queue.get()
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6 assert(isinstance(cmd, Socks5Command))
assert_equal(cmd.atyp, AddressType.DOMAINNAME) # Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534") assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.port, 5443) assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534")
if not auth: assert_equal(cmd.port, 5443)
assert_equal(cmd.username, None) if not auth:
assert_equal(cmd.password, None) assert_equal(cmd.username, None)
rv.append(cmd) assert_equal(cmd.password, None)
rv.append(cmd)
if test_onion: if test_onion:
# Test: outgoing onion connection through node # Test: outgoing onion connection through node
@ -137,10 +147,11 @@ class ProxyTest(BitcoinTestFramework):
rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True) rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True)
# Check that credentials as used for -proxyrandomize connections are unique # Check that credentials as used for -proxyrandomize connections are unique
credentials = set((x.username,x.password) for x in rv) credentials = set((x.username,x.password) for x in rv)
assert_equal(len(credentials), 4) assert_equal(len(credentials), len(rv))
# proxy on IPv6 localhost if self.have_ipv6:
self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False) # proxy on IPv6 localhost
self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False)
def networks_dict(d): def networks_dict(d):
r = {} r = {}
@ -169,11 +180,12 @@ class ProxyTest(BitcoinTestFramework):
assert_equal(n2[net]['proxy_randomize_credentials'], True) assert_equal(n2[net]['proxy_randomize_credentials'], True)
assert_equal(n2['onion']['reachable'], True) assert_equal(n2['onion']['reachable'], True)
n3 = networks_dict(self.nodes[3].getnetworkinfo()) if self.have_ipv6:
for net in ['ipv4','ipv6']: n3 = networks_dict(self.nodes[3].getnetworkinfo())
assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr)) for net in ['ipv4','ipv6']:
assert_equal(n3[net]['proxy_randomize_credentials'], False) assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr))
assert_equal(n3['onion']['reachable'], False) assert_equal(n3[net]['proxy_randomize_credentials'], False)
assert_equal(n3['onion']['reachable'], False)
if __name__ == '__main__': if __name__ == '__main__':
ProxyTest().main() ProxyTest().main()

View File

@ -137,3 +137,18 @@ def addr_to_hex(addr):
else: else:
raise ValueError('Could not parse address %s' % addr) raise ValueError('Could not parse address %s' % addr)
return binascii.hexlify(bytearray(addr)) return binascii.hexlify(bytearray(addr))
def test_ipv6_local():
'''
Check for (local) IPv6 support.
'''
import socket
# By using SOCK_DGRAM this will not actually make a connection, but it will
# fail if there is no route to IPv6 localhost.
have_ipv6 = True
try:
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s.connect(('::1', 0))
except socket.error:
have_ipv6 = False
return have_ipv6