PageRenderTime 25ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/External.LCA_RESTRICTED/Languages/CPython/27/Lib/test/test_socketserver.py

http://github.com/IronLanguages/main
Python | 284 lines | 206 code | 41 blank | 37 comment | 42 complexity | 5e571848abf654519f46c6dfe862647c MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception
  1. """
  2. Test suite for SocketServer.py.
  3. """
  4. import contextlib
  5. import imp
  6. import os
  7. import select
  8. import signal
  9. import socket
  10. import tempfile
  11. import unittest
  12. import SocketServer
  13. import test.test_support
  14. from test.test_support import reap_children, reap_threads, verbose
  15. try:
  16. import threading
  17. except ImportError:
  18. threading = None
  19. test.test_support.requires("network")
  20. TEST_STR = "hello world\n"
  21. HOST = test.test_support.HOST
  22. HAVE_UNIX_SOCKETS = hasattr(socket, "AF_UNIX")
  23. HAVE_FORKING = hasattr(os, "fork") and os.name != "os2"
  24. def signal_alarm(n):
  25. """Call signal.alarm when it exists (i.e. not on Windows)."""
  26. if hasattr(signal, 'alarm'):
  27. signal.alarm(n)
  28. def receive(sock, n, timeout=20):
  29. r, w, x = select.select([sock], [], [], timeout)
  30. if sock in r:
  31. return sock.recv(n)
  32. else:
  33. raise RuntimeError, "timed out on %r" % (sock,)
  34. if HAVE_UNIX_SOCKETS:
  35. class ForkingUnixStreamServer(SocketServer.ForkingMixIn,
  36. SocketServer.UnixStreamServer):
  37. pass
  38. class ForkingUnixDatagramServer(SocketServer.ForkingMixIn,
  39. SocketServer.UnixDatagramServer):
  40. pass
  41. @contextlib.contextmanager
  42. def simple_subprocess(testcase):
  43. pid = os.fork()
  44. if pid == 0:
  45. # Don't throw an exception; it would be caught by the test harness.
  46. os._exit(72)
  47. yield None
  48. pid2, status = os.waitpid(pid, 0)
  49. testcase.assertEqual(pid2, pid)
  50. testcase.assertEqual(72 << 8, status)
  51. @unittest.skipUnless(threading, 'Threading required for this test.')
  52. class SocketServerTest(unittest.TestCase):
  53. """Test all socket servers."""
  54. def setUp(self):
  55. signal_alarm(20) # Kill deadlocks after 20 seconds.
  56. self.port_seed = 0
  57. self.test_files = []
  58. def tearDown(self):
  59. signal_alarm(0) # Didn't deadlock.
  60. reap_children()
  61. for fn in self.test_files:
  62. try:
  63. os.remove(fn)
  64. except os.error:
  65. pass
  66. self.test_files[:] = []
  67. def pickaddr(self, proto):
  68. if proto == socket.AF_INET:
  69. return (HOST, 0)
  70. else:
  71. # XXX: We need a way to tell AF_UNIX to pick its own name
  72. # like AF_INET provides port==0.
  73. dir = None
  74. if os.name == 'os2':
  75. dir = '\socket'
  76. fn = tempfile.mktemp(prefix='unix_socket.', dir=dir)
  77. if os.name == 'os2':
  78. # AF_UNIX socket names on OS/2 require a specific prefix
  79. # which can't include a drive letter and must also use
  80. # backslashes as directory separators
  81. if fn[1] == ':':
  82. fn = fn[2:]
  83. if fn[0] in (os.sep, os.altsep):
  84. fn = fn[1:]
  85. if os.sep == '/':
  86. fn = fn.replace(os.sep, os.altsep)
  87. else:
  88. fn = fn.replace(os.altsep, os.sep)
  89. self.test_files.append(fn)
  90. return fn
  91. def make_server(self, addr, svrcls, hdlrbase):
  92. class MyServer(svrcls):
  93. def handle_error(self, request, client_address):
  94. self.close_request(request)
  95. self.server_close()
  96. raise
  97. class MyHandler(hdlrbase):
  98. def handle(self):
  99. line = self.rfile.readline()
  100. self.wfile.write(line)
  101. if verbose: print "creating server"
  102. server = MyServer(addr, MyHandler)
  103. self.assertEqual(server.server_address, server.socket.getsockname())
  104. return server
  105. @unittest.skipUnless(threading, 'Threading required for this test.')
  106. @reap_threads
  107. def run_server(self, svrcls, hdlrbase, testfunc):
  108. server = self.make_server(self.pickaddr(svrcls.address_family),
  109. svrcls, hdlrbase)
  110. # We had the OS pick a port, so pull the real address out of
  111. # the server.
  112. addr = server.server_address
  113. if verbose:
  114. print "server created"
  115. print "ADDR =", addr
  116. print "CLASS =", svrcls
  117. t = threading.Thread(
  118. name='%s serving' % svrcls,
  119. target=server.serve_forever,
  120. # Short poll interval to make the test finish quickly.
  121. # Time between requests is short enough that we won't wake
  122. # up spuriously too many times.
  123. kwargs={'poll_interval':0.01})
  124. t.daemon = True # In case this function raises.
  125. t.start()
  126. if verbose: print "server running"
  127. for i in range(3):
  128. if verbose: print "test client", i
  129. testfunc(svrcls.address_family, addr)
  130. if verbose: print "waiting for server"
  131. server.shutdown()
  132. t.join()
  133. if verbose: print "done"
  134. def stream_examine(self, proto, addr):
  135. s = socket.socket(proto, socket.SOCK_STREAM)
  136. s.connect(addr)
  137. s.sendall(TEST_STR)
  138. buf = data = receive(s, 100)
  139. while data and '\n' not in buf:
  140. data = receive(s, 100)
  141. buf += data
  142. self.assertEqual(buf, TEST_STR)
  143. s.close()
  144. def dgram_examine(self, proto, addr):
  145. s = socket.socket(proto, socket.SOCK_DGRAM)
  146. s.sendto(TEST_STR, addr)
  147. buf = data = receive(s, 100)
  148. while data and '\n' not in buf:
  149. data = receive(s, 100)
  150. buf += data
  151. self.assertEqual(buf, TEST_STR)
  152. s.close()
  153. def test_TCPServer(self):
  154. self.run_server(SocketServer.TCPServer,
  155. SocketServer.StreamRequestHandler,
  156. self.stream_examine)
  157. def test_ThreadingTCPServer(self):
  158. self.run_server(SocketServer.ThreadingTCPServer,
  159. SocketServer.StreamRequestHandler,
  160. self.stream_examine)
  161. if HAVE_FORKING:
  162. def test_ForkingTCPServer(self):
  163. with simple_subprocess(self):
  164. self.run_server(SocketServer.ForkingTCPServer,
  165. SocketServer.StreamRequestHandler,
  166. self.stream_examine)
  167. if HAVE_UNIX_SOCKETS:
  168. def test_UnixStreamServer(self):
  169. self.run_server(SocketServer.UnixStreamServer,
  170. SocketServer.StreamRequestHandler,
  171. self.stream_examine)
  172. def test_ThreadingUnixStreamServer(self):
  173. self.run_server(SocketServer.ThreadingUnixStreamServer,
  174. SocketServer.StreamRequestHandler,
  175. self.stream_examine)
  176. if HAVE_FORKING:
  177. def test_ForkingUnixStreamServer(self):
  178. with simple_subprocess(self):
  179. self.run_server(ForkingUnixStreamServer,
  180. SocketServer.StreamRequestHandler,
  181. self.stream_examine)
  182. def test_UDPServer(self):
  183. self.run_server(SocketServer.UDPServer,
  184. SocketServer.DatagramRequestHandler,
  185. self.dgram_examine)
  186. def test_ThreadingUDPServer(self):
  187. self.run_server(SocketServer.ThreadingUDPServer,
  188. SocketServer.DatagramRequestHandler,
  189. self.dgram_examine)
  190. if HAVE_FORKING:
  191. def test_ForkingUDPServer(self):
  192. with simple_subprocess(self):
  193. self.run_server(SocketServer.ForkingUDPServer,
  194. SocketServer.DatagramRequestHandler,
  195. self.dgram_examine)
  196. # Alas, on Linux (at least) recvfrom() doesn't return a meaningful
  197. # client address so this cannot work:
  198. # if HAVE_UNIX_SOCKETS:
  199. # def test_UnixDatagramServer(self):
  200. # self.run_server(SocketServer.UnixDatagramServer,
  201. # SocketServer.DatagramRequestHandler,
  202. # self.dgram_examine)
  203. #
  204. # def test_ThreadingUnixDatagramServer(self):
  205. # self.run_server(SocketServer.ThreadingUnixDatagramServer,
  206. # SocketServer.DatagramRequestHandler,
  207. # self.dgram_examine)
  208. #
  209. # if HAVE_FORKING:
  210. # def test_ForkingUnixDatagramServer(self):
  211. # self.run_server(SocketServer.ForkingUnixDatagramServer,
  212. # SocketServer.DatagramRequestHandler,
  213. # self.dgram_examine)
  214. @reap_threads
  215. def test_shutdown(self):
  216. # Issue #2302: shutdown() should always succeed in making an
  217. # other thread leave serve_forever().
  218. class MyServer(SocketServer.TCPServer):
  219. pass
  220. class MyHandler(SocketServer.StreamRequestHandler):
  221. pass
  222. threads = []
  223. for i in range(20):
  224. s = MyServer((HOST, 0), MyHandler)
  225. t = threading.Thread(
  226. name='MyServer serving',
  227. target=s.serve_forever,
  228. kwargs={'poll_interval':0.01})
  229. t.daemon = True # In case this function raises.
  230. threads.append((t, s))
  231. for t, s in threads:
  232. t.start()
  233. s.shutdown()
  234. for t, s in threads:
  235. t.join()
  236. def test_main():
  237. if imp.lock_held():
  238. # If the import lock is held, the threads will hang
  239. raise unittest.SkipTest("can't run when import lock is held")
  240. test.test_support.run_unittest(SocketServerTest)
  241. if __name__ == "__main__":
  242. test_main()
  243. signal_alarm(3) # Shutdown shouldn't take more than 3 seconds.