blob: 2d6ee2da55b83c6049b3db34636496a69c9756fd [file] [log] [blame]
Guido van Rossum39f1b362001-07-10 11:52:38 +00001# Test suite for SocketServer.py
2
3# XXX This must be run manually -- somehow the I/O redirection of the
4# regression test breaks the test.
5
6from test_support import verbose, verify, TESTFN
7if not verbose:
8 raise ImportError, "test_socketserver can only be run manually"
9
10from SocketServer import *
11import socket
12import select
13import time
14import threading
15import os
16
17NREQ = 3
18DELAY = 0.5
19
20class MyMixinHandler:
21 def handle(self):
22 time.sleep(DELAY)
23 line = self.rfile.readline()
24 time.sleep(DELAY)
25 self.wfile.write(line)
26
27class MyStreamHandler(MyMixinHandler, StreamRequestHandler):
28 pass
29
30class MyDatagramHandler(MyMixinHandler, DatagramRequestHandler):
31 pass
32
33class MyMixinServer:
34 def serve_a_few(self):
35 for i in range(NREQ):
36 self.handle_request()
37 def handle_error(self, request, client_address):
38 self.close_request(request)
39 self.server_close()
40 raise
41
42teststring = "hello world\n"
43
44def receive(sock, n, timeout=20):
45 r, w, x = select.select([sock], [], [], timeout)
46 if sock in r:
47 return sock.recv(n)
48 else:
49 raise RuntimeError, "timed out on %s" % `sock`
50
51def testdgram(proto, addr):
52 s = socket.socket(proto, socket.SOCK_DGRAM)
53 s.sendto(teststring, addr)
54 buf = data = receive(s, 100)
55 while data and '\n' not in buf:
56 data = receive(s, 100)
57 buf += data
58 verify(buf == teststring)
59 s.close()
60
61def teststream(proto, addr):
62 s = socket.socket(proto, socket.SOCK_STREAM)
63 s.connect(addr)
64 s.send(teststring)
65 buf = data = receive(s, 100)
66 while data and '\n' not in buf:
67 data = receive(s, 100)
68 buf += data
69 verify(buf == teststring)
70 s.close()
71
72class ServerThread(threading.Thread):
73 def __init__(self, addr, svrcls, hdlrcls):
74 threading.Thread.__init__(self)
75 self.__addr = addr
76 self.__svrcls = svrcls
77 self.__hdlrcls = hdlrcls
78 def run(self):
79 class svrcls(MyMixinServer, self.__svrcls):
80 pass
81 if verbose: print "thread: creating server"
82 svr = svrcls(self.__addr, self.__hdlrcls)
83 if verbose: print "thread: serving three times"
84 svr.serve_a_few()
85 if verbose: print "thread: done"
86
87seed = 0
88def pickport():
89 global seed
90 seed += 1
91 return 10000 + (os.getpid() % 1000)*10 + seed
92
93host = ""
94testfiles = []
95def pickaddr(proto):
96 if proto == socket.AF_INET:
97 return (host, pickport())
98 else:
99 fn = TESTFN + str(pickport())
100 testfiles.append(fn)
101 return fn
102
103def cleanup():
104 for fn in testfiles:
105 try:
106 os.remove(fn)
107 except os.error:
108 pass
109 testfiles[:] = []
110
111def testloop(proto, servers, hdlrcls, testfunc):
112 for svrcls in servers:
113 addr = pickaddr(proto)
114 if verbose:
115 print "ADDR =", addr
116 print "CLASS =", svrcls
117 t = ServerThread(addr, svrcls, hdlrcls)
118 if verbose: print "server created"
119 t.start()
120 if verbose: print "server running"
121 for i in range(NREQ):
122 time.sleep(DELAY)
123 if verbose: print "test client", i
124 testfunc(proto, addr)
125 if verbose: print "waiting for server"
126 t.join()
127 if verbose: print "done"
128
129tcpservers = [TCPServer, ThreadingTCPServer]
130if hasattr(os, 'fork'):
131 tcpservers.append(ForkingTCPServer)
132udpservers = [UDPServer, ThreadingUDPServer]
133if hasattr(os, 'fork'):
134 udpservers.append(ForkingUDPServer)
135
136if not hasattr(socket, 'AF_UNIX'):
137 streamservers = []
138 dgramservers = []
139else:
140 class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass
141 streamservers = [UnixStreamServer, ThreadingUnixStreamServer,
142 ForkingUnixStreamServer]
143 class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass
144 dgramservers = [UnixDatagramServer, ThreadingUnixDatagramServer,
145 ForkingUnixDatagramServer]
146
147def testall():
148 testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream)
149 testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram)
150 testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream)
151 # Alas, on Linux (at least) recvfrom() doesn't return a meaningful
152 # client address so this cannot work:
153 ##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram)
154
155def main():
156 try:
157 testall()
158 finally:
159 cleanup()
160
161main()