PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/greentest/test_socket.py

https://bitbucket.org/lericson/gevent
Python | 1037 lines | 873 code | 96 blank | 68 comment | 41 complexity | d2c04bdda50751928f74dbe9508812eb MD5 | raw file
  1. #!/usr/bin/env python
  2. from gevent import monkey
  3. monkey.patch_all()
  4. import greentest
  5. import test_support
  6. import socket
  7. import select
  8. import time
  9. import thread, threading
  10. import Queue
  11. import sys
  12. import array
  13. from weakref import proxy
  14. import signal
  15. PORT = 50007
  16. HOST = 'localhost'
  17. MSG = 'Michael Gilfix was here\n'
  18. class SocketTCPTest(greentest.TestCase):
  19. def setUp(self):
  20. self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  21. self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  22. global PORT
  23. PORT = test_support.bind_port(self.serv, HOST, PORT)
  24. self.serv.listen(1)
  25. def tearDown(self):
  26. self.serv.close()
  27. self.serv = None
  28. class SocketUDPTest(greentest.TestCase):
  29. def setUp(self):
  30. self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  31. self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  32. global PORT
  33. PORT = test_support.bind_port(self.serv, HOST, PORT)
  34. def tearDown(self):
  35. self.serv.close()
  36. self.serv = None
  37. class ThreadableTest:
  38. """Threadable Test class
  39. The ThreadableTest class makes it easy to create a threaded
  40. client/server pair from an existing unit test. To create a
  41. new threaded class from an existing unit test, use multiple
  42. inheritance:
  43. class NewClass (OldClass, ThreadableTest):
  44. pass
  45. This class defines two new fixture functions with obvious
  46. purposes for overriding:
  47. clientSetUp ()
  48. clientTearDown ()
  49. Any new test functions within the class must then define
  50. tests in pairs, where the test name is preceeded with a
  51. '_' to indicate the client portion of the test. Ex:
  52. def testFoo(self):
  53. # Server portion
  54. def _testFoo(self):
  55. # Client portion
  56. Any exceptions raised by the clients during their tests
  57. are caught and transferred to the main thread to alert
  58. the testing framework.
  59. Note, the server setup function cannot call any blocking
  60. functions that rely on the client thread during setup,
  61. unless serverExplicityReady() is called just before
  62. the blocking call (such as in setting up a client/server
  63. connection and performing the accept() in setUp().
  64. """
  65. def __init__(self):
  66. # Swap the true setup function
  67. self.__setUp = self.setUp
  68. self.__tearDown = self.tearDown
  69. self.setUp = self._setUp
  70. self.tearDown = self._tearDown
  71. def serverExplicitReady(self):
  72. """This method allows the server to explicitly indicate that
  73. it wants the client thread to proceed. This is useful if the
  74. server is about to execute a blocking routine that is
  75. dependent upon the client thread during its setup routine."""
  76. self.server_ready.set()
  77. def _setUp(self):
  78. #self.server_ready = threading.Event()
  79. #self.client_ready = threading.Event()
  80. #self.done = threading.Event()
  81. #self.queue = Queue.Queue(1)
  82. # monkey-patched threading.Event and threading.Queue work fine here too
  83. # but let's test gevent classes
  84. from gevent.event import Event
  85. from gevent.queue import Queue
  86. self.server_ready = Event()
  87. self.client_ready = Event()
  88. self.done = Event()
  89. self.queue = Queue(1)
  90. # Do some munging to start the client test.
  91. methodname = self.id()
  92. i = methodname.rfind('.')
  93. methodname = methodname[i+1:]
  94. test_method = getattr(self, '_' + methodname)
  95. self.client_thread = thread.start_new_thread(
  96. self.clientRun, (test_method,))
  97. self.__setUp()
  98. if not self.server_ready.isSet():
  99. self.server_ready.set()
  100. self.client_ready.wait()
  101. def _tearDown(self):
  102. self.__tearDown()
  103. self.done.wait()
  104. if not self.queue.empty():
  105. msg = self.queue.get()
  106. self.fail(msg)
  107. def clientRun(self, test_func):
  108. self.server_ready.wait()
  109. self.client_ready.set()
  110. self.clientSetUp()
  111. if not callable(test_func):
  112. raise TypeError, "test_func must be a callable function"
  113. try:
  114. test_func()
  115. except Exception, strerror:
  116. self.queue.put(strerror)
  117. self.clientTearDown()
  118. def clientSetUp(self):
  119. raise NotImplementedError, "clientSetUp must be implemented."
  120. def clientTearDown(self):
  121. self.done.set()
  122. thread.exit()
  123. class ThreadedTCPSocketTest(SocketTCPTest, ThreadableTest):
  124. def __init__(self, methodName='runTest'):
  125. SocketTCPTest.__init__(self, methodName=methodName)
  126. ThreadableTest.__init__(self)
  127. def clientSetUp(self):
  128. self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  129. def clientTearDown(self):
  130. self.cli.close()
  131. self.cli = None
  132. ThreadableTest.clientTearDown(self)
  133. class ThreadedUDPSocketTest(SocketUDPTest, ThreadableTest):
  134. def __init__(self, methodName='runTest'):
  135. SocketUDPTest.__init__(self, methodName=methodName)
  136. ThreadableTest.__init__(self)
  137. def clientSetUp(self):
  138. self.cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  139. class SocketConnectedTest(ThreadedTCPSocketTest):
  140. def __init__(self, methodName='runTest'):
  141. ThreadedTCPSocketTest.__init__(self, methodName=methodName)
  142. def setUp(self):
  143. ThreadedTCPSocketTest.setUp(self)
  144. # Indicate explicitly we're ready for the client thread to
  145. # proceed and then perform the blocking call to accept
  146. self.serverExplicitReady()
  147. conn, addr = self.serv.accept()
  148. self.cli_conn = conn
  149. def tearDown(self):
  150. self.cli_conn.close()
  151. self.cli_conn = None
  152. ThreadedTCPSocketTest.tearDown(self)
  153. def clientSetUp(self):
  154. ThreadedTCPSocketTest.clientSetUp(self)
  155. self.cli.connect((HOST, PORT))
  156. self.serv_conn = self.cli
  157. def clientTearDown(self):
  158. self.serv_conn.close()
  159. self.serv_conn = None
  160. ThreadedTCPSocketTest.clientTearDown(self)
  161. class SocketPairTest(greentest.TestCase, ThreadableTest):
  162. def __init__(self, methodName='runTest'):
  163. greentest.TestCase.__init__(self, methodName=methodName)
  164. ThreadableTest.__init__(self)
  165. def setUp(self):
  166. self.serv, self.cli = socket.socketpair()
  167. def tearDown(self):
  168. self.serv.close()
  169. self.serv = None
  170. def clientSetUp(self):
  171. pass
  172. def clientTearDown(self):
  173. self.cli.close()
  174. self.cli = None
  175. ThreadableTest.clientTearDown(self)
  176. #######################################################################
  177. ## Begin Tests
  178. class GeneralModuleTests(greentest.TestCase):
  179. def test_weakref(self):
  180. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  181. p = proxy(s)
  182. self.assertEqual(p.fileno(), s.fileno())
  183. s.close()
  184. s = None
  185. try:
  186. p.fileno()
  187. except ReferenceError:
  188. pass
  189. else:
  190. self.fail('Socket proxy still exists')
  191. def testSocketError(self):
  192. # Testing socket module exceptions
  193. def raise_error(*args, **kwargs):
  194. raise socket.error
  195. def raise_herror(*args, **kwargs):
  196. raise socket.herror
  197. def raise_gaierror(*args, **kwargs):
  198. raise socket.gaierror
  199. self.failUnlessRaises(socket.error, raise_error,
  200. "Error raising socket exception.")
  201. self.failUnlessRaises(socket.error, raise_herror,
  202. "Error raising socket exception.")
  203. self.failUnlessRaises(socket.error, raise_gaierror,
  204. "Error raising socket exception.")
  205. def testCrucialConstants(self):
  206. # Testing for mission critical constants
  207. socket.AF_INET
  208. socket.SOCK_STREAM
  209. socket.SOCK_DGRAM
  210. socket.SOCK_RAW
  211. socket.SOCK_RDM
  212. socket.SOCK_SEQPACKET
  213. socket.SOL_SOCKET
  214. socket.SO_REUSEADDR
  215. def testHostnameRes(self):
  216. # Testing hostname resolution mechanisms
  217. hostname = socket.gethostname()
  218. try:
  219. ip = socket.gethostbyname(hostname)
  220. except socket.error:
  221. # Probably name lookup wasn't set up right; skip this test
  222. return
  223. self.assert_(ip.find('.') >= 0, "Error resolving host to ip.")
  224. try:
  225. hname, aliases, ipaddrs = socket.gethostbyaddr(ip)
  226. except socket.error:
  227. # Probably a similar problem as above; skip this test
  228. return
  229. all_host_names = [hostname, hname] + aliases
  230. fqhn = socket.getfqdn(ip)
  231. if not fqhn in all_host_names:
  232. self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names)))
  233. def testRefCountGetNameInfo(self):
  234. # Testing reference count for getnameinfo
  235. import sys
  236. if hasattr(sys, "getrefcount"):
  237. try:
  238. # On some versions, this loses a reference
  239. orig = sys.getrefcount(__name__)
  240. socket.getnameinfo(__name__,0)
  241. except SystemError:
  242. if sys.getrefcount(__name__) <> orig:
  243. self.fail("socket.getnameinfo loses a reference")
  244. def testInterpreterCrash(self):
  245. # Making sure getnameinfo doesn't crash the interpreter
  246. try:
  247. # On some versions, this crashes the interpreter.
  248. socket.getnameinfo(('x', 0, 0, 0), 0)
  249. except socket.error:
  250. pass
  251. def testNtoH(self):
  252. # This just checks that htons etc. are their own inverse,
  253. # when looking at the lower 16 or 32 bits.
  254. sizes = {socket.htonl: 32, socket.ntohl: 32,
  255. socket.htons: 16, socket.ntohs: 16}
  256. for func, size in sizes.items():
  257. mask = (1L<<size) - 1
  258. for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210):
  259. self.assertEqual(i & mask, func(func(i&mask)) & mask)
  260. swapped = func(mask)
  261. self.assertEqual(swapped & mask, mask)
  262. self.assertRaises(OverflowError, func, 1L<<34)
  263. def testGetServBy(self):
  264. eq = self.assertEqual
  265. # Find one service that exists, then check all the related interfaces.
  266. # I've ordered this by protocols that have both a tcp and udp
  267. # protocol, at least for modern Linuxes.
  268. if sys.platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
  269. 'freebsd7', 'darwin'):
  270. # avoid the 'echo' service on this platform, as there is an
  271. # assumption breaking non-standard port/protocol entry
  272. services = ('daytime', 'qotd', 'domain')
  273. else:
  274. services = ('echo', 'daytime', 'domain')
  275. for service in services:
  276. try:
  277. port = socket.getservbyname(service, 'tcp')
  278. break
  279. except socket.error:
  280. pass
  281. else:
  282. raise socket.error
  283. # Try same call with optional protocol omitted
  284. port2 = socket.getservbyname(service)
  285. eq(port, port2)
  286. # Try udp, but don't barf it it doesn't exist
  287. try:
  288. udpport = socket.getservbyname(service, 'udp')
  289. except socket.error:
  290. udpport = None
  291. else:
  292. eq(udpport, port)
  293. # Now make sure the lookup by port returns the same service name
  294. eq(socket.getservbyport(port2), service)
  295. eq(socket.getservbyport(port, 'tcp'), service)
  296. if udpport is not None:
  297. eq(socket.getservbyport(udpport, 'udp'), service)
  298. def testDefaultTimeout(self):
  299. # Testing default timeout
  300. # The default timeout should initially be None
  301. self.assertEqual(socket.getdefaulttimeout(), None)
  302. s = socket.socket()
  303. self.assertEqual(s.gettimeout(), None)
  304. s.close()
  305. # Set the default timeout to 10, and see if it propagates
  306. socket.setdefaulttimeout(10)
  307. self.assertEqual(socket.getdefaulttimeout(), 10)
  308. s = socket.socket()
  309. self.assertEqual(s.gettimeout(), 10)
  310. s.close()
  311. # Reset the default timeout to None, and see if it propagates
  312. socket.setdefaulttimeout(None)
  313. self.assertEqual(socket.getdefaulttimeout(), None)
  314. s = socket.socket()
  315. self.assertEqual(s.gettimeout(), None)
  316. s.close()
  317. # Check that setting it to an invalid value raises ValueError
  318. self.assertRaises(ValueError, socket.setdefaulttimeout, -1)
  319. # Check that setting it to an invalid type raises TypeError
  320. self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
  321. def testIPv4toString(self):
  322. if not hasattr(socket, 'inet_pton'):
  323. return # No inet_pton() on this platform
  324. from socket import inet_aton as f, inet_pton, AF_INET
  325. g = lambda a: inet_pton(AF_INET, a)
  326. self.assertEquals('\x00\x00\x00\x00', f('0.0.0.0'))
  327. self.assertEquals('\xff\x00\xff\x00', f('255.0.255.0'))
  328. self.assertEquals('\xaa\xaa\xaa\xaa', f('170.170.170.170'))
  329. self.assertEquals('\x01\x02\x03\x04', f('1.2.3.4'))
  330. self.assertEquals('\xff\xff\xff\xff', f('255.255.255.255'))
  331. self.assertEquals('\x00\x00\x00\x00', g('0.0.0.0'))
  332. self.assertEquals('\xff\x00\xff\x00', g('255.0.255.0'))
  333. self.assertEquals('\xaa\xaa\xaa\xaa', g('170.170.170.170'))
  334. self.assertEquals('\xff\xff\xff\xff', g('255.255.255.255'))
  335. def testIPv6toString(self):
  336. if not hasattr(socket, 'inet_pton'):
  337. return # No inet_pton() on this platform
  338. try:
  339. from socket import inet_pton, AF_INET6, has_ipv6
  340. if not has_ipv6:
  341. return
  342. except ImportError:
  343. return
  344. f = lambda a: inet_pton(AF_INET6, a)
  345. self.assertEquals('\x00' * 16, f('::'))
  346. self.assertEquals('\x00' * 16, f('0::0'))
  347. self.assertEquals('\x00\x01' + '\x00' * 14, f('1::'))
  348. self.assertEquals(
  349. '\x45\xef\x76\xcb\x00\x1a\x56\xef\xaf\xeb\x0b\xac\x19\x24\xae\xae',
  350. f('45ef:76cb:1a:56ef:afeb:bac:1924:aeae')
  351. )
  352. def testStringToIPv4(self):
  353. if not hasattr(socket, 'inet_ntop'):
  354. return # No inet_ntop() on this platform
  355. from socket import inet_ntoa as f, inet_ntop, AF_INET
  356. g = lambda a: inet_ntop(AF_INET, a)
  357. self.assertEquals('1.0.1.0', f('\x01\x00\x01\x00'))
  358. self.assertEquals('170.85.170.85', f('\xaa\x55\xaa\x55'))
  359. self.assertEquals('255.255.255.255', f('\xff\xff\xff\xff'))
  360. self.assertEquals('1.2.3.4', f('\x01\x02\x03\x04'))
  361. self.assertEquals('1.0.1.0', g('\x01\x00\x01\x00'))
  362. self.assertEquals('170.85.170.85', g('\xaa\x55\xaa\x55'))
  363. self.assertEquals('255.255.255.255', g('\xff\xff\xff\xff'))
  364. def testStringToIPv6(self):
  365. if not hasattr(socket, 'inet_ntop'):
  366. return # No inet_ntop() on this platform
  367. try:
  368. from socket import inet_ntop, AF_INET6, has_ipv6
  369. if not has_ipv6:
  370. return
  371. except ImportError:
  372. return
  373. f = lambda a: inet_ntop(AF_INET6, a)
  374. self.assertEquals('::', f('\x00' * 16))
  375. self.assertEquals('::1', f('\x00' * 15 + '\x01'))
  376. self.assertEquals(
  377. 'aef:b01:506:1001:ffff:9997:55:170',
  378. f('\x0a\xef\x0b\x01\x05\x06\x10\x01\xff\xff\x99\x97\x00\x55\x01\x70')
  379. )
  380. # XXX The following don't test module-level functionality...
  381. def testSockName(self):
  382. # Testing getsockname()
  383. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  384. sock.bind(("0.0.0.0", PORT+1))
  385. name = sock.getsockname()
  386. # XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate
  387. # it reasonable to get the host's addr in addition to 0.0.0.0.
  388. # At least for eCos. This is required for the S/390 to pass.
  389. my_ip_addr = socket.gethostbyname(socket.gethostname())
  390. self.assert_(name[0] in ("0.0.0.0", my_ip_addr), '%s invalid' % name[0])
  391. self.assertEqual(name[1], PORT+1)
  392. def testGetSockOpt(self):
  393. # Testing getsockopt()
  394. # We know a socket should start without reuse==0
  395. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  396. reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
  397. self.failIf(reuse != 0, "initial mode is reuse")
  398. def testSetSockOpt(self):
  399. # Testing setsockopt()
  400. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  401. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  402. reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
  403. self.failIf(reuse == 0, "failed to set reuse mode")
  404. __timeout__ = 2
  405. def testSendAfterClose(self):
  406. # testing send() after close() with timeout
  407. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  408. sock.settimeout(1)
  409. sock.close()
  410. self.assertRaises(socket.error, sock.send, "spam")
  411. def testNewAttributes(self):
  412. # testing .family, .type and .protocol
  413. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  414. self.assertEqual(sock.family, socket.AF_INET)
  415. self.assertEqual(sock.type, socket.SOCK_STREAM)
  416. self.assertEqual(sock.proto, 0)
  417. sock.close()
  418. class BasicTCPTest(SocketConnectedTest):
  419. def __init__(self, methodName='runTest'):
  420. SocketConnectedTest.__init__(self, methodName=methodName)
  421. def testRecv(self):
  422. # Testing large receive over TCP
  423. msg = self.cli_conn.recv(1024)
  424. self.assertEqual(msg, MSG)
  425. def _testRecv(self):
  426. self.serv_conn.send(MSG)
  427. def testOverFlowRecv(self):
  428. # Testing receive in chunks over TCP
  429. seg1 = self.cli_conn.recv(len(MSG) - 3)
  430. seg2 = self.cli_conn.recv(1024)
  431. msg = seg1 + seg2
  432. self.assertEqual(msg, MSG)
  433. def _testOverFlowRecv(self):
  434. self.serv_conn.send(MSG)
  435. def testRecvFrom(self):
  436. # Testing large recvfrom() over TCP
  437. msg, addr = self.cli_conn.recvfrom(1024)
  438. self.assertEqual(msg, MSG)
  439. def _testRecvFrom(self):
  440. self.serv_conn.send(MSG)
  441. def testOverFlowRecvFrom(self):
  442. # Testing recvfrom() in chunks over TCP
  443. seg1, addr = self.cli_conn.recvfrom(len(MSG)-3)
  444. seg2, addr = self.cli_conn.recvfrom(1024)
  445. msg = seg1 + seg2
  446. self.assertEqual(msg, MSG)
  447. def _testOverFlowRecvFrom(self):
  448. self.serv_conn.send(MSG)
  449. def testSendAll(self):
  450. # Testing sendall() with a 2048 byte string over TCP
  451. msg = ''
  452. while 1:
  453. read = self.cli_conn.recv(1024)
  454. if not read:
  455. break
  456. msg += read
  457. self.assertEqual(msg, 'f' * 2048)
  458. def _testSendAll(self):
  459. big_chunk = 'f' * 2048
  460. self.serv_conn.sendall(big_chunk)
  461. def testFromFd(self):
  462. # Testing fromfd()
  463. if not hasattr(socket, "fromfd"):
  464. return # On Windows, this doesn't exist
  465. fd = self.cli_conn.fileno()
  466. sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
  467. msg = sock.recv(1024)
  468. self.assertEqual(msg, MSG)
  469. def _testFromFd(self):
  470. self.serv_conn.send(MSG)
  471. def testShutdown(self):
  472. # Testing shutdown()
  473. msg = self.cli_conn.recv(1024)
  474. self.assertEqual(msg, MSG)
  475. def _testShutdown(self):
  476. self.serv_conn.send(MSG)
  477. self.serv_conn.shutdown(2)
  478. class BasicUDPTest(ThreadedUDPSocketTest):
  479. def __init__(self, methodName='runTest'):
  480. ThreadedUDPSocketTest.__init__(self, methodName=methodName)
  481. def testSendtoAndRecv(self):
  482. # Testing sendto() and Recv() over UDP
  483. msg = self.serv.recv(len(MSG))
  484. self.assertEqual(msg, MSG)
  485. def _testSendtoAndRecv(self):
  486. self.cli.sendto(MSG, 0, (HOST, PORT))
  487. def testRecvFrom(self):
  488. # Testing recvfrom() over UDP
  489. msg, addr = self.serv.recvfrom(len(MSG))
  490. self.assertEqual(msg, MSG)
  491. def _testRecvFrom(self):
  492. self.cli.sendto(MSG, 0, (HOST, PORT))
  493. def testRecvFromNegative(self):
  494. # Negative lengths passed to recvfrom should give ValueError.
  495. self.assertRaises(ValueError, self.serv.recvfrom, -1)
  496. def _testRecvFromNegative(self):
  497. self.cli.sendto(MSG, 0, (HOST, PORT))
  498. class TCPCloserTest(ThreadedTCPSocketTest):
  499. def testClose(self):
  500. conn, addr = self.serv.accept()
  501. conn.close()
  502. sd = self.cli
  503. read, write, err = select.select([sd], [], [], 1.0)
  504. self.assertEqual(read, [sd])
  505. self.assertEqual(sd.recv(1), '')
  506. def _testClose(self):
  507. self.cli.connect((HOST, PORT))
  508. time.sleep(1.0)
  509. class BasicSocketPairTest(SocketPairTest):
  510. def __init__(self, methodName='runTest'):
  511. SocketPairTest.__init__(self, methodName=methodName)
  512. def testRecv(self):
  513. msg = self.serv.recv(1024)
  514. self.assertEqual(msg, MSG)
  515. def _testRecv(self):
  516. self.cli.send(MSG)
  517. def testSend(self):
  518. self.serv.send(MSG)
  519. def _testSend(self):
  520. msg = self.cli.recv(1024)
  521. self.assertEqual(msg, MSG)
  522. class NonBlockingTCPTests(ThreadedTCPSocketTest):
  523. def __init__(self, methodName='runTest'):
  524. ThreadedTCPSocketTest.__init__(self, methodName=methodName)
  525. def testSetBlocking(self):
  526. # Testing whether set blocking works
  527. self.serv.setblocking(0)
  528. start = time.time()
  529. try:
  530. self.serv.accept()
  531. except socket.error:
  532. pass
  533. end = time.time()
  534. self.assert_((end - start) < 1.0, "Error setting non-blocking mode.")
  535. def _testSetBlocking(self):
  536. pass
  537. def testAccept(self):
  538. # Testing non-blocking accept
  539. self.serv.setblocking(0)
  540. try:
  541. conn, addr = self.serv.accept()
  542. except socket.error:
  543. pass
  544. else:
  545. self.fail("Error trying to do non-blocking accept.")
  546. read, write, err = select.select([self.serv], [], [])
  547. if self.serv in read:
  548. conn, addr = self.serv.accept()
  549. else:
  550. self.fail("Error trying to do accept after select.")
  551. def _testAccept(self):
  552. time.sleep(0.1)
  553. self.cli.connect((HOST, PORT))
  554. def testConnect(self):
  555. # Testing non-blocking connect
  556. conn, addr = self.serv.accept()
  557. def _testConnect(self):
  558. self.cli.settimeout(10)
  559. self.cli.connect((HOST, PORT))
  560. def testRecv(self):
  561. # Testing non-blocking recv
  562. conn, addr = self.serv.accept()
  563. conn.setblocking(0)
  564. try:
  565. msg = conn.recv(len(MSG))
  566. except socket.error:
  567. pass
  568. else:
  569. self.fail("Error trying to do non-blocking recv.")
  570. read, write, err = select.select([conn], [], [])
  571. if conn in read:
  572. msg = conn.recv(len(MSG))
  573. self.assertEqual(msg, MSG)
  574. else:
  575. self.fail("Error during select call to non-blocking socket.")
  576. def _testRecv(self):
  577. self.cli.connect((HOST, PORT))
  578. time.sleep(0.1)
  579. self.cli.send(MSG)
  580. class FileObjectClassTestCase(SocketConnectedTest):
  581. bufsize = -1 # Use default buffer size
  582. def __init__(self, methodName='runTest'):
  583. SocketConnectedTest.__init__(self, methodName=methodName)
  584. def setUp(self):
  585. SocketConnectedTest.setUp(self)
  586. self.serv_file = self.cli_conn.makefile('rb', self.bufsize)
  587. def tearDown(self):
  588. self.serv_file.close()
  589. self.assert_(self.serv_file.closed)
  590. self.serv_file = None
  591. SocketConnectedTest.tearDown(self)
  592. def clientSetUp(self):
  593. SocketConnectedTest.clientSetUp(self)
  594. self.cli_file = self.serv_conn.makefile('wb')
  595. def clientTearDown(self):
  596. self.cli_file.close()
  597. self.assert_(self.cli_file.closed)
  598. self.cli_file = None
  599. SocketConnectedTest.clientTearDown(self)
  600. def testSmallRead(self):
  601. # Performing small file read test
  602. first_seg = self.serv_file.read(len(MSG)-3)
  603. second_seg = self.serv_file.read(3)
  604. msg = first_seg + second_seg
  605. self.assertEqual(msg, MSG)
  606. def _testSmallRead(self):
  607. self.cli_file.write(MSG)
  608. self.cli_file.flush()
  609. def testFullRead(self):
  610. # read until EOF
  611. msg = self.serv_file.read()
  612. self.assertEqual(msg, MSG)
  613. def _testFullRead(self):
  614. self.cli_file.write(MSG)
  615. self.cli_file.close()
  616. def testUnbufferedRead(self):
  617. # Performing unbuffered file read test
  618. buf = ''
  619. while 1:
  620. char = self.serv_file.read(1)
  621. if not char:
  622. break
  623. buf += char
  624. self.assertEqual(buf, MSG)
  625. def _testUnbufferedRead(self):
  626. self.cli_file.write(MSG)
  627. self.cli_file.flush()
  628. def testReadline(self):
  629. # Performing file readline test
  630. line = self.serv_file.readline()
  631. self.assertEqual(line, MSG)
  632. def _testReadline(self):
  633. self.cli_file.write(MSG)
  634. self.cli_file.flush()
  635. def testReadlineAfterRead(self):
  636. a_baloo_is = self.serv_file.read(len("A baloo is"))
  637. self.assertEqual("A baloo is", a_baloo_is)
  638. _a_bear = self.serv_file.read(len(" a bear"))
  639. self.assertEqual(" a bear", _a_bear)
  640. line = self.serv_file.readline()
  641. self.assertEqual("\n", line)
  642. line = self.serv_file.readline()
  643. self.assertEqual("A BALOO IS A BEAR.\n", line)
  644. line = self.serv_file.readline()
  645. self.assertEqual(MSG, line)
  646. def _testReadlineAfterRead(self):
  647. self.cli_file.write("A baloo is a bear\n")
  648. self.cli_file.write("A BALOO IS A BEAR.\n")
  649. self.cli_file.write(MSG)
  650. self.cli_file.flush()
  651. def testReadlineAfterReadNoNewline(self):
  652. end_of_ = self.serv_file.read(len("End Of "))
  653. self.assertEqual("End Of ", end_of_)
  654. line = self.serv_file.readline()
  655. self.assertEqual("Line", line)
  656. def _testReadlineAfterReadNoNewline(self):
  657. self.cli_file.write("End Of Line")
  658. def testClosedAttr(self):
  659. self.assert_(not self.serv_file.closed)
  660. def _testClosedAttr(self):
  661. self.assert_(not self.cli_file.closed)
  662. class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase):
  663. """Repeat the tests from FileObjectClassTestCase with bufsize==0.
  664. In this case (and in this case only), it should be possible to
  665. create a file object, read a line from it, create another file
  666. object, read another line from it, without loss of data in the
  667. first file object's buffer. Note that httplib relies on this
  668. when reading multiple requests from the same socket."""
  669. bufsize = 0 # Use unbuffered mode
  670. def testUnbufferedReadline(self):
  671. # Read a line, create a new file object, read another line with it
  672. line = self.serv_file.readline() # first line
  673. self.assertEqual(line, "A. " + MSG) # first line
  674. self.serv_file = self.cli_conn.makefile('rb', 0)
  675. line = self.serv_file.readline() # second line
  676. self.assertEqual(line, "B. " + MSG) # second line
  677. def _testUnbufferedReadline(self):
  678. self.cli_file.write("A. " + MSG)
  679. self.cli_file.write("B. " + MSG)
  680. self.cli_file.flush()
  681. class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
  682. bufsize = 1 # Default-buffered for reading; line-buffered for writing
  683. class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
  684. bufsize = 2 # Exercise the buffering code
  685. class Urllib2FileobjectTest(greentest.TestCase):
  686. # urllib2.HTTPHandler has "borrowed" socket._fileobject, and requires that
  687. # it close the socket if the close c'tor argument is true
  688. def testClose(self):
  689. class MockSocket:
  690. closed = False
  691. def flush(self): pass
  692. def close(self): self.closed = True
  693. # must not close unless we request it: the original use of _fileobject
  694. # by module socket requires that the underlying socket not be closed until
  695. # the _socketobject that created the _fileobject is closed
  696. s = MockSocket()
  697. f = socket._fileobject(s)
  698. f.close()
  699. self.assert_(not s.closed)
  700. s = MockSocket()
  701. f = socket._fileobject(s, close=True)
  702. f.close()
  703. self.assert_(s.closed)
  704. class TCPTimeoutTest(SocketTCPTest):
  705. def testTCPTimeout(self):
  706. def raise_timeout(*args, **kwargs):
  707. self.serv.settimeout(1.0)
  708. self.serv.accept()
  709. self.failUnlessRaises(socket.timeout, raise_timeout,
  710. "Error generating a timeout exception (TCP)")
  711. def testTimeoutZero(self):
  712. ok = False
  713. try:
  714. self.serv.settimeout(0.0)
  715. foo = self.serv.accept()
  716. except socket.timeout:
  717. self.fail("caught timeout instead of error (TCP)")
  718. except socket.error:
  719. ok = True
  720. except:
  721. self.fail("caught unexpected exception (TCP)")
  722. if not ok:
  723. self.fail("accept() returned success when we did not expect it")
  724. def testInterruptedTimeout(self):
  725. # XXX I don't know how to do this test on MSWindows or any other
  726. # plaform that doesn't support signal.alarm() or os.kill(), though
  727. # the bug should have existed on all platforms.
  728. if not hasattr(signal, "alarm"):
  729. return # can only test on *nix
  730. self.serv.settimeout(5.0) # must be longer than alarm
  731. class Alarm(Exception):
  732. pass
  733. def alarm_handler(signal, frame):
  734. raise Alarm
  735. import gevent
  736. myalarm = gevent.signal(signal.SIGALRM, alarm_handler, signal.SIGALRM, None)
  737. try:
  738. try:
  739. signal.alarm(2) # POSIX allows alarm to be up to 1 second early
  740. try:
  741. foo = self.serv.accept()
  742. except socket.timeout:
  743. self.fail("caught timeout instead of Alarm")
  744. except Alarm:
  745. pass
  746. except:
  747. self.fail("caught other exception instead of Alarm")
  748. else:
  749. self.fail("nothing caught")
  750. signal.alarm(0) # shut off alarm
  751. except Alarm:
  752. self.fail("got Alarm in wrong place")
  753. finally:
  754. # no alarm can be pending. Safe to restore old handler.
  755. myalarm.cancel()
  756. class UDPTimeoutTest(SocketUDPTest):
  757. def testUDPTimeout(self):
  758. def raise_timeout(*args, **kwargs):
  759. self.serv.settimeout(1.0)
  760. self.serv.recv(1024)
  761. self.failUnlessRaises(socket.timeout, raise_timeout,
  762. "Error generating a timeout exception (UDP)")
  763. def testTimeoutZero(self):
  764. ok = False
  765. try:
  766. self.serv.settimeout(0.0)
  767. foo = self.serv.recv(1024)
  768. except socket.timeout:
  769. self.fail("caught timeout instead of error (UDP)")
  770. except socket.error:
  771. ok = True
  772. except:
  773. self.fail("caught unexpected exception (UDP)")
  774. if not ok:
  775. self.fail("recv() returned success when we did not expect it")
  776. class TestExceptions(greentest.TestCase):
  777. def testExceptionTree(self):
  778. self.assert_(issubclass(socket.error, Exception))
  779. self.assert_(issubclass(socket.herror, socket.error))
  780. self.assert_(issubclass(socket.gaierror, socket.error))
  781. self.assert_(issubclass(socket.timeout, socket.error))
  782. class TestLinuxAbstractNamespace(greentest.TestCase):
  783. UNIX_PATH_MAX = 108
  784. def testLinuxAbstractNamespace(self):
  785. address = "\x00python-test-hello\x00\xff"
  786. s1 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  787. s1.bind(address)
  788. s1.listen(1)
  789. s2 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  790. s2.connect(s1.getsockname())
  791. s1.accept()
  792. self.assertEqual(s1.getsockname(), address)
  793. self.assertEqual(s2.getpeername(), address)
  794. def testMaxName(self):
  795. address = "\x00" + "h" * (self.UNIX_PATH_MAX - 1)
  796. s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  797. s.bind(address)
  798. self.assertEqual(s.getsockname(), address)
  799. def testNameOverflow(self):
  800. address = "\x00" + "h" * self.UNIX_PATH_MAX
  801. s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  802. self.assertRaises(socket.error, s.bind, address)
  803. class BufferIOTest(SocketConnectedTest):
  804. """
  805. Test the buffer versions of socket.recv() and socket.send().
  806. """
  807. def __init__(self, methodName='runTest'):
  808. SocketConnectedTest.__init__(self, methodName=methodName)
  809. def testRecvInto(self):
  810. buf = array.array('c', ' '*1024)
  811. nbytes = self.cli_conn.recv_into(buf)
  812. self.assertEqual(nbytes, len(MSG))
  813. msg = buf.tostring()[:len(MSG)]
  814. self.assertEqual(msg, MSG)
  815. def _testRecvInto(self):
  816. buf = buffer(MSG)
  817. self.serv_conn.send(buf)
  818. def testRecvFromInto(self):
  819. buf = array.array('c', ' '*1024)
  820. nbytes, addr = self.cli_conn.recvfrom_into(buf)
  821. self.assertEqual(nbytes, len(MSG))
  822. msg = buf.tostring()[:len(MSG)]
  823. self.assertEqual(msg, MSG)
  824. def _testRecvFromInto(self):
  825. buf = buffer(MSG)
  826. self.serv_conn.send(buf)
  827. def test_main():
  828. tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest,
  829. TestExceptions, BufferIOTest]
  830. if sys.platform != 'mac':
  831. tests.extend([ BasicUDPTest, UDPTimeoutTest ])
  832. tests.extend([
  833. NonBlockingTCPTests,
  834. FileObjectClassTestCase,
  835. UnbufferedFileObjectClassTestCase,
  836. LineBufferedFileObjectClassTestCase,
  837. SmallBufferedFileObjectClassTestCase,
  838. Urllib2FileobjectTest,
  839. ])
  840. if hasattr(socket, "socketpair"):
  841. tests.append(BasicSocketPairTest)
  842. if sys.platform == 'linux2':
  843. tests.append(TestLinuxAbstractNamespace)
  844. thread_info = test_support.threading_setup()
  845. test_support.run_unittest(*tests)
  846. test_support.threading_cleanup(*thread_info)
  847. if __name__ == "__main__":
  848. test_main()