diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2014-11-20 14:33:04 +0100 |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2014-11-20 14:33:04 +0100 |
commit | bd1da296903bb34e116fb5003594efaf7f206474 (patch) | |
tree | aab3afe4a14983e919a5e35d61a30e55c152d854 | |
parent | fca11e3534eca930e1adeebb74b1c039e983542b (diff) | |
parent | 4377c749acb8e05dfd0fb762c860a4f29c99dd7a (diff) | |
download | trollius-bd1da296903bb34e116fb5003594efaf7f206474.tar.gz |
Merge Tulip into Trollius
-rw-r--r-- | tests/test_events.py | 19 | ||||
-rw-r--r-- | tests/test_futures.py | 70 | ||||
-rw-r--r-- | tests/test_unix_events.py | 12 | ||||
-rw-r--r-- | trollius/futures.py | 7 | ||||
-rw-r--r-- | trollius/unix_events.py | 3 |
5 files changed, 77 insertions, 34 deletions
diff --git a/tests/test_events.py b/tests/test_events.py index 5f11136..04149cd 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -625,9 +625,12 @@ class EventLoopTestsMixin(object): conn_fut = create_connection(ssl=test_utils.dummy_ssl_context()) self._basetest_create_ssl_connection(conn_fut, check_sockname) - if not asyncio.BACKPORT_SSL_CONTEXT: - def create_context(purpose=ssl.Purpose.SERVER_AUTH, - cafile=None, capath=None, cadata=None): + # ssl.Purpose was introduced in Python 3.4 + #if not asyncio.BACKPORT_SSL_CONTEXT: + 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 cert validation. @@ -635,21 +638,21 @@ class EventLoopTestsMixin(object): self.assertEqual(purpose, ssl.Purpose.SERVER_AUTH) return test_utils.dummy_ssl_context() - # With ssl=True, ssl.create_default_context() should be called with mock.patch('ssl.create_default_context', - side_effect=create_context) as m: + side_effect=_dummy_ssl_create_context) as m: conn_fut = create_connection(ssl=True) self._basetest_create_ssl_connection(conn_fut, check_sockname) self.assertEqual(m.call_count, 1) + if not asyncio.BACKPORT_SSL_CONTEXT: # With the real ssl.create_default_context(), certificate # validation will fail with self.assertRaises(ssl.SSLError) as cm: conn_fut = create_connection(ssl=True) - self._basetest_create_ssl_connection(conn_fut, check_sockname) - - self.assertEqual(cm.exception.reason, 'CERTIFICATE_VERIFY_FAILED') + # Ignore the "SSL handshake failed" log in debug mode + with test_utils.disable_logger(): + self._basetest_create_ssl_connection(conn_fut, check_sockname) @test_utils.skipIf(ssl is None, 'No ssl module') def test_create_ssl_connection(self): diff --git a/tests/test_futures.py b/tests/test_futures.py index fc5c043..643b0a0 100644 --- a/tests/test_futures.py +++ b/tests/test_futures.py @@ -10,6 +10,7 @@ import threading import unittest import trollius as asyncio +from trollius import compat from trollius import test_utils from trollius import test_support as support # gc_collect from trollius.test_utils import mock @@ -282,8 +283,8 @@ class FutureTests(test_utils.TestCase): self.check_soure_traceback(future._source_traceback, -1) @mock.patch('trollius.base_events.logger') - def test_future_exception_never_retrieved(self, m_log): - self.loop.set_debug(True) + def check_future_exception_never_retrieved(self, debug, m_log): + self.loop.set_debug(debug) def memory_error(): try: @@ -293,40 +294,63 @@ class FutureTests(test_utils.TestCase): exc = memory_error() future = asyncio.Future(loop=self.loop) - source_traceback = future._source_traceback + if debug: + source_traceback = future._source_traceback future.set_exception(exc) future = None test_utils.run_briefly(self.loop) support.gc_collect() if sys.version_info >= (3, 4): - frame = source_traceback[-1] - regex = (r'^Future exception was never retrieved\n' - r'future: <Future finished exception=MemoryError\(\) created at {filename}:{lineno}>\n' - r'source_traceback: Object created at \(most recent call last\):\n' - r' File' - r'.*\n' - r' File "{filename}", line {lineno}, in test_future_exception_never_retrieved\n' - r' future = asyncio\.Future\(loop=self\.loop\)$' - ).format(filename=re.escape(frame[0]), lineno=frame[1]) + if debug: + frame = source_traceback[-1] + regex = (r'^Future exception was never retrieved\n' + r'future: <Future finished exception=MemoryError\(\) created at {filename}:{lineno}>\n' + r'source_traceback: Object created at \(most recent call last\):\n' + r' File' + r'.*\n' + r' File "{filename}", line {lineno}, in check_future_exception_never_retrieved\n' + r' future = asyncio\.Future\(loop=self\.loop\)$' + ).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__) m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) else: - frame = source_traceback[-1] - regex = (r'^Future/Task exception was never retrieved\n' - r'Future/Task created at \(most recent call last\):\n' - r' File' - r'.*\n' - r' File "{filename}", line {lineno}, in test_future_exception_never_retrieved\n' - r' future = asyncio\.Future\(loop=self\.loop\)\n' - r'Traceback \(most recent call last\):\n' - r'.*\n' - r'MemoryError$' - ).format(filename=re.escape(frame[0]), lineno=frame[1]) + if debug: + frame = source_traceback[-1] + regex = (r'^Future/Task exception was never retrieved\n' + r'Future/Task created at \(most recent call last\):\n' + r' File' + r'.*\n' + r' File "{filename}", line {lineno}, in check_future_exception_never_retrieved\n' + r' future = asyncio\.Future\(loop=self\.loop\)\n' + r'Traceback \(most recent call last\):\n' + r'.*\n' + r'MemoryError$' + ).format(filename=re.escape(frame[0]), lineno=frame[1]) + elif compat.PY3: + regex = (r'^Future/Task exception was never retrieved\n' + r'Traceback \(most recent call last\):\n' + r'.*\n' + r'MemoryError$' + ) + else: + regex = (r'^Future/Task exception was never retrieved\n' + r'MemoryError$' + ) m_log.error.assert_called_once_with(mock.ANY, exc_info=False) message = m_log.error.call_args[0][0] 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): fut = asyncio.Future(loop=self.loop) fut.cancel() diff --git a/tests/test_unix_events.py b/tests/test_unix_events.py index 6468371..932c6da 100644 --- a/tests/test_unix_events.py +++ b/tests/test_unix_events.py @@ -66,6 +66,18 @@ class SelectorEventLoopSignalTests(test_utils.TestCase): signal.SIGINT, lambda: True) @mock.patch('trollius.unix_events.signal') + def test_add_signal_handler_coroutine_error(self, m_signal): + + @asyncio.coroutine + def simple_coroutine(): + yield None + + self.assertRaises( + TypeError, + self.loop.add_signal_handler, + signal.SIGINT, simple_coroutine) + + @mock.patch('trollius.unix_events.signal') def test_add_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG diff --git a/trollius/futures.py b/trollius/futures.py index a771057..aff0186 100644 --- a/trollius/futures.py +++ b/trollius/futures.py @@ -107,10 +107,11 @@ class _TracebackLogger(object): def __del__(self): if self.tb: - msg = 'Future/Task exception was never retrieved' + msg = 'Future/Task exception was never retrieved\n' if self.source_traceback: - msg += '\nFuture/Task created at (most recent call last):\n' - msg += ''.join(traceback.format_list(self.source_traceback)) + src = ''.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() self.loop.call_exception_handler({'message': msg}) diff --git a/trollius/unix_events.py b/trollius/unix_events.py index d797441..ad40f18 100644 --- a/trollius/unix_events.py +++ b/trollius/unix_events.py @@ -17,6 +17,7 @@ from . import base_events from . import base_subprocess from . import compat from . import constants +from . import coroutines from . import events from . import selector_events from . import selectors @@ -80,6 +81,8 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): Raise ValueError if the signal number is invalid or uncatchable. Raise RuntimeError if there is a problem setting up the handler. """ + if coroutines.iscoroutinefunction(callback): + raise TypeError("coroutines cannot be used with call_soon()") self._check_signal(sig) try: # set_wakeup_fd() raises ValueError if this is not the |