From 5e133b6899f86b0ca29fa6df182c30f64fd7e920 Mon Sep 17 00:00:00 2001 From: Jonas Obrist Date: Tue, 24 Jan 2017 19:08:44 +0900 Subject: [PATCH] More informative error message if no protocol found for http2 Added a more informative error message if a HTTP2 connection was unable to select a protocol, added a test for this error message. Changed integration tests to use mock to override acceptable protocols, so as not to leak those changes to other tests. --- hyper/http20/connection.py | 5 ++++- test/test_http20.py | 42 ++++++++++++++++++++++++++++++++++++++ test/test_integration.py | 7 +++++-- 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 test/test_http20.py diff --git a/hyper/http20/connection.py b/hyper/http20/connection.py index b8a2901e..8b2a71e8 100644 --- a/hyper/http20/connection.py +++ b/hyper/http20/connection.py @@ -375,7 +375,10 @@ def connect(self): proto = H2C_PROTOCOL log.debug("Selected NPN protocol: %s", proto) - assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL + assert proto in H2_NPN_PROTOCOLS or proto == H2C_PROTOCOL, ( + "No suitable protocol found. Supported protocols: %s. " + "Check your OpenSSL version." + ) % ','.join(H2_NPN_PROTOCOLS + [H2C_PROTOCOL]) self._sock = BufferedSocket(sock, self.network_buffer_size) diff --git a/test/test_http20.py b/test/test_http20.py new file mode 100644 index 00000000..d187c315 --- /dev/null +++ b/test/test_http20.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +""" +test_http20.py +~~~~~~~~~~~~~~ + +Unit tests for hyper's HTTP/2.0 implementation. +""" +import pytest +from mock import patch + +from server import SocketLevelTest + + +class TestHTTP20Connection(SocketLevelTest): + h2 = True + + def test_useful_error_with_no_protocol(self): + self.set_up() + + def socket_handler(listener): + sock = listener.accept()[0] + sock.close() + + self._start_server(socket_handler) + conn = self.get_connection() + + with patch('hyper.http20.connection.wrap_socket') as mock: + mock.return_value = (None, None) + with pytest.raises(AssertionError) as exc_info: + conn.connect() + assert ( + "No suitable protocol found." + in + str(exc_info) + ) + assert ( + "Check your OpenSSL version." + in + str(exc_info) + ) + + self.tear_down() diff --git a/test/test_integration.py b/test/test_integration.py index c51f061f..96a8af76 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -12,6 +12,7 @@ import hyper import hyper.http11.connection import pytest +from mock import patch from h2.frame_buffer import FrameBuffer from hyper.compat import ssl from hyper.contrib import HTTP20Adapter @@ -34,8 +35,8 @@ hyper.tls._context.check_hostname = False hyper.tls._context.verify_mode = ssl.CERT_NONE - # Cover our bases because NPN doesn't yet work on all our test platforms. - hyper.http20.connection.H2_NPN_PROTOCOLS += ['', None] +# Cover our bases because NPN doesn't yet work on all our test platforms. +PROTOCOLS = hyper.http20.connection.H2_NPN_PROTOCOLS + ['', None] def decode_frame(frame_data): @@ -76,6 +77,7 @@ def receive_preamble(sock): return +@patch('hyper.http20.connection.H2_NPN_PROTOCOLS', PROTOCOLS) class TestHyperIntegration(SocketLevelTest): # These are HTTP/2 tests. h2 = True @@ -1031,6 +1033,7 @@ def socket_handler(listener): self.tear_down() +@patch('hyper.http20.connection.H2_NPN_PROTOCOLS', PROTOCOLS) class TestRequestsAdapter(SocketLevelTest): # This uses HTTP/2. h2 = True