]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Refactor connection-closed tests.
authorBen Darnell <ben@bendarnell.com>
Sun, 11 Jan 2015 16:21:42 +0000 (11:21 -0500)
committerBen Darnell <ben@bendarnell.com>
Sun, 11 Jan 2015 16:23:06 +0000 (11:23 -0500)
On CI servers, port numbers get reused frequently, so a closed
port cannot be relied upon to refuse connections for long.
We now use an open client-side socket's ephemeral port,
which will always refuse connections and cannot be reused
for as log as the socket is open.

tornado/test/iostream_test.py
tornado/test/simple_httpclient_test.py
tornado/test/tcpclient_test.py
tornado/test/util.py

index f54eed6bb8113c4eb320174005513c2779b2c95a..b0e94fb20f8e53a67ffff2a38753822476076e94 100644 (file)
@@ -8,7 +8,7 @@ from tornado.log import gen_log, app_log
 from tornado.netutil import ssl_wrap_socket
 from tornado.stack_context import NullContext
 from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog, gen_test
-from tornado.test.util import unittest, skipIfNonUnix
+from tornado.test.util import unittest, skipIfNonUnix, refusing_port
 from tornado.web import RequestHandler, Application
 import certifi
 import errno
@@ -217,8 +217,8 @@ class TestIOStreamMixin(object):
         # 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)
-        server_socket, port = bind_unused_port()
-        server_socket.close()
+        cleanup_func, port = refusing_port()
+        self.addCleanup(cleanup_func)
         stream = IOStream(socket.socket(), self.io_loop)
         self.connect_called = False
 
index 11cf059917c8f90c0a20199e0ad8d5f512041445..a059bc933f50eabf72dfac772c1bbc081da21f4b 100644 (file)
@@ -19,8 +19,8 @@ from tornado.netutil import Resolver, bind_sockets
 from tornado.simple_httpclient import SimpleAsyncHTTPClient, _default_ca_certs
 from tornado.test.httpclient_test import ChunkHandler, CountdownHandler, HelloWorldHandler
 from tornado.test import httpclient_test
-from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, bind_unused_port, ExpectLog
-from tornado.test.util import skipOnTravis, skipIfNoIPv6
+from tornado.testing import AsyncHTTPTestCase, AsyncHTTPSTestCase, AsyncTestCase, ExpectLog
+from tornado.test.util import skipOnTravis, skipIfNoIPv6, refusing_port
 from tornado.web import RequestHandler, Application, asynchronous, url, stream_request_body
 
 
@@ -322,8 +322,8 @@ class SimpleHTTPClientTestMixin(object):
         self.assertTrue(host_re.match(response.body), response.body)
 
     def test_connection_refused(self):
-        server_socket, port = bind_unused_port()
-        server_socket.close()
+        cleanup_func, port = refusing_port()
+        self.addCleanup(cleanup_func)
         with ExpectLog(gen_log, ".*", required=False):
             self.http_client.fetch("http://localhost:%d/" % port, self.stop)
             response = self.wait()
index 5df4a7abb30e398eebb247da67bf18ad2a1dcb4b..1a4201e6b7712afdf5a00574868114d1dc7380bf 100644 (file)
@@ -24,8 +24,8 @@ from tornado.concurrent import Future
 from tornado.netutil import bind_sockets, Resolver
 from tornado.tcpclient import TCPClient, _Connector
 from tornado.tcpserver import TCPServer
-from tornado.testing import AsyncTestCase, bind_unused_port, gen_test
-from tornado.test.util import skipIfNoIPv6, unittest
+from tornado.testing import AsyncTestCase, gen_test
+from tornado.test.util import skipIfNoIPv6, unittest, refusing_port
 
 # Fake address families for testing.  Used in place of AF_INET
 # and AF_INET6 because some installations do not have AF_INET6.
@@ -120,8 +120,8 @@ class TCPClientTest(AsyncTestCase):
 
     @gen_test
     def test_refused_ipv4(self):
-        sock, port = bind_unused_port()
-        sock.close()
+        cleanup_func, port = refusing_port()
+        self.addCleanup(cleanup_func)
         with self.assertRaises(IOError):
             yield self.client.connect('127.0.0.1', port)
 
index d31bbba33d8019865d1c44abd43eb246fa639c1f..4f0c07e5e2216ecaa9e2fe672c49711e2984094a 100644 (file)
@@ -4,6 +4,8 @@ import os
 import socket
 import sys
 
+from tornado.testing import bind_unused_port
+
 # Encapsulate the choice of unittest or unittest2 here.
 # To be used as 'from tornado.test.util import unittest'.
 if sys.version_info < (2, 7):
@@ -28,3 +30,21 @@ skipIfNoNetwork = unittest.skipIf('NO_NETWORK' in os.environ,
                                   'network access disabled')
 
 skipIfNoIPv6 = unittest.skipIf(not socket.has_ipv6, 'ipv6 support not present')
+
+def refusing_port():
+    """Returns a local port number that will refuse all connections.
+
+    Return value is (cleanup_func, port); the cleanup function
+    must be called to free the port to be reused.
+    """
+    # On travis-ci, port numbers are reassigned frequently. To avoid
+    # collisions with other tests, we use an open client-side socket's
+    # ephemeral port number to ensure that nothing can listen on that
+    # port.
+    server_socket, port = bind_unused_port()
+    client_socket = socket.socket()
+    client_socket.connect(("127.0.0.1", port))
+    conn, client_addr = server_socket.accept()
+    conn.close()
+    server_socket.close()
+    return (client_socket.close, client_addr[1])