From d2394d7c6d79d37b96474e7ab6bff27ffe87424a Mon Sep 17 00:00:00 2001 From: SpaceOne Date: Fri, 6 Jan 2023 00:39:31 +0100 Subject: [PATCH] perf(test): enhance test performance Fix #279 --- tests/conftest.py | 24 ++++++++ tests/core/test_call_wait_instance.py | 18 ++---- tests/core/test_component_targeting.py | 18 ++---- tests/core/test_coroutine.py | 22 +++----- tests/core/test_errors.py | 16 ++---- tests/core/test_memory_leaks.py | 20 ++----- tests/core/test_new_filter.py | 21 ++----- tests/core/test_value.py | 12 ++-- tests/net/test_tcp.py | 10 ++-- tests/node/test_node.py | 14 ++--- tests/node/test_protocol.py | 78 ++++++++------------------ 11 files changed, 99 insertions(+), 154 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 555b1759f..bf22a31c0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -107,20 +107,44 @@ def wait_for(obj, attr, value=True, timeout=30.0): class SimpleManager(Manager): + watcher = None + def tick(self, timeout=-1): self._running = False return super().tick(timeout) + def watch(self): + if self.watcher is not None: + return + self.watcher = Watcher().register(self) + + def run_until(self, *args, **kwargs): + self.run() + return self.watcher.wait(*args, **kwargs) + + def clear(self, *args, **kwargs): + return self.watcher.clear(*args, **kwargs) + + def count(self, *args, **kwargs): + return self.watcher.count(*args, **kwargs) + @pytest.fixture def simple_manager(request): + """A manager main loop which runs in the MainThread until all events are processed. + It leaves out the generate_events event and can therefore not be used to FileIO or socket components. + """ manager = SimpleManager() Debugger(events=request.config.option.verbose).register(manager) + manager.watch() + manager.run() + manager.clear() return manager @pytest.fixture def manager(request): + """A manager main loop started in a separate thread""" manager = Manager() def finalizer(): diff --git a/tests/core/test_call_wait_instance.py b/tests/core/test_call_wait_instance.py index 6e28d22cb..23448da2d 100644 --- a/tests/core/test_call_wait_instance.py +++ b/tests/core/test_call_wait_instance.py @@ -30,21 +30,13 @@ def hello(self): @pytest.fixture -def app(request, manager, watcher): - app = App().register(manager) - assert watcher.wait("registered") +def app(simple_manager): + return App().register(simple_manager) - def finalizer(): - app.unregister() - request.addfinalizer(finalizer) - - return app - - -def test_wait_instance(manager, watcher, app): - x = manager.fire(wait()) - assert watcher.wait("wait_success") +def test_wait_instance(simple_manager, app): + x = simple_manager.fire(wait()) + assert simple_manager.run_until("wait_success") value = x.value assert value == "Hello World!" diff --git a/tests/core/test_component_targeting.py b/tests/core/test_component_targeting.py index 1ee7ada1b..5cc633863 100644 --- a/tests/core/test_component_targeting.py +++ b/tests/core/test_component_targeting.py @@ -20,21 +20,13 @@ def hello(self): @pytest.fixture -def app(request, manager, watcher): - app = App().register(manager) - assert watcher.wait("registered") +def app(simple_manager): + return App().register(simple_manager) - def finalizer(): - app.unregister() - request.addfinalizer(finalizer) - - return app - - -def test(manager, watcher, app): - x = manager.fire(hello(), app) - assert watcher.wait("hello_success") +def test(simple_manager, app): + x = simple_manager.fire(hello(), app) + assert simple_manager.run_until("hello_success") value = x.value assert value == "Hello World!" diff --git a/tests/core/test_coroutine.py b/tests/core/test_coroutine.py index 3b7390533..a8ff23c92 100644 --- a/tests/core/test_coroutine.py +++ b/tests/core/test_coroutine.py @@ -49,24 +49,16 @@ def coroutine2(self): @pytest.fixture -def app(request, manager, watcher): - app = App().register(manager) - assert watcher.wait("registered") +def app(simple_manager): + return App().register(simple_manager) - def finalizer(): - app.unregister() - request.addfinalizer(finalizer) - - return app - - -def test_coroutine(manager, watcher, app): - manager.fire(coroutine1()) - assert watcher.wait("coroutine1_complete") +def test_coroutine(simple_manager, app): + simple_manager.fire(coroutine1()) + assert simple_manager.run_until("coroutine1_complete") assert app.returned, "coroutine1" app.returned = False - manager.fire(coroutine2()) - assert watcher.wait("coroutine2_complete") + simple_manager.fire(coroutine2()) + assert simple_manager.run_until("coroutine2_complete") assert app.returned, "coroutine2" diff --git a/tests/core/test_errors.py b/tests/core/test_errors.py index 939a27229..95b5b2b12 100644 --- a/tests/core/test_errors.py +++ b/tests/core/test_errors.py @@ -36,22 +36,14 @@ def reraise(e): @pytest.fixture -def app(request, manager, watcher): - app = App().register(manager) - watcher.wait("registered") +def app(simple_manager): + return App().register(simple_manager) - def finalizer(): - app.unregister() - request.addfinalizer(finalizer) - - return app - - -def test_main(app, watcher): +def test_main(app, simple_manager): e = test() app.fire(e) - watcher.wait("exception") + assert simple_manager.run_until("exception") assert app.etype == NameError pytest.raises(NameError, lambda e: reraise(e), app.evalue) diff --git a/tests/core/test_memory_leaks.py b/tests/core/test_memory_leaks.py index a041100b9..cfb0a5a70 100644 --- a/tests/core/test_memory_leaks.py +++ b/tests/core/test_memory_leaks.py @@ -27,20 +27,12 @@ def hello(self): @pytest.fixture -def app(request, manager, watcher): - app = App().register(manager) - assert watcher.wait("registered") +def app(simple_manager): + return App().register(simple_manager) - def finalizer(): - app.unregister() - request.addfinalizer(finalizer) - - return app - - -def test_done_handlers_dont_leak(manager, watcher, app): - manager.fire(call()) - manager.fire(call()) - assert watcher.wait("call_success") +def test_done_handlers_dont_leak(simple_manager, app): + simple_manager.fire(call()) + simple_manager.fire(call()) + assert simple_manager.run_until("call_success") assert "hello_done" not in app._handlers diff --git a/tests/core/test_new_filter.py b/tests/core/test_new_filter.py index 73041594c..a87adc702 100644 --- a/tests/core/test_new_filter.py +++ b/tests/core/test_new_filter.py @@ -20,26 +20,17 @@ def hello(self, event, *args, **kwargs): @pytest.fixture -def app(request, manager, watcher): - app = (App() + App()).register(manager) - watcher.wait("registered") +def app(simple_manager): + return (App() + App()).register(simple_manager) - def finalizer(): - app.unregister() - watcher.wait("unregistered") - request.addfinalizer(finalizer) - - return app - - -def test_normal(app, watcher): +def test_normal(app, simple_manager): x = app.fire(hello()) - watcher.wait("hello_success") + assert simple_manager.run_until("hello_success") assert x.value == ["Hello World!", "Hello World!"] -def test_filter(app, watcher): +def test_filter(app, simple_manager): x = app.fire(hello(stop=True)) - watcher.wait("hello_success") + assert simple_manager.run_until("hello_success") assert x.value == "Hello World!" diff --git a/tests/core/test_value.py b/tests/core/test_value.py index 583d616f4..8d04b926d 100644 --- a/tests/core/test_value.py +++ b/tests/core/test_value.py @@ -67,7 +67,7 @@ def app(request, simple_manager): def test_value(app, simple_manager): x = app.fire(hello()) - simple_manager.run() + assert simple_manager.run_until('hello') assert "Hello World!" in x assert x.value == "Hello World!" @@ -75,7 +75,7 @@ def test_value(app, simple_manager): def test_nested_value(app, simple_manager): x = app.fire(test()) - simple_manager.run() + assert simple_manager.run_until('test') assert x.value == "Hello World!" assert str(x) == "Hello World!" @@ -86,7 +86,7 @@ def test_value_notify(app, simple_manager): ev.notify = True x = app.fire(ev) - simple_manager.run() + assert simple_manager.run_until('hello_value_changed') assert "Hello World!" in x assert x.value == "Hello World!" @@ -98,7 +98,7 @@ def test_nested_value_notify(app, simple_manager): ev.notify = True x = app.fire(ev) - simple_manager.run() + assert simple_manager.run_until('test_value_changed') assert x.value == "Hello World!" assert str(x) == "Hello World!" @@ -107,7 +107,7 @@ def test_nested_value_notify(app, simple_manager): def test_error_value(app, simple_manager): x = app.fire(foo()) - simple_manager.run() + assert simple_manager.run_until('foo') etype, evalue, etraceback = x assert etype is Exception @@ -117,7 +117,7 @@ def test_error_value(app, simple_manager): def test_multiple_values(app, simple_manager): v = app.fire(values()) - simple_manager.run() + assert simple_manager.run_until('values_complete') assert isinstance(v.value, list) diff --git a/tests/net/test_tcp.py b/tests/net/test_tcp.py index 391fe0193..e43dd8f27 100644 --- a/tests/net/test_tcp.py +++ b/tests/net/test_tcp.py @@ -322,8 +322,8 @@ def test_tcp_bind(Poller, ipv6): m.stop() -def test_tcp_lookup_failure(manager, watcher, Poller, ipv6): - poller = Poller().register(manager) +def test_tcp_lookup_failure(simple_manager, Poller, ipv6): + poller = Poller().register(simple_manager) if ipv6: tcp_client = TCP6Client() @@ -331,13 +331,13 @@ def test_tcp_lookup_failure(manager, watcher, Poller, ipv6): tcp_client = TCPClient() client = Client() + tcp_client - client.register(manager) + client.register(simple_manager) try: - assert watcher.wait("ready", "client") + assert simple_manager.run_until("ready", "client") client.fire(connect("foo.bar.baz", 1234)) - assert watcher.wait("error", "client") + assert simple_manager.run_until("error", "client") if pytest.PLATFORM == "win32": assert client.error.errno == 11004 diff --git a/tests/node/test_node.py b/tests/node/test_node.py index 43f36429d..316bac140 100644 --- a/tests/node/test_node.py +++ b/tests/node/test_node.py @@ -30,17 +30,17 @@ def remote_value_changed(self, value): @fixture() -def bind(request, manager, watcher): - server = UDPServer(0).register(manager) - assert watcher.wait('ready') +def bind(request, simple_manager): + server = UDPServer(0).register(simple_manager) + assert simple_manager.run_until("ready") host, port = server.host, server.port server.fire(close()) - assert watcher.wait('closed') + assert simple_manager.run_until("closed") server.unregister() - assert watcher.wait('unregistered') + assert simple_manager.run_until("unregistered") return host, port @@ -49,13 +49,13 @@ def bind(request, manager, watcher): def app(request, manager, watcher, bind): app = App().register(manager) node = Node().register(app) - watcher.wait('ready') + assert watcher.wait('ready') child = (App() + Node(port=bind[1], server_ip=bind[0])) child.start(process=True) node.add('child', *bind) - watcher.wait('connected') + assert watcher.wait('connected') def finalizer(): child.stop() diff --git a/tests/node/test_protocol.py b/tests/node/test_protocol.py index 426649ad6..e05b614e8 100644 --- a/tests/node/test_protocol.py +++ b/tests/node/test_protocol.py @@ -62,65 +62,35 @@ def write(self, sock, data): @pytest.fixture() -def app_client(request, manager, watcher): - app = AppClient() - app.register(manager) - watcher.wait('registered') - +def app_client(request, simple_manager): + app = AppClient().register(simple_manager) app.protocol = Protocol().register(app) - watcher.wait('registered') - - def finalizer(): - app.unregister() - - request.addfinalizer(finalizer) - return app @pytest.fixture() -def app_firewall(request, manager, watcher): - app = AppFirewall() - app.register(manager) - watcher.wait('registered') - +def app_firewall(request, simple_manager): + app = AppFirewall().register(simple_manager) app.protocol = Protocol( sock='sock obj', receive_event_firewall=app.fw_receive, send_event_firewall=app.fw_send, ).register(app) - watcher.wait('registered') - - def finalizer(): - app.unregister() - - request.addfinalizer(finalizer) - return app @pytest.fixture() -def app_server(request, manager, watcher): - app = AppServer() - app.register(manager) - watcher.wait('registered') - +def app_server(request, simple_manager): + app = AppServer().register(simple_manager) app.protocol = Protocol(sock='sock obj', server=True).register(app) - watcher.wait('registered') - - def finalizer(): - app.unregister() - - request.addfinalizer(finalizer) - return app -def test_add_buffer(app_client, watcher): +def test_add_buffer(app_client, simple_manager): packet = str.encode(dump_event(return_value(), 1)) app_client.protocol.add_buffer(packet) - assert watcher.wait('return_value_success') - assert watcher.wait('write') + assert simple_manager.run_until('return_value_success') + assert simple_manager.run_until('write') value = Value() value.value = 'Hello server!' @@ -129,11 +99,11 @@ def test_add_buffer(app_client, watcher): assert app_client.write_data == str.encode(dump_value(value) + '~~~') -def test_add_buffer_server(app_server, watcher): +def test_add_buffer_server(app_server, simple_manager): packet = str.encode(dump_event(return_value(), 1)) app_server.protocol.add_buffer(packet) - assert watcher.wait('return_value_success') - assert watcher.wait('write') + assert simple_manager.run_until('return_value_success') + assert simple_manager.run_until('write') value = Value() value.value = 'Hello client!' @@ -143,52 +113,52 @@ def test_add_buffer_server(app_server, watcher): assert app_server.write_sock == 'sock obj' -def test_firewall_receive(app_firewall, watcher): +def test_firewall_receive(app_firewall, simple_manager): # good event packet = str.encode(dump_event(return_value(), 1)) app_firewall.protocol.add_buffer(packet) - assert watcher.wait('return_value') + assert simple_manager.run_until('return_value') # bad name packet = str.encode(dump_event(Event.create('unallow_event'), 1)) app_firewall.protocol.add_buffer(packet) - assert watcher.wait('firewall_block') + assert simple_manager.run_until('firewall_block') # bad channel event = return_value() event.channels = ('prohibits_channel',) packet = str.encode(dump_event(event, 1)) app_firewall.protocol.add_buffer(packet) - assert watcher.wait('firewall_block') + assert simple_manager.run_until('firewall_block') -def test_firewall_send(app_firewall, watcher): +def test_firewall_send(app_firewall, simple_manager): # good event event = return_value() generator = app_firewall.protocol.send(event) next(generator) # exec - assert watcher.wait('write') + assert simple_manager.run_until('write') assert app_firewall.write_data == str.encode(dump_event(event, 0) + '~~~') # bad name generator = app_firewall.protocol.send(Event.create('unallow_event')) next(generator) # exec - assert watcher.wait('firewall_block') + assert simple_manager.run_until('firewall_block') # bad channel event = return_value() event.channels = ('prohibits_channel',) generator = app_firewall.protocol.send(event) next(generator) # exec - assert watcher.wait('firewall_block') + assert simple_manager.run_until('firewall_block') -def test_send(app_client, watcher): +def test_send(app_client, simple_manager): event = return_value() generator = app_client.protocol.send(event) next(generator) # exec - assert watcher.wait('write') + assert simple_manager.run_until('write') assert app_client.write_data == str.encode(dump_event(event, 0) + '~~~') value = Value() @@ -200,12 +170,12 @@ def test_send(app_client, watcher): assert next(generator).getValue() == value.value -def test_send_server(app_server, watcher): +def test_send_server(app_server, simple_manager): event = return_value() generator = app_server.protocol.send(event) next(generator) # exec - assert watcher.wait('write') + assert simple_manager.run_until('write') assert app_server.write_data == str.encode(dump_event(event, 0) + '~~~') assert app_server.write_sock == 'sock obj'