Merge with 3.4 (asyncio)

This commit is contained in:
Victor Stinner 2014-11-20 14:19:49 +01:00
commit 8beadd3d96
3 changed files with 67 additions and 43 deletions

View File

@ -104,10 +104,11 @@ class _TracebackLogger:
def __del__(self): def __del__(self):
if self.tb: if self.tb:
msg = 'Future/Task exception was never retrieved' msg = 'Future/Task exception was never retrieved\n'
if self.source_traceback: if self.source_traceback:
msg += '\nFuture/Task created at (most recent call last):\n' src = ''.join(traceback.format_list(self.source_traceback))
msg += ''.join(traceback.format_list(self.source_traceback)) msg += 'Future/Task created at (most recent call last):\n'
msg += '%s\n' % src.rstrip()
msg += ''.join(self.tb).rstrip() msg += ''.join(self.tb).rstrip()
self.loop.call_exception_handler({'message': msg}) self.loop.call_exception_handler({'message': msg})

View File

@ -606,9 +606,16 @@ class EventLoopTestsMixin:
self.assertGreater(pr.nbytes, 0) self.assertGreater(pr.nbytes, 0)
tr.close() tr.close()
if ssl: def _test_create_ssl_connection(self, httpd, create_connection,
def _dummy_ssl_create_context(self, purpose=ssl.Purpose.SERVER_AUTH, *, check_sockname=True):
cafile=None, capath=None, cadata=None): conn_fut = create_connection(ssl=test_utils.dummy_ssl_context())
self._basetest_create_ssl_connection(conn_fut, check_sockname)
# ssl.Purpose was introduced in Python 3.4
if hasattr(ssl, 'Purpose'):
def _dummy_ssl_create_context(purpose=ssl.Purpose.SERVER_AUTH, *,
cafile=None, capath=None,
cadata=None):
""" """
A ssl.create_default_context() replacement that doesn't enable A ssl.create_default_context() replacement that doesn't enable
cert validation. cert validation.
@ -616,14 +623,9 @@ class EventLoopTestsMixin:
self.assertEqual(purpose, ssl.Purpose.SERVER_AUTH) self.assertEqual(purpose, ssl.Purpose.SERVER_AUTH)
return test_utils.dummy_ssl_context() return test_utils.dummy_ssl_context()
def _test_create_ssl_connection(self, httpd, create_connection,
check_sockname=True):
conn_fut = create_connection(ssl=test_utils.dummy_ssl_context())
self._basetest_create_ssl_connection(conn_fut, check_sockname)
# With ssl=True, ssl.create_default_context() should be called # With ssl=True, ssl.create_default_context() should be called
with mock.patch('ssl.create_default_context', with mock.patch('ssl.create_default_context',
side_effect=self._dummy_ssl_create_context) as m: side_effect=_dummy_ssl_create_context) as m:
conn_fut = create_connection(ssl=True) conn_fut = create_connection(ssl=True)
self._basetest_create_ssl_connection(conn_fut, check_sockname) self._basetest_create_ssl_connection(conn_fut, check_sockname)
self.assertEqual(m.call_count, 1) self.assertEqual(m.call_count, 1)
@ -632,6 +634,8 @@ class EventLoopTestsMixin:
# validation will fail # validation will fail
with self.assertRaises(ssl.SSLError) as cm: with self.assertRaises(ssl.SSLError) as cm:
conn_fut = create_connection(ssl=True) conn_fut = create_connection(ssl=True)
# Ignore the "SSL handshake failed" log in debug mode
with test_utils.disable_logger():
self._basetest_create_ssl_connection(conn_fut, check_sockname) self._basetest_create_ssl_connection(conn_fut, check_sockname)
self.assertEqual(cm.exception.reason, 'CERTIFICATE_VERIFY_FAILED') self.assertEqual(cm.exception.reason, 'CERTIFICATE_VERIFY_FAILED')

View File

@ -307,8 +307,8 @@ class FutureTests(test_utils.TestCase):
'test_future_source_traceback')) 'test_future_source_traceback'))
@mock.patch('asyncio.base_events.logger') @mock.patch('asyncio.base_events.logger')
def test_future_exception_never_retrieved(self, m_log): def check_future_exception_never_retrieved(self, debug, m_log):
self.loop.set_debug(True) self.loop.set_debug(debug)
def memory_error(): def memory_error():
try: try:
@ -318,6 +318,7 @@ class FutureTests(test_utils.TestCase):
exc = memory_error() exc = memory_error()
future = asyncio.Future(loop=self.loop) future = asyncio.Future(loop=self.loop)
if debug:
source_traceback = future._source_traceback source_traceback = future._source_traceback
future.set_exception(exc) future.set_exception(exc)
future = None future = None
@ -325,33 +326,51 @@ class FutureTests(test_utils.TestCase):
support.gc_collect() support.gc_collect()
if sys.version_info >= (3, 4): if sys.version_info >= (3, 4):
if debug:
frame = source_traceback[-1] frame = source_traceback[-1]
regex = (r'^Future exception was never retrieved\n' regex = (r'^Future exception was never retrieved\n'
r'future: <Future finished exception=MemoryError\(\) created at {filename}:{lineno}>\n' r'future: <Future finished exception=MemoryError\(\) created at {filename}:{lineno}>\n'
r'source_traceback: Object created at \(most recent call last\):\n' r'source_traceback: Object created at \(most recent call last\):\n'
r' File' r' File'
r'.*\n' r'.*\n'
r' File "{filename}", line {lineno}, in test_future_exception_never_retrieved\n' r' File "{filename}", line {lineno}, in check_future_exception_never_retrieved\n'
r' future = asyncio\.Future\(loop=self\.loop\)$' r' future = asyncio\.Future\(loop=self\.loop\)$'
).format(filename=re.escape(frame[0]), lineno=frame[1]) ).format(filename=re.escape(frame[0]), lineno=frame[1])
else:
regex = (r'^Future exception was never retrieved\n'
r'future: <Future finished exception=MemoryError\(\)>$'
)
exc_info = (type(exc), exc, exc.__traceback__) exc_info = (type(exc), exc, exc.__traceback__)
m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info)
else: else:
if debug:
frame = source_traceback[-1] frame = source_traceback[-1]
regex = (r'^Future/Task exception was never retrieved\n' regex = (r'^Future/Task exception was never retrieved\n'
r'Future/Task created at \(most recent call last\):\n' r'Future/Task created at \(most recent call last\):\n'
r' File' r' File'
r'.*\n' r'.*\n'
r' File "{filename}", line {lineno}, in test_future_exception_never_retrieved\n' r' File "{filename}", line {lineno}, in check_future_exception_never_retrieved\n'
r' future = asyncio\.Future\(loop=self\.loop\)\n' r' future = asyncio\.Future\(loop=self\.loop\)\n'
r'Traceback \(most recent call last\):\n' r'Traceback \(most recent call last\):\n'
r'.*\n' r'.*\n'
r'MemoryError$' r'MemoryError$'
).format(filename=re.escape(frame[0]), lineno=frame[1]) ).format(filename=re.escape(frame[0]), lineno=frame[1])
else:
regex = (r'^Future/Task exception was never retrieved\n'
r'Traceback \(most recent call last\):\n'
r'.*\n'
r'MemoryError$'
)
m_log.error.assert_called_once_with(mock.ANY, exc_info=False) m_log.error.assert_called_once_with(mock.ANY, exc_info=False)
message = m_log.error.call_args[0][0] message = m_log.error.call_args[0][0]
self.assertRegex(message, re.compile(regex, re.DOTALL)) self.assertRegex(message, re.compile(regex, re.DOTALL))
def test_future_exception_never_retrieved(self):
self.check_future_exception_never_retrieved(False)
def test_future_exception_never_retrieved_debug(self):
self.check_future_exception_never_retrieved(True)
def test_set_result_unless_cancelled(self): def test_set_result_unless_cancelled(self):
fut = asyncio.Future(loop=self.loop) fut = asyncio.Future(loop=self.loop)
fut.cancel() fut.cancel()