Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions Lib/test/test_asyncio/functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def setUp(self):

self.loop.set_exception_handler(self.loop_exception_handler)
self.__unhandled_exceptions = []
self.__abort_exception = None

def tearDown(self):
try:
Expand All @@ -38,9 +39,13 @@ def tearDown(self):
pprint.pprint(self.__unhandled_exceptions)
self.fail('unexpected calls to loop.call_exception_handler()')

if self.__abort_exception is not None:
raise self.__abort_exception

finally:
asyncio.set_event_loop(None)
self.loop = None
self.__abort_exception = None

def tcp_server(self, server_prog, *,
family=socket.AF_INET,
Expand Down Expand Up @@ -104,10 +109,18 @@ def unix_sock_name(self):
pass

def _abort_socket_test(self, ex):
# This runs in the client/server thread, not the main thread, so
# it must not call self.fail(): the AssertionError would escape
# Thread.run() without failing the test. Stash the exception and
# let tearDown() re-raise it on the main thread.
try:
self.loop.stop()
self.loop.call_soon_threadsafe(self.loop.stop)
except RuntimeError:
# The loop is already closed; nothing left to stop.
pass
finally:
self.fail(ex)
if self.__abort_exception is None:
self.__abort_exception = ex


##############################################################################
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Fix ``test_asyncio``'s socket test harness so that a failure in the client
or server thread actually fails the test. ``_abort_socket_test()`` called
``self.fail()`` from a worker thread, where the resulting
:exc:`AssertionError` cannot fail the test; it now records the exception and
re-raises it on the main thread. It also stops the event loop with
:meth:`~asyncio.loop.call_soon_threadsafe` rather than calling
:meth:`~asyncio.loop.stop` directly from a non-main thread.
Loading