Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(23)

Delta Between Two Patch Sets: Lib/test/test_socketserver.py

Issue 26404: socketserver context manager
Left Patch Set: Created 3 years, 12 months ago
Right Patch Set: Created 3 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 """ 1 """
2 Test suite for socketserver. 2 Test suite for socketserver.
3 """ 3 """
4 4
5 import contextlib 5 import contextlib
6 import os 6 import os
7 import select 7 import select
8 import signal 8 import signal
9 import socket 9 import socket
10 import select 10 import select
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 if proto == socket.AF_INET: 93 if proto == socket.AF_INET:
94 return (HOST, 0) 94 return (HOST, 0)
95 else: 95 else:
96 # XXX: We need a way to tell AF_UNIX to pick its own name 96 # XXX: We need a way to tell AF_UNIX to pick its own name
97 # like AF_INET provides port==0. 97 # like AF_INET provides port==0.
98 dir = None 98 dir = None
99 fn = tempfile.mktemp(prefix='unix_socket.', dir=dir) 99 fn = tempfile.mktemp(prefix='unix_socket.', dir=dir)
100 self.test_files.append(fn) 100 self.test_files.append(fn)
101 return fn 101 return fn
102 102
103 @reap_threads 103 def make_server(self, addr, svrcls, hdlrbase):
104 def run_server(self, svrcls, hdlrbase, testfunc):
105 class MyServer(svrcls): 104 class MyServer(svrcls):
106 def handle_error(self, request, client_address): 105 def handle_error(self, request, client_address):
107 self.close_request(request) 106 self.close_request(request)
108 raise 107 raise
109 108
110 class MyHandler(hdlrbase): 109 class MyHandler(hdlrbase):
111 def handle(self): 110 def handle(self):
112 line = self.rfile.readline() 111 line = self.rfile.readline()
113 self.wfile.write(line) 112 self.wfile.write(line)
114 113
115 if verbose: print("creating server") 114 if verbose: print("creating server")
116 with MyServer(self.pickaddr(svrcls.address_family), MyHandler) as server : 115 server = MyServer(addr, MyHandler)
117 self.assertEqual(server.server_address, server.socket.getsockname()) 116 self.assertEqual(server.server_address, server.socket.getsockname())
118 # We had the OS pick a port, so pull the real address out of 117 return server
119 # the server. 118
120 addr = server.server_address 119 @reap_threads
121 if verbose: 120 def run_server(self, svrcls, hdlrbase, testfunc):
122 print("ADDR =", addr) 121 server = self.make_server(self.pickaddr(svrcls.address_family),
123 print("CLASS =", svrcls) 122 svrcls, hdlrbase)
124 123 # We had the OS pick a port, so pull the real address out of
125 t = threading.Thread( 124 # the server.
126 name='%s serving' % svrcls, 125 addr = server.server_address
127 target=server.serve_forever, 126 if verbose:
128 # Short poll interval to make the test finish quickly. 127 print("ADDR =", addr)
129 # Time between requests is short enough that we won't wake 128 print("CLASS =", svrcls)
130 # up spuriously too many times. 129
131 kwargs={'poll_interval':0.01}) 130 t = threading.Thread(
132 t.daemon = True # In case this function raises. 131 name='%s serving' % svrcls,
133 t.start() 132 target=server.serve_forever,
134 if verbose: print("server running") 133 # Short poll interval to make the test finish quickly.
135 for i in range(3): 134 # Time between requests is short enough that we won't wake
136 if verbose: print("test client", i) 135 # up spuriously too many times.
137 testfunc(svrcls.address_family, addr) 136 kwargs={'poll_interval':0.01})
138 if verbose: print("waiting for server") 137 t.daemon = True # In case this function raises.
139 server.shutdown() 138 t.start()
140 t.join() 139 if verbose: print("server running")
140 for i in range(3):
141 if verbose: print("test client", i)
142 testfunc(svrcls.address_family, addr)
143 if verbose: print("waiting for server")
144 server.shutdown()
145 t.join()
146 server.server_close()
141 self.assertEqual(-1, server.socket.fileno()) 147 self.assertEqual(-1, server.socket.fileno())
142 if verbose: print("done") 148 if verbose: print("done")
143 149
144 def stream_examine(self, proto, addr): 150 def stream_examine(self, proto, addr):
145 s = socket.socket(proto, socket.SOCK_STREAM) 151 s = socket.socket(proto, socket.SOCK_STREAM)
146 s.connect(addr) 152 s.connect(addr)
147 s.sendall(TEST_STR) 153 s.sendall(TEST_STR)
148 buf = data = receive(s, 100) 154 buf = data = receive(s, 100)
149 while data and b'\n' not in buf: 155 while data and b'\n' not in buf:
150 data = receive(s, 100) 156 data = receive(s, 100)
151 buf += data 157 buf += data
152 self.assertEqual(buf, TEST_STR) 158 self.assertEqual(buf, TEST_STR)
153 s.close() 159 s.close()
154 160
155 def dgram_examine(self, proto, addr): 161 def dgram_examine(self, proto, addr):
156 s = socket.socket(proto, socket.SOCK_DGRAM) 162 s = socket.socket(proto, socket.SOCK_DGRAM)
163 if HAVE_UNIX_SOCKETS and proto == socket.AF_UNIX:
164 s.bind(self.pickaddr(proto))
157 s.sendto(TEST_STR, addr) 165 s.sendto(TEST_STR, addr)
158 buf = data = receive(s, 100) 166 buf = data = receive(s, 100)
159 while data and b'\n' not in buf: 167 while data and b'\n' not in buf:
160 data = receive(s, 100) 168 data = receive(s, 100)
161 buf += data 169 buf += data
162 self.assertEqual(buf, TEST_STR) 170 self.assertEqual(buf, TEST_STR)
163 s.close() 171 s.close()
164 172
165 def test_TCPServer(self): 173 def test_TCPServer(self):
166 self.run_server(socketserver.TCPServer, 174 self.run_server(socketserver.TCPServer,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 socketserver.DatagramRequestHandler, 217 socketserver.DatagramRequestHandler,
210 self.dgram_examine) 218 self.dgram_examine)
211 219
212 @requires_forking 220 @requires_forking
213 def test_ForkingUDPServer(self): 221 def test_ForkingUDPServer(self):
214 with simple_subprocess(self): 222 with simple_subprocess(self):
215 self.run_server(socketserver.ForkingUDPServer, 223 self.run_server(socketserver.ForkingUDPServer,
216 socketserver.DatagramRequestHandler, 224 socketserver.DatagramRequestHandler,
217 self.dgram_examine) 225 self.dgram_examine)
218 226
219 # Alas, on Linux (at least) recvfrom() doesn't return a meaningful 227 @requires_unix_sockets
220 # client address so this cannot work: 228 def test_UnixDatagramServer(self):
221 229 self.run_server(socketserver.UnixDatagramServer,
222 # @requires_unix_sockets 230 socketserver.DatagramRequestHandler,
223 # def test_UnixDatagramServer(self): 231 self.dgram_examine)
224 # self.run_server(socketserver.UnixDatagramServer, 232
225 # socketserver.DatagramRequestHandler, 233 @requires_unix_sockets
226 # self.dgram_examine) 234 def test_ThreadingUnixDatagramServer(self):
227 # 235 self.run_server(socketserver.ThreadingUnixDatagramServer,
228 # @requires_unix_sockets 236 socketserver.DatagramRequestHandler,
229 # def test_ThreadingUnixDatagramServer(self): 237 self.dgram_examine)
230 # self.run_server(socketserver.ThreadingUnixDatagramServer, 238
231 # socketserver.DatagramRequestHandler, 239 @requires_unix_sockets
232 # self.dgram_examine) 240 @requires_forking
233 # 241 def test_ForkingUnixDatagramServer(self):
234 # @requires_unix_sockets 242 self.run_server(ForkingUnixDatagramServer,
235 # @requires_forking 243 socketserver.DatagramRequestHandler,
236 # def test_ForkingUnixDatagramServer(self): 244 self.dgram_examine)
237 # self.run_server(socketserver.ForkingUnixDatagramServer,
238 # socketserver.DatagramRequestHandler,
239 # self.dgram_examine)
240 245
241 @reap_threads 246 @reap_threads
242 def test_shutdown(self): 247 def test_shutdown(self):
243 # Issue #2302: shutdown() should always succeed in making an 248 # Issue #2302: shutdown() should always succeed in making an
244 # other thread leave serve_forever(). 249 # other thread leave serve_forever().
245 class MyServer(socketserver.TCPServer): 250 class MyServer(socketserver.TCPServer):
246 pass 251 pass
247 252
248 class MyHandler(socketserver.StreamRequestHandler): 253 class MyHandler(socketserver.StreamRequestHandler):
249 pass 254 pass
(...skipping 17 matching lines...) Expand all
267 def test_tcpserver_bind_leak(self): 272 def test_tcpserver_bind_leak(self):
268 # Issue #22435: the server socket wouldn't be closed if bind()/listen() 273 # Issue #22435: the server socket wouldn't be closed if bind()/listen()
269 # failed. 274 # failed.
270 # Create many servers for which bind() will fail, to see if this result 275 # Create many servers for which bind() will fail, to see if this result
271 # in FD exhaustion. 276 # in FD exhaustion.
272 for i in range(1024): 277 for i in range(1024):
273 with self.assertRaises(OverflowError): 278 with self.assertRaises(OverflowError):
274 socketserver.TCPServer((HOST, -1), 279 socketserver.TCPServer((HOST, -1),
275 socketserver.StreamRequestHandler) 280 socketserver.StreamRequestHandler)
276 281
282 def test_context_manager(self):
283 with socketserver.TCPServer((HOST, 0),
284 socketserver.StreamRequestHandler) as server :
285 pass
286 self.assertEqual(-1, server.socket.fileno())
287
277 288
278 class ErrorHandlerTest(unittest.TestCase): 289 class ErrorHandlerTest(unittest.TestCase):
279 """Test that the servers pass normal exceptions from the handler to 290 """Test that the servers pass normal exceptions from the handler to
280 handle_error(), and that exiting exceptions like SystemExit and 291 handle_error(), and that exiting exceptions like SystemExit and
281 KeyboardInterrupt are not passed.""" 292 KeyboardInterrupt are not passed."""
282 293
283 def tearDown(self): 294 def tearDown(self):
284 test.support.unlink(test.support.TESTFN) 295 test.support.unlink(test.support.TESTFN)
285 296
286 def test_sync_handled(self): 297 def test_sync_handled(self):
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 s = socket.socket(server.address_family, socket.SOCK_STREAM) 406 s = socket.socket(server.address_family, socket.SOCK_STREAM)
396 s.connect(server.server_address) 407 s.connect(server.server_address)
397 s.close() 408 s.close()
398 server.handle_request() 409 server.handle_request()
399 self.assertEqual(server.shutdown_called, 1) 410 self.assertEqual(server.shutdown_called, 1)
400 server.server_close() 411 server.server_close()
401 412
402 413
403 if __name__ == "__main__": 414 if __name__ == "__main__":
404 unittest.main() 415 unittest.main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+