2 Test suite for socketserver.
19 from test
.support
import reap_children
, verbose
20 from test
.support
import TESTFN
as TEST_FILE
22 test
.support
.requires("network")
24 TEST_STR
= b
"hello world\n"
25 HOST
= test
.support
.HOST
27 HAVE_UNIX_SOCKETS
= hasattr(socket
, "AF_UNIX")
28 HAVE_FORKING
= hasattr(os
, "fork") and os
.name
!= "os2"
31 """Call signal.alarm when it exists (i.e. not on Windows)."""
32 if hasattr(signal
, 'alarm'):
35 def receive(sock
, n
, timeout
=20):
36 r
, w
, x
= select
.select([sock
], [], [], timeout
)
40 raise RuntimeError("timed out on %r" % (sock
,))
43 class ForkingUnixStreamServer(socketserver
.ForkingMixIn
,
44 socketserver
.UnixStreamServer
):
47 class ForkingUnixDatagramServer(socketserver
.ForkingMixIn
,
48 socketserver
.UnixDatagramServer
):
52 @contextlib.contextmanager
53 def simple_subprocess(testcase
):
56 # Don't throw an exception; it would be caught by the test harness.
59 pid2
, status
= os
.waitpid(pid
, 0)
60 testcase
.assertEquals(pid2
, pid
)
61 testcase
.assertEquals(72 << 8, status
)
64 class SocketServerTest(unittest
.TestCase
):
65 """Test all socket servers."""
68 signal_alarm(20) # Kill deadlocks after 20 seconds.
73 signal_alarm(0) # Didn't deadlock.
76 for fn
in self
.test_files
:
81 self
.test_files
[:] = []
83 def pickaddr(self
, proto
):
84 if proto
== socket
.AF_INET
:
87 # XXX: We need a way to tell AF_UNIX to pick its own name
88 # like AF_INET provides port==0.
92 fn
= tempfile
.mktemp(prefix
='unix_socket.', dir=dir)
94 # AF_UNIX socket names on OS/2 require a specific prefix
95 # which can't include a drive letter and must also use
96 # backslashes as directory separators
99 if fn
[0] in (os
.sep
, os
.altsep
):
102 fn
= fn
.replace(os
.sep
, os
.altsep
)
104 fn
= fn
.replace(os
.altsep
, os
.sep
)
105 self
.test_files
.append(fn
)
108 def make_server(self
, addr
, svrcls
, hdlrbase
):
109 class MyServer(svrcls
):
110 def handle_error(self
, request
, client_address
):
111 self
.close_request(request
)
115 class MyHandler(hdlrbase
):
117 line
= self
.rfile
.readline()
118 self
.wfile
.write(line
)
120 if verbose
: print("creating server")
121 server
= MyServer(addr
, MyHandler
)
122 self
.assertEquals(server
.server_address
, server
.socket
.getsockname())
125 def run_server(self
, svrcls
, hdlrbase
, testfunc
):
126 server
= self
.make_server(self
.pickaddr(svrcls
.address_family
),
128 # We had the OS pick a port, so pull the real address out of
130 addr
= server
.server_address
132 print("ADDR =", addr
)
133 print("CLASS =", svrcls
)
135 t
= threading
.Thread(
136 name
='%s serving' % svrcls
,
137 target
=server
.serve_forever
,
138 # Short poll interval to make the test finish quickly.
139 # Time between requests is short enough that we won't wake
140 # up spuriously too many times.
141 kwargs
={'poll_interval':0.01})
142 t
.daemon
= True # In case this function raises.
144 if verbose
: print("server running")
146 if verbose
: print("test client", i
)
147 testfunc(svrcls
.address_family
, addr
)
148 if verbose
: print("waiting for server")
151 if verbose
: print("done")
153 def stream_examine(self
, proto
, addr
):
154 s
= socket
.socket(proto
, socket
.SOCK_STREAM
)
157 buf
= data
= receive(s
, 100)
158 while data
and b
'\n' not in buf
:
159 data
= receive(s
, 100)
161 self
.assertEquals(buf
, TEST_STR
)
164 def dgram_examine(self
, proto
, addr
):
165 s
= socket
.socket(proto
, socket
.SOCK_DGRAM
)
166 s
.sendto(TEST_STR
, addr
)
167 buf
= data
= receive(s
, 100)
168 while data
and b
'\n' not in buf
:
169 data
= receive(s
, 100)
171 self
.assertEquals(buf
, TEST_STR
)
174 def test_TCPServer(self
):
175 self
.run_server(socketserver
.TCPServer
,
176 socketserver
.StreamRequestHandler
,
179 def test_ThreadingTCPServer(self
):
180 self
.run_server(socketserver
.ThreadingTCPServer
,
181 socketserver
.StreamRequestHandler
,
185 def test_ForkingTCPServer(self
):
186 with
simple_subprocess(self
):
187 self
.run_server(socketserver
.ForkingTCPServer
,
188 socketserver
.StreamRequestHandler
,
191 if HAVE_UNIX_SOCKETS
:
192 def test_UnixStreamServer(self
):
193 self
.run_server(socketserver
.UnixStreamServer
,
194 socketserver
.StreamRequestHandler
,
197 def test_ThreadingUnixStreamServer(self
):
198 self
.run_server(socketserver
.ThreadingUnixStreamServer
,
199 socketserver
.StreamRequestHandler
,
203 def test_ForkingUnixStreamServer(self
):
204 with
simple_subprocess(self
):
205 self
.run_server(ForkingUnixStreamServer
,
206 socketserver
.StreamRequestHandler
,
209 def test_UDPServer(self
):
210 self
.run_server(socketserver
.UDPServer
,
211 socketserver
.DatagramRequestHandler
,
214 def test_ThreadingUDPServer(self
):
215 self
.run_server(socketserver
.ThreadingUDPServer
,
216 socketserver
.DatagramRequestHandler
,
220 def test_ForkingUDPServer(self
):
221 with
simple_subprocess(self
):
222 self
.run_server(socketserver
.ForkingUDPServer
,
223 socketserver
.DatagramRequestHandler
,
226 # Alas, on Linux (at least) recvfrom() doesn't return a meaningful
227 # client address so this cannot work:
229 # if HAVE_UNIX_SOCKETS:
230 # def test_UnixDatagramServer(self):
231 # self.run_server(socketserver.UnixDatagramServer,
232 # socketserver.DatagramRequestHandler,
233 # self.dgram_examine)
235 # def test_ThreadingUnixDatagramServer(self):
236 # self.run_server(socketserver.ThreadingUnixDatagramServer,
237 # socketserver.DatagramRequestHandler,
238 # self.dgram_examine)
241 # def test_ForkingUnixDatagramServer(self):
242 # self.run_server(socketserver.ForkingUnixDatagramServer,
243 # socketserver.DatagramRequestHandler,
244 # self.dgram_examine)
249 # If the import lock is held, the threads will hang
250 raise unittest
.SkipTest("can't run when import lock is held")
252 test
.support
.run_unittest(SocketServerTest
)
254 if __name__
== "__main__":
256 signal_alarm(3) # Shutdown shouldn't take more than 3 seconds.