From: Ben Darnell Date: Mon, 11 Jun 2018 02:19:58 +0000 (-0400) Subject: test: Convert more tests to non-deprecated interfaces X-Git-Tag: v5.1.0b1~2^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F2417%2Fhead;p=thirdparty%2Ftornado.git test: Convert more tests to non-deprecated interfaces Now the only tests using ignore_deprecation are the ones actually testing deprecated interfaces, so the tests can be removed in 6.0. --- diff --git a/tornado/test/httpserver_test.py b/tornado/test/httpserver_test.py index 5abb7fe3c..acaf2a002 100644 --- a/tornado/test/httpserver_test.py +++ b/tornado/test/httpserver_test.py @@ -13,7 +13,7 @@ from tornado.log import gen_log from tornado.netutil import ssl_options_to_context from tornado.simple_httpclient import SimpleAsyncHTTPClient from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog, gen_test # noqa: E501 -from tornado.test.util import unittest, skipOnTravis, ignore_deprecation +from tornado.test.util import unittest, skipOnTravis from tornado.web import Application, RequestHandler, stream_request_body from contextlib import closing @@ -209,9 +209,7 @@ class HTTPConnectionTest(AsyncHTTPTestCase): def raw_fetch(self, headers, body, newline=b"\r\n"): with closing(IOStream(socket.socket())) as stream: - with ignore_deprecation(): - stream.connect(('127.0.0.1', self.get_http_port()), self.stop) - self.wait() + self.io_loop.run_sync(lambda: stream.connect(('127.0.0.1', self.get_http_port()))) stream.write( newline.join(headers + [utf8("Content-Length: %d" % len(body))]) + diff --git a/tornado/test/iostream_test.py b/tornado/test/iostream_test.py index cb0967f8c..abdd6b99e 100644 --- a/tornado/test/iostream_test.py +++ b/tornado/test/iostream_test.py @@ -15,7 +15,6 @@ from tornado.test.util import (unittest, skipIfNonUnix, refusing_port, skipPypy3 from tornado.web import RequestHandler, Application import errno import hashlib -import logging import os import platform import random @@ -94,33 +93,19 @@ class TestIOStreamWebMixin(object): @gen_test def test_write_while_connecting(self): stream = self._make_client_iostream() - connected = [False] - cond = Condition() - - def connected_callback(): - connected[0] = True - cond.notify() - with ignore_deprecation(): - stream.connect(("127.0.0.1", self.get_http_port()), - callback=connected_callback) + connect_fut = stream.connect(("127.0.0.1", self.get_http_port())) # unlike the previous tests, try to write before the connection # is complete. - written = [False] + write_fut = stream.write(b"GET / HTTP/1.0\r\nConnection: close\r\n\r\n") + self.assertFalse(connect_fut.done()) - def write_callback(): - written[0] = True - cond.notify() - with ignore_deprecation(): - stream.write(b"GET / HTTP/1.0\r\nConnection: close\r\n\r\n", - callback=write_callback) - self.assertTrue(not connected[0]) - # by the time the write has flushed, the connection callback has - # also run - try: - while not (connected[0] and written[0]): - yield cond.wait() - finally: - logging.debug((connected, written)) + # connect will always complete before write. + it = gen.WaitIterator(connect_fut, write_fut) + resolved_order = [] + while not it.done(): + yield it.next() + resolved_order.append(it.current_future) + self.assertEqual(resolved_order, [connect_fut, write_fut]) data = yield stream.read_until_close() self.assertTrue(data.endswith(b"Hello")) @@ -470,8 +455,7 @@ class TestReadWriteMixin(object): self.assertEqual(res, OK) ws.close() - with ignore_deprecation(): - rs.read_until(b"\r\n", lambda x: x) + rs.read_until(b"\r\n") # If _close_callback (self.stop) is not called, # an AssertionError: Async operation timed out after 5 seconds # will be raised. @@ -570,7 +554,7 @@ class TestReadWriteMixin(object): rs.close() @gen_test - def test_read_until_max_bytes_inline(self): + def test_read_until_max_bytes_inline_legacy(self): rs, ws = yield self.make_iostream_pair() closed = Event() rs.set_close_callback(closed.set) @@ -588,6 +572,25 @@ class TestReadWriteMixin(object): ws.close() rs.close() + @gen_test + def test_read_until_max_bytes_inline(self): + rs, ws = yield self.make_iostream_pair() + closed = Event() + rs.set_close_callback(closed.set) + try: + # Similar to the error case in the previous test, but the + # ws writes first so rs reads are satisfied + # inline. For consistency with the out-of-line case, we + # do not raise the error synchronously. + ws.write(b"123456") + with ExpectLog(gen_log, "Unsatisfiable read"): + with self.assertRaises(StreamClosedError): + yield rs.read_until(b"def", max_bytes=5) + yield closed.wait() + finally: + ws.close() + rs.close() + @gen_test def test_read_until_max_bytes_ignores_extra(self): rs, ws = yield self.make_iostream_pair() @@ -871,7 +874,7 @@ class TestIOStreamMixin(TestReadWriteMixin): listener.close() raise gen.Return((server_stream, client_stream)) - def test_connection_refused(self): + def test_connection_refused_legacy(self): # When a connection is refused, the connect callback should not # be run. (The kqueue IOLoop used to behave differently from the # epoll IOLoop in this respect) @@ -898,7 +901,31 @@ class TestIOStreamMixin(TestReadWriteMixin): # cygwin's errnos don't match those used on native windows python self.assertTrue(stream.error.args[0] in _ERRNO_CONNREFUSED) + @gen_test + def test_connection_refused(self): + # When a connection is refused, the connect callback should not + # be run. (The kqueue IOLoop used to behave differently from the + # epoll IOLoop in this respect) + cleanup_func, port = refusing_port() + self.addCleanup(cleanup_func) + stream = IOStream(socket.socket()) + + stream.set_close_callback(self.stop) + # log messages vary by platform and ioloop implementation + with ExpectLog(gen_log, ".*", required=False): + with self.assertRaises(StreamClosedError): + yield stream.connect(("127.0.0.1", port)) + + self.assertTrue(isinstance(stream.error, socket.error), stream.error) + if sys.platform != 'cygwin': + _ERRNO_CONNREFUSED = (errno.ECONNREFUSED,) + if hasattr(errno, "WSAECONNREFUSED"): + _ERRNO_CONNREFUSED += (errno.WSAECONNREFUSED,) + # cygwin's errnos don't match those used on native windows python + self.assertTrue(stream.error.args[0] in _ERRNO_CONNREFUSED) + @unittest.skipIf(mock is None, 'mock package not present') + @gen_test def test_gaierror(self): # Test that IOStream sets its exc_info on getaddrinfo error. # It's difficult to reliably trigger a getaddrinfo error; @@ -910,11 +937,9 @@ class TestIOStreamMixin(TestReadWriteMixin): stream.set_close_callback(self.stop) with mock.patch('socket.socket.connect', side_effect=socket.gaierror(errno.EIO, 'boom')): - with ExpectLog(gen_log, "Connect error"): - with ignore_deprecation(): - stream.connect(('localhost', 80), callback=self.stop) - self.wait() - self.assertIsInstance(stream.error, socket.gaierror) + with self.assertRaises(StreamClosedError): + yield stream.connect(('localhost', 80)) + self.assertTrue(isinstance(stream.error, socket.gaierror)) @gen_test def test_read_callback_error(self): @@ -945,8 +970,7 @@ class TestIOStreamMixin(TestReadWriteMixin): with mock.patch('tornado.iostream.BaseIOStream._try_inline_read', side_effect=IOError('boom')): with self.assertRaisesRegexp(IOError, 'boom'): - with ignore_deprecation(): - client.read_until_close(lambda x: None) + client.read_until_close() finally: server.close() client.close() @@ -982,8 +1006,7 @@ class TestIOStreamMixin(TestReadWriteMixin): server.set_close_callback(closed.set) try: # Start a read that will be fulfilled asynchronously. - with ignore_deprecation(): - server.read_bytes(1, lambda data: None) + server.read_bytes(1) client.write(b'a') # Stub out read_from_fd to make it fail. @@ -1250,12 +1273,12 @@ class WaitForHandshakeTest(AsyncTestCase): handshake_future = Future() class TestServer(TCPServer): + @gen.coroutine def handle_stream(self, stream, address): - with ignore_deprecation(): - stream.wait_for_handshake(self.handshake_done) + fut = stream.wait_for_handshake() test.assertRaises(RuntimeError, stream.wait_for_handshake) + yield fut - def handshake_done(self): handshake_future.set_result(None) yield self.connect_to_server(TestServer) @@ -1266,16 +1289,10 @@ class WaitForHandshakeTest(AsyncTestCase): handshake_future = Future() class TestServer(TCPServer): + @gen.coroutine def handle_stream(self, stream, address): - self.stream = stream - with ignore_deprecation(): - stream.wait_for_handshake(self.handshake_done) - - def handshake_done(self): - with ignore_deprecation(): - self.stream.wait_for_handshake(self.handshake2_done) - - def handshake2_done(self): + yield stream.wait_for_handshake() + yield stream.wait_for_handshake() handshake_future.set_result(None) yield self.connect_to_server(TestServer) diff --git a/tornado/test/simple_httpclient_test.py b/tornado/test/simple_httpclient_test.py index 77a04ce4c..b3f4dcb7c 100644 --- a/tornado/test/simple_httpclient_test.py +++ b/tornado/test/simple_httpclient_test.py @@ -26,8 +26,7 @@ from tornado.test.httpclient_test import ChunkHandler, CountdownHandler, HelloWo from tornado.test import httpclient_test from tornado.testing import (AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog, gen_test) -from tornado.test.util import (skipOnTravis, skipIfNoIPv6, refusing_port, skipBefore35, - exec_test, ignore_deprecation) +from tornado.test.util import skipOnTravis, skipIfNoIPv6, refusing_port, skipBefore35, exec_test from tornado.web import RequestHandler, Application, url, stream_request_body @@ -251,36 +250,26 @@ class SimpleHTTPClientTestMixin(object): @gen_test def test_connect_timeout(self): timeout = 0.1 - timeout_min, timeout_max = 0.099, 1.0 class TimeoutResolver(Resolver): def resolve(self, *args, **kwargs): return Future() # never completes with closing(self.create_client(resolver=TimeoutResolver())) as client: - with ignore_deprecation(): - response = yield client.fetch(self.get_url('/hello'), - connect_timeout=timeout, - raise_error=False) - self.assertEqual(response.code, 599) - self.assertTrue(timeout_min < response.request_time < timeout_max, - response.request_time) - self.assertEqual(str(response.error), "Timeout while connecting") + with self.assertRaises(HTTPTimeoutError): + yield client.fetch(self.get_url('/hello'), + connect_timeout=timeout, + request_timeout=3600, + raise_error=True) @skipOnTravis def test_request_timeout(self): timeout = 0.1 - timeout_min, timeout_max = 0.099, 0.15 if os.name == 'nt': timeout = 0.5 - timeout_min, timeout_max = 0.4, 0.6 - - with ignore_deprecation(): - response = self.fetch('/trigger?wake=false', request_timeout=timeout) - self.assertEqual(response.code, 599) - self.assertTrue(timeout_min < response.request_time < timeout_max, - response.request_time) - self.assertEqual(str(response.error), "Timeout during request") + + with self.assertRaises(HTTPTimeoutError): + self.fetch('/trigger?wake=false', request_timeout=timeout, raise_error=True) # trigger the hanging request to let it clean up after itself self.triggers.popleft()() @@ -345,41 +334,33 @@ class SimpleHTTPClientTestMixin(object): cleanup_func, port = refusing_port() self.addCleanup(cleanup_func) with ExpectLog(gen_log, ".*", required=False): - with ignore_deprecation(): - response = self.fetch("http://127.0.0.1:%d/" % port) - self.assertEqual(599, response.code) + with self.assertRaises(socket.error) as cm: + self.fetch("http://127.0.0.1:%d/" % port, raise_error=True) if sys.platform != 'cygwin': # cygwin returns EPERM instead of ECONNREFUSED here - contains_errno = str(errno.ECONNREFUSED) in str(response.error) + contains_errno = str(errno.ECONNREFUSED) in str(cm.exception) if not contains_errno and hasattr(errno, "WSAECONNREFUSED"): - contains_errno = str(errno.WSAECONNREFUSED) in str(response.error) - self.assertTrue(contains_errno, response.error) + contains_errno = str(errno.WSAECONNREFUSED) in str(cm.exception) + self.assertTrue(contains_errno, cm.exception) # This is usually "Connection refused". # On windows, strerror is broken and returns "Unknown error". expected_message = os.strerror(errno.ECONNREFUSED) - self.assertTrue(expected_message in str(response.error), - response.error) + self.assertTrue(expected_message in str(cm.exception), + cm.exception) def test_queue_timeout(self): - with ignore_deprecation(): - with closing(self.create_client(max_clients=1)) as client: - # Wait for the trigger request to block, not complete. - fut1 = client.fetch(self.get_url('/trigger'), - request_timeout=10, raise_error=False) - self.wait() - fut2 = client.fetch(self.get_url('/hello'), - connect_timeout=0.1, raise_error=False) - fut2.add_done_callback(self.stop) - response = self.wait().result() - - self.assertEqual(response.code, 599) - self.assertTrue(response.request_time < 1, response.request_time) - self.assertEqual(str(response.error), "Timeout in request queue") - self.triggers.popleft()() - fut1.add_done_callback(self.stop) - self.wait() - fut1.result() + with closing(self.create_client(max_clients=1)) as client: + # Wait for the trigger request to block, not complete. + fut1 = client.fetch(self.get_url('/trigger'), request_timeout=10) + self.wait() + with self.assertRaises(HTTPTimeoutError) as cm: + self.io_loop.run_sync(lambda: client.fetch( + self.get_url('/hello'), connect_timeout=0.1, raise_error=True)) + + self.assertEqual(str(cm.exception), "Timeout in request queue") + self.triggers.popleft()() + self.io_loop.run_sync(lambda: fut1) def test_no_content_length(self): response = self.fetch("/no_content_length") @@ -578,16 +559,15 @@ class HTTP100ContinueTestCase(AsyncHTTPTestCase): request.connection.finish() return self.request = request - with ignore_deprecation(): - self.request.connection.stream.write( - b"HTTP/1.1 100 CONTINUE\r\n\r\n", - self.respond_200) + fut = self.request.connection.stream.write( + b"HTTP/1.1 100 CONTINUE\r\n\r\n") + fut.add_done_callback(self.respond_200) - def respond_200(self): - with ignore_deprecation(): - self.request.connection.stream.write( - b"HTTP/1.1 200 OK\r\nContent-Length: 1\r\n\r\nA", - self.request.connection.stream.close) + def respond_200(self, fut): + fut.result() + fut = self.request.connection.stream.write( + b"HTTP/1.1 200 OK\r\nContent-Length: 1\r\n\r\nA") + fut.add_done_callback(lambda f: self.request.connection.stream.close()) def get_app(self): # Not a full Application, but works as an HTTPServer callback @@ -638,13 +618,12 @@ class HTTP204NoContentTestCase(AsyncHTTPTestCase): def test_204_invalid_content_length(self): # 204 status with non-zero content length is malformed with ExpectLog(gen_log, ".*Response with code 204 should not have body"): - with ignore_deprecation(): - response = self.fetch("/?error=1") - if not self.http1: - self.skipTest("requires HTTP/1.x") - if self.http_client.configured_class != SimpleAsyncHTTPClient: - self.skipTest("curl client accepts invalid headers") - self.assertEqual(response.code, 599) + with self.assertRaises(HTTPStreamClosedError): + self.fetch("/?error=1", raise_error=True) + if not self.http1: + self.skipTest("requires HTTP/1.x") + if self.http_client.configured_class != SimpleAsyncHTTPClient: + self.skipTest("curl client accepts invalid headers") class HostnameMappingTestCase(AsyncHTTPTestCase): diff --git a/tornado/test/testing_test.py b/tornado/test/testing_test.py index 9b47c92bc..0f0ceba79 100644 --- a/tornado/test/testing_test.py +++ b/tornado/test/testing_test.py @@ -2,6 +2,7 @@ from __future__ import absolute_import, division, print_function from tornado import gen, ioloop from tornado.log import app_log +from tornado.simple_httpclient import SimpleAsyncHTTPClient, HTTPTimeoutError from tornado.test.util import unittest, skipBefore35, exec_test, ignore_deprecation from tornado.testing import AsyncHTTPTestCase, AsyncTestCase, bind_unused_port, gen_test, ExpectLog from tornado.web import Application @@ -98,19 +99,23 @@ class AsyncHTTPTestCaseTest(AsyncHTTPTestCase): response = self.fetch(path) self.assertEqual(response.request.url, self.get_url(path)) + @gen_test def test_fetch_full_http_url(self): path = 'http://localhost:%d/path' % self.external_port - with ignore_deprecation(): - response = self.fetch(path, request_timeout=0.1, raise_error=False) - self.assertEqual(response.request.url, path) + with contextlib.closing(SimpleAsyncHTTPClient(force_instance=True)) as client: + with self.assertRaises(HTTPTimeoutError) as cm: + yield client.fetch(path, request_timeout=0.1, raise_error=True) + self.assertEqual(cm.exception.response.request.url, path) + @gen_test def test_fetch_full_https_url(self): path = 'https://localhost:%d/path' % self.external_port - with ignore_deprecation(): - response = self.fetch(path, request_timeout=0.1) - self.assertEqual(response.request.url, path) + with contextlib.closing(SimpleAsyncHTTPClient(force_instance=True)) as client: + with self.assertRaises(HTTPTimeoutError) as cm: + yield client.fetch(path, request_timeout=0.1, raise_error=True) + self.assertEqual(cm.exception.response.request.url, path) @classmethod def tearDownClass(cls): diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index b77311df0..9a435c300 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -626,9 +626,8 @@ class EmptyFlushCallbackHandler(RequestHandler): # Ensure that the flush callback is run whether or not there # was any output. The gen.Task and direct yield forms are # equivalent. - with ignore_deprecation(): - yield gen.Task(self.flush) # "empty" flush, but writes headers - yield gen.Task(self.flush) # empty flush + yield self.flush() # "empty" flush, but writes headers + yield self.flush() # empty flush self.write("o") yield self.flush() # flushes the "o" yield self.flush() # empty flush @@ -2410,11 +2409,11 @@ class ClientCloseTest(SimpleHandlerTestCase): self.write('requires HTTP/1.x') def test_client_close(self): - with ignore_deprecation(): - response = self.fetch('/') - if response.body == b'requires HTTP/1.x': - self.skipTest('requires HTTP/1.x') - self.assertEqual(response.code, 599) + with self.assertRaises((HTTPClientError, unittest.SkipTest)): + response = self.fetch('/', raise_error=True) + if response.body == b'requires HTTP/1.x': + self.skipTest('requires HTTP/1.x') + self.assertEqual(response.code, 599) class SignedValueTest(unittest.TestCase):