From bcb29facaac12b47df7adfadeddacde08c9ebfaf Mon Sep 17 00:00:00 2001
From: Dmitri Bogomolov <4glitch@gmail.com>
Date: Mon, 29 Jul 2019 14:19:18 +0300
Subject: [PATCH] A test for bootstrapping, have problem with
 test_tcpconnection ):

---
 src/tests/core.py | 48 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/src/tests/core.py b/src/tests/core.py
index a323be83..a9df05fc 100644
--- a/src/tests/core.py
+++ b/src/tests/core.py
@@ -13,9 +13,11 @@ import unittest
 
 import knownnodes
 import state
+from bmconfigparser import BMConfigParser
 from helper_msgcoding import MsgEncode, MsgDecode
 from network import asyncore_pollchoose as asyncore
-from network.tcp import TCPConnection
+from network.connectionpool import BMConnectionPool
+from network.tcp import Socks4aBMConnection, Socks5BMConnection, TCPConnection
 from queues import excQueue
 
 knownnodes_file = os.path.join(state.appdata, 'knownnodes.dat')
@@ -80,8 +82,10 @@ class TestCore(unittest.TestCase):
                 ' with no subject!' % e
             )
 
+    @unittest.skip('Bad environment for asyncore.loop')
     def test_tcpconnection(self):
         """initial fill script from network.tcp"""
+        BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true')
         try:
             for peer in (state.Peer("127.0.0.1", 8448),):
                 direct = TCPConnection(peer)
@@ -91,10 +95,18 @@ class TestCore(unittest.TestCase):
         except:
             self.fail('Exception in test loop')
 
-    def _wipe_knownnodes(self):
+    @staticmethod
+    def _wipe_knownnodes():
         with knownnodes.knownNodesLock:
             knownnodes.knownNodes = {stream: {} for stream in range(1, 4)}
 
+    @staticmethod
+    def _outdate_knownnodes():
+        with knownnodes.knownNodesLock:
+            for nodes in knownnodes.knownNodes.itervalues():
+                for node in nodes.itervalues():
+                    node['lastseen'] -= 2419205  # older than 28 days
+
     def test_knownnodes_pickle(self):
         """ensure that 3 nodes was imported for each stream"""
         pickle_knownnodes()
@@ -117,9 +129,7 @@ class TestCore(unittest.TestCase):
 
     def test_0_cleaner(self):
         """test knownnodes starvation leading to IndexError in Asyncore"""
-        for nodes in knownnodes.knownNodes.itervalues():
-            for node in nodes.itervalues():
-                node['lastseen'] -= 2419205  # older than 28 days
+        self._outdate_knownnodes()
         # time.sleep(303)  # singleCleaner wakes up every 5 min
         knownnodes.cleanupKnownNodes()
         while True:
@@ -130,6 +140,34 @@ class TestCore(unittest.TestCase):
             if thread == 'Asyncore' and isinstance(exc, IndexError):
                 self.fail("IndexError because of empty knownNodes!")
 
+    def test_bootstrap(self):
+        """test bootstrapping"""
+        BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true')
+        self._outdate_knownnodes()
+        knownnodes.cleanupKnownNodes()
+        # it's weird, knownnodes appear empty
+        knownnodes.addKnownNode(1, state.Peer('127.0.0.1', 8444), is_self=True)
+        time.sleep(0.25)
+        BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
+        proxy_type = BMConfigParser().safeGet(
+            'bitmessagesettings', 'socksproxytype')
+        if proxy_type == 'SOCKS5':
+            connection_base = Socks5BMConnection
+        elif proxy_type == 'SOCKS4a':
+            connection_base = Socks4aBMConnection
+        else:
+            connection_base = TCPConnection
+        _started = time.time()
+        for _ in range(180):
+            time.sleep(1)
+            for peer, con in BMConnectionPool().outboundConnections.iteritems():
+                if not peer.host.startswith('bootstrap'):
+                    self.assertIsInstance(con, connection_base)
+                    return
+        else:  # pylint: disable=useless-else-on-loop
+            self.fail(
+                'Failed to connect during %s sec' % (time.time() - _started))
+
 
 def run():
     """Starts all tests defined in this module"""