1292d351fc1a7dc9feccd412843832808680a631fChristian Heimes""" 2ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre VassalottiTest suite for socketserver. 3292d351fc1a7dc9feccd412843832808680a631fChristian Heimes""" 439f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum 570e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimesimport contextlib 634eeed42901666fce099947f93dfdfc05411f286Martin Panterimport io 79e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimesimport os 839f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossumimport select 99e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimesimport signal 109e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimesimport socket 119e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimesimport tempfile 12292d351fc1a7dc9feccd412843832808680a631fChristian Heimesimport unittest 13ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalottiimport socketserver 14292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 15ee8712cda46338d223509cc5751fd36509ad3860Benjamin Petersonimport test.support 16c00d4b437d544268b699fc57fe9e7c57ae89f1b3Antoine Pitroufrom test.support import reap_children, reap_threads, verbose 1745df820591c319061a625bdd99d7bbd2a26f8117Victor Stinnertry: 1845df820591c319061a625bdd99d7bbd2a26f8117Victor Stinner import threading 1945df820591c319061a625bdd99d7bbd2a26f8117Victor Stinnerexcept ImportError: 2045df820591c319061a625bdd99d7bbd2a26f8117Victor Stinner threading = None 21292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 22ee8712cda46338d223509cc5751fd36509ad3860Benjamin Petersontest.support.requires("network") 2339f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum 24292d351fc1a7dc9feccd412843832808680a631fChristian HeimesTEST_STR = b"hello world\n" 25ee8712cda46338d223509cc5751fd36509ad3860Benjamin PetersonHOST = test.support.HOST 26292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 27292d351fc1a7dc9feccd412843832808680a631fChristian HeimesHAVE_UNIX_SOCKETS = hasattr(socket, "AF_UNIX") 2843767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchakarequires_unix_sockets = unittest.skipUnless(HAVE_UNIX_SOCKETS, 2943767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka 'requires Unix sockets') 30f1af7057208da7b3d15703645688fea971a4fb5eJesus CeaHAVE_FORKING = hasattr(os, "fork") 3143767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchakarequires_forking = unittest.skipUnless(HAVE_FORKING, 'requires forking') 32292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 33dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimesdef signal_alarm(n): 34dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes """Call signal.alarm when it exists (i.e. not on Windows).""" 35dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes if hasattr(signal, 'alarm'): 36dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes signal.alarm(n) 3739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum 38f18d6f3f443bdfe3f349b2f49231a3c08a5b2d3fAntoine Pitrou# Remember real select() to avoid interferences with mocking 39f18d6f3f443bdfe3f349b2f49231a3c08a5b2d3fAntoine Pitrou_real_select = select.select 40f18d6f3f443bdfe3f349b2f49231a3c08a5b2d3fAntoine Pitrou 41292d351fc1a7dc9feccd412843832808680a631fChristian Heimesdef receive(sock, n, timeout=20): 42f18d6f3f443bdfe3f349b2f49231a3c08a5b2d3fAntoine Pitrou r, w, x = _real_select([sock], [], [], timeout) 43292d351fc1a7dc9feccd412843832808680a631fChristian Heimes if sock in r: 44292d351fc1a7dc9feccd412843832808680a631fChristian Heimes return sock.recv(n) 45292d351fc1a7dc9feccd412843832808680a631fChristian Heimes else: 46292d351fc1a7dc9feccd412843832808680a631fChristian Heimes raise RuntimeError("timed out on %r" % (sock,)) 47292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 48a945969d717dc8fcb5ca22691f98198b5173b740Gregory P. Smith ext:(%if HAVE_UNIX_SOCKETS and HAVE_FORKING: 49ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti class ForkingUnixStreamServer(socketserver.ForkingMixIn, 50ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti socketserver.UnixStreamServer): 5115ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes pass 5215ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes 53ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti class ForkingUnixDatagramServer(socketserver.ForkingMixIn, 54ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti socketserver.UnixDatagramServer): 5515ebc88d87d2ff8f520581a9f6a6816d78a7e504Christian Heimes pass 56292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 57292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 5870e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimes@contextlib.contextmanager 5970e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimesdef simple_subprocess(testcase): 60d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter """Tests that a custom child process is not waited on (Issue 1540386)""" 6170e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimes pid = os.fork() 6270e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimes if pid == 0: 63737fb89dd15e4db6ef30d25963e774ae09cc49dcAndrew Svetlov # Don't raise an exception; it would be caught by the test harness. 6470e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimes os._exit(72) 6570e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimes yield None 6670e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimes pid2, status = os.waitpid(pid, 0) 67b3aedd48621ed9d33b5f42f946b256bce4a50673Ezio Melotti testcase.assertEqual(pid2, pid) 68b3aedd48621ed9d33b5f42f946b256bce4a50673Ezio Melotti testcase.assertEqual(72 << 8, status) 6970e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimes 7070e7ea23f18aacc31f429787645ff8c074c0ad86Christian Heimes 715f22e72e6dc5e4fdebd6cd41a7f9692f986ce9d4Victor Stinner@unittest.skipUnless(threading, 'Threading required for this test.') 72292d351fc1a7dc9feccd412843832808680a631fChristian Heimesclass SocketServerTest(unittest.TestCase): 73292d351fc1a7dc9feccd412843832808680a631fChristian Heimes """Test all socket servers.""" 74292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 75292d351fc1a7dc9feccd412843832808680a631fChristian Heimes def setUp(self): 765702ae6f3f3884339be54f92ce26503373543caeVictor Stinner signal_alarm(60) # Kill deadlocks after 60 seconds. 77292d351fc1a7dc9feccd412843832808680a631fChristian Heimes self.port_seed = 0 78292d351fc1a7dc9feccd412843832808680a631fChristian Heimes self.test_files = [] 79292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 80292d351fc1a7dc9feccd412843832808680a631fChristian Heimes def tearDown(self): 81fe337bfd0d89c62917e3625111c65f4aa187c6b4Christian Heimes signal_alarm(0) # Didn't deadlock. 82292d351fc1a7dc9feccd412843832808680a631fChristian Heimes reap_children() 83292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 84292d351fc1a7dc9feccd412843832808680a631fChristian Heimes for fn in self.test_files: 85292d351fc1a7dc9feccd412843832808680a631fChristian Heimes try: 86292d351fc1a7dc9feccd412843832808680a631fChristian Heimes os.remove(fn) 87ad28c7f9dad791567afa0624acfb3ba430851965Andrew Svetlov except OSError: 88292d351fc1a7dc9feccd412843832808680a631fChristian Heimes pass 89292d351fc1a7dc9feccd412843832808680a631fChristian Heimes self.test_files[:] = [] 90292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 91292d351fc1a7dc9feccd412843832808680a631fChristian Heimes def pickaddr(self, proto): 92292d351fc1a7dc9feccd412843832808680a631fChristian Heimes if proto == socket.AF_INET: 939e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes return (HOST, 0) 94292d351fc1a7dc9feccd412843832808680a631fChristian Heimes else: 959e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes # XXX: We need a way to tell AF_UNIX to pick its own name 969e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes # like AF_INET provides port==0. 979e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes dir = None 989e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes fn = tempfile.mktemp(prefix='unix_socket.', dir=dir) 99292d351fc1a7dc9feccd412843832808680a631fChristian Heimes self.test_files.append(fn) 100292d351fc1a7dc9feccd412843832808680a631fChristian Heimes return fn 101292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 102dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes def make_server(self, addr, svrcls, hdlrbase): 103dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes class MyServer(svrcls): 104dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes def handle_error(self, request, client_address): 105dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes self.close_request(request) 106dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes raise 1079e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes 1089e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes class MyHandler(hdlrbase): 1099e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes def handle(self): 1109e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes line = self.rfile.readline() 1119e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes self.wfile.write(line) 1129e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes 113dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes if verbose: print("creating server") 114dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes server = MyServer(addr, MyHandler) 115b3aedd48621ed9d33b5f42f946b256bce4a50673Ezio Melotti self.assertEqual(server.server_address, server.socket.getsockname()) 116dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes return server 117dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes 118c00d4b437d544268b699fc57fe9e7c57ae89f1b3Antoine Pitrou @reap_threads 119dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes def run_server(self, svrcls, hdlrbase, testfunc): 120dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes server = self.make_server(self.pickaddr(svrcls.address_family), 121dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes svrcls, hdlrbase) 122dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes # We had the OS pick a port, so pull the real address out of 123dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes # the server. 124dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes addr = server.server_address 1259e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes if verbose: 1269e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes print("ADDR =", addr) 1279e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes print("CLASS =", svrcls) 128dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes 129dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes t = threading.Thread( 130dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes name='%s serving' % svrcls, 131dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes target=server.serve_forever, 132dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes # Short poll interval to make the test finish quickly. 133dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes # Time between requests is short enough that we won't wake 134dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes # up spuriously too many times. 135dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes kwargs={'poll_interval':0.01}) 136727537077043bb03a0c9e537cacbb9e695f7f4a8Benjamin Peterson t.daemon = True # In case this function raises. 1379e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes t.start() 1389e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes if verbose: print("server running") 139dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes for i in range(3): 1409e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes if verbose: print("test client", i) 1419e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes testfunc(svrcls.address_family, addr) 1429e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes if verbose: print("waiting for server") 143dd15f6c315f20c1a9a540dd757cd63e27dbe9f3cChristian Heimes server.shutdown() 1449e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes t.join() 145109761ba076842a9ab4343f083d46658829067b9Victor Stinner server.server_close() 1461ee9283254446998c9f423896b1edffe42f246d3Robert Collins self.assertEqual(-1, server.socket.fileno()) 1479e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes if verbose: print("done") 148292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 149292d351fc1a7dc9feccd412843832808680a631fChristian Heimes def stream_examine(self, proto, addr): 150292d351fc1a7dc9feccd412843832808680a631fChristian Heimes s = socket.socket(proto, socket.SOCK_STREAM) 151292d351fc1a7dc9feccd412843832808680a631fChristian Heimes s.connect(addr) 152292d351fc1a7dc9feccd412843832808680a631fChristian Heimes s.sendall(TEST_STR) 153292d351fc1a7dc9feccd412843832808680a631fChristian Heimes buf = data = receive(s, 100) 154fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes while data and b'\n' not in buf: 155292d351fc1a7dc9feccd412843832808680a631fChristian Heimes data = receive(s, 100) 156292d351fc1a7dc9feccd412843832808680a631fChristian Heimes buf += data 157b3aedd48621ed9d33b5f42f946b256bce4a50673Ezio Melotti self.assertEqual(buf, TEST_STR) 158292d351fc1a7dc9feccd412843832808680a631fChristian Heimes s.close() 159292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 160292d351fc1a7dc9feccd412843832808680a631fChristian Heimes def dgram_examine(self, proto, addr): 161292d351fc1a7dc9feccd412843832808680a631fChristian Heimes s = socket.socket(proto, socket.SOCK_DGRAM) 1621827eff03087d0e7975806967a68a349e10e5188Martin Panter if HAVE_UNIX_SOCKETS and proto == socket.AF_UNIX: 1631827eff03087d0e7975806967a68a349e10e5188Martin Panter s.bind(self.pickaddr(proto)) 164292d351fc1a7dc9feccd412843832808680a631fChristian Heimes s.sendto(TEST_STR, addr) 165292d351fc1a7dc9feccd412843832808680a631fChristian Heimes buf = data = receive(s, 100) 166fdb6bb56c19c6c0d332d61fb3f6416cf91be2d02Christian Heimes while data and b'\n' not in buf: 167292d351fc1a7dc9feccd412843832808680a631fChristian Heimes data = receive(s, 100) 168292d351fc1a7dc9feccd412843832808680a631fChristian Heimes buf += data 169b3aedd48621ed9d33b5f42f946b256bce4a50673Ezio Melotti self.assertEqual(buf, TEST_STR) 170292d351fc1a7dc9feccd412843832808680a631fChristian Heimes s.close() 171292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 1729e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes def test_TCPServer(self): 173ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti self.run_server(socketserver.TCPServer, 174ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti socketserver.StreamRequestHandler, 1759e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes self.stream_examine) 1769e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes 1779e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes def test_ThreadingTCPServer(self): 178ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti self.run_server(socketserver.ThreadingTCPServer, 179ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti socketserver.StreamRequestHandler, 1809e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes self.stream_examine) 1819e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes 18243767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka @requires_forking 18343767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka def test_ForkingTCPServer(self): 18443767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka with simple_subprocess(self): 18543767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka self.run_server(socketserver.ForkingTCPServer, 186ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti socketserver.StreamRequestHandler, 1879e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes self.stream_examine) 1889e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes 18943767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka @requires_unix_sockets 19043767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka def test_UnixStreamServer(self): 19143767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka self.run_server(socketserver.UnixStreamServer, 19243767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka socketserver.StreamRequestHandler, 19343767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka self.stream_examine) 19443767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka 19543767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka @requires_unix_sockets 19643767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka def test_ThreadingUnixStreamServer(self): 19743767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka self.run_server(socketserver.ThreadingUnixStreamServer, 19843767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka socketserver.StreamRequestHandler, 19943767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka self.stream_examine) 20043767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka 20143767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka @requires_unix_sockets 20243767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka @requires_forking 20343767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka def test_ForkingUnixStreamServer(self): 20443767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka with simple_subprocess(self): 20543767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka self.run_server(ForkingUnixStreamServer, 206ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti socketserver.StreamRequestHandler, 2079e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes self.stream_examine) 2089e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes 2099e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes def test_UDPServer(self): 210ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti self.run_server(socketserver.UDPServer, 211ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti socketserver.DatagramRequestHandler, 2129e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes self.dgram_examine) 2139e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes 2149e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes def test_ThreadingUDPServer(self): 215ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti self.run_server(socketserver.ThreadingUDPServer, 216ce261952e640b2d09ada1b160f0cfa37db32f928Alexandre Vassalotti socketserver.DatagramRequestHandler, 2179e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes self.dgram_examine) 2189e7f1d2e965400edcb2c0cb7fee625ef2b595eb5Christian Heimes 21943767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka @requires_forking 22043767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka def test_ForkingUDPServer(self): 22143767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka with simple_subprocess(self): 22243767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka self.run_server(socketserver.ForkingUDPServer, 22343767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka socketserver.DatagramRequestHandler, 22443767638a9590689fd8bcd1fcedd15bbe4660856Serhiy Storchaka self.dgram_examine) 225292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 2261827eff03087d0e7975806967a68a349e10e5188Martin Panter @requires_unix_sockets 2271827eff03087d0e7975806967a68a349e10e5188Martin Panter def test_UnixDatagramServer(self): 2281827eff03087d0e7975806967a68a349e10e5188Martin Panter self.run_server(socketserver.UnixDatagramServer, 2291827eff03087d0e7975806967a68a349e10e5188Martin Panter socketserver.DatagramRequestHandler, 2301827eff03087d0e7975806967a68a349e10e5188Martin Panter self.dgram_examine) 2311827eff03087d0e7975806967a68a349e10e5188Martin Panter 2321827eff03087d0e7975806967a68a349e10e5188Martin Panter @requires_unix_sockets 2331827eff03087d0e7975806967a68a349e10e5188Martin Panter def test_ThreadingUnixDatagramServer(self): 2341827eff03087d0e7975806967a68a349e10e5188Martin Panter self.run_server(socketserver.ThreadingUnixDatagramServer, 2351827eff03087d0e7975806967a68a349e10e5188Martin Panter socketserver.DatagramRequestHandler, 2361827eff03087d0e7975806967a68a349e10e5188Martin Panter self.dgram_examine) 2371827eff03087d0e7975806967a68a349e10e5188Martin Panter 2381827eff03087d0e7975806967a68a349e10e5188Martin Panter @requires_unix_sockets 2391827eff03087d0e7975806967a68a349e10e5188Martin Panter @requires_forking 2401827eff03087d0e7975806967a68a349e10e5188Martin Panter def test_ForkingUnixDatagramServer(self): 2411827eff03087d0e7975806967a68a349e10e5188Martin Panter self.run_server(ForkingUnixDatagramServer, 2421827eff03087d0e7975806967a68a349e10e5188Martin Panter socketserver.DatagramRequestHandler, 2431827eff03087d0e7975806967a68a349e10e5188Martin Panter self.dgram_examine) 244292d351fc1a7dc9feccd412843832808680a631fChristian Heimes 2453bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou @reap_threads 2463bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou def test_shutdown(self): 2473bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou # Issue #2302: shutdown() should always succeed in making an 2483bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou # other thread leave serve_forever(). 2493bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou class MyServer(socketserver.TCPServer): 2503bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou pass 2513bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou 2523bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou class MyHandler(socketserver.StreamRequestHandler): 2533bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou pass 2543bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou 2553bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou threads = [] 2563bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou for i in range(20): 2573bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou s = MyServer((HOST, 0), MyHandler) 2583bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou t = threading.Thread( 2593bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou name='MyServer serving', 2603bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou target=s.serve_forever, 2613bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou kwargs={'poll_interval':0.01}) 2623bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou t.daemon = True # In case this function raises. 2633bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou threads.append((t, s)) 2643bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou for t, s in threads: 2653bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou t.start() 2663bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou s.shutdown() 2673bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou for t, s in threads: 2683bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou t.join() 269109761ba076842a9ab4343f083d46658829067b9Victor Stinner s.server_close() 2703bcba8e2889708f646df50953cd45a4f2cf28b02Antoine Pitrou 2710f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali def test_tcpserver_bind_leak(self): 2720f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali # Issue #22435: the server socket wouldn't be closed if bind()/listen() 2730f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali # failed. 2740f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali # Create many servers for which bind() will fail, to see if this result 2750f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali # in FD exhaustion. 2760f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali for i in range(1024): 2770f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali with self.assertRaises(OverflowError): 2780f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali socketserver.TCPServer((HOST, -1), 2790f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali socketserver.StreamRequestHandler) 2800f4f048fa5ff06438a4624bc1dc02aa458a79748Charles-François Natali 2810cab9c1ebaa11bb7838a552c671c903156262ab7Martin Panter def test_context_manager(self): 2820cab9c1ebaa11bb7838a552c671c903156262ab7Martin Panter with socketserver.TCPServer((HOST, 0), 2830cab9c1ebaa11bb7838a552c671c903156262ab7Martin Panter socketserver.StreamRequestHandler) as server: 2840cab9c1ebaa11bb7838a552c671c903156262ab7Martin Panter pass 2850cab9c1ebaa11bb7838a552c671c903156262ab7Martin Panter self.assertEqual(-1, server.socket.fileno()) 2860cab9c1ebaa11bb7838a552c671c903156262ab7Martin Panter 28739f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum 288d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panterclass ErrorHandlerTest(unittest.TestCase): 289d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter """Test that the servers pass normal exceptions from the handler to 290d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter handle_error(), and that exiting exceptions like SystemExit and 291d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter KeyboardInterrupt are not passed.""" 292d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 293d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def tearDown(self): 294d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter test.support.unlink(test.support.TESTFN) 295d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 296d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def test_sync_handled(self): 297d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter BaseErrorTestServer(ValueError) 298d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.check_result(handled=True) 299d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 300d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def test_sync_not_handled(self): 301d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter with self.assertRaises(SystemExit): 302d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter BaseErrorTestServer(SystemExit) 303d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.check_result(handled=False) 304d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 305d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter @unittest.skipUnless(threading, 'Threading required for this test.') 306d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def test_threading_handled(self): 307d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter ThreadingErrorTestServer(ValueError) 308d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.check_result(handled=True) 309d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 310d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter @unittest.skipUnless(threading, 'Threading required for this test.') 311d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def test_threading_not_handled(self): 312d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter ThreadingErrorTestServer(SystemExit) 313d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.check_result(handled=False) 314d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 315d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter @requires_forking 316d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def test_forking_handled(self): 317d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter ForkingErrorTestServer(ValueError) 318d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.check_result(handled=True) 319d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 320d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter @requires_forking 321d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def test_forking_not_handled(self): 322d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter ForkingErrorTestServer(SystemExit) 323d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.check_result(handled=False) 324d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 325d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def check_result(self, handled): 326d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter with open(test.support.TESTFN) as log: 327d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter expected = 'Handler called\n' + 'Error handled\n' * handled 328d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.assertEqual(log.read(), expected) 329d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 330d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 331d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panterclass BaseErrorTestServer(socketserver.TCPServer): 332d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def __init__(self, exception): 333d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.exception = exception 334d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter super().__init__((HOST, 0), BadHandler) 335d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter with socket.create_connection(self.server_address): 336d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter pass 337d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter try: 338d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.handle_request() 339d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter finally: 340d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.server_close() 341d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.wait_done() 342d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 343d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def handle_error(self, request, client_address): 344d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter with open(test.support.TESTFN, 'a') as log: 345d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter log.write('Error handled\n') 346d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 347d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def wait_done(self): 348d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter pass 349d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 350d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 351d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panterclass BadHandler(socketserver.BaseRequestHandler): 352d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def handle(self): 353d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter with open(test.support.TESTFN, 'a') as log: 354d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter log.write('Handler called\n') 355d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter raise self.server.exception('Test error') 356d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 357d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 358d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panterclass ThreadingErrorTestServer(socketserver.ThreadingMixIn, 359d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter BaseErrorTestServer): 360d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def __init__(self, *pos, **kw): 361d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.done = threading.Event() 362d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter super().__init__(*pos, **kw) 363d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 364d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def shutdown_request(self, *pos, **kw): 365d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter super().shutdown_request(*pos, **kw) 366d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.done.set() 367d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 368d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter def wait_done(self): 369d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter self.done.wait() 370d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 371d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 372a945969d717dc8fcb5ca22691f98198b5173b740Gregory P. Smith ext:(%if HAVE_FORKING: 373a945969d717dc8fcb5ca22691f98198b5173b740Gregory P. Smith ext:(% class ForkingErrorTestServer(socketserver.ForkingMixIn, BaseErrorTestServer): 374a945969d717dc8fcb5ca22691f98198b5173b740Gregory P. Smith ext:(% def wait_done(self): 375a945969d717dc8fcb5ca22691f98198b5173b740Gregory P. Smith ext:(% [child] = self.active_children 376a945969d717dc8fcb5ca22691f98198b5173b740Gregory P. Smith ext:(% os.waitpid(child, 0) 377a945969d717dc8fcb5ca22691f98198b5173b740Gregory P. Smith ext:(% self.active_children.clear() 378d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 379d9108d1253eef9f43c60e0ed5f1ec5603c1fba6cMartin Panter 38034eeed42901666fce099947f93dfdfc05411f286Martin Panterclass SocketWriterTest(unittest.TestCase): 38134eeed42901666fce099947f93dfdfc05411f286Martin Panter def test_basics(self): 38234eeed42901666fce099947f93dfdfc05411f286Martin Panter class Handler(socketserver.StreamRequestHandler): 38334eeed42901666fce099947f93dfdfc05411f286Martin Panter def handle(self): 38434eeed42901666fce099947f93dfdfc05411f286Martin Panter self.server.wfile = self.wfile 38534eeed42901666fce099947f93dfdfc05411f286Martin Panter self.server.wfile_fileno = self.wfile.fileno() 38634eeed42901666fce099947f93dfdfc05411f286Martin Panter self.server.request_fileno = self.request.fileno() 38734eeed42901666fce099947f93dfdfc05411f286Martin Panter 38834eeed42901666fce099947f93dfdfc05411f286Martin Panter server = socketserver.TCPServer((HOST, 0), Handler) 38934eeed42901666fce099947f93dfdfc05411f286Martin Panter self.addCleanup(server.server_close) 39034eeed42901666fce099947f93dfdfc05411f286Martin Panter s = socket.socket( 39134eeed42901666fce099947f93dfdfc05411f286Martin Panter server.address_family, socket.SOCK_STREAM, socket.IPPROTO_TCP) 39234eeed42901666fce099947f93dfdfc05411f286Martin Panter with s: 39334eeed42901666fce099947f93dfdfc05411f286Martin Panter s.connect(server.server_address) 39434eeed42901666fce099947f93dfdfc05411f286Martin Panter server.handle_request() 39534eeed42901666fce099947f93dfdfc05411f286Martin Panter self.assertIsInstance(server.wfile, io.BufferedIOBase) 39634eeed42901666fce099947f93dfdfc05411f286Martin Panter self.assertEqual(server.wfile_fileno, server.request_fileno) 39734eeed42901666fce099947f93dfdfc05411f286Martin Panter 39834eeed42901666fce099947f93dfdfc05411f286Martin Panter @unittest.skipUnless(threading, 'Threading required for this test.') 39934eeed42901666fce099947f93dfdfc05411f286Martin Panter def test_write(self): 40034eeed42901666fce099947f93dfdfc05411f286Martin Panter # Test that wfile.write() sends data immediately, and that it does 40134eeed42901666fce099947f93dfdfc05411f286Martin Panter # not truncate sends when interrupted by a Unix signal 40234eeed42901666fce099947f93dfdfc05411f286Martin Panter pthread_kill = test.support.get_attribute(signal, 'pthread_kill') 40334eeed42901666fce099947f93dfdfc05411f286Martin Panter 40434eeed42901666fce099947f93dfdfc05411f286Martin Panter class Handler(socketserver.StreamRequestHandler): 40534eeed42901666fce099947f93dfdfc05411f286Martin Panter def handle(self): 40634eeed42901666fce099947f93dfdfc05411f286Martin Panter self.server.sent1 = self.wfile.write(b'write data\n') 40734eeed42901666fce099947f93dfdfc05411f286Martin Panter # Should be sent immediately, without requiring flush() 40834eeed42901666fce099947f93dfdfc05411f286Martin Panter self.server.received = self.rfile.readline() 4095f1a5187f72acb75d59fa67286ecf5c186bae619Serhiy Storchaka big_chunk = b'\0' * test.support.SOCK_MAX_SIZE 41034eeed42901666fce099947f93dfdfc05411f286Martin Panter self.server.sent2 = self.wfile.write(big_chunk) 41134eeed42901666fce099947f93dfdfc05411f286Martin Panter 41234eeed42901666fce099947f93dfdfc05411f286Martin Panter server = socketserver.TCPServer((HOST, 0), Handler) 41334eeed42901666fce099947f93dfdfc05411f286Martin Panter self.addCleanup(server.server_close) 41434eeed42901666fce099947f93dfdfc05411f286Martin Panter interrupted = threading.Event() 41534eeed42901666fce099947f93dfdfc05411f286Martin Panter 41634eeed42901666fce099947f93dfdfc05411f286Martin Panter def signal_handler(signum, frame): 41734eeed42901666fce099947f93dfdfc05411f286Martin Panter interrupted.set() 41834eeed42901666fce099947f93dfdfc05411f286Martin Panter 41934eeed42901666fce099947f93dfdfc05411f286Martin Panter original = signal.signal(signal.SIGUSR1, signal_handler) 42034eeed42901666fce099947f93dfdfc05411f286Martin Panter self.addCleanup(signal.signal, signal.SIGUSR1, original) 42134eeed42901666fce099947f93dfdfc05411f286Martin Panter response1 = None 42234eeed42901666fce099947f93dfdfc05411f286Martin Panter received2 = None 42334eeed42901666fce099947f93dfdfc05411f286Martin Panter main_thread = threading.get_ident() 42434eeed42901666fce099947f93dfdfc05411f286Martin Panter 42534eeed42901666fce099947f93dfdfc05411f286Martin Panter def run_client(): 42634eeed42901666fce099947f93dfdfc05411f286Martin Panter s = socket.socket(server.address_family, socket.SOCK_STREAM, 42734eeed42901666fce099947f93dfdfc05411f286Martin Panter socket.IPPROTO_TCP) 42834eeed42901666fce099947f93dfdfc05411f286Martin Panter with s, s.makefile('rb') as reader: 42934eeed42901666fce099947f93dfdfc05411f286Martin Panter s.connect(server.server_address) 43034eeed42901666fce099947f93dfdfc05411f286Martin Panter nonlocal response1 43134eeed42901666fce099947f93dfdfc05411f286Martin Panter response1 = reader.readline() 43234eeed42901666fce099947f93dfdfc05411f286Martin Panter s.sendall(b'client response\n') 43334eeed42901666fce099947f93dfdfc05411f286Martin Panter 43434eeed42901666fce099947f93dfdfc05411f286Martin Panter reader.read(100) 43534eeed42901666fce099947f93dfdfc05411f286Martin Panter # The main thread should now be blocking in a send() syscall. 43634eeed42901666fce099947f93dfdfc05411f286Martin Panter # But in theory, it could get interrupted by other signals, 43734eeed42901666fce099947f93dfdfc05411f286Martin Panter # and then retried. So keep sending the signal in a loop, in 43834eeed42901666fce099947f93dfdfc05411f286Martin Panter # case an earlier signal happens to be delivered at an 43934eeed42901666fce099947f93dfdfc05411f286Martin Panter # inconvenient moment. 44034eeed42901666fce099947f93dfdfc05411f286Martin Panter while True: 44134eeed42901666fce099947f93dfdfc05411f286Martin Panter pthread_kill(main_thread, signal.SIGUSR1) 44234eeed42901666fce099947f93dfdfc05411f286Martin Panter if interrupted.wait(timeout=float(1)): 44334eeed42901666fce099947f93dfdfc05411f286Martin Panter break 44434eeed42901666fce099947f93dfdfc05411f286Martin Panter nonlocal received2 44534eeed42901666fce099947f93dfdfc05411f286Martin Panter received2 = len(reader.read()) 44634eeed42901666fce099947f93dfdfc05411f286Martin Panter 44734eeed42901666fce099947f93dfdfc05411f286Martin Panter background = threading.Thread(target=run_client) 44834eeed42901666fce099947f93dfdfc05411f286Martin Panter background.start() 44934eeed42901666fce099947f93dfdfc05411f286Martin Panter server.handle_request() 45034eeed42901666fce099947f93dfdfc05411f286Martin Panter background.join() 45134eeed42901666fce099947f93dfdfc05411f286Martin Panter self.assertEqual(server.sent1, len(response1)) 45234eeed42901666fce099947f93dfdfc05411f286Martin Panter self.assertEqual(response1, b'write data\n') 45334eeed42901666fce099947f93dfdfc05411f286Martin Panter self.assertEqual(server.received, b'client response\n') 45434eeed42901666fce099947f93dfdfc05411f286Martin Panter self.assertEqual(server.sent2, test.support.SOCK_MAX_SIZE) 45534eeed42901666fce099947f93dfdfc05411f286Martin Panter self.assertEqual(received2, test.support.SOCK_MAX_SIZE - 100) 45634eeed42901666fce099947f93dfdfc05411f286Martin Panter 45734eeed42901666fce099947f93dfdfc05411f286Martin Panter 4583265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksagclass MiscTestCase(unittest.TestCase): 4593265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag 4603265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag def test_all(self): 4613265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag # objects defined in the module should be in __all__ 4623265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag expected = [] 4633265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag for name in dir(socketserver): 4643265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag if not name.startswith('_'): 4653265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag mod_object = getattr(socketserver, name) 4663265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag if getattr(mod_object, '__module__', None) == 'socketserver': 4673265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag expected.append(name) 4683265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag self.assertCountEqual(socketserver.__all__, expected) 469a9f6f22f72833e49d01539f37effab67aa21391bTim Peters 4704bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter def test_shutdown_request_called_if_verify_request_false(self): 4714bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter # Issue #26309: BaseServer should call shutdown_request even if 4724bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter # verify_request is False 4734bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter 4744bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter class MyServer(socketserver.TCPServer): 4754bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter def verify_request(self, request, client_address): 4764bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter return False 4774bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter 4784bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter shutdown_called = 0 4794bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter def shutdown_request(self, request): 4804bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter self.shutdown_called += 1 4814bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter socketserver.TCPServer.shutdown_request(self, request) 4824bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter 4834bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter server = MyServer((HOST, 0), socketserver.StreamRequestHandler) 4844bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter s = socket.socket(server.address_family, socket.SOCK_STREAM) 4854bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter s.connect(server.server_address) 4864bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter s.close() 4874bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter server.handle_request() 4884bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter self.assertEqual(server.shutdown_called, 1) 4894bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter server.server_close() 4904bf427495fc65f331ae11903b57f6aa712a35ee3Martin Panter 49139f1b3656ed1fdd98d908a21e1b0aafa6b4e75c4Guido van Rossum 492a9f6f22f72833e49d01539f37effab67aa21391bTim Petersif __name__ == "__main__": 4933265344a85a2bac749230c2d6ef1b20edcd63906Berker Peksag unittest.main() 494