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

/tests/net/test_tcp.py

https://bitbucket.org/prologic/circuits/
Python | 259 lines | 200 code | 51 blank | 8 comment | 22 complexity | bef6cfea65aa28f52ea795746adbefaa MD5 | raw file
  1. #!/usr/bin/env python
  2. import pytest
  3. import select
  4. from socket import error as SocketError
  5. from socket import EAI_NODATA, EAI_NONAME
  6. from socket import socket, AF_INET, AF_INET6, SOCK_STREAM, has_ipv6
  7. from circuits import Manager, Debugger
  8. from circuits.net.events import close, connect, write
  9. from circuits.core.pollers import Select, Poll, EPoll, KQueue
  10. from circuits.net.sockets import TCPServer, TCP6Server, TCPClient, TCP6Client
  11. from .client import Client
  12. from .server import Server
  13. from tests.conftest import WaitEvent
  14. def wait_host(server):
  15. def checker(obj, attr):
  16. return all((getattr(obj, a) for a in attr))
  17. assert pytest.wait_for(server, ("host", "port"), checker)
  18. def _pytest_generate_tests(metafunc, ipv6):
  19. metafunc.addcall(funcargs={"Poller": Select, "ipv6": ipv6})
  20. if hasattr(select, "poll"):
  21. metafunc.addcall(funcargs={"Poller": Poll, "ipv6": ipv6})
  22. if hasattr(select, "epoll"):
  23. metafunc.addcall(funcargs={"Poller": EPoll, "ipv6": ipv6})
  24. if hasattr(select, "kqueue"):
  25. metafunc.addcall(funcargs={"Poller": KQueue, "ipv6": ipv6})
  26. def pytest_generate_tests(metafunc):
  27. _pytest_generate_tests(metafunc, ipv6=False)
  28. if has_ipv6:
  29. _pytest_generate_tests(metafunc, ipv6=True)
  30. def test_tcp_basic(Poller, ipv6):
  31. m = Manager() + Poller()
  32. if ipv6:
  33. tcp_server = TCP6Server(("::1", 0))
  34. tcp_client = TCP6Client()
  35. else:
  36. tcp_server = TCPServer(0)
  37. tcp_client = TCPClient()
  38. server = Server() + tcp_server
  39. client = Client() + tcp_client
  40. server.register(m)
  41. client.register(m)
  42. m.start()
  43. try:
  44. assert pytest.wait_for(client, "ready")
  45. assert pytest.wait_for(server, "ready")
  46. wait_host(server)
  47. client.fire(connect(server.host, server.port))
  48. assert pytest.wait_for(client, "connected")
  49. assert pytest.wait_for(server, "connected")
  50. assert pytest.wait_for(client, "data", b"Ready")
  51. client.fire(write(b"foo"))
  52. assert pytest.wait_for(server, "data", b"foo")
  53. assert pytest.wait_for(client, "data", b"foo")
  54. client.fire(close())
  55. assert pytest.wait_for(client, "disconnected")
  56. assert pytest.wait_for(server, "disconnected")
  57. server.fire(close())
  58. assert pytest.wait_for(server, "closed")
  59. finally:
  60. m.stop()
  61. def test_tcp_reconnect(Poller, ipv6):
  62. ### XXX: Apparently this doesn't work on Windows either?
  63. ### XXX: UPDATE: Apparently Broken on Windows + Python 3.2
  64. ### TODO: Need to look into this. Find out why...
  65. if pytest.PLATFORM == "win32" and pytest.PYVER[:2] >= (3, 2):
  66. pytest.skip("Broken on Windows on Python 3.2")
  67. m = Manager() + Poller()
  68. if ipv6:
  69. tcp_server = TCP6Server(("::1", 0))
  70. tcp_client = TCP6Client()
  71. else:
  72. tcp_server = TCPServer(0)
  73. tcp_client = TCPClient()
  74. server = Server() + tcp_server
  75. client = Client() + tcp_client
  76. server.register(m)
  77. client.register(m)
  78. m.start()
  79. try:
  80. assert pytest.wait_for(client, "ready")
  81. assert pytest.wait_for(server, "ready")
  82. wait_host(server)
  83. # 1st connect
  84. client.fire(connect(server.host, server.port))
  85. assert pytest.wait_for(client, "connected")
  86. assert pytest.wait_for(server, "connected")
  87. assert pytest.wait_for(client, "data", b"Ready")
  88. client.fire(write(b"foo"))
  89. assert pytest.wait_for(server, "data", b"foo")
  90. # disconnect
  91. client.fire(close())
  92. assert pytest.wait_for(client, "disconnected")
  93. # 2nd reconnect
  94. client.fire(connect(server.host, server.port))
  95. assert pytest.wait_for(client, "connected")
  96. assert pytest.wait_for(server, "connected")
  97. assert pytest.wait_for(client, "data", b"Ready")
  98. client.fire(write(b"foo"))
  99. assert pytest.wait_for(server, "data", b"foo")
  100. client.fire(close())
  101. assert pytest.wait_for(client, "disconnected")
  102. assert pytest.wait_for(server, "disconnected")
  103. server.fire(close())
  104. assert pytest.wait_for(server, "closed")
  105. finally:
  106. m.stop()
  107. def test_tcp_connect_closed_port(Poller, ipv6):
  108. if pytest.PLATFORM == "win32":
  109. pytest.skip("Broken on Windows")
  110. m = Manager() + Poller() + Debugger()
  111. if ipv6:
  112. tcp_server = TCP6Server(("::1", 0))
  113. tcp_client = TCP6Client(connect_timeout=1)
  114. else:
  115. tcp_server = TCPServer(0)
  116. tcp_client = TCPClient(connect_timeout=1)
  117. server = Server() + tcp_server
  118. client = Client() + tcp_client
  119. server.register(m)
  120. client.register(m)
  121. m.start()
  122. try:
  123. assert pytest.wait_for(client, "ready")
  124. assert pytest.wait_for(server, "ready")
  125. wait_host(server)
  126. host, port = server.host, server.port
  127. tcp_server._sock.close()
  128. # 1st connect
  129. client.fire(connect(host, port))
  130. waiter = WaitEvent(m, "unreachable", channel='client')
  131. assert waiter.wait()
  132. finally:
  133. server.unregister()
  134. client.unregister()
  135. m.stop()
  136. def test_tcp_bind(Poller, ipv6):
  137. m = Manager() + Poller()
  138. if ipv6:
  139. sock = socket(AF_INET6, SOCK_STREAM)
  140. sock.bind(("::1", 0))
  141. sock.listen(5)
  142. _, bind_port, _, _ = sock.getsockname()
  143. sock.close()
  144. server = Server() + TCP6Server(("::1", 0))
  145. client = Client() + TCP6Client()
  146. else:
  147. sock = socket(AF_INET, SOCK_STREAM)
  148. sock.bind(("", 0))
  149. sock.listen(5)
  150. _, bind_port = sock.getsockname()
  151. sock.close()
  152. server = Server() + TCPServer(0)
  153. client = Client() + TCPClient()
  154. server.register(m)
  155. client.register(m)
  156. m.start()
  157. try:
  158. assert pytest.wait_for(client, "ready")
  159. assert pytest.wait_for(server, "ready")
  160. wait_host(server)
  161. client.fire(connect(server.host, server.port))
  162. assert pytest.wait_for(client, "connected")
  163. assert pytest.wait_for(server, "connected")
  164. assert pytest.wait_for(client, "data", b"Ready")
  165. #assert server.client[1] == bind_port
  166. client.fire(write(b"foo"))
  167. assert pytest.wait_for(server, "data", b"foo")
  168. client.fire(close())
  169. assert pytest.wait_for(client, "disconnected")
  170. assert pytest.wait_for(server, "disconnected")
  171. server.fire(close())
  172. assert pytest.wait_for(server, "closed")
  173. finally:
  174. m.stop()
  175. def test_tcp_lookup_failure(Poller, ipv6):
  176. m = Manager() + Poller()
  177. if ipv6:
  178. tcp_client = TCP6Client()
  179. else:
  180. tcp_client = TCPClient()
  181. client = Client() + tcp_client
  182. client.register(m)
  183. m.start()
  184. try:
  185. assert pytest.wait_for(client, "ready")
  186. client.fire(connect("foo", 1234))
  187. assert pytest.wait_for(client, "error", lambda obj, attr: isinstance(getattr(obj, attr), SocketError))
  188. if pytest.PLATFORM == "win32":
  189. assert client.error.errno == 11004
  190. else:
  191. assert client.error.errno in (EAI_NODATA, EAI_NONAME,)
  192. finally:
  193. m.stop()