summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2014-11-20 14:33:04 +0100
committerVictor Stinner <victor.stinner@gmail.com>2014-11-20 14:33:04 +0100
commitbd1da296903bb34e116fb5003594efaf7f206474 (patch)
treeaab3afe4a14983e919a5e35d61a30e55c152d854
parentfca11e3534eca930e1adeebb74b1c039e983542b (diff)
parent4377c749acb8e05dfd0fb762c860a4f29c99dd7a (diff)
downloadtrollius-bd1da296903bb34e116fb5003594efaf7f206474.tar.gz
Merge Tulip into Trollius
-rw-r--r--tests/test_events.py19
-rw-r--r--tests/test_futures.py70
-rw-r--r--tests/test_unix_events.py12
-rw-r--r--trollius/futures.py7
-rw-r--r--trollius/unix_events.py3
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