diff --git a/minode/i2p/listener.py b/minode/i2p/listener.py index 9b3d058..f63de06 100644 --- a/minode/i2p/listener.py +++ b/minode/i2p/listener.py @@ -49,6 +49,7 @@ class I2PListener(I2PThread): destination, 'i2p', self.s, 'i2p', True, destination) c.start() self.state.connections.add(c) + c = None self.new_socket() except socket.timeout: pass diff --git a/minode/listener.py b/minode/listener.py index bec5365..815c02d 100644 --- a/minode/listener.py +++ b/minode/listener.py @@ -39,3 +39,4 @@ class Listener(threading.Thread): c = Connection(*addr[:2], conn, server=True) c.start() shared.connections.add(c) + c = None diff --git a/minode/tests/test_memory.py b/minode/tests/test_memory.py new file mode 100644 index 0000000..dae2377 --- /dev/null +++ b/minode/tests/test_memory.py @@ -0,0 +1,57 @@ +"""Tests for memory usage""" + +import gc +import time + +from minode import shared + +from .test_network import TestProcessProto, run_listener + + +class TestListener(TestProcessProto): + """A separate test case for Listener with a process with --trusted-peer""" + _process_cmd = ['minode', '--trusted-peer', '127.0.0.1'] + + def setUp(self): + shared.shutting_down = False + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + shared.shutting_down = False + + def test_listener(self): + """Start Listener and disconnect a client""" + with run_listener() as listener: + if not listener: + self.fail('Failed to start listener') + + shared.connection_limit = 2 + connected = False + started = time.time() + while not connected: + time.sleep(0.2) + if time.time() - started > 90: + self.fail('Failed to establish the connection') + for c in shared.connections: + if c.status == 'fully_established': + connected = True + + if not self._stop_process(10): + self.fail('Failed to stop the client process') + + for c in shared.connections.copy(): + if not c.is_alive() or c.status == 'disconnected': + shared.connections.remove(c) + c = None + break + else: + self.fail('The connection is alive') + + gc.collect() + for obj in gc.get_objects(): + if ( + isinstance(obj, shared.connection) + and obj not in shared.connections + ): + self.fail('Connection %s remains in memory' % obj)