From 57a3abe51500d32b2b6eccd6a5834ed66fbe7c87 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 7 Nov 2016 19:27:37 -0500 Subject: [PATCH] tests: Do set_event_loop(None) in unittests uvloop should consistently pass around the loop reference in its internal APIs. Even though explicit passing of event loop objects is discouraged in asyncio programs, uvloop itself is too low-level to rely on get_event_loop. --- tests/test_aiohttp.py | 3 +++ tests/test_base.py | 4 ++-- tests/test_executors.py | 2 +- tests/test_tcp.py | 2 +- uvloop/_testbase.py | 22 +++++++++++++++++++++- 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/tests/test_aiohttp.py b/tests/test_aiohttp.py index f880385..8578f19 100644 --- a/tests/test_aiohttp.py +++ b/tests/test_aiohttp.py @@ -6,6 +6,7 @@ except ImportError: else: skip_tests = False +import asyncio import unittest from uvloop import _testbase as tb @@ -29,6 +30,8 @@ class _TestAioHTTP: response.write(PAYLOAD) await response.write_eof() + asyncio.set_event_loop(self.loop) + f = self.loop.create_server( lambda: HttpRequestHandler(keepalive_timeout=1), '0.0.0.0', '0') diff --git a/tests/test_base.py b/tests/test_base.py index 4b97776..affbc75 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -149,9 +149,9 @@ class _TestBase: # libuv cached time. async def main(): - await asyncio.sleep(0.001) + await asyncio.sleep(0.001, loop=self.loop) time.sleep(0.01) - await asyncio.sleep(0.01) + await asyncio.sleep(0.01, loop=self.loop) started = time.monotonic() self.loop.run_until_complete(main()) diff --git a/tests/test_executors.py b/tests/test_executors.py index 1d0b3cb..8046061 100644 --- a/tests/test_executors.py +++ b/tests/test_executors.py @@ -21,7 +21,7 @@ class _TestExecutors: coros.append(self.loop.run_in_executor(pool, fib, i)) res = await asyncio.gather(*coros, loop=self.loop) self.assertEqual(res, fib10) - await asyncio.sleep(0.01) + await asyncio.sleep(0.01, loop=self.loop) fib10 = [fib(i) for i in range(10)] self.loop.run_until_complete(run()) diff --git a/tests/test_tcp.py b/tests/test_tcp.py index 9059350..7a40009 100644 --- a/tests/test_tcp.py +++ b/tests/test_tcp.py @@ -708,7 +708,7 @@ class Test_UV_TCP(_TestTCP, tb.UVTestCase): self.loop.create_task(run()) self.loop.run_until_complete(srv.wait_closed()) gc.collect() - self.loop.run_until_complete(asyncio.sleep(0.1)) + self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop)) # Since one TCPTransport handle wasn't closed correctly, # we need to disable this check: diff --git a/uvloop/_testbase.py b/uvloop/_testbase.py index 2a658e8..6ae9220 100644 --- a/uvloop/_testbase.py +++ b/uvloop/_testbase.py @@ -2,6 +2,7 @@ import asyncio +import asyncio.events import collections import contextlib import gc @@ -68,12 +69,20 @@ class BaseTestCase(unittest.TestCase, metaclass=BaseTestCaseMeta): def setUp(self): self.loop = self.new_loop() - asyncio.set_event_loop(self.loop) + asyncio.set_event_loop(None) self._check_unclosed_resources_in_debug = True + if hasattr(asyncio, '_get_running_loop'): + # Disable `_get_running_loop`. + self._get_running_loop = asyncio.events._get_running_loop + asyncio.events._get_running_loop = lambda: None + def tearDown(self): self.loop.close() + if hasattr(asyncio, '_get_running_loop'): + asyncio.events._get_running_loop = self._get_running_loop + if not self._check_unclosed_resources_in_debug: return @@ -199,6 +208,17 @@ class UVTestCase(BaseTestCase): class AIOTestCase(BaseTestCase): + def setUp(self): + super().setUp() + + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(self.loop) + asyncio.set_child_watcher(watcher) + + def tearDown(self): + asyncio.set_child_watcher(None) + super().tearDown() + def new_loop(self): return asyncio.new_event_loop()