diff options
author | Christian Heimes <christian@cheimes.de> | 2008-02-03 16:51:08 (GMT) |
---|---|---|
committer | Christian Heimes <christian@cheimes.de> | 2008-02-03 16:51:08 (GMT) |
commit | 292d351fc1a7dc9feccd412843832808680a631f (patch) | |
tree | 918a0dea0d70345e0279b9b9649c6e427a076118 /Lib/test/test_socketserver.py | |
parent | ec17d204f963f37da02e6457f676c57fb66db406 (diff) | |
download | cpython-292d351fc1a7dc9feccd412843832808680a631f.zip cpython-292d351fc1a7dc9feccd412843832808680a631f.tar.gz cpython-292d351fc1a7dc9feccd412843832808680a631f.tar.bz2 |
Merged revisions 60481,60485,60489-60520,60523-60527,60530-60533,60535-60538,60540-60551 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
NOTE: I blocked the following revisions:
svnmerge.py block -r 60521,60522,60528,60529,60534,60539
The new tests must be merged with lots of manual work.
........
r60493 | georg.brandl | 2008-02-01 12:59:08 +0100 (Fri, 01 Feb 2008) | 2 lines
Update IPv6 RFC number.
........
r60497 | georg.brandl | 2008-02-01 16:50:15 +0100 (Fri, 01 Feb 2008) | 2 lines
Add link checker builder, written for GHOP by Thomas Lamb.
........
r60500 | georg.brandl | 2008-02-01 19:08:09 +0100 (Fri, 01 Feb 2008) | 2 lines
Rename batch file.
........
r60504 | christian.heimes | 2008-02-01 19:49:26 +0100 (Fri, 01 Feb 2008) | 1 line
More int -> pid_t.
........
r60507 | georg.brandl | 2008-02-01 20:24:01 +0100 (Fri, 01 Feb 2008) | 2 lines
Wording nit.
........
r60510 | georg.brandl | 2008-02-01 21:45:33 +0100 (Fri, 01 Feb 2008) | 2 lines
Update for latest sphinx latex writer.
........
r60511 | raymond.hettinger | 2008-02-01 22:30:23 +0100 (Fri, 01 Feb 2008) | 1 line
Issue #1996: float.as_integer_ratio() should return fraction in lowest terms.
........
r60512 | raymond.hettinger | 2008-02-01 23:15:52 +0100 (Fri, 01 Feb 2008) | 1 line
Integer ratio should return ints instead of longs whereever possible.
........
r60513 | raymond.hettinger | 2008-02-01 23:22:50 +0100 (Fri, 01 Feb 2008) | 1 line
labs() takes a long for an input.
........
r60514 | raymond.hettinger | 2008-02-01 23:42:59 +0100 (Fri, 01 Feb 2008) | 1 line
Test round-trip on float.as_integer_ratio() and float.__truediv__().
........
r60515 | marc-andre.lemburg | 2008-02-01 23:58:17 +0100 (Fri, 01 Feb 2008) | 3 lines
Bump distutils version number to match Python version.
........
r60516 | raymond.hettinger | 2008-02-02 00:12:19 +0100 (Sat, 02 Feb 2008) | 1 line
Fix int/long typecase. Add check for non-binary floating point.
........
r60517 | raymond.hettinger | 2008-02-02 00:45:44 +0100 (Sat, 02 Feb 2008) | 1 line
Add protection from weirdness while scaling the mantissa to an integer.
........
r60518 | raymond.hettinger | 2008-02-02 06:11:40 +0100 (Sat, 02 Feb 2008) | 1 line
Simpler solution to handling non-IEEE 754 environments.
........
r60519 | raymond.hettinger | 2008-02-02 06:24:44 +0100 (Sat, 02 Feb 2008) | 1 line
Neaten-up a bit.
........
r60520 | georg.brandl | 2008-02-02 10:56:20 +0100 (Sat, 02 Feb 2008) | 2 lines
Amendments to the urllib2 docs, written for GHOP by Thomas Lamb.
........
r60525 | georg.brandl | 2008-02-02 11:49:58 +0100 (Sat, 02 Feb 2008) | 3 lines
Add email example how to send a multipart message.
Written for GHOP by Martin Matejek.
........
r60526 | georg.brandl | 2008-02-02 12:05:00 +0100 (Sat, 02 Feb 2008) | 2 lines
Rewrite test_socketserver as unittest, written for GHOP by Benjamin Petersen.
........
r60527 | georg.brandl | 2008-02-02 12:05:34 +0100 (Sat, 02 Feb 2008) | 2 lines
Add GHOP contributor.
........
r60530 | mark.dickinson | 2008-02-02 18:16:13 +0100 (Sat, 02 Feb 2008) | 2 lines
Make the Rational constructor accept '3.' and '.2' as well as '3.2'.
........
r60531 | neal.norwitz | 2008-02-02 19:52:51 +0100 (Sat, 02 Feb 2008) | 1 line
Update the leaky tests (ie, ignore these tests if they report leaks). This version has been running for a while.
........
r60533 | skip.montanaro | 2008-02-02 20:11:57 +0100 (Sat, 02 Feb 2008) | 7 lines
Split the refleak mail body into two parts, the first being those failing
tests which are deemed more important issues, the second those which are
known to have difficult to solve problems and are generally expected to
leak. Hopefully this doesn't break the script...
........
r60535 | georg.brandl | 2008-02-03 01:04:50 +0100 (Sun, 03 Feb 2008) | 3 lines
Wait for a delay before reaping children -- this should fix the
test_socketserver failures on several platforms.
........
r60536 | brett.cannon | 2008-02-03 03:07:55 +0100 (Sun, 03 Feb 2008) | 2 lines
Fix a minor typo.
........
r60537 | brett.cannon | 2008-02-03 03:08:45 +0100 (Sun, 03 Feb 2008) | 3 lines
Directories from CPPFLAGS and LDFLAGS were being added in the reverse order for
searches as to how they were listed in the environment variable.
........
r60538 | brett.cannon | 2008-02-03 03:34:14 +0100 (Sun, 03 Feb 2008) | 2 lines
Remove extra tick marks and add a missing closing parenthesis.
........
r60540 | andrew.macintyre | 2008-02-03 07:58:06 +0100 (Sun, 03 Feb 2008) | 2 lines
Update OS/2 EMX build bits for 2.6.
........
r60541 | andrew.macintyre | 2008-02-03 08:01:11 +0100 (Sun, 03 Feb 2008) | 2 lines
Rename module definition file to reflect v2.6.
........
r60542 | andrew.macintyre | 2008-02-03 08:07:31 +0100 (Sun, 03 Feb 2008) | 6 lines
The wrapper function is supposed to be for spawnvpe() so that's
what we should call [this wrapper only available on OS/2].
Backport candidate to 2.5.
........
r60544 | gregory.p.smith | 2008-02-03 08:20:53 +0100 (Sun, 03 Feb 2008) | 6 lines
Merge this fix from the pybsddb tree:
r293 | jcea | 2008-01-31 01:08:19 -0800 (Thu, 31 Jan 2008) | 4 lines
Solved memory leak when using cursors with
databases without environment.
........
r60546 | gregory.p.smith | 2008-02-03 09:01:46 +0100 (Sun, 03 Feb 2008) | 2 lines
remove a repeated occurance of a hardcoded berkeleydb library version number
........
r60549 | brett.cannon | 2008-02-03 10:59:21 +0100 (Sun, 03 Feb 2008) | 2 lines
Add an entry for r60537.
........
r60550 | georg.brandl | 2008-02-03 13:29:00 +0100 (Sun, 03 Feb 2008) | 2 lines
#2003: fix sentence.
........
r60551 | christian.heimes | 2008-02-03 15:34:18 +0100 (Sun, 03 Feb 2008) | 2 lines
Fixed paths to Windows build directories in build_ext.py
Use vsbuild instead of devenv in build.bat and _bsddb.vcproj
........
Diffstat (limited to 'Lib/test/test_socketserver.py')
-rw-r--r-- | Lib/test/test_socketserver.py | 290 |
1 files changed, 174 insertions, 116 deletions
diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 3e0c7a4..5ae8e6d 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -1,20 +1,32 @@ -# Test suite for SocketServer.py +""" +Test suite for SocketServer.py. +""" -from test import test_support -from test.test_support import (verbose, verify, TESTFN, TestSkipped, - reap_children) -test_support.requires('network') - -from SocketServer import * +import os import socket import errno +import imp import select import time import threading -import os +from functools import wraps +import unittest +import SocketServer + +import test.test_support +from test.test_support import reap_children, verbose, TestSkipped +from test.test_support import TESTFN as TEST_FILE + +test.test_support.requires("network") NREQ = 3 DELAY = 0.5 +TEST_STR = b"hello world\n" +HOST = "localhost" + +HAVE_UNIX_SOCKETS = hasattr(socket, "AF_UNIX") +HAVE_FORKING = hasattr(os, "fork") and os.name != "os2" + class MyMixinHandler: def handle(self): @@ -23,23 +35,41 @@ class MyMixinHandler: time.sleep(DELAY) self.wfile.write(line) -class MyStreamHandler(MyMixinHandler, StreamRequestHandler): + +def receive(sock, n, timeout=20): + r, w, x = select.select([sock], [], [], timeout) + if sock in r: + return sock.recv(n) + else: + raise RuntimeError("timed out on %r" % (sock,)) + + +class MyStreamHandler(MyMixinHandler, SocketServer.StreamRequestHandler): pass -class MyDatagramHandler(MyMixinHandler, DatagramRequestHandler): +class MyDatagramHandler(MyMixinHandler, + SocketServer.DatagramRequestHandler): pass +class ForkingUnixStreamServer(SocketServer.ForkingMixIn, + SocketServer.UnixStreamServer): + pass + +class ForkingUnixDatagramServer(SocketServer.ForkingMixIn, + SocketServer.UnixDatagramServer): + pass + + class MyMixinServer: def serve_a_few(self): for i in range(NREQ): self.handle_request() + def handle_error(self, request, client_address): self.close_request(request) self.server_close() raise -teststring = b"hello world\n" - def receive(sock, n, timeout=20): r, w, x = select.select([sock], [], [], timeout) if sock in r: @@ -75,6 +105,7 @@ class ServerThread(threading.Thread): self.__svrcls = svrcls self.__hdlrcls = hdlrcls self.ready = threading.Event() + def run(self): class svrcls(MyMixinServer, self.__svrcls): pass @@ -93,64 +124,8 @@ class ServerThread(threading.Thread): svr.serve_a_few() if verbose: print("thread: done") -seed = 0 -def pickport(): - global seed - seed += 1 - return 10000 + (os.getpid() % 1000)*10 + seed - -host = "localhost" -testfiles = [] -def pickaddr(proto): - if proto == socket.AF_INET: - return (host, pickport()) - else: - fn = TESTFN + str(pickport()) - if os.name == 'os2': - # AF_UNIX socket names on OS/2 require a specific prefix - # which can't include a drive letter and must also use - # backslashes as directory separators - if fn[1] == ':': - fn = fn[2:] - if fn[0] in (os.sep, os.altsep): - fn = fn[1:] - fn = os.path.join('\socket', fn) - if os.sep == '/': - fn = fn.replace(os.sep, os.altsep) - else: - fn = fn.replace(os.altsep, os.sep) - testfiles.append(fn) - return fn - -def cleanup(): - for fn in testfiles: - try: - os.remove(fn) - except os.error: - pass - testfiles[:] = [] - -def testloop(proto, servers, hdlrcls, testfunc): - for svrcls in servers: - addr = pickaddr(proto) - if verbose: - print("ADDR =", addr) - print("CLASS =", svrcls) - t = ServerThread(addr, svrcls, hdlrcls) - if verbose: print("server created") - t.start() - if verbose: print("server running") - for i in range(NREQ): - t.ready.wait(10*DELAY) - if not t.ready.isSet(): - raise RuntimeError("Server not ready within a reasonable time") - if verbose: print("test client", i) - testfunc(proto, addr) - if verbose: print("waiting for server") - t.join() - if verbose: print("done") - -class ForgivingTCPServer(TCPServer): + +class ForgivingTCPServer(SocketServer.TCPServer): # prevent errors if another process is using the port we want def server_bind(self): host, default_port = self.server_address @@ -160,7 +135,7 @@ class ForgivingTCPServer(TCPServer): for port in [default_port, 3434, 8798, 23833]: try: self.server_address = host, port - TCPServer.server_bind(self) + SocketServer.TCPServer.server_bind(self) break except socket.error as e: (err, msg) = e @@ -168,56 +143,139 @@ class ForgivingTCPServer(TCPServer): raise print(' WARNING: failed to listen on port %d, trying another' % port, file=sys.__stderr__) -tcpservers = [ForgivingTCPServer, ThreadingTCPServer] -if hasattr(os, 'fork') and os.name not in ('os2',): - tcpservers.append(ForkingTCPServer) -udpservers = [UDPServer, ThreadingUDPServer] -if hasattr(os, 'fork') and os.name not in ('os2',): - udpservers.append(ForkingUDPServer) - -if not hasattr(socket, 'AF_UNIX'): - streamservers = [] - dgramservers = [] -else: - class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass - streamservers = [UnixStreamServer, ThreadingUnixStreamServer] - if hasattr(os, 'fork') and os.name not in ('os2',): - streamservers.append(ForkingUnixStreamServer) - class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass - dgramservers = [UnixDatagramServer, ThreadingUnixDatagramServer] - if hasattr(os, 'fork') and os.name not in ('os2',): - dgramservers.append(ForkingUnixDatagramServer) - -def sloppy_cleanup(): - # See http://python.org/sf/1540386 - # We need to reap children here otherwise a child from one server - # can be left running for the next server and cause a test failure. - time.sleep(DELAY) - reap_children() - -def testall(): - testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream) - sloppy_cleanup() - testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram) - if hasattr(socket, 'AF_UNIX'): - sloppy_cleanup() - testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream) - # Alas, on Linux (at least) recvfrom() doesn't return a meaningful - # client address so this cannot work: - ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram) +class SocketServerTest(unittest.TestCase): + """Test all socket servers.""" + + def setUp(self): + self.port_seed = 0 + self.test_files = [] + + def tearDown(self): + time.sleep(DELAY) + reap_children() + + for fn in self.test_files: + try: + os.remove(fn) + except os.error: + pass + self.test_files[:] = [] + + def pickport(self): + self.port_seed += 1 + return 10000 + (os.getpid() % 1000)*10 + self.port_seed + + def pickaddr(self, proto): + if proto == socket.AF_INET: + return (HOST, self.pickport()) + else: + fn = TEST_FILE + str(self.pickport()) + if os.name == 'os2': + # AF_UNIX socket names on OS/2 require a specific prefix + # which can't include a drive letter and must also use + # backslashes as directory separators + if fn[1] == ':': + fn = fn[2:] + if fn[0] in (os.sep, os.altsep): + fn = fn[1:] + fn = os.path.join('\socket', fn) + if os.sep == '/': + fn = fn.replace(os.sep, os.altsep) + else: + fn = fn.replace(os.altsep, os.sep) + self.test_files.append(fn) + return fn + + def run_servers(self, proto, servers, hdlrcls, testfunc): + for svrcls in servers: + addr = self.pickaddr(proto) + if verbose: + print "ADDR =", addr + print "CLASS =", svrcls + t = ServerThread(addr, svrcls, hdlrcls) + if verbose: print "server created" + t.start() + if verbose: print "server running" + for i in range(NREQ): + t.ready.wait(10*DELAY) + self.assert_(t.ready.isSet(), + "Server not ready within a reasonable time") + if verbose: print "test client", i + testfunc(proto, addr) + if verbose: print "waiting for server" + t.join() + if verbose: print "done" + + def stream_examine(self, proto, addr): + s = socket.socket(proto, socket.SOCK_STREAM) + s.connect(addr) + s.sendall(TEST_STR) + buf = data = receive(s, 100) + while data and '\n' not in buf: + data = receive(s, 100) + buf += data + self.assertEquals(buf, TEST_STR) + s.close() + + def dgram_examine(self, proto, addr): + s = socket.socket(proto, socket.SOCK_DGRAM) + s.sendto(TEST_STR, addr) + buf = data = receive(s, 100) + while data and '\n' not in buf: + data = receive(s, 100) + buf += data + self.assertEquals(buf, TEST_STR) + s.close() + + def test_TCPServers(self): + # Test SocketServer.TCPServer + servers = [ForgivingTCPServer, SocketServer.ThreadingTCPServer] + if HAVE_FORKING: + servers.append(SocketServer.ForkingTCPServer) + self.run_servers(socket.AF_INET, servers, + MyStreamHandler, self.stream_examine) + + def test_UDPServers(self): + # Test SocketServer.UDPServer + servers = [SocketServer.UDPServer, + SocketServer.ThreadingUDPServer] + if HAVE_FORKING: + servers.append(SocketServer.ForkingUDPServer) + self.run_servers(socket.AF_INET, servers, MyDatagramHandler, + self.dgram_examine) + + def test_stream_servers(self): + # Test SocketServer's stream servers + if not HAVE_UNIX_SOCKETS: + return + servers = [SocketServer.UnixStreamServer, + SocketServer.ThreadingUnixStreamServer] + if HAVE_FORKING: + servers.append(ForkingUnixStreamServer) + self.run_servers(socket.AF_UNIX, servers, MyStreamHandler, + self.stream_examine) + + # Alas, on Linux (at least) recvfrom() doesn't return a meaningful + # client address so this cannot work: + + # def test_dgram_servers(self): + # # Test SocketServer.UnixDatagramServer + # if not HAVE_UNIX_SOCKETS: + # return + # servers = [SocketServer.UnixDatagramServer, + # SocketServer.ThreadingUnixDatagramServer] + # if HAVE_FORKING: + # servers.append(ForkingUnixDatagramServer) + # self.run_servers(socket.AF_UNIX, servers, MyDatagramHandler, + # self.dgram_examine) + def test_main(): - import imp if imp.lock_held(): - # If the import lock is held, the threads will hang. + # If the import lock is held, the threads will hang raise TestSkipped("can't run when import lock is held") - reap_children() - try: - testall() - finally: - cleanup() - reap_children() + test.test_support.run_unittest(SocketServerTest) if __name__ == "__main__": test_main() |