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