Improving the network communication #4
|
@ -5,6 +5,7 @@ import random
|
||||||
import unittest
|
import unittest
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from minode import connection, main, shared
|
from minode import connection, main, shared
|
||||||
from minode.manager import Manager
|
from minode.manager import Manager
|
||||||
|
@ -15,6 +16,21 @@ logging.basicConfig(
|
||||||
format='[%(asctime)s] [%(levelname)s] %(message)s')
|
format='[%(asctime)s] [%(levelname)s] %(message)s')
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def time_offset(offset):
|
||||||
|
"""
|
||||||
|
Replace time.time() by a mock returning a constant value
|
||||||
|
with given offset from current time.
|
||||||
|
"""
|
||||||
|
started = time.time()
|
||||||
|
time_call = time.time
|
||||||
|
try:
|
||||||
|
time.time = lambda: started + offset
|
||||||
|
yield time_call
|
||||||
|
finally:
|
||||||
|
time.time = time_call
|
||||||
|
|
||||||
|
|
||||||
class TestNetwork(unittest.TestCase):
|
class TestNetwork(unittest.TestCase):
|
||||||
"""Test case starting connections"""
|
"""Test case starting connections"""
|
||||||
|
|
||||||
|
@ -31,14 +47,17 @@ class TestNetwork(unittest.TestCase):
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_connection(self):
|
def _make_initial_nodes(self):
|
||||||
"""Check a normal connection - should receive objects"""
|
|
||||||
Manager.load_data()
|
Manager.load_data()
|
||||||
self.assertGreaterEqual(len(shared.core_nodes), 3)
|
self.assertGreaterEqual(len(shared.core_nodes), 3)
|
||||||
|
|
||||||
main.bootstrap_from_dns()
|
main.bootstrap_from_dns()
|
||||||
self.assertGreaterEqual(len(shared.unchecked_node_pool), 3)
|
self.assertGreaterEqual(len(shared.unchecked_node_pool), 3)
|
||||||
|
|
||||||
|
def test_connection(self):
|
||||||
|
"""Check a normal connection - should receive objects"""
|
||||||
|
self._make_initial_nodes()
|
||||||
|
|
||||||
started = time.time()
|
started = time.time()
|
||||||
nodes = list(shared.core_nodes.union(shared.unchecked_node_pool))
|
nodes = list(shared.core_nodes.union(shared.unchecked_node_pool))
|
||||||
random.shuffle(nodes)
|
random.shuffle(nodes)
|
||||||
|
@ -67,3 +86,33 @@ class TestNetwork(unittest.TestCase):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.fail('Failed to establish a proper connection')
|
self.fail('Failed to establish a proper connection')
|
||||||
|
|
||||||
|
def test_time_offset(self):
|
||||||
|
"""Assert the network bans for large time offset"""
|
||||||
|
def try_connect(nodes, timeout, call):
|
||||||
|
started = call()
|
||||||
|
for node in nodes:
|
||||||
|
c = connection.Connection(*node)
|
||||||
|
c.start()
|
||||||
|
while call() < started + timeout:
|
||||||
|
if c.status == 'fully_established':
|
||||||
|
return 'Established a connection'
|
||||||
|
if c.status in ('disconnected', 'failed'):
|
||||||
|
break
|
||||||
|
time.sleep(0.2)
|
||||||
|
else:
|
||||||
|
return 'Spent too much time trying to connect'
|
||||||
|
|
||||||
|
def time_offset_connections(nodes, offset):
|
||||||
|
"""Spoof time.time and open connections with given time offset"""
|
||||||
|
with time_offset(offset) as time_call:
|
||||||
|
result = try_connect(nodes, 200, time_call)
|
||||||
|
if result:
|
||||||
|
self.fail(result)
|
||||||
|
|
||||||
|
self._make_initial_nodes()
|
||||||
|
nodes = random.sample(
|
||||||
|
tuple(shared.core_nodes.union(shared.unchecked_node_pool)), 5)
|
||||||
|
|
||||||
|
time_offset_connections(nodes, 4000)
|
||||||
|
time_offset_connections(nodes, -4000)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user