Add a test for connections with large time offset

This commit is contained in:
Lee Miller 2023-08-26 19:13:05 +03:00
parent cfd054fcf4
commit 131512a5e6
Signed by: lee.miller
GPG Key ID: 4F97A5EA88F4AB63

View File

@ -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(
shared.core_nodes.union(shared.unchecked_node_pool), 5)
time_offset_connections(nodes, 4000)
time_offset_connections(nodes, -4000)