test_socketserver.py revision 15ebc88d87d2ff8f520581a9f6a6816d78a7e504
1292d351fc1a7dc9feccd412843832808680a631fChristian Heimes"""
2292d351fc1a7dc9feccd412843832808680a631fChristian HeimesTest suite for SocketServer.py.
3292d351fc1a7dc9feccd412843832808680a631fChristian Heimes"""
439f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
5292d351fc1a7dc9feccd412843832808680a631fChristian Heimesimport os
639f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumimport socket
70e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Woutersimport errno
8292d351fc1a7dc9feccd412843832808680a631fChristian Heimesimport imp
939f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumimport select
1039f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumimport time
1139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumimport threading
12292d351fc1a7dc9feccd412843832808680a631fChristian Heimesfrom functools import wraps
13292d351fc1a7dc9feccd412843832808680a631fChristian Heimesimport unittest
14292d351fc1a7dc9feccd412843832808680a631fChristian Heimesimport SocketServer
15292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
16292d351fc1a7dc9feccd412843832808680a631fChristian Heimesimport test.test_support
17292d351fc1a7dc9feccd412843832808680a631fChristian Heimesfrom test.test_support import reap_children, verbose, TestSkipped
18292d351fc1a7dc9feccd412843832808680a631fChristian Heimesfrom test.test_support import TESTFN as TEST_FILE
19292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
20292d351fc1a7dc9feccd412843832808680a631fChristian Heimestest.test_support.requires("network")
2139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
2239f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van RossumNREQ = 3
2339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van RossumDELAY = 0.5
24292d351fc1a7dc9feccd412843832808680a631fChristian HeimesTEST_STR = b"hello world\n"
25292d351fc1a7dc9feccd412843832808680a631fChristian HeimesHOST = "localhost"
26292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
27292d351fc1a7dc9feccd412843832808680a631fChristian HeimesHAVE_UNIX_SOCKETS = hasattr(socket, "AF_UNIX")
28292d351fc1a7dc9feccd412843832808680a631fChristian HeimesHAVE_FORKING = hasattr(os, "fork") and os.name != "os2"
29292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
3039f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
3139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumclass MyMixinHandler:
3239f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    def handle(self):
3339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        time.sleep(DELAY)
3439f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        line = self.rfile.readline()
3539f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        time.sleep(DELAY)
3639f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        self.wfile.write(line)
3739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
38292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
39292d351fc1a7dc9feccd412843832808680a631fChristian Heimesdef receive(sock, n, timeout=20):
40292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    r, w, x = select.select([sock], [], [], timeout)
41292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    if sock in r:
42292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        return sock.recv(n)
43292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    else:
44292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        raise RuntimeError("timed out on %r" % (sock,))
45292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
46292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
47292d351fc1a7dc9feccd412843832808680a631fChristian Heimesclass MyStreamHandler(MyMixinHandler, SocketServer.StreamRequestHandler):
4839f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    pass
4939f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
50292d351fc1a7dc9feccd412843832808680a631fChristian Heimesclass MyDatagramHandler(MyMixinHandler,
51292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    SocketServer.DatagramRequestHandler):
5239f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    pass
5339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
5415ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimesif HAVE_UNIX_SOCKETS:
5515ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes    class ForkingUnixStreamServer(SocketServer.ForkingMixIn,
5615ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes                                  SocketServer.UnixStreamServer):
5715ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes        pass
5815ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes
5915ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes    class ForkingUnixDatagramServer(SocketServer.ForkingMixIn,
6015ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes                                    SocketServer.UnixDatagramServer):
6115ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes        pass
62292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
63292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
6439f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumclass MyMixinServer:
6539f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    def serve_a_few(self):
6639f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        for i in range(NREQ):
6739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum            self.handle_request()
68292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
6939f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    def handle_error(self, request, client_address):
7039f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        self.close_request(request)
7139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        self.server_close()
7239f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        raise
7339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
7439f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumdef receive(sock, n, timeout=20):
7539f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    r, w, x = select.select([sock], [], [], timeout)
7639f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    if sock in r:
7739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        return sock.recv(n)
7839f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    else:
793add4d78ff9f5de02e2c0de09efe9a9b5317539fCollin Winter        raise RuntimeError("timed out on %r" % (sock,))
8039f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
8139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumdef testdgram(proto, addr):
8239f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    s = socket.socket(proto, socket.SOCK_DGRAM)
8339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    s.sendto(teststring, addr)
8439f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    buf = data = receive(s, 100)
8515863ea07ab4eed2d91ce55b274245e8d420723dGuido van Rossum    while data and b'\n' not in buf:
8639f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        data = receive(s, 100)
8739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        buf += data
8839f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    verify(buf == teststring)
8939f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    s.close()
9039f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
9139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumdef teststream(proto, addr):
9239f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    s = socket.socket(proto, socket.SOCK_STREAM)
9339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    s.connect(addr)
949bd1401bbbbc828b457cda4a5753d643333e08cbGuido van Rossum    s.sendall(teststring)
9539f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    buf = data = receive(s, 100)
9615863ea07ab4eed2d91ce55b274245e8d420723dGuido van Rossum    while data and b'\n' not in buf:
9739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        data = receive(s, 100)
9839f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        buf += data
9939f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    verify(buf == teststring)
10039f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    s.close()
10139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
10239f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumclass ServerThread(threading.Thread):
10339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    def __init__(self, addr, svrcls, hdlrcls):
10439f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        threading.Thread.__init__(self)
10539f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        self.__addr = addr
10639f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        self.__svrcls = svrcls
10739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        self.__hdlrcls = hdlrcls
108d8faa3654c2887eaa146dcdb553a9f9793bd2e5aGuido van Rossum        self.ready = threading.Event()
109292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
11039f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum    def run(self):
11139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        class svrcls(MyMixinServer, self.__svrcls):
11239f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum            pass
113be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        if verbose: print("thread: creating server")
11439f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        svr = svrcls(self.__addr, self.__hdlrcls)
1150e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        # pull the address out of the server in case it changed
1160e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        # this can happen if another process is using the port
117d8faa3654c2887eaa146dcdb553a9f9793bd2e5aGuido van Rossum        addr = svr.server_address
1180e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        if addr:
1190e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters            self.__addr = addr
120d8faa3654c2887eaa146dcdb553a9f9793bd2e5aGuido van Rossum            if self.__addr != svr.socket.getsockname():
121d8faa3654c2887eaa146dcdb553a9f9793bd2e5aGuido van Rossum                raise RuntimeError('server_address was %s, expected %s' %
122d8faa3654c2887eaa146dcdb553a9f9793bd2e5aGuido van Rossum                                       (self.__addr, svr.socket.getsockname()))
123d8faa3654c2887eaa146dcdb553a9f9793bd2e5aGuido van Rossum        self.ready.set()
124be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        if verbose: print("thread: serving three times")
12539f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum        svr.serve_a_few()
126be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum        if verbose: print("thread: done")
12739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
128292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
129292d351fc1a7dc9feccd412843832808680a631fChristian Heimesclass ForgivingTCPServer(SocketServer.TCPServer):
1300e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters    # prevent errors if another process is using the port we want
1310e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters    def server_bind(self):
1320e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        host, default_port = self.server_address
1330e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        # this code shamelessly stolen from test.test_support
1340e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        # the ports were changed to protect the innocent
1350e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        import sys
1360e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters        for port in [default_port, 3434, 8798, 23833]:
1370e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters            try:
1380e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters                self.server_address = host, port
139292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                SocketServer.TCPServer.server_bind(self)
1400e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters                break
141b940e113bf90ff71b0ef57414ea2beea9d2a4bc0Guido van Rossum            except socket.error as e:
142b940e113bf90ff71b0ef57414ea2beea9d2a4bc0Guido van Rossum                (err, msg) = e
1430e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters                if err != errno.EADDRINUSE:
1440e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters                    raise
145be19ed77ddb047e02fe94d142181062af6d99dccGuido van Rossum                print('  WARNING: failed to listen on port %d, trying another' % port, file=sys.__stderr__)
1460e3f591aeeef9ed715f8770320f4c4c7332a8794Thomas Wouters
147292d351fc1a7dc9feccd412843832808680a631fChristian Heimesclass SocketServerTest(unittest.TestCase):
148292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    """Test all socket servers."""
149292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
150292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def setUp(self):
151292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.port_seed = 0
152292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.test_files = []
153292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
154292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def tearDown(self):
155292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        time.sleep(DELAY)
156292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        reap_children()
157292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
158292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        for fn in self.test_files:
159292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            try:
160292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                os.remove(fn)
161292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            except os.error:
162292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                pass
163292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.test_files[:] = []
164292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
165292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def pickport(self):
166292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.port_seed += 1
167292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        return 10000 + (os.getpid() % 1000)*10 + self.port_seed
168292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
169292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def pickaddr(self, proto):
170292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        if proto == socket.AF_INET:
171292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            return (HOST, self.pickport())
172292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        else:
173292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            fn = TEST_FILE + str(self.pickport())
174292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            if os.name == 'os2':
175292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                # AF_UNIX socket names on OS/2 require a specific prefix
176292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                # which can't include a drive letter and must also use
177292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                # backslashes as directory separators
178292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                if fn[1] == ':':
179292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                    fn = fn[2:]
180292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                if fn[0] in (os.sep, os.altsep):
181292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                    fn = fn[1:]
182292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                fn = os.path.join('\socket', fn)
183292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                if os.sep == '/':
184292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                    fn = fn.replace(os.sep, os.altsep)
185292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                else:
186292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                    fn = fn.replace(os.altsep, os.sep)
187292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            self.test_files.append(fn)
188292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            return fn
189292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
190292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def run_servers(self, proto, servers, hdlrcls, testfunc):
191292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        for svrcls in servers:
192292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            addr = self.pickaddr(proto)
193292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            if verbose:
194fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes                print("ADDR =", addr)
195fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes                print("CLASS =", svrcls)
196292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            t = ServerThread(addr, svrcls, hdlrcls)
197fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes            if verbose: print("server created")
198292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            t.start()
199fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes            if verbose: print("server running")
200292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            for i in range(NREQ):
201292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                t.ready.wait(10*DELAY)
202292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                self.assert_(t.ready.isSet(),
203292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                    "Server not ready within a reasonable time")
204fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes                if verbose: print("test client", i)
205292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                testfunc(proto, addr)
206fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes            if verbose: print("waiting for server")
207292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            t.join()
208fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes            if verbose: print("done")
209292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
210292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def stream_examine(self, proto, addr):
211292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        s = socket.socket(proto, socket.SOCK_STREAM)
212292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        s.connect(addr)
213292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        s.sendall(TEST_STR)
214292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        buf = data = receive(s, 100)
215fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes        while data and b'\n' not in buf:
216292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            data = receive(s, 100)
217292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            buf += data
218292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.assertEquals(buf, TEST_STR)
219292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        s.close()
220292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
221292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def dgram_examine(self, proto, addr):
222292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        s = socket.socket(proto, socket.SOCK_DGRAM)
223292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        s.sendto(TEST_STR, addr)
224292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        buf = data = receive(s, 100)
225fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes        while data and b'\n' not in buf:
226292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            data = receive(s, 100)
227292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            buf += data
228292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.assertEquals(buf, TEST_STR)
229292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        s.close()
230292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
231292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def test_TCPServers(self):
232292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        # Test SocketServer.TCPServer
233292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        servers = [ForgivingTCPServer, SocketServer.ThreadingTCPServer]
234292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        if HAVE_FORKING:
235292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            servers.append(SocketServer.ForkingTCPServer)
236292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.run_servers(socket.AF_INET, servers,
237292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                         MyStreamHandler, self.stream_examine)
238292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
239292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def test_UDPServers(self):
240292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        # Test SocketServer.UDPServer
241292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        servers = [SocketServer.UDPServer,
242292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                   SocketServer.ThreadingUDPServer]
243292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        if HAVE_FORKING:
244292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            servers.append(SocketServer.ForkingUDPServer)
245292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.run_servers(socket.AF_INET, servers, MyDatagramHandler,
246292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                         self.dgram_examine)
247292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
248292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    def test_stream_servers(self):
249292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        # Test SocketServer's stream servers
250292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        if not HAVE_UNIX_SOCKETS:
251292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            return
252292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        servers = [SocketServer.UnixStreamServer,
253292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                   SocketServer.ThreadingUnixStreamServer]
254292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        if HAVE_FORKING:
255292d351fc1a7dc9feccd412843832808680a631fChristian Heimes            servers.append(ForkingUnixStreamServer)
256292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        self.run_servers(socket.AF_UNIX, servers, MyStreamHandler,
257292d351fc1a7dc9feccd412843832808680a631fChristian Heimes                         self.stream_examine)
258292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
259292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    # Alas, on Linux (at least) recvfrom() doesn't return a meaningful
260292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    # client address so this cannot work:
261292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
262292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    # def test_dgram_servers(self):
263292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #     # Test SocketServer.UnixDatagramServer
264292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #     if not HAVE_UNIX_SOCKETS:
265292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #         return
266292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #     servers = [SocketServer.UnixDatagramServer,
267292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #                SocketServer.ThreadingUnixDatagramServer]
268292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #     if HAVE_FORKING:
269292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #         servers.append(ForkingUnixDatagramServer)
270292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #     self.run_servers(socket.AF_UNIX, servers, MyDatagramHandler,
271292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    #                      self.dgram_examine)
272292d351fc1a7dc9feccd412843832808680a631fChristian Heimes
27339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
274a9f6f22f72833e49d01539f37effab67aa21391bTim Petersdef test_main():
275a9f6f22f72833e49d01539f37effab67aa21391bTim Peters    if imp.lock_held():
276292d351fc1a7dc9feccd412843832808680a631fChristian Heimes        # If the import lock is held, the threads will hang
277a9f6f22f72833e49d01539f37effab67aa21391bTim Peters        raise TestSkipped("can't run when import lock is held")
278a9f6f22f72833e49d01539f37effab67aa21391bTim Peters
279292d351fc1a7dc9feccd412843832808680a631fChristian Heimes    test.test_support.run_unittest(SocketServerTest)
28039f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum
281a9f6f22f72833e49d01539f37effab67aa21391bTim Petersif __name__ == "__main__":
282a9f6f22f72833e49d01539f37effab67aa21391bTim Peters    test_main()
283