From: Andrew M. Kuchling Date: Fri, 29 Sep 2006 18:30:59 +0000 (+0000) Subject: [Backport rev. 46882 by neal.norwitz] X-Git-Tag: v2.4.4c1~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c138772a20abe3235712cef258c116430cf1ae84;p=thirdparty%2FPython%2Fcpython.git [Backport rev. 46882 by neal.norwitz] Fix the socket tests so they can be run concurrently. Backport candidate --- diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 14e80f1a4087..4b4a628dae4d 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -20,7 +20,8 @@ class SocketTCPTest(unittest.TestCase): def setUp(self): self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.serv.bind((HOST, PORT)) + global PORT + PORT = test_support.bind_port(self.serv, HOST, PORT) self.serv.listen(1) def tearDown(self): @@ -32,7 +33,8 @@ class SocketUDPTest(unittest.TestCase): def setUp(self): self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - self.serv.bind((HOST, PORT)) + global PORT + PORT = test_support.bind_port(self.serv, HOST, PORT) def tearDown(self): self.serv.close() diff --git a/Lib/test/test_socket_ssl.py b/Lib/test/test_socket_ssl.py index e9de5f2b09d9..9c37de4b78dc 100644 --- a/Lib/test/test_socket_ssl.py +++ b/Lib/test/test_socket_ssl.py @@ -72,10 +72,10 @@ def test_rude_shutdown(): return # some random port to connect to - PORT = 9934 + PORT = [9934] def listener(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.bind(('', PORT)) + PORT[0] = test_support.bind_port(s, '', PORT[0]) s.listen(5) s.accept() del s @@ -83,7 +83,7 @@ def test_rude_shutdown(): def connector(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect(('localhost', PORT)) + s.connect(('localhost', PORT[0])) try: ssl_sock = socket.ssl(s) except socket.sslerror: diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 1245ba5fbf27..93165470f922 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -6,6 +6,7 @@ test_support.requires('network') from SocketServer import * import socket +import errno import select import time import threading @@ -77,6 +78,11 @@ class ServerThread(threading.Thread): pass if verbose: print "thread: creating server" svr = svrcls(self.__addr, self.__hdlrcls) + # pull the address out of the server in case it changed + # this can happen if another process is using the port + addr = getattr(svr, 'server_address') + if addr: + self.__addr = addr if verbose: print "thread: serving three times" svr.serve_a_few() if verbose: print "thread: done" @@ -136,7 +142,25 @@ def testloop(proto, servers, hdlrcls, testfunc): t.join() if verbose: print "done" -tcpservers = [TCPServer, ThreadingTCPServer] +class ForgivingTCPServer(TCPServer): + # prevent errors if another process is using the port we want + def server_bind(self): + host, default_port = self.server_address + # this code shamelessly stolen from test.test_support + # the ports were changed to protect the innocent + import sys + for port in [default_port, 3434, 8798, 23833]: + try: + self.server_address = host, port + TCPServer.server_bind(self) + break + except socket.error, (err, msg): + if err != errno.EADDRINUSE: + raise + print >>sys.__stderr__, \ + ' WARNING: failed to listen on port %d, trying another' % port + +tcpservers = [ForgivingTCPServer, ThreadingTCPServer] if hasattr(os, 'fork') and os.name not in ('os2',): tcpservers.append(ForkingTCPServer) udpservers = [UDPServer, ThreadingUDPServer] diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index a296caf6d058..6318a211c6ee 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -86,6 +86,24 @@ def requires(resource, msg=None): msg = "Use of the `%s' resource not enabled" % resource raise ResourceDenied(msg) +def bind_port(sock, host='', preferred_port=54321): + """Try to bind the sock to a port. If we are running multiple + tests and we don't try multiple ports, the test can fails. This + makes the test more robust.""" + + import socket, errno + # some random ports that hopefully no one is listening on. + for port in [preferred_port, 9907, 10243, 32999]: + try: + sock.bind((host, port)) + return port + except socket.error, (err, msg): + if err != errno.EADDRINUSE: + raise + print >>sys.__stderr__, \ + ' WARNING: failed to listen on port %d, trying another' % port + raise TestFailed, 'unable to find port to listen on' + FUZZ = 1e-6 def fcmp(x, y): # fuzzy comparison function diff --git a/Misc/NEWS b/Misc/NEWS index c3d8a126c7fa..4df5d63d74dd 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -228,6 +228,8 @@ Tests - Patch #1529686: test_iterlen and test_email_codecs are now actually run by regrtest.py. +- Fix the socket tests so they can be run concurrently. + What's New in Python 2.4.3? ===========================