Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_protocols.py 7.2KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. # Copyright (c) Twisted Matrix Laboratories.
  2. # See LICENSE for details.
  3. """
  4. Test cases for twisted.protocols package.
  5. """
  6. from twisted.internet import address, defer, protocol, reactor
  7. from twisted.protocols import portforward, wire
  8. from twisted.python.compat import iterbytes
  9. from twisted.test import proto_helpers
  10. from twisted.trial import unittest
  11. class WireTests(unittest.TestCase):
  12. """
  13. Test wire protocols.
  14. """
  15. def test_echo(self):
  16. """
  17. Test wire.Echo protocol: send some data and check it send it back.
  18. """
  19. t = proto_helpers.StringTransport()
  20. a = wire.Echo()
  21. a.makeConnection(t)
  22. a.dataReceived(b"hello")
  23. a.dataReceived(b"world")
  24. a.dataReceived(b"how")
  25. a.dataReceived(b"are")
  26. a.dataReceived(b"you")
  27. self.assertEqual(t.value(), b"helloworldhowareyou")
  28. def test_who(self):
  29. """
  30. Test wire.Who protocol.
  31. """
  32. t = proto_helpers.StringTransport()
  33. a = wire.Who()
  34. a.makeConnection(t)
  35. self.assertEqual(t.value(), b"root\r\n")
  36. def test_QOTD(self):
  37. """
  38. Test wire.QOTD protocol.
  39. """
  40. t = proto_helpers.StringTransport()
  41. a = wire.QOTD()
  42. a.makeConnection(t)
  43. self.assertEqual(t.value(), b"An apple a day keeps the doctor away.\r\n")
  44. def test_discard(self):
  45. """
  46. Test wire.Discard protocol.
  47. """
  48. t = proto_helpers.StringTransport()
  49. a = wire.Discard()
  50. a.makeConnection(t)
  51. a.dataReceived(b"hello")
  52. a.dataReceived(b"world")
  53. a.dataReceived(b"how")
  54. a.dataReceived(b"are")
  55. a.dataReceived(b"you")
  56. self.assertEqual(t.value(), b"")
  57. class TestableProxyClientFactory(portforward.ProxyClientFactory):
  58. """
  59. Test proxy client factory that keeps the last created protocol instance.
  60. @ivar protoInstance: the last instance of the protocol.
  61. @type protoInstance: L{portforward.ProxyClient}
  62. """
  63. def buildProtocol(self, addr):
  64. """
  65. Create the protocol instance and keeps track of it.
  66. """
  67. proto = portforward.ProxyClientFactory.buildProtocol(self, addr)
  68. self.protoInstance = proto
  69. return proto
  70. class TestableProxyFactory(portforward.ProxyFactory):
  71. """
  72. Test proxy factory that keeps the last created protocol instance.
  73. @ivar protoInstance: the last instance of the protocol.
  74. @type protoInstance: L{portforward.ProxyServer}
  75. @ivar clientFactoryInstance: client factory used by C{protoInstance} to
  76. create forward connections.
  77. @type clientFactoryInstance: L{TestableProxyClientFactory}
  78. """
  79. def buildProtocol(self, addr):
  80. """
  81. Create the protocol instance, keeps track of it, and makes it use
  82. C{clientFactoryInstance} as client factory.
  83. """
  84. proto = portforward.ProxyFactory.buildProtocol(self, addr)
  85. self.clientFactoryInstance = TestableProxyClientFactory()
  86. # Force the use of this specific instance
  87. proto.clientProtocolFactory = lambda: self.clientFactoryInstance
  88. self.protoInstance = proto
  89. return proto
  90. class PortforwardingTests(unittest.TestCase):
  91. """
  92. Test port forwarding.
  93. """
  94. def setUp(self):
  95. self.serverProtocol = wire.Echo()
  96. self.clientProtocol = protocol.Protocol()
  97. self.openPorts = []
  98. def tearDown(self):
  99. try:
  100. self.proxyServerFactory.protoInstance.transport.loseConnection()
  101. except AttributeError:
  102. pass
  103. try:
  104. pi = self.proxyServerFactory.clientFactoryInstance.protoInstance
  105. pi.transport.loseConnection()
  106. except AttributeError:
  107. pass
  108. try:
  109. self.clientProtocol.transport.loseConnection()
  110. except AttributeError:
  111. pass
  112. try:
  113. self.serverProtocol.transport.loseConnection()
  114. except AttributeError:
  115. pass
  116. return defer.gatherResults(
  117. [defer.maybeDeferred(p.stopListening) for p in self.openPorts]
  118. )
  119. def test_portforward(self):
  120. """
  121. Test port forwarding through Echo protocol.
  122. """
  123. realServerFactory = protocol.ServerFactory()
  124. realServerFactory.protocol = lambda: self.serverProtocol
  125. realServerPort = reactor.listenTCP(0, realServerFactory, interface="127.0.0.1")
  126. self.openPorts.append(realServerPort)
  127. self.proxyServerFactory = TestableProxyFactory(
  128. "127.0.0.1", realServerPort.getHost().port
  129. )
  130. proxyServerPort = reactor.listenTCP(
  131. 0, self.proxyServerFactory, interface="127.0.0.1"
  132. )
  133. self.openPorts.append(proxyServerPort)
  134. nBytes = 1000
  135. received = []
  136. d = defer.Deferred()
  137. def testDataReceived(data):
  138. received.extend(iterbytes(data))
  139. if len(received) >= nBytes:
  140. self.assertEqual(b"".join(received), b"x" * nBytes)
  141. d.callback(None)
  142. self.clientProtocol.dataReceived = testDataReceived
  143. def testConnectionMade():
  144. self.clientProtocol.transport.write(b"x" * nBytes)
  145. self.clientProtocol.connectionMade = testConnectionMade
  146. clientFactory = protocol.ClientFactory()
  147. clientFactory.protocol = lambda: self.clientProtocol
  148. reactor.connectTCP("127.0.0.1", proxyServerPort.getHost().port, clientFactory)
  149. return d
  150. def test_registerProducers(self):
  151. """
  152. The proxy client registers itself as a producer of the proxy server and
  153. vice versa.
  154. """
  155. # create a ProxyServer instance
  156. addr = address.IPv4Address("TCP", "127.0.0.1", 0)
  157. server = portforward.ProxyFactory("127.0.0.1", 0).buildProtocol(addr)
  158. # set the reactor for this test
  159. reactor = proto_helpers.MemoryReactor()
  160. server.reactor = reactor
  161. # make the connection
  162. serverTransport = proto_helpers.StringTransport()
  163. server.makeConnection(serverTransport)
  164. # check that the ProxyClientFactory is connecting to the backend
  165. self.assertEqual(len(reactor.tcpClients), 1)
  166. # get the factory instance and check it's the one we expect
  167. host, port, clientFactory, timeout, _ = reactor.tcpClients[0]
  168. self.assertIsInstance(clientFactory, portforward.ProxyClientFactory)
  169. # Connect it
  170. client = clientFactory.buildProtocol(addr)
  171. clientTransport = proto_helpers.StringTransport()
  172. client.makeConnection(clientTransport)
  173. # check that the producers are registered
  174. self.assertIs(clientTransport.producer, serverTransport)
  175. self.assertIs(serverTransport.producer, clientTransport)
  176. # check the streaming attribute in both transports
  177. self.assertTrue(clientTransport.streaming)
  178. self.assertTrue(serverTransport.streaming)
  179. class StringTransportTests(unittest.TestCase):
  180. """
  181. Test L{proto_helpers.StringTransport} helper behaviour.
  182. """
  183. def test_noUnicode(self):
  184. """
  185. Test that L{proto_helpers.StringTransport} doesn't accept unicode data.
  186. """
  187. s = proto_helpers.StringTransport()
  188. self.assertRaises(TypeError, s.write, "foo")