Fixing tor related tests:
- knownnodes.cleanupKnownNodes() should set knownNodesActual = False if there are no nodes in stream 1 (repeated bootstrapping) - set socksproxytype before _initiate_bootstrap() - wait 5 sec in _initiate_bootstrap() to be sure all connections are closed - plugins do not work on travis - use socksproxytype = SOCKS5, check tor presence by trying to bind on port 9050 - successfull connection to 3 onion nodes in 6 minutes is not guaranteed - check that bitmessage doesn't try non-onion nodes
This commit is contained in:
parent
e9073d736a
commit
9540d5fabe
|
@ -1,6 +1,8 @@
|
||||||
"""
|
"""
|
||||||
Manipulations with knownNodes dictionary.
|
Manipulations with knownNodes dictionary.
|
||||||
"""
|
"""
|
||||||
|
# TODO: knownnodes object maybe?
|
||||||
|
# pylint: disable=global-statement
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
@ -65,7 +67,7 @@ def json_deserialize_knownnodes(source):
|
||||||
"""
|
"""
|
||||||
Read JSON from source and make knownnodes dict
|
Read JSON from source and make knownnodes dict
|
||||||
"""
|
"""
|
||||||
global knownNodesActual # pylint: disable=global-statement
|
global knownNodesActual
|
||||||
for node in json.load(source):
|
for node in json.load(source):
|
||||||
peer = node['peer']
|
peer = node['peer']
|
||||||
info = node['info']
|
info = node['info']
|
||||||
|
@ -82,7 +84,7 @@ def pickle_deserialize_old_knownnodes(source):
|
||||||
the old format was {Peer:lastseen, ...}
|
the old format was {Peer:lastseen, ...}
|
||||||
the new format is {Peer:{"lastseen":i, "rating":f}}
|
the new format is {Peer:{"lastseen":i, "rating":f}}
|
||||||
"""
|
"""
|
||||||
global knownNodes # pylint: disable=global-statement
|
global knownNodes
|
||||||
knownNodes = pickle.load(source)
|
knownNodes = pickle.load(source)
|
||||||
for stream in knownNodes.keys():
|
for stream in knownNodes.keys():
|
||||||
for node, params in knownNodes[stream].iteritems():
|
for node, params in knownNodes[stream].iteritems():
|
||||||
|
@ -230,6 +232,7 @@ def cleanupKnownNodes():
|
||||||
"""
|
"""
|
||||||
Cleanup knownnodes: remove old nodes and nodes with low rating
|
Cleanup knownnodes: remove old nodes and nodes with low rating
|
||||||
"""
|
"""
|
||||||
|
global knownNodesActual
|
||||||
now = int(time.time())
|
now = int(time.time())
|
||||||
needToWriteKnownNodesToDisk = False
|
needToWriteKnownNodesToDisk = False
|
||||||
|
|
||||||
|
@ -240,6 +243,8 @@ def cleanupKnownNodes():
|
||||||
keys = knownNodes[stream].keys()
|
keys = knownNodes[stream].keys()
|
||||||
for node in keys:
|
for node in keys:
|
||||||
if len(knownNodes[stream]) <= 1: # leave at least one node
|
if len(knownNodes[stream]) <= 1: # leave at least one node
|
||||||
|
if stream == 1:
|
||||||
|
knownNodesActual = False
|
||||||
break
|
break
|
||||||
try:
|
try:
|
||||||
age = now - knownNodes[stream][node]["lastseen"]
|
age = now - knownNodes[stream][node]["lastseen"]
|
||||||
|
|
|
@ -21,7 +21,6 @@ import helper_addressbook
|
||||||
|
|
||||||
from bmconfigparser import BMConfigParser
|
from bmconfigparser import BMConfigParser
|
||||||
from helper_msgcoding import MsgEncode, MsgDecode
|
from helper_msgcoding import MsgEncode, MsgDecode
|
||||||
from helper_startup import start_proxyconfig
|
|
||||||
from helper_sql import sqlQuery
|
from helper_sql import sqlQuery
|
||||||
from network import asyncore_pollchoose as asyncore, knownnodes
|
from network import asyncore_pollchoose as asyncore, knownnodes
|
||||||
from network.bmproto import BMProto
|
from network.bmproto import BMProto
|
||||||
|
@ -34,9 +33,10 @@ from version import softwareVersion
|
||||||
from common import cleanup
|
from common import cleanup
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import stem.version as stem_version
|
socket.socket().bind(('127.0.0.1', 9050))
|
||||||
except ImportError:
|
tor_port_free = True
|
||||||
stem_version = None
|
except (OSError, socket.error):
|
||||||
|
tor_port_free = False
|
||||||
|
|
||||||
knownnodes_file = os.path.join(state.appdata, 'knownnodes.dat')
|
knownnodes_file = os.path.join(state.appdata, 'knownnodes.dat')
|
||||||
|
|
||||||
|
@ -159,12 +159,12 @@ class TestCore(unittest.TestCase):
|
||||||
|
|
||||||
def _initiate_bootstrap(self):
|
def _initiate_bootstrap(self):
|
||||||
BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true')
|
BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true')
|
||||||
self._outdate_knownnodes()
|
self._wipe_knownnodes()
|
||||||
knownnodes.addKnownNode(1, Peer('127.0.0.1', 8444), is_self=True)
|
knownnodes.addKnownNode(1, Peer('127.0.0.1', 8444), is_self=True)
|
||||||
knownnodes.cleanupKnownNodes()
|
knownnodes.cleanupKnownNodes()
|
||||||
time.sleep(2)
|
time.sleep(5)
|
||||||
|
|
||||||
def _check_connection(self):
|
def _check_connection(self, full=False):
|
||||||
"""
|
"""
|
||||||
Check if there is at least one outbound connection to remote host
|
Check if there is at least one outbound connection to remote host
|
||||||
with name not starting with "bootstrap" in 6 minutes at most,
|
with name not starting with "bootstrap" in 6 minutes at most,
|
||||||
|
@ -185,7 +185,10 @@ class TestCore(unittest.TestCase):
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
c -= 2
|
c -= 2
|
||||||
for peer, con in BMConnectionPool().outboundConnections.iteritems():
|
for peer, con in BMConnectionPool().outboundConnections.iteritems():
|
||||||
if peer.host.startswith('bootstrap'):
|
if (
|
||||||
|
peer.host.startswith('bootstrap')
|
||||||
|
or peer.host == 'quzwelsuziwqgpt2.onion'
|
||||||
|
):
|
||||||
if c < 60:
|
if c < 60:
|
||||||
self.fail(
|
self.fail(
|
||||||
'Still connected to bootstrap node %s after % seconds' %
|
'Still connected to bootstrap node %s after % seconds' %
|
||||||
|
@ -195,6 +198,8 @@ class TestCore(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
self.assertIsInstance(con, connection_base)
|
self.assertIsInstance(con, connection_base)
|
||||||
self.assertNotEqual(peer.host, '127.0.0.1')
|
self.assertNotEqual(peer.host, '127.0.0.1')
|
||||||
|
if full and not con.fullyEstablished:
|
||||||
|
continue
|
||||||
return
|
return
|
||||||
self.fail(
|
self.fail(
|
||||||
'Failed to connect during %s sec' % (time.time() - _started))
|
'Failed to connect during %s sec' % (time.time() - _started))
|
||||||
|
@ -212,43 +217,43 @@ class TestCore(unittest.TestCase):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
knownnodes.addKnownNode(1, Peer(addr, port))
|
knownnodes.addKnownNode(1, Peer(addr, port))
|
||||||
self._check_connection()
|
self._check_connection(True)
|
||||||
|
|
||||||
def test_bootstrap(self):
|
def test_bootstrap(self):
|
||||||
"""test bootstrapping"""
|
"""test bootstrapping"""
|
||||||
|
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none')
|
||||||
self._initiate_bootstrap()
|
self._initiate_bootstrap()
|
||||||
self._check_connection()
|
self._check_connection()
|
||||||
|
|
||||||
@unittest.skipUnless(stem_version, 'No stem, skipping tor dependent test')
|
@unittest.skipIf(tor_port_free, 'no running tor detected')
|
||||||
def test_bootstrap_tor(self):
|
def test_bootstrap_tor(self):
|
||||||
"""test bootstrapping with tor"""
|
"""test bootstrapping with tor"""
|
||||||
|
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
|
||||||
self._initiate_bootstrap()
|
self._initiate_bootstrap()
|
||||||
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'stem')
|
|
||||||
start_proxyconfig()
|
|
||||||
self._check_connection()
|
self._check_connection()
|
||||||
|
|
||||||
@unittest.skipUnless(stem_version, 'No stem, skipping tor dependent test')
|
@unittest.skipIf(tor_port_free, 'no running tor detected')
|
||||||
def test_onionservicesonly(self): # this should start after bootstrap
|
def test_onionservicesonly(self):
|
||||||
"""
|
"""ensure bitmessage doesn't try to connect to non-onion nodes
|
||||||
set onionservicesonly, wait for 3 connections and check them all
|
if onionservicesonly set, wait at least 3 onion nodes
|
||||||
are onions
|
|
||||||
"""
|
"""
|
||||||
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
|
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
|
||||||
BMConfigParser().set('bitmessagesettings', 'onionservicesonly', 'true')
|
BMConfigParser().set('bitmessagesettings', 'onionservicesonly', 'true')
|
||||||
self._initiate_bootstrap()
|
self._initiate_bootstrap()
|
||||||
BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
|
BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
|
||||||
|
tried_hosts = set()
|
||||||
for _ in range(360):
|
for _ in range(360):
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
for n, peer in enumerate(BMConnectionPool().outboundConnections):
|
for peer in BMConnectionPool().outboundConnections:
|
||||||
if n > 2:
|
if peer.host.endswith('.onion'):
|
||||||
|
tried_hosts.add(peer.host)
|
||||||
|
else:
|
||||||
|
if not peer.host.startswith('bootstrap'):
|
||||||
|
self.fail(
|
||||||
|
'Found non onion hostname %s in outbound'
|
||||||
|
'connections!' % peer.host)
|
||||||
|
if len(tried_hosts) > 2:
|
||||||
return
|
return
|
||||||
if (
|
|
||||||
not peer.host.endswith('.onion')
|
|
||||||
and not peer.host.startswith('bootstrap')
|
|
||||||
):
|
|
||||||
self.fail(
|
|
||||||
'Found non onion hostname %s in outbound connections!'
|
|
||||||
% peer.host)
|
|
||||||
self.fail('Failed to connect to at least 3 nodes within 360 sec')
|
self.fail('Failed to connect to at least 3 nodes within 360 sec')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
Reference in New Issue
Block a user