diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2015-01-14 16:51:38 +0100 |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2015-01-14 16:51:38 +0100 |
commit | 398fdbe6590522e803cc4c4eac353bf5fc344552 (patch) | |
tree | 030a113c980d7d376d233d699a23cfe5380b4bc2 /tests | |
parent | 9d44c821817898cf8d0452080374f5d0d9c35f9d (diff) | |
download | trollius-git-398fdbe6590522e803cc4c4eac353bf5fc344552.tar.gz |
Python issue #23197: On SSL handshake failure, check if the waiter is cancelled
before setting its exception.
Add unit tests for this case.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test_selector_events.py | 20 | ||||
-rw-r--r-- | tests/test_sslproto.py | 45 |
2 files changed, 61 insertions, 4 deletions
diff --git a/tests/test_selector_events.py b/tests/test_selector_events.py index 360327a..64c2e65 100644 --- a/tests/test_selector_events.py +++ b/tests/test_selector_events.py @@ -1148,16 +1148,28 @@ class SelectorSslTransportTests(test_utils.TestCase): self.assertTrue(self.sslsock.close.called) def test_on_handshake_base_exc(self): + waiter = asyncio.Future(loop=self.loop) transport = _SelectorSslTransport( - self.loop, self.sock, self.protocol, self.sslcontext) - transport._waiter = asyncio.Future(loop=self.loop) + self.loop, self.sock, self.protocol, self.sslcontext, waiter) exc = BaseException() self.sslsock.do_handshake.side_effect = exc with test_utils.disable_logger(): self.assertRaises(BaseException, transport._on_handshake, 0) self.assertTrue(self.sslsock.close.called) - self.assertTrue(transport._waiter.done()) - self.assertIs(exc, transport._waiter.exception()) + self.assertTrue(waiter.done()) + self.assertIs(exc, waiter.exception()) + + def test_cancel_handshake(self): + # Python issue #23197: cancelling an handshake must not raise an + # exception or log an error, even if the handshake failed + waiter = asyncio.Future(loop=self.loop) + transport = _SelectorSslTransport( + self.loop, self.sock, self.protocol, self.sslcontext, waiter) + waiter.cancel() + exc = ValueError() + self.sslsock.do_handshake.side_effect = exc + with test_utils.disable_logger(): + transport._on_handshake(0) def test_pause_resume_reading(self): tr = self._make_one() diff --git a/tests/test_sslproto.py b/tests/test_sslproto.py new file mode 100644 index 0000000..053fefe --- /dev/null +++ b/tests/test_sslproto.py @@ -0,0 +1,45 @@ +"""Tests for asyncio/sslproto.py.""" + +import unittest +from unittest import mock + +import asyncio +from asyncio import sslproto +from asyncio import test_utils + + +class SslProtoHandshakeTests(test_utils.TestCase): + + def setUp(self): + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) + + def test_cancel_handshake(self): + # Python issue #23197: cancelling an handshake must not raise an + # exception or log an error, even if the handshake failed + sslcontext = test_utils.dummy_ssl_context() + app_proto = asyncio.Protocol() + waiter = asyncio.Future(loop=self.loop) + ssl_proto = sslproto.SSLProtocol(self.loop, app_proto, sslcontext, + waiter) + handshake_fut = asyncio.Future(loop=self.loop) + + def do_handshake(callback): + exc = Exception() + callback(exc) + handshake_fut.set_result(None) + return [] + + waiter.cancel() + transport = mock.Mock() + sslpipe = mock.Mock() + sslpipe.do_handshake.side_effect = do_handshake + with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe): + ssl_proto.connection_made(transport) + + with test_utils.disable_logger(): + self.loop.run_until_complete(handshake_fut) + + +if __name__ == '__main__': + unittest.main() |