def test_transfer(self): """ An attempt is made to transfer the zone for the domain the L{SecondaryAuthority} was constructed with from the server address it was constructed with when L{SecondaryAuthority.transfer} is called. """ secondary = SecondaryAuthority.fromServerAddressAndDomain( ('192.168.1.2', 1234), 'example.com') secondary._reactor = reactor = MemoryReactorClock() secondary.transfer() # Verify a connection attempt to the server address above host, port, factory, timeout, bindAddress = reactor.tcpClients.pop(0) self.assertEqual(host, '192.168.1.2') self.assertEqual(port, 1234) # See if a zone transfer query is issued. proto = factory.buildProtocol((host, port)) transport = StringTransport() proto.makeConnection(transport) msg = Message() # DNSProtocol.writeMessage length encodes the message by prepending a # 2 byte message length to the buffered value. msg.decode(StringIO(transport.value()[2:])) self.assertEqual( [dns.Query('example.com', dns.AXFR, dns.IN)], msg.queries)
def setUp(self): """ Set up a store with a location, a player and an observer. """ self.store = store.Store() locContainer = createLocation( self.store, u"Test Location", u"Location for testing.") self.location = locContainer.thing self.world = ImaginaryWorld(store=self.store, origin=self.location) self.player = self.world.create( u"Test Player", gender=self.genderForTest) self.playerContainer = iimaginary.IContainer(self.player) self.playerWrapper = player.Player(self.player) self.playerWrapper.useColors = False locContainer.add(self.player) self.transport = StringTransport() self.playerWrapper.setProtocol(PlayerProtocol(self.transport)) self.observer = self.world.create( u"Observer Player", gender=language.Gender.FEMALE) self.observerWrapper = player.Player(self.observer) locContainer.add(self.observer) self.otransport = StringTransport() self.observerWrapper.setProtocol(PlayerProtocol(self.otransport)) # Clear the transport, since we don't care about the observer # arrival event. self.transport.clear()
def test_portalRejectedAnonymousSender(self): """ Test that a C{MAIL FROM} command issued without first authenticating when a portal has been configured to disallow anonymous logins is responded to with the correct error code. """ realm = SingletonRealm(smtp.IMessageDelivery, NotImplementedDelivery()) portal = Portal(realm, []) proto = smtp.SMTP() proto.portal = portal trans = StringTransport() proto.makeConnection(trans) # Deal with the necessary preliminaries proto.dataReceived('HELO example.com\r\n') trans.clear() # Try to specify our sender address proto.dataReceived('MAIL FROM:<*****@*****.**>\r\n') # Clean up the protocol before doing anything that might raise an # exception. proto.connectionLost(error.ConnectionLost()) # Make sure that we received exactly the correct response self.assertEqual( trans.value(), '550 Cannot receive from specified address ' '<*****@*****.**>: Unauthenticated senders not allowed\r\n')
def test_acceptSenderAddress(self): """ Test that a C{MAIL FROM} command with an acceptable address is responded to with the correct success code. """ class AcceptanceDelivery(NotImplementedDelivery): """ Delivery object which accepts all senders as valid. """ def validateFrom(self, helo, origin): return origin realm = SingletonRealm(smtp.IMessageDelivery, AcceptanceDelivery()) portal = Portal(realm, [AllowAnonymousAccess()]) proto = smtp.SMTP() proto.portal = portal trans = StringTransport() proto.makeConnection(trans) # Deal with the necessary preliminaries proto.dataReceived('HELO example.com\r\n') trans.clear() # Try to specify our sender address proto.dataReceived('MAIL FROM:<*****@*****.**>\r\n') # Clean up the protocol before doing anything that might raise an # exception. proto.connectionLost(error.ConnectionLost()) # Make sure that we received exactly the correct response self.assertEqual( trans.value(), '250 Sender address accepted\r\n')
def testCookieHeaderParsing(self): factory = client.HTTPClientFactory(b"http://foo.example.com/") proto = factory.buildProtocol("127.42.42.42") transport = StringTransport() proto.makeConnection(transport) for line in [ b"200 Ok", b"Squash: yes", b"Hands: stolen", b"Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT", b"Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/", b"Set-Cookie: SHIPPING=FEDEX; path=/foo", b"", b"body", b"more body", ]: proto.dataReceived(line + b"\r\n") self.assertEqual( transport.value(), b"GET / HTTP/1.0\r\n" b"Host: foo.example.com\r\n" b"User-Agent: Twisted PageGetter\r\n" b"\r\n", ) self.assertEqual( factory.cookies, {b"CUSTOMER": b"WILE_E_COYOTE", b"PART_NUMBER": b"ROCKET_LAUNCHER_0001", b"SHIPPING": b"FEDEX"}, )
def setUp(self): """ Set up a store with a location, a player and an observer. """ self.store = store.Store() self.location = objects.Thing( store=self.store, name=u"Test Location", description=u"Location for testing.", proper=True) locContainer = objects.Container.createFor(self.location, capacity=1000) self.world = ImaginaryWorld(store=self.store, origin=self.location) self.player = self.world.create( u"Test Player", gender=language.Gender.FEMALE) self.playerContainer = iimaginary.IContainer(self.player) self.playerWrapper = player.Player(self.player) self.playerWrapper.useColors = False locContainer.add(self.player) self.transport = StringTransport() self.playerWrapper.setProtocol(PlayerProtocol(self.transport)) self.observer = self.world.create( u"Observer Player", gender=language.Gender.FEMALE) self.observerWrapper = player.Player(self.observer) locContainer.add(self.observer) self.otransport = StringTransport() self.observerWrapper.setProtocol(PlayerProtocol(self.otransport)) # Clear the transport, since we don't care about the observer # arrival event. self.transport.clear()
def test_earlyHeaders(self): """ When a connection is made, L{HTTPPagerGetter} sends the headers from its factory's C{headers} dict. If I{Host} or I{Content-Length} is present in this dict, the values are not sent, since they are sent with special values before the C{headers} dict is processed. If I{User-Agent} is present in the dict, it overrides the value of the C{agent} attribute of the factory. If I{Cookie} is present in the dict, its value is added to the values from the factory's C{cookies} attribute. """ factory = client.HTTPClientFactory( b'http://foo/bar', agent=b"foobar", cookies={b'baz': b'quux'}, postdata=b"some data", headers={ b'Host': b'example.net', b'User-Agent': b'fooble', b'Cookie': b'blah blah', b'Content-Length': b'12981', b'Useful': b'value'}) transport = StringTransport() protocol = client.HTTPPageGetter() protocol.factory = factory protocol.makeConnection(transport) result = transport.value() for expectedHeader in [ b"Host: example.net\r\n", b"User-Agent: foobar\r\n", b"Content-Length: 9\r\n", b"Useful: value\r\n", b"connection: close\r\n", b"Cookie: blah blah; baz=quux\r\n"]: self.assertIn(expectedHeader, result)
def testCookieHeaderParsing(self): factory = client.HTTPClientFactory(b'http://foo.example.com/') proto = factory.buildProtocol('127.42.42.42') transport = StringTransport() proto.makeConnection(transport) for line in [ b'200 Ok', b'Squash: yes', b'Hands: stolen', b'Set-Cookie: CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT', b'Set-Cookie: PART_NUMBER=ROCKET_LAUNCHER_0001; path=/', b'Set-Cookie: SHIPPING=FEDEX; path=/foo', b'', b'body', b'more body', ]: proto.dataReceived(line + b'\r\n') self.assertEqual(transport.value(), b'GET / HTTP/1.0\r\n' b'Host: foo.example.com\r\n' b'User-Agent: Twisted PageGetter\r\n' b'\r\n') self.assertEqual(factory.cookies, { b'CUSTOMER': b'WILE_E_COYOTE', b'PART_NUMBER': b'ROCKET_LAUNCHER_0001', b'SHIPPING': b'FEDEX', })
class MockClient(Client): factory = MockFactory() def __init__(self): Client.__init__(self) self.transport = StringTransport() self.makeConnection(self.transport) def connectionMade(self): self.host = self.transport.getHost().host self.server_host = 'testing_srv' def dataReceived(self, data): LineOnlyReceiver.dataReceived(self, data) def t_get_data(self): return self.transport.value() def t_flush_data(self): self.transport.clear() def t_send_lines(self, *lines): lines = '\n'.join(lines) self.dataReceived(lines + '\n') def t_send_line(self, line): self.dataReceived(line + '\n')
def _test(self, factory, testvalue): transport = StringTransport() protocol = client.ScrapyHTTPPageGetter() protocol.factory = factory protocol.makeConnection(transport) self.assertEqual(transport.value(), testvalue) return testvalue
def test03_make_echo_with_collector(self): """ Test with correct handler used in the package. - Get the request from server - Sending the same response """ clock = Clock() sessions = Sessions(False, 10, clock) trigger = DummyTrigger() factory = GatheringFactory() collector = Collector(sessions) factory.protocol.set_handler(collector) factory.protocol.set_trigger(trigger) protocol = factory.buildProtocol(("127.0.0.1", 0)) transport = StringTransport() protocol.makeConnection(transport) protocol.dataReceived("hello") uid, ip, data = collector.get() collector.release(uid, data) self.assertEqual(transport.value(), "hello")
def _test(self, factory, testvalue): transport = StringTransport() protocol = client.pyrakeHTTPPageGetter() protocol.factory = factory protocol.makeConnection(transport) self.assertEqual( set(transport.value().splitlines()), set(testvalue.splitlines())) return testvalue
def request(self, method, uri, headers=None, bodyProducer=None): """ Implement IAgent.request. """ # We want to use Agent to parse the HTTP response, so let's ask it to # make a request against our in-memory reactor. response = self._realAgent.request(method, uri, headers, bodyProducer) # That will try to establish an HTTP connection with the reactor's # connectTCP method, and MemoryReactor will place Agent's factory into # the tcpClients list. We'll extract that. host, port, factory, timeout, bindAddress = ( self._memoryReactor.tcpClients[0]) # Then we need to convince that factory it's connected to something and # it will give us a protocol for that connection. protocol = factory.buildProtocol(None) # We want to capture the output of that connection so we'll make an # in-memory transport. clientTransport = AbortableStringTransport() # When the protocol is connected to a transport, it ought to send the # whole request because callers of this should not use an asynchronous # bodyProducer. protocol.makeConnection(clientTransport) # Get the data from the request. requestData = clientTransport.io.getvalue() # Now time for the server to do its job. Ask it to build an HTTP # channel. channel = get_site(self._rootResource).buildProtocol(None) # Connect the channel to another in-memory transport so we can collect # the response. serverTransport = StringTransport() serverTransport.hostAddr = IPv4Address('TCP', '127.0.0.1', 80) channel.makeConnection(serverTransport) # Feed it the data that the Agent synthesized. channel.dataReceived(requestData) # Tell it that the connection is now complete so it can clean up. channel.connectionLost(Failure(ConnectionDone())) # Now we have the response data, let's give it back to the Agent. protocol.dataReceived(serverTransport.io.getvalue()) # By now the Agent should have all it needs to parse a response. protocol.connectionLost(Failure(ConnectionDone())) # Return the response in the accepted format (Deferred firing # IResponse). This should be synchronously fired, and if not, it's the # system under test's problem. return response
def test_init(self): """ Initialize it with a chunk of stdin. """ p = SimpleProtocol('foo') t = StringTransport() t.closeStdin = Mock() p.makeConnection(t) self.assertEqual(t.value(), 'foo') self.assertTrue(t.closeStdin.called)
def setUp(self): """ Set up a transport, a result stream and a protocol instance. """ self.serverTransport = StringTransport() self.clientTransport = StringTransport() self.server = WorkerProtocol() self.server.makeConnection(self.serverTransport) self.client = FakeAMP() self.client.makeConnection(self.clientTransport)
def test_pid(self): """ Should have the same pid as the transport. """ p = Channel3Protocol('joe', None, MagicMock()) self.assertEqual(p.pid, None) t = StringTransport() t.pid = 23 p.makeConnection(t) self.assertEqual(p.pid, 23)
class FingerTestCase(unittest.TestCase): """ Tests for L{finger.Finger}. """ def setUp(self): """ Create and connect a L{finger.Finger} instance. """ self.transport = StringTransport() self.protocol = finger.Finger() self.protocol.makeConnection(self.transport) def test_simple(self): """ When L{finger.Finger} receives a CR LF terminated line, it responds with the default user status message - that no such user exists. """ self.protocol.dataReceived("moshez\r\n") self.assertEqual( self.transport.value(), "Login: moshez\nNo such user\n") def test_simpleW(self): """ The behavior for a query which begins with C{"/w"} is the same as the behavior for one which does not. The user is reported as not existing. """ self.protocol.dataReceived("/w moshez\r\n") self.assertEqual( self.transport.value(), "Login: moshez\nNo such user\n") def test_forwarding(self): """ When L{finger.Finger} receives a request for a remote user, it responds with a message rejecting the request. """ self.protocol.dataReceived("[email protected]\r\n") self.assertEqual( self.transport.value(), "Finger forwarding service denied\n") def test_list(self): """ When L{finger.Finger} receives a blank line, it responds with a message rejecting the request for all online users. """ self.protocol.dataReceived("\r\n") self.assertEqual( self.transport.value(), "Finger online list denied\n")
def require(packageName, fixName): if (packageName, fixName) in _alreadyInstalled: return if (packageName, fixName) == ("twisted", "filepath_copyTo"): from twisted.python import filepath if filepath.FilePath("a") != filepath.FilePath("a"): from vmc.contrib.epsilon.hotfixes import filepath_copyTo filepath_copyTo.install() elif (packageName, fixName) == ("twisted", "timeoutmixin_calllater"): from twisted.protocols import policies if not hasattr(policies.TimeoutMixin, "callLater"): from vmc.contrib.epsilon.hotfixes import timeoutmixin_calllater timeoutmixin_calllater.install() elif (packageName, fixName) == ("twisted", "delayedcall_seconds"): from twisted.internet import base args = inspect.getargs(base.DelayedCall.__init__.func_code)[0] if "seconds" not in args: from vmc.contrib.epsilon.hotfixes import delayedcall_seconds delayedcall_seconds.install() elif (packageName, fixName) == ("twisted", "deferredgenerator_tfailure"): from twisted.internet import defer result = [] def test(): d = defer.waitForDeferred(defer.succeed(1)) yield d result.append(d.getResult()) defer.deferredGenerator(test)() if result == [1]: from vmc.contrib.epsilon.hotfixes import deferredgenerator_tfailure deferredgenerator_tfailure.install() else: assert result == [None] elif (packageName, fixName) == ("twisted", "proto_helpers_stringtransport"): from twisted.test.proto_helpers import StringTransport st = StringTransport() try: st.write(u"foo") except TypeError, e: pass else: from vmc.contrib.epsilon.hotfixes import proto_helpers_stringtransport proto_helpers_stringtransport.install()
def test_eventReceived(self): """ An event should be written as JSON to the transport. """ p = EventFeedLineProtocol() p.factory = MagicMock() t = StringTransport() p.makeConnection(t) p.eventReceived(['hey', 'ho']) self.assertEqual(t.value(), json.dumps(['hey', 'ho']) + '\n')
def write(self, data): """Write some data""" StringTransport.write(self, data) if not self.done: if "\r\n\r\n" in self.value(): self.done = True self.reply_func(self.value()) else: if self.remote_func is not None: self.remote_func(self.value())
def testESMTPGreetingExtended(self): """ Test that the string "ESMTP" does appear in the ESMTP server's greeting since L{smtp.ESMTP} does support the SMTP extensions which that advertises to the client. """ s = smtp.ESMTP() t = StringTransport() s.makeConnection(t) s.connectionLost(error.ConnectionDone()) self.assertIn("ESMTP", t.value())
def testSMTPGreetingHost(self, serverClass=smtp.SMTP): """ Test that the specified hostname shows up in the SMTP server's greeting. """ s = serverClass() s.host = "example.com" t = StringTransport() s.makeConnection(t) s.connectionLost(error.ConnectionDone()) self.assertIn("example.com", t.value())
def test_login(self): """ When L{IRCProto} is connected to a transport, it sends I{NICK} and I{USER} commands with the username from the account object. """ transport = StringTransport() self.proto.makeConnection(transport) self.assertEquals( transport.value(), "NICK alice\r\n" "USER alice foo bar :Twisted-IM user\r\n")
def testSMTPGreetingNotExtended(self): """ Test that the string "ESMTP" does not appear in the SMTP server's greeting since that string strongly suggests the presence of support for various SMTP extensions which are not supported by L{smtp.SMTP}. """ s = smtp.SMTP() t = StringTransport() s.makeConnection(t) s.connectionLost(error.ConnectionDone()) self.assertNotIn("ESMTP", t.value())
class PlayerTest(unittest.TestCase): def setUp(self): self.store = store.Store() self.bob = objects.Thing(store=self.store, name=u"bob") self.room = objects.Thing(store=self.store, name=u"a place") roomContainer = Container.createFor(self.room, capacity=1000) self.bob.moveTo(roomContainer) self.actor = objects.Actor.createFor(self.bob) self.player = player.Player(self.bob) self.player.useColors = False from twisted.test.proto_helpers import StringTransport self.transport = StringTransport() class Protocol: write = self.transport.write self.player.setProtocol(Protocol()) def testSend(self): self.player.send("Hi\n") self.assertEquals(self.transport.value(), "Hi\n") self.player.send(("Hi", "\n")) self.assertEquals(self.transport.value(), "Hi\nHi\n") self.player.send(["Hi", "\n"]) self.assertEquals(self.transport.value(), "Hi\nHi\nHi\n") self.player.send(i for i in ("Hi", "\n")) self.assertEquals(self.transport.value(), "Hi\nHi\nHi\nHi\n") def testDisconnect(self): self.player.proto.terminal = None self.player.disconnect() self.assertIdentical(self.actor.getIntelligence(), None) def test_ambiguity(self): """ When the player refers to something ambiguously, the error message should enumerate the objects in question. """ for color in [u'red', u'green', u'blue']: it = objects.Thing(store=self.store, name=u'%s thing' % (color,)) it.moveTo(self.room) self.player.parse("take thing") self.assertEquals(self.transport.value(), "> take thing\n" "Could you be more specific? When you said 'thing', " "did you mean: a red thing, a green thing, " "or a blue thing?\r\n")
def test_nextLine(self): """ L{ServerProtocol.nextLine} writes C{"\r\n"} to its transport. """ # Why doesn't it write ESC E? Because ESC E is poorly supported. For # example, gnome-terminal (many different versions) fails to scroll if # it receives ESC E and the cursor is already on the last row. protocol = ServerProtocol() transport = StringTransport() protocol.makeConnection(transport) protocol.nextLine() self.assertEqual(transport.value(), b"\r\n")
def test_sendOtherError(self): """ If L{smtp.SMTPClient.sendError} is called with an exception which is not an L{SMTPClientError}, it disconnects its transport without writing anything more to it. """ client = smtp.SMTPClient(None) transport = StringTransport() client.makeConnection(transport) client.sendError(Exception("foo")) self.assertEqual(transport.value(), "") self.assertTrue(transport.disconnecting)
def test_data_cancels_timeout(self): """ When data is received, the timeout is canceled """ clock = Clock() protocol = HangCheckProtocol(Protocol(), reactor=clock) transport = StringTransport() transport.protocol = protocol protocol.makeConnection(transport) protocol.dataReceived('some-data') assert_clock_idle(self, clock)
def test_sendNonFatalError(self): """ If L{smtp.SMTPClient.sendError} is called with an L{SMTPClientError} which is not fatal, it sends C{"QUIT"} and waits for the server to close the connection. """ client = smtp.SMTPClient(None) transport = StringTransport() client.makeConnection(transport) client.sendError(smtp.SMTPClientError(123, "foo", isFatal=False)) self.assertEqual(transport.value(), "QUIT\r\n") self.assertFalse(transport.disconnecting)
def test_sendFatalError(self): """ If L{smtp.SMTPClient.sendError} is called with an L{SMTPClientError} which is fatal, it disconnects its transport without writing anything more to it. """ client = smtp.SMTPClient(None) transport = StringTransport() client.makeConnection(transport) client.sendError(smtp.SMTPClientError(123, "foo", isFatal=True)) self.assertEqual(transport.value(), "") self.assertTrue(transport.disconnecting)
def test_protocol(reactor_mock): protocol = SyncClientProtocol() transport = StringTransport() protocol.makeConnection(transport) # test send event - created or deleted # test for folder protocol.send_event("created", True, "./test") assert transport.value() == b"created::1::./test\r\r\r\n\n\n" transport.clear() # test for file protocol.send_event("deleted", False, "./test1.log") assert transport.value() == b"deleted::0::./test1.log\r\r\r\n\n\n" transport.clear() # test moved event # test for folder protocol.send_move_event(True, "./test1", "./test2") assert transport.value() == b"moved::1::./test1::./test2\r\r\r\n\n\n" transport.clear() # test for file protocol.send_move_event(False, "./test1.log", "./test2.log") assert transport.value( ) == b"moved::0::./test1.log::./test2.log\r\r\r\n\n\n" transport.clear() # test modify event protocol.send_modify_event("./test.log", b"Logging data for testing.") assert transport.value( ) == b"modified::0::./test.log::Logging data for testing.\r\r\r\n\n\n" transport.clear() # test connection lost protocol.connectionLost("test reason") reactor_mock.stop.assert_called_once()
class WsClientMethodsTestCase(unittest.TestCase): def setUp(self): self.transport = StringTransport() self.handler = Handler() self.factory = WebSocketFactory(self.handler) self.proto = self.factory.buildProtocol(None) self.proto.makeConnection(self.transport) self.proto.dataReceived('HTTP/1.1 101 OK\r\n\r\n') self.proto.socket.rand = Random(1) self.transport.clear() def test_notify(self): self.transport.clear() defer = self.factory.notify('nt', {'a':1,'b':2}, device_id='123', device_key='321') s = decode_ws_message(self.transport.value()) self.assertEquals({u'action': u'notification/insert', u'notification': {u'notification': u'nt', u'parameters': {u'a': 1, u'b': 2}}, u'deviceKey': u'321', u'deviceId': u'123', u'requestId': max(self.proto.msg_callbacks.keys())}, json.loads(s)) def test_subscribe(self): self.transport.clear() defer = self.factory.subscribe('123', '321') s = decode_ws_message(self.transport.value()) self.assertEquals({u'action': u'command/subscribe', u'deviceId': u'123', u'deviceKey': u'321', u'requestId': max(self.proto.msg_callbacks.keys())}, json.loads(s)) def test_unsubscribe(self): self.transport.clear() defer = self.factory.unsubscribe('123', '312') s = decode_ws_message(self.transport.value()) self.assertEquals({u'action': u'command/unsubscribe', u'deviceKey': u'312', u'deviceId': u'123', u'requestId': max(self.proto.msg_callbacks.keys())}, json.loads(s)) def test_authenticate(self): self.factory.authenticate('123', '321') s = decode_ws_message(self.transport.value()) self.assertEquals({u'action': u'authenticate', u'deviceId': u'123', u'deviceKey': u'321', u'requestId': max(self.proto.msg_callbacks.keys())}, json.loads(s)) def create_test_device(self): class TestDev(object): implements(IDeviceInfo) id = 'td_id' key = 'td_key' name = 'td_name' equipment = [] status = None network = None device_class = None data = None return TestDev() def test_device_save_minimal_message(self): info = self.create_test_device() self.factory.device_save(info) s = decode_ws_message(self.transport.value()) self.assertDictEqual({ u'action': u'device/save', u'device': { u'equipment': [], u'name': u'td_name', u'key': u'td_key', }, u'deviceKey': u'td_key', u'deviceId': u'td_id', u'requestId': max(self.proto.msg_callbacks.keys()), }, json.loads(s)) def test_device_save_with_equipment(self): info = self.create_test_device() info.equipment = (devicehive.Equipment(name='en', code='cd', type='tp', data=None), ) self.factory.device_save(info) s = decode_ws_message(self.transport.value()) self.assertDictEqual({ u'action': u'device/save', u'device': { u'equipment': [{u'name': u'en', u'code': u'cd', u'type': u'tp', }, ], u'name': u'td_name', u'key': u'td_key' }, u'deviceKey': u'td_key', u'deviceId': u'td_id', u'requestId': max(self.proto.msg_callbacks.keys()), }, json.loads(s)) def test_device_save_with_equipment_and_data(self): info = self.create_test_device() info.equipment = (devicehive.Equipment(name='en', code='cd', type='tp', data='dt'), ) self.factory.device_save(info) s = decode_ws_message(self.transport.value()) self.assertDictEqual({ u'action': u'device/save', u'device': { u'equipment': [{u'name': u'en', u'code': u'cd', u'type': u'tp', u'data': u'dt', }, ], u'name': u'td_name', u'key': u'td_key' }, u'deviceKey': u'td_key', u'deviceId': u'td_id', u'requestId': max(self.proto.msg_callbacks.keys()), }, json.loads(s)) def test_device_save_with_network(self): info = self.create_test_device() info.network = devicehive.Network(id='nid', key='nkey', name='nname', descr='ndesr') self.factory.device_save(info) result = json.loads(decode_ws_message(self.transport.value())) self.assertDictEqual({ u'action': u'device/save', u'device': { u'equipment': [], u'name': u'td_name', u'key': u'td_key', u'network': { u'id': u'nid', u'name': u'nname', u'key': u'nkey', u'description': 'ndesr' } }, u'deviceKey': u'td_key', u'deviceId': u'td_id', u'requestId': max(self.proto.msg_callbacks.keys()), }, result)
class ESMTPAuthenticationTestCase(unittest.TestCase): def assertServerResponse(self, bytes, response): """ Assert that when the given bytes are delivered to the ESMTP server instance, it responds with the indicated lines. @type bytes: str @type response: list of str """ self.transport.clear() self.server.dataReceived(bytes) self.assertEqual(response, self.transport.value().splitlines()) def assertServerAuthenticated(self, loginArgs, username="******", password="******"): """ Assert that a login attempt has been made, that the credentials and interfaces passed to it are correct, and that when the login request is satisfied, a successful response is sent by the ESMTP server instance. @param loginArgs: A C{list} previously passed to L{portalFactory}. """ d, credentials, mind, interfaces = loginArgs.pop() self.assertEqual(loginArgs, []) self.failUnless( twisted.cred.credentials.IUsernamePassword.providedBy(credentials)) self.assertEqual(credentials.username, username) self.failUnless(credentials.checkPassword(password)) self.assertIn(smtp.IMessageDeliveryFactory, interfaces) self.assertIn(smtp.IMessageDelivery, interfaces) d.callback((smtp.IMessageDeliveryFactory, None, lambda: None)) self.assertEqual(["235 Authentication successful."], self.transport.value().splitlines()) def setUp(self): """ Create an ESMTP instance attached to a StringTransport. """ self.server = smtp.ESMTP({'LOGIN': imap4.LOGINCredentials}) self.server.host = 'localhost' self.transport = StringTransport( peerAddress=address.IPv4Address('TCP', '127.0.0.1', 12345)) self.server.makeConnection(self.transport) def tearDown(self): """ Disconnect the ESMTP instance to clean up its timeout DelayedCall. """ self.server.connectionLost(error.ConnectionDone()) def portalFactory(self, loginList): class DummyPortal: def login(self, credentials, mind, *interfaces): d = defer.Deferred() loginList.append((d, credentials, mind, interfaces)) return d return DummyPortal() def test_authenticationCapabilityAdvertised(self): """ Test that AUTH is advertised to clients which issue an EHLO command. """ self.transport.clear() self.server.dataReceived('EHLO\r\n') responseLines = self.transport.value().splitlines() self.assertEqual(responseLines[0], "250-localhost Hello 127.0.0.1, nice to meet you") self.assertEqual(responseLines[1], "250 AUTH LOGIN") self.assertEqual(len(responseLines), 2) def test_plainAuthentication(self): """ Test that the LOGIN authentication mechanism can be used """ loginArgs = [] self.server.portal = self.portalFactory(loginArgs) self.server.dataReceived('EHLO\r\n') self.transport.clear() self.assertServerResponse( 'AUTH LOGIN\r\n', ["334 " + "User Name\0".encode('base64').strip()]) self.assertServerResponse( 'username'.encode('base64') + '\r\n', ["334 " + "Password\0".encode('base64').strip()]) self.assertServerResponse('password'.encode('base64').strip() + '\r\n', []) self.assertServerAuthenticated(loginArgs) def test_plainAuthenticationEmptyPassword(self): """ Test that giving an empty password for plain auth succeeds. """ loginArgs = [] self.server.portal = self.portalFactory(loginArgs) self.server.dataReceived('EHLO\r\n') self.transport.clear() self.assertServerResponse( 'AUTH LOGIN\r\n', ["334 " + "User Name\0".encode('base64').strip()]) self.assertServerResponse( 'username'.encode('base64') + '\r\n', ["334 " + "Password\0".encode('base64').strip()]) self.assertServerResponse('\r\n', []) self.assertServerAuthenticated(loginArgs, password='') def test_plainAuthenticationInitialResponse(self): """ The response to the first challenge may be included on the AUTH command line. Test that this is also supported. """ loginArgs = [] self.server.portal = self.portalFactory(loginArgs) self.server.dataReceived('EHLO\r\n') self.transport.clear() self.assertServerResponse( 'AUTH LOGIN ' + "username".encode('base64').strip() + '\r\n', ["334 " + "Password\0".encode('base64').strip()]) self.assertServerResponse('password'.encode('base64').strip() + '\r\n', []) self.assertServerAuthenticated(loginArgs) def test_abortAuthentication(self): """ Test that a challenge/response sequence can be aborted by the client. """ loginArgs = [] self.server.portal = self.portalFactory(loginArgs) self.server.dataReceived('EHLO\r\n') self.server.dataReceived('AUTH LOGIN\r\n') self.assertServerResponse('*\r\n', ['501 Authentication aborted']) def test_invalidBase64EncodedResponse(self): """ Test that a response which is not properly Base64 encoded results in the appropriate error code. """ loginArgs = [] self.server.portal = self.portalFactory(loginArgs) self.server.dataReceived('EHLO\r\n') self.server.dataReceived('AUTH LOGIN\r\n') self.assertServerResponse( 'x\r\n', ['501 Syntax error in parameters or arguments']) self.assertEqual(loginArgs, []) def test_invalidBase64EncodedInitialResponse(self): """ Like L{test_invalidBase64EncodedResponse} but for the case of an initial response included with the C{AUTH} command. """ loginArgs = [] self.server.portal = self.portalFactory(loginArgs) self.server.dataReceived('EHLO\r\n') self.assertServerResponse( 'AUTH LOGIN x\r\n', ['501 Syntax error in parameters or arguments']) self.assertEqual(loginArgs, [])
def test_resetTimeoutWhileSending(self): """ The timeout is not allowed to expire after the server has accepted a DATA command and the client is actively sending data to it. """ class SlowFile: """ A file-like which returns one byte from each read call until the specified number of bytes have been returned. """ def __init__(self, size): self._size = size def read(self, max=None): if self._size: self._size -= 1 return 'x' return '' failed = [] onDone = defer.Deferred() onDone.addErrback(failed.append) clientFactory = smtp.SMTPSenderFactory('source@address', 'recipient@address', SlowFile(1), onDone, retries=0, timeout=3) clientFactory.domain = "example.org" clock = task.Clock() client = clientFactory.buildProtocol( address.IPv4Address('TCP', 'example.net', 25)) client.callLater = clock.callLater transport = StringTransport() client.makeConnection(transport) client.dataReceived("220 Ok\r\n" # Greet the client "250 Ok\r\n" # Respond to HELO "250 Ok\r\n" # Respond to MAIL FROM "250 Ok\r\n" # Respond to RCPT TO "354 Ok\r\n" # Respond to DATA ) # Now the client is producing data to the server. Any time # resumeProducing is called on the producer, the timeout should be # extended. First, a sanity check. This test is only written to # handle pull producers. self.assertNotIdentical(transport.producer, None) self.assertFalse(transport.streaming) # Now, allow 2 seconds (1 less than the timeout of 3 seconds) to # elapse. clock.advance(2) # The timeout has not expired, so the failure should not have happened. self.assertEqual(failed, []) # Let some bytes be produced, extending the timeout. Then advance the # clock some more and verify that the timeout still hasn't happened. transport.producer.resumeProducing() clock.advance(2) self.assertEqual(failed, []) # The file has been completely produced - the next resume producing # finishes the upload, successfully. transport.producer.resumeProducing() client.dataReceived("250 Ok\r\n") self.assertEqual(failed, []) # Verify that the client actually did send the things expected. self.assertEqual( transport.value(), "HELO example.org\r\n" "MAIL FROM:<source@address>\r\n" "RCPT TO:<recipient@address>\r\n" "DATA\r\n" "x\r\n" ".\r\n" # This RSET is just an implementation detail. It's nice, but this # test doesn't really care about it. "RSET\r\n")
def setUp(self): carbon_client.settings = TestSettings() # reset to defaults factory = CarbonClientFactory(('127.0.0.1', 2003, 'a')) self.protocol = factory.buildProtocol(('127.0.0.1', 2003)) self.transport = StringTransport() self.protocol.makeConnection(self.transport)
def __init__(self): self.string_transport = StringTransport()
def test_multipartFormatCorrection(self): requestBody = BytesIO() class TestRequest(DreamuploaderRequest): def process(self): requestBody.write(self.content.read()) self.write(b"done") self.finish() channel = http.HTTPChannel() channel.requestFactory = TestRequest transport = StringTransport() channel.makeConnection(transport) channel.dataReceived(b'''\ POST /upload HTTP/1.0 User-Agent: Mozilla/3.0 (DreamPassport/3.15) Content-Type: multipart/form-data; boundary=-----------------------------3943144700513 Content-Length: 6714 -----------------------------3943144700513 Content-Disposition: form-data; name="upfile" filename=C_TAXI02.R00&fs=4608&bl=9&tp=0&fl=16&of=0&tm=200508210125370 SVS+ENT4QdFb7eA5EOA5EYceSyJDENzZXYM56aA5IMyS9YNDEYzZyYY5EOA5EOA5YY2LdSS5YZ5YyaWy yAAAAAYAASAAAccUeRvAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2/vAHSLRK////RL0AAAAAAAAAAAAAAAA AAAAAAAAAAAZAAAAAAAAAAAAASAAAAAAAzAAAAAAASAAASAAASAAASASAAAAAzAAAZYAAZAAAAYAAAAA AAASAAASAAYAAAYAAZAAASAAYAAZAAAZAAAzAAASAAYAAAYZAAAAAZAZYAAAASAZYAAOEaEaAAASASAA AAYAAzAeE+Ea6+EZAZYAAAAzAAASEkEaEa6kESAZYAAAYSAAYt6aEaEt6kEAAzAZAzYAAO6+EaEaEk6+ AAYSASYzYAEtEaEk6+Et6bAzYAYZYzYt6+Ek6kEaEtEzYzAZAZYeEaEt6k6+EaEbYzYAASAZEazO6k6k EaEaEzYSAAAAAeTYEt6k6aEaE5YzYAAAAZEaEa6k6+EaEaAZYzYAAAYeTOEt6kEaEaE5YzYzYAYzEaEa Et6aEaEaYzYzYzYzYe6MTOEaEaEaEzYzYzYzYzEkEaEaEaEaEzzYzYzYzOYe6+EaEaEaEbNYzOEMzYEb YtEaEaE+YzYIzYEazYSaEzEaEaEt6+YzzYSaTYzOEbYeEaEa6k6bNYzYzYzYEaYzYaEaEk6+YIzYEMzO EaEzYzEaEt6k6bzYSaTYSaEbYzYeEa6k6+NYzOEMzYEbYzYzYe6k6+EIzYEazYSaEzYzYzyeEaTyIaEa EeEaEbYzYzYyyyyyyyYaEbYeEaYzYzYzYzYzYzYzYzYzYzYzYzYzYyTNIO2R69IGSYZASYZASYZASYZA zY6uPeVmIOVL6LM26IEVzIcL6IcASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASLER6LIRiLEF6LY+c96wP9AR6LAR6LAR6LAR6LAR6LA+6LZImMYjXOJTmtEjIMZASYZA SYZASO2R6LAR6LAR6LAR6LAR6LAR6tARSYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAEOA5EOZLSyE5P+ZTS2ycSIGASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAEOARTk60Et6GSYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAcO2+EYceSyJDENT3SIzASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAS2NeSYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAeIcN9INiSYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZA6LYu6LAR6LAR6LIRiLEF6LY+cIZASYZASYZASYZASYZASYZA SYZAATC6AAZLQrNo7yzb7dM+PIbJqdVbg0y+PIzLP9ER6LY5EOA5EA5AAAAZAAAAAAAAAAAAAAO5O5AA pRAAALQiAAAAAAAAAAAAAAAAAAAAAAAAAIkxyNSqy4EcIrNe54yeKyPIIs4eH4SbBMUY94Ji/zSiLBGi vYogB4yevNPyI84OgRVySaFaSba/Q5V+Yyy+EBEUQMu+Byy+aBm7Q8c+U4YZQxJH9sGia5YZAtNiOyGi AyGyBE4Q44+4BPzyBPWQFVk6B6GyB6uQsV+CBmNyBTbQM4+cBE4yBEDQbN+LBETzZN+ZB4FHBnuyBnyQ f4FpBdZyBNuQyVFIBNTyBNcQyVFqBdzyBduQQyFVBnbyBnJQlNFWBnGz6NF/B4F/BnVyBnJQqVFkBnZy BdGQfNF8BdJyBduQfNFRBnzyBnqQ74FvBnVNeVFHBnW7BnvyZyFHBnVQlNF1SSEZBnFQ7VFvBnVNONFH BnW7BnGyBnFQ74FwBnyNAVFkBnTQQyF+yyFkBnzQqVFoyyFvBnVQl4F/yAT7BnWQl4FvzSNQ7VFoBn4Q 74yQlNFWBnGQlVSNB4F/BnFQ7NyQQVFuBdbQDYIZBdNQBVF7BdNyBd4QfVF2BnqyBnJQlNFWBnGznNF/ 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 -----------------------------3943144700513 Content-Disposition: form-data; name="name" CTAXI2R0 -----------------------------3943144700513 Content-Disposition: form-data; name="submit" Upload -----------------------------3943144700513-- '''.replace(b"\n", b"\r\n")) channel.connectionLost(IOError("all done")) self.assertEqual( requestBody.getvalue().replace(b"\r\n", b"\n"), b'''\ -------------------------------3943144700513 Content-Disposition: form-data; name="upfile" filename=C_TAXI02.R00&fs=4608&bl=9&tp=0&fl=16&of=0&tm=200508210125370 SVS+ENT4QdFb7eA5EOA5EYceSyJDENzZXYM56aA5IMyS9YNDEYzZyYY5EOA5EOA5YY2LdSS5YZ5YyaWy yAAAAAYAASAAAccUeRvAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2/vAHSLRK////RL0AAAAAAAAAAAAAAAA AAAAAAAAAAAZAAAAAAAAAAAAASAAAAAAAzAAAAAAASAAASAAASAAASASAAAAAzAAAZYAAZAAAAYAAAAA AAASAAASAAYAAAYAAZAAASAAYAAZAAAZAAAzAAASAAYAAAYZAAAAAZAZYAAAASAZYAAOEaEaAAASASAA AAYAAzAeE+Ea6+EZAZYAAAAzAAASEkEaEa6kESAZYAAAYSAAYt6aEaEt6kEAAzAZAzYAAO6+EaEaEk6+ AAYSASYzYAEtEaEk6+Et6bAzYAYZYzYt6+Ek6kEaEtEzYzAZAZYeEaEt6k6+EaEbYzYAASAZEazO6k6k EaEaEzYSAAAAAeTYEt6k6aEaE5YzYAAAAZEaEa6k6+EaEaAZYzYAAAYeTOEt6kEaEaE5YzYzYAYzEaEa Et6aEaEaYzYzYzYzYe6MTOEaEaEaEzYzYzYzYzEkEaEaEaEaEzzYzYzYzOYe6+EaEaEaEbNYzOEMzYEb YtEaEaE+YzYIzYEazYSaEzEaEaEt6+YzzYSaTYzOEbYeEaEa6k6bNYzYzYzYEaYzYaEaEk6+YIzYEMzO EaEzYzEaEt6k6bzYSaTYSaEbYzYeEa6k6+NYzOEMzYEbYzYzYe6k6+EIzYEazYSaEzYzYzyeEaTyIaEa EeEaEbYzYzYyyyyyyyYaEbYeEaYzYzYzYzYzYzYzYzYzYzYzYzYzYyTNIO2R69IGSYZASYZASYZASYZA zY6uPeVmIOVL6LM26IEVzIcL6IcASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASLER6LIRiLEF6LY+c96wP9AR6LAR6LAR6LAR6LAR6LA+6LZImMYjXOJTmtEjIMZASYZA SYZASO2R6LAR6LAR6LAR6LAR6LAR6tARSYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAEOA5EOZLSyE5P+ZTS2ycSIGASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAEOARTk60Et6GSYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAcO2+EYceSyJDENT3SIzASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAS2NeSYZASYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZAeIcN9INiSYZASYZASYZASYZASYZASYZASYZASYZASYZASYZA SYZASYZASYZASYZASYZASYZASYZASYZA6LYu6LAR6LAR6LIRiLEF6LY+cIZASYZASYZASYZASYZASYZA SYZAATC6AAZLQrNo7yzb7dM+PIbJqdVbg0y+PIzLP9ER6LY5EOA5EA5AAAAZAAAAAAAAAAAAAAO5O5AA pRAAALQiAAAAAAAAAAAAAAAAAAAAAAAAAIkxyNSqy4EcIrNe54yeKyPIIs4eH4SbBMUY94Ji/zSiLBGi vYogB4yevNPyI84OgRVySaFaSba/Q5V+Yyy+EBEUQMu+Byy+aBm7Q8c+U4YZQxJH9sGia5YZAtNiOyGi AyGyBE4Q44+4BPzyBPWQFVk6B6GyB6uQsV+CBmNyBTbQM4+cBE4yBEDQbN+LBETzZN+ZB4FHBnuyBnyQ f4FpBdZyBNuQyVFIBNTyBNcQyVFqBdzyBduQQyFVBnbyBnJQlNFWBnGz6NF/B4F/BnVyBnJQqVFkBnZy BdGQfNF8BdJyBduQfNFRBnzyBnqQ74FvBnVNeVFHBnW7BnvyZyFHBnVQlNF1SSEZBnFQ7VFvBnVNONFH BnW7BnGyBnFQ74FwBnyNAVFkBnTQQyF+yyFkBnzQqVFoyyFvBnVQl4F/yAT7BnWQl4FvzSNQ7VFoBn4Q 74yQlNFWBnGQlVSNB4F/BnFQ7NyQQVFuBdbQDYIZBdNQBVF7BdNyBd4QfVF2BnqyBnJQlNFWBnGznNF/ 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 -------------------------------3943144700513 Content-Disposition: form-data; name="name" CTAXI2R0 -------------------------------3943144700513 Content-Disposition: form-data; name="submit" Upload -------------------------------3943144700513-- ''')
class ServerProtocolOutputTests(unittest.TestCase): """ Tests for the bytes L{ServerProtocol} writes to its transport when its methods are called. """ # From ECMA 48: CSI is represented by bit combinations 01/11 # (representing ESC) and 05/11 in a 7-bit code or by bit # combination 09/11 in an 8-bit code ESC = _ecmaCodeTableCoordinate(1, 11) CSI = ESC + _ecmaCodeTableCoordinate(5, 11) def setUp(self): self.protocol = ServerProtocol() self.transport = StringTransport() self.protocol.makeConnection(self.transport) def test_cursorUp(self): """ L{ServerProtocol.cursorUp} writes the control sequence ending with L{CSFinalByte.CUU} to its transport. """ self.protocol.cursorUp(1) self.assertEqual(self.transport.value(), self.CSI + b"1" + CSFinalByte.CUU.value) def test_cursorDown(self): """ L{ServerProtocol.cursorDown} writes the control sequence ending with L{CSFinalByte.CUD} to its transport. """ self.protocol.cursorDown(1) self.assertEqual(self.transport.value(), self.CSI + b"1" + CSFinalByte.CUD.value) def test_cursorForward(self): """ L{ServerProtocol.cursorForward} writes the control sequence ending with L{CSFinalByte.CUF} to its transport. """ self.protocol.cursorForward(1) self.assertEqual(self.transport.value(), self.CSI + b"1" + CSFinalByte.CUF.value) def test_cursorBackward(self): """ L{ServerProtocol.cursorBackward} writes the control sequence ending with L{CSFinalByte.CUB} to its transport. """ self.protocol.cursorBackward(1) self.assertEqual(self.transport.value(), self.CSI + b"1" + CSFinalByte.CUB.value) def test_cursorPosition(self): """ L{ServerProtocol.cursorPosition} writes a control sequence ending with L{CSFinalByte.CUP} and containing the expected coordinates to its transport. """ self.protocol.cursorPosition(0, 0) self.assertEqual(self.transport.value(), self.CSI + b"1;1" + CSFinalByte.CUP.value) def test_cursorHome(self): """ L{ServerProtocol.cursorHome} writes a control sequence ending with L{CSFinalByte.CUP} and no parameters, so that the client defaults to (1, 1). """ self.protocol.cursorHome() self.assertEqual(self.transport.value(), self.CSI + CSFinalByte.CUP.value) def test_index(self): """ L{ServerProtocol.index} writes the control sequence ending in the 8-bit code table coordinates 4, 4. Note that ECMA48 5th Edition removes C{IND}. """ self.protocol.index() self.assertEqual(self.transport.value(), self.ESC + _ecmaCodeTableCoordinate(4, 4)) def test_reverseIndex(self): """ L{ServerProtocol.reverseIndex} writes the control sequence ending in the L{C1SevenBit.RI}. """ self.protocol.reverseIndex() self.assertEqual(self.transport.value(), self.ESC + C1SevenBit.RI.value) def test_nextLine(self): """ L{ServerProtocol.nextLine} writes C{"\r\n"} to its transport. """ # Why doesn't it write ESC E? Because ESC E is poorly supported. For # example, gnome-terminal (many different versions) fails to scroll if # it receives ESC E and the cursor is already on the last row. self.protocol.nextLine() self.assertEqual(self.transport.value(), b"\r\n") def test_setModes(self): """ L{ServerProtocol.setModes} writes a control sequence containing the requested modes and ending in the L{CSFinalByte.SM}. """ modesToSet = [modes.KAM, modes.IRM, modes.LNM] self.protocol.setModes(modesToSet) self.assertEqual( self.transport.value(), self.CSI + b";".join(b"%d" % (m, ) for m in modesToSet) + CSFinalByte.SM.value, ) def test_setPrivateModes(self): """ L{ServerProtocol.setPrivatesModes} writes a control sequence containing the requested private modes and ending in the L{CSFinalByte.SM}. """ privateModesToSet = [ privateModes.ERROR, privateModes.COLUMN, privateModes.ORIGIN, ] self.protocol.setModes(privateModesToSet) self.assertEqual( self.transport.value(), self.CSI + b";".join(b"%d" % (m, ) for m in privateModesToSet) + CSFinalByte.SM.value, ) def test_resetModes(self): """ L{ServerProtocol.resetModes} writes the control sequence ending in the L{CSFinalByte.RM}. """ modesToSet = [modes.KAM, modes.IRM, modes.LNM] self.protocol.resetModes(modesToSet) self.assertEqual( self.transport.value(), self.CSI + b";".join(b"%d" % (m, ) for m in modesToSet) + CSFinalByte.RM.value, ) def test_singleShift2(self): """ L{ServerProtocol.singleShift2} writes an escape sequence followed by L{C1SevenBit.SS2} """ self.protocol.singleShift2() self.assertEqual(self.transport.value(), self.ESC + C1SevenBit.SS2.value) def test_singleShift3(self): """ L{ServerProtocol.singleShift3} writes an escape sequence followed by L{C1SevenBit.SS3} """ self.protocol.singleShift3() self.assertEqual(self.transport.value(), self.ESC + C1SevenBit.SS3.value) def test_selectGraphicRendition(self): """ L{ServerProtocol.selectGraphicRendition} writes a control sequence containing the requested attributes and ending with L{CSFinalByte.SGR} """ self.protocol.selectGraphicRendition(str(BLINK), str(UNDERLINE)) self.assertEqual( self.transport.value(), self.CSI + b"%d;%d" % (BLINK, UNDERLINE) + CSFinalByte.SGR.value, ) def test_horizontalTabulationSet(self): """ L{ServerProtocol.horizontalTabulationSet} writes the escape sequence ending in L{C1SevenBit.HTS} """ self.protocol.horizontalTabulationSet() self.assertEqual(self.transport.value(), self.ESC + C1SevenBit.HTS.value) def test_eraseToLineEnd(self): """ L{ServerProtocol.eraseToLineEnd} writes the control sequence sequence ending in L{CSFinalByte.EL} and no parameters, forcing the client to default to 0 (from the active present position's current location to the end of the line.) """ self.protocol.eraseToLineEnd() self.assertEqual(self.transport.value(), self.CSI + CSFinalByte.EL.value) def test_eraseToLineBeginning(self): """ L{ServerProtocol.eraseToLineBeginning} writes the control sequence sequence ending in L{CSFinalByte.EL} and a parameter of 1 (from the beginning of the line up to and include the active present position's current location.) """ self.protocol.eraseToLineBeginning() self.assertEqual(self.transport.value(), self.CSI + b"1" + CSFinalByte.EL.value) def test_eraseLine(self): """ L{ServerProtocol.eraseLine} writes the control sequence sequence ending in L{CSFinalByte.EL} and a parameter of 2 (the entire line.) """ self.protocol.eraseLine() self.assertEqual(self.transport.value(), self.CSI + b"2" + CSFinalByte.EL.value) def test_eraseToDisplayEnd(self): """ L{ServerProtocol.eraseToDisplayEnd} writes the control sequence sequence ending in L{CSFinalByte.ED} and no parameters, forcing the client to default to 0 (from the active present position's current location to the end of the page.) """ self.protocol.eraseToDisplayEnd() self.assertEqual(self.transport.value(), self.CSI + CSFinalByte.ED.value) def test_eraseToDisplayBeginning(self): """ L{ServerProtocol.eraseToDisplayBeginning} writes the control sequence sequence ending in L{CSFinalByte.ED} a parameter of 1 (from the beginning of the page up to and include the active present position's current location.) """ self.protocol.eraseToDisplayBeginning() self.assertEqual(self.transport.value(), self.CSI + b"1" + CSFinalByte.ED.value) def test_eraseToDisplay(self): """ L{ServerProtocol.eraseDisplay} writes the control sequence sequence ending in L{CSFinalByte.ED} a parameter of 2 (the entire page) """ self.protocol.eraseDisplay() self.assertEqual(self.transport.value(), self.CSI + b"2" + CSFinalByte.ED.value) def test_deleteCharacter(self): """ L{ServerProtocol.deleteCharacter} writes the control sequence containing the number of characters to delete and ending in L{CSFinalByte.DCH} """ self.protocol.deleteCharacter(4) self.assertEqual(self.transport.value(), self.CSI + b"4" + CSFinalByte.DCH.value) def test_insertLine(self): """ L{ServerProtocol.insertLine} writes the control sequence containing the number of lines to insert and ending in L{CSFinalByte.IL} """ self.protocol.insertLine(5) self.assertEqual(self.transport.value(), self.CSI + b"5" + CSFinalByte.IL.value) def test_deleteLine(self): """ L{ServerProtocol.deleteLine} writes the control sequence containing the number of lines to delete and ending in L{CSFinalByte.DL} """ self.protocol.deleteLine(6) self.assertEqual(self.transport.value(), self.CSI + b"6" + CSFinalByte.DL.value) def test_setScrollRegionNoArgs(self): """ With no arguments, L{ServerProtocol.setScrollRegion} writes a control sequence with no parameters, but a parameter separator, and ending in C{b'r'}. """ self.protocol.setScrollRegion() self.assertEqual(self.transport.value(), self.CSI + b";" + b"r") def test_setScrollRegionJustFirst(self): """ With just a value for its C{first} argument, L{ServerProtocol.setScrollRegion} writes a control sequence with that parameter, a parameter separator, and finally a C{b'r'}. """ self.protocol.setScrollRegion(first=1) self.assertEqual(self.transport.value(), self.CSI + b"1;" + b"r") def test_setScrollRegionJustLast(self): """ With just a value for its C{last} argument, L{ServerProtocol.setScrollRegion} writes a control sequence with a parameter separator, that parameter, and finally a C{b'r'}. """ self.protocol.setScrollRegion(last=1) self.assertEqual(self.transport.value(), self.CSI + b";1" + b"r") def test_setScrollRegionFirstAndLast(self): """ When given both C{first} and C{last} L{ServerProtocol.setScrollRegion} writes a control sequence with the first parameter, a parameter separator, the last parameter, and finally a C{b'r'}. """ self.protocol.setScrollRegion(first=1, last=2) self.assertEqual(self.transport.value(), self.CSI + b"1;2" + b"r") def test_reportCursorPosition(self): """ L{ServerProtocol.reportCursorPosition} writes a control sequence ending in L{CSFinalByte.DSR} with a parameter of 6 (the Device Status Report returns the current active position.) """ self.protocol.reportCursorPosition() self.assertEqual(self.transport.value(), self.CSI + b"6" + CSFinalByte.DSR.value)
class ClientControlSequencesTests(unittest.TestCase, MockMixin): def setUp(self): self.transport = StringTransport() self.proto = Mock() self.parser = ClientProtocol(lambda: self.proto) self.parser.factory = self self.parser.makeConnection(self.transport) result = self.assertCall( occurrences(self.proto).pop(0), "makeConnection", (self.parser, )) self.assertFalse(occurrences(result)) def testSimpleCardinals(self): self.parser.dataReceived(b"".join(b"\x1b[" + n + ch for ch in iterbytes(b"BACD") for n in (b"", b"2", b"20", b"200"))) occs = occurrences(self.proto) for meth in ("Down", "Up", "Forward", "Backward"): for count in (1, 2, 20, 200): result = self.assertCall(occs.pop(0), "cursor" + meth, (count, )) self.assertFalse(occurrences(result)) self.assertFalse(occs) def testScrollRegion(self): self.parser.dataReceived(b"\x1b[5;22r\x1b[r") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "setScrollRegion", (5, 22)) self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "setScrollRegion", (None, None)) self.assertFalse(occurrences(result)) self.assertFalse(occs) def testHeightAndWidth(self): self.parser.dataReceived(b"\x1b#3\x1b#4\x1b#5\x1b#6") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "doubleHeightLine", (True, )) self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "doubleHeightLine", (False, )) self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "singleWidthLine") self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "doubleWidthLine") self.assertFalse(occurrences(result)) self.assertFalse(occs) def testCharacterSet(self): self.parser.dataReceived(b"".join([ b"".join([b"\x1b" + g + n for n in iterbytes(b"AB012")]) for g in iterbytes(b"()") ])) occs = occurrences(self.proto) for which in (G0, G1): for charset in ( CS_UK, CS_US, CS_DRAWING, CS_ALTERNATE, CS_ALTERNATE_SPECIAL, ): result = self.assertCall(occs.pop(0), "selectCharacterSet", (charset, which)) self.assertFalse(occurrences(result)) self.assertFalse(occs) def testShifting(self): self.parser.dataReceived(b"\x15\x14") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "shiftIn") self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "shiftOut") self.assertFalse(occurrences(result)) self.assertFalse(occs) def testSingleShifts(self): self.parser.dataReceived(b"\x1bN\x1bO") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "singleShift2") self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "singleShift3") self.assertFalse(occurrences(result)) self.assertFalse(occs) def testKeypadMode(self): self.parser.dataReceived(b"\x1b=\x1b>") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "applicationKeypadMode") self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "numericKeypadMode") self.assertFalse(occurrences(result)) self.assertFalse(occs) def testCursor(self): self.parser.dataReceived(b"\x1b7\x1b8") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "saveCursor") self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "restoreCursor") self.assertFalse(occurrences(result)) self.assertFalse(occs) def testReset(self): self.parser.dataReceived(b"\x1bc") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "reset") self.assertFalse(occurrences(result)) self.assertFalse(occs) def testIndex(self): self.parser.dataReceived(b"\x1bD\x1bM\x1bE") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "index") self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "reverseIndex") self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "nextLine") self.assertFalse(occurrences(result)) self.assertFalse(occs) def testModes(self): self.parser.dataReceived(b"\x1b[" + b";".join( b"%d" % (m, ) for m in [modes.KAM, modes.IRM, modes.LNM]) + b"h") self.parser.dataReceived(b"\x1b[" + b";".join( b"%d" % (m, ) for m in [modes.KAM, modes.IRM, modes.LNM]) + b"l") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "setModes", ([modes.KAM, modes.IRM, modes.LNM], )) self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "resetModes", ([modes.KAM, modes.IRM, modes.LNM], )) self.assertFalse(occurrences(result)) self.assertFalse(occs) def testErasure(self): self.parser.dataReceived( b"\x1b[K\x1b[1K\x1b[2K\x1b[J\x1b[1J\x1b[2J\x1b[3P") occs = occurrences(self.proto) for meth in ( "eraseToLineEnd", "eraseToLineBeginning", "eraseLine", "eraseToDisplayEnd", "eraseToDisplayBeginning", "eraseDisplay", ): result = self.assertCall(occs.pop(0), meth) self.assertFalse(occurrences(result)) result = self.assertCall(occs.pop(0), "deleteCharacter", (3, )) self.assertFalse(occurrences(result)) self.assertFalse(occs) def testLineDeletion(self): self.parser.dataReceived(b"\x1b[M\x1b[3M") occs = occurrences(self.proto) for arg in (1, 3): result = self.assertCall(occs.pop(0), "deleteLine", (arg, )) self.assertFalse(occurrences(result)) self.assertFalse(occs) def testLineInsertion(self): self.parser.dataReceived(b"\x1b[L\x1b[3L") occs = occurrences(self.proto) for arg in (1, 3): result = self.assertCall(occs.pop(0), "insertLine", (arg, )) self.assertFalse(occurrences(result)) self.assertFalse(occs) def testCursorPosition(self): methods(self.proto)["reportCursorPosition"] = (6, 7) self.parser.dataReceived(b"\x1b[6n") self.assertEqual(self.transport.value(), b"\x1b[7;8R") occs = occurrences(self.proto) result = self.assertCall(occs.pop(0), "reportCursorPosition") # This isn't really an interesting assert, since it only tests that # our mock setup is working right, but I'll include it anyway. self.assertEqual(result, (6, 7)) def test_applicationDataBytes(self): """ Contiguous non-control bytes are passed to a single call to the C{write} method of the terminal to which the L{ClientProtocol} is connected. """ occs = occurrences(self.proto) self.parser.dataReceived(b"a") self.assertCall(occs.pop(0), "write", (b"a", )) self.parser.dataReceived(b"bc") self.assertCall(occs.pop(0), "write", (b"bc", )) def _applicationDataTest(self, data, calls): occs = occurrences(self.proto) self.parser.dataReceived(data) while calls: self.assertCall(occs.pop(0), *calls.pop(0)) self.assertFalse(occs, "No other calls should happen: {!r}".format(occs)) def test_shiftInAfterApplicationData(self): """ Application data bytes followed by a shift-in command are passed to a call to C{write} before the terminal's C{shiftIn} method is called. """ self._applicationDataTest(b"ab\x15", [("write", (b"ab", )), ("shiftIn", )]) def test_shiftOutAfterApplicationData(self): """ Application data bytes followed by a shift-out command are passed to a call to C{write} before the terminal's C{shiftOut} method is called. """ self._applicationDataTest(b"ab\x14", [("write", (b"ab", )), ("shiftOut", )]) def test_cursorBackwardAfterApplicationData(self): """ Application data bytes followed by a cursor-backward command are passed to a call to C{write} before the terminal's C{cursorBackward} method is called. """ self._applicationDataTest(b"ab\x08", [("write", (b"ab", )), ("cursorBackward", )]) def test_escapeAfterApplicationData(self): """ Application data bytes followed by an escape character are passed to a call to C{write} before the terminal's handler method for the escape is called. """ # Test a short escape self._applicationDataTest(b"ab\x1bD", [("write", (b"ab", )), ("index", )]) # And a long escape self._applicationDataTest(b"ab\x1b[4h", [("write", (b"ab", )), ("setModes", ([4], ))])
def require(packageName, fixName): if (packageName, fixName) in _alreadyInstalled: return if (packageName, fixName) == ('twisted', 'filepath_copyTo'): from twisted.python import filepath if filepath.FilePath('a') != filepath.FilePath('a'): from epsilon.hotfixes import filepath_copyTo filepath_copyTo.install() elif (packageName, fixName) == ('twisted', 'timeoutmixin_calllater'): from twisted.protocols import policies if not hasattr(policies.TimeoutMixin, 'callLater'): from epsilon.hotfixes import timeoutmixin_calllater timeoutmixin_calllater.install() elif (packageName, fixName) == ('twisted', 'delayedcall_seconds'): from twisted.internet import base args = inspect.getargs(base.DelayedCall.__init__.__code__)[0] if 'seconds' not in args: from epsilon.hotfixes import delayedcall_seconds delayedcall_seconds.install() elif (packageName, fixName) == ('twisted', 'deferredgenerator_tfailure'): from twisted.internet import defer result = [] def test(): d = defer.waitForDeferred(defer.succeed(1)) yield d result.append(d.getResult()) defer.deferredGenerator(test)() if result == [1]: from epsilon.hotfixes import deferredgenerator_tfailure deferredgenerator_tfailure.install() else: assert result == [None] elif (packageName, fixName) == ("twisted", "proto_helpers_stringtransport"): from twisted.test.proto_helpers import StringTransport st = StringTransport() try: st.write('foo') except TypeError as e: pass else: from epsilon.hotfixes import proto_helpers_stringtransport proto_helpers_stringtransport.install() elif (packageName, fixName) == ("twisted", "internet_task_Clock"): from twisted.internet.task import Clock from twisted.internet import base from twisted import version from epsilon.hotfixes import internet_task_clock if internet_task_clock.clockIsBroken(): internet_task_clock.install() elif (packageName, fixName) == ("twisted", "trial_assertwarns"): from twisted.trial.unittest import TestCase if not hasattr(TestCase, "failUnlessWarns"): from epsilon.hotfixes import trial_assertwarns trial_assertwarns.install() elif (packageName, fixName) == ("twisted", "plugin_package_paths"): try: from twisted.plugin import pluginPackagePaths except ImportError: from epsilon.hotfixes import plugin_package_paths plugin_package_paths.install() elif (packageName, fixName) == ("twisted", "loopbackasync_reentrancy"): # This one is really hard to detect reasonably. Invoking the code # involves triggering the reactor, which it would be good to avoid. from twisted import version if (version.major, version.minor) < (8, 2): from epsilon.hotfixes import loopbackasync_reentrancy loopbackasync_reentrancy.install() else: raise NoSuchHotfix(packageName, fixName) _alreadyInstalled.add((packageName, fixName))
def test_client_get(self): """ happy-path test of a GET request """ @defer.inlineCallbacks def do_request(): with LoggingContext("one") as context: fetch_d = self.cl.get_json("testserv:8008", "foo/bar") # Nothing happened yet self.assertNoResult(fetch_d) # should have reset logcontext to the sentinel check_logcontext(LoggingContext.sentinel) try: fetch_res = yield fetch_d defer.returnValue(fetch_res) finally: check_logcontext(context) test_d = do_request() self.pump() # Nothing happened yet self.assertNoResult(test_d) # Make sure treq is trying to connect clients = self.reactor.tcpClients self.assertEqual(len(clients), 1) (host, port, factory, _timeout, _bindAddress) = clients[0] self.assertEqual(host, '1.2.3.4') self.assertEqual(port, 8008) # complete the connection and wire it up to a fake transport protocol = factory.buildProtocol(None) transport = StringTransport() protocol.makeConnection(transport) # that should have made it send the request to the transport self.assertRegex(transport.value(), b"^GET /foo/bar") self.assertRegex(transport.value(), b"Host: testserv:8008") # Deferred is still without a result self.assertNoResult(test_d) # Send it the HTTP response res_json = '{ "a": 1 }'.encode('ascii') protocol.dataReceived( b"HTTP/1.1 200 OK\r\n" b"Server: Fake\r\n" b"Content-Type: application/json\r\n" b"Content-Length: %i\r\n" b"\r\n" b"%s" % (len(res_json), res_json) ) self.pump() res = self.successResultOf(test_d) # check the response is as expected self.assertEqual(res, {"a": 1})
class LocalWorkerAMPTestCase(TestCase): """ Test case for distributed trial's manager-side local worker AMP protocol """ def setUp(self): self.managerTransport = StringTransport() self.managerAMP = LocalWorkerAMP() self.managerAMP.makeConnection(self.managerTransport) self.result = TestResult() self.workerTransport = StringTransport() self.worker = AMP() self.worker.makeConnection(self.workerTransport) config = trial.Options() self.testName = "twisted.doesnexist" config['tests'].append(self.testName) self.testCase = trial._getSuite(config)._tests.pop() self.managerAMP.run(self.testCase, self.result) self.managerTransport.clear() def pumpTransports(self): """ Sends data from C{self.workerTransport} to C{self.managerAMP}, and then data from C{self.managerTransport} back to C{self.worker}. """ self.managerAMP.dataReceived(self.workerTransport.value()) self.workerTransport.clear() self.worker.dataReceived(self.managerTransport.value()) def test_runSuccess(self): """ Run a test, and succeed. """ results = [] d = self.worker.callRemote(managercommands.AddSuccess, testName=self.testName) d.addCallback(lambda result: results.append(result['success'])) self.pumpTransports() self.assertTrue(results) def test_runExpectedFailure(self): """ Run a test, and fail expectedly. """ results = [] d = self.worker.callRemote(managercommands.AddExpectedFailure, testName=self.testName, error='error', todo='todoReason') d.addCallback(lambda result: results.append(result['success'])) self.pumpTransports() self.assertEqual(self.testCase, self.result.expectedFailures[0][0]) self.assertTrue(results) def test_runError(self): """ Run a test, and encounter an error. """ results = [] d = self.worker.callRemote(managercommands.AddError, testName=self.testName, error='error', errorClass='exceptions.ValueError', frames=[]) d.addCallback(lambda result: results.append(result['success'])) self.pumpTransports() self.assertEqual(self.testCase, self.result.errors[0][0]) self.assertTrue(results) def test_runErrorWithFrames(self): """ L{LocalWorkerAMP._buildFailure} recreates the C{Failure.frames} from the C{frames} argument passed to C{AddError}. """ results = [] d = self.worker.callRemote(managercommands.AddError, testName=self.testName, error='error', errorClass='exceptions.ValueError', frames=["file.py", "invalid code", "3"]) d.addCallback(lambda result: results.append(result['success'])) self.pumpTransports() self.assertEqual(self.testCase, self.result.errors[0][0]) self.assertEqual([('file.py', 'invalid code', 3, [], [])], self.result.errors[0][1].frames) self.assertTrue(results) def test_runFailure(self): """ Run a test, and fail. """ results = [] d = self.worker.callRemote(managercommands.AddFailure, testName=self.testName, fail='fail', failClass='exceptions.RuntimeError', frames=[]) d.addCallback(lambda result: results.append(result['success'])) self.pumpTransports() self.assertEqual(self.testCase, self.result.failures[0][0]) self.assertTrue(results) def test_runSkip(self): """ Run a test, but skip it. """ results = [] d = self.worker.callRemote(managercommands.AddSkip, testName=self.testName, reason='reason') d.addCallback(lambda result: results.append(result['success'])) self.pumpTransports() self.assertEqual(self.testCase, self.result.skips[0][0]) self.assertTrue(results) def test_runUnexpectedSuccesses(self): """ Run a test, and succeed unexpectedly. """ results = [] d = self.worker.callRemote(managercommands.AddUnexpectedSuccess, testName=self.testName, todo='todo') d.addCallback(lambda result: results.append(result['success'])) self.pumpTransports() self.assertEqual(self.testCase, self.result.unexpectedSuccesses[0][0]) self.assertTrue(results) def test_testWrite(self): """ L{LocalWorkerAMP.testWrite} writes the data received to its test stream. """ results = [] stream = StringIO() self.managerAMP.setTestStream(stream) d = self.worker.callRemote(managercommands.TestWrite, out="Some output") d.addCallback(lambda result: results.append(result['success'])) self.pumpTransports() self.assertEqual("Some output\n", stream.getvalue()) self.assertTrue(results) def test_stopAfterRun(self): """ L{LocalWorkerAMP.run} calls C{stopTest} on its test result once the C{Run} commands has succeeded. """ result = object() stopped = [] def fakeCallRemote(command, testCase): return succeed(result) self.managerAMP.callRemote = fakeCallRemote class StopTestResult(TestResult): def stopTest(self, test): stopped.append(test) d = self.managerAMP.run(self.testCase, StopTestResult()) self.assertEqual([self.testCase], stopped) return d.addCallback(self.assertIdentical, result)
def createProtocol(ignored): protocol = factory.buildProtocol(None) info.constructedProtocols.append(protocol) transport = StringTransport() protocol.makeConnection(transport) return protocol
def test_clean_session_destroys_session(self): """ Setting the clean_session flag to True when connecting means that any existing session for that user ID will be destroyed. Compliance statement MQTT-3.2.2-1 """ sessions = {} h = BasicHandler() r = Clock() t = StringTransport() p = MQTTServerTwistedProtocol(h, r, sessions) p.makeConnection(t) data = (Connect(client_id=u"test123", flags=ConnectFlags(clean_session=False)).serialise()) for x in iterbytes(data): p.dataReceived(x) self.assertFalse(t.disconnecting) self.assertEqual(list(sessions.keys()), [u"test123"]) old_session = sessions[u"test123"] # Close the connection p.connectionLost(None) # New session, clean_session=True data = (Connect(client_id=u"test123", flags=ConnectFlags(clean_session=True)).serialise()) r2 = Clock() t2 = StringTransport() p2 = MQTTServerTwistedProtocol(h, r2, sessions) cp2 = MQTTClientParser() p2.makeConnection(t2) # Send the same connect, with the same client ID for x in iterbytes(data): p2.dataReceived(x) # Connection allowed events = cp2.data_received(t2.value()) self.assertEqual(len(events), 1) self.assertEqual(attr.asdict(events[0]), { 'return_code': 0, 'session_present': False, }) self.assertEqual(list(sessions.keys()), [u"test123"]) new_session = sessions[u"test123"] # Brand new session, that won't survive self.assertIsNot(old_session, new_session) self.assertFalse(new_session.survives) # We close the connection, the session is destroyed p2.connectionLost(None) self.assertEqual(list(sessions.keys()), [])
def setUp(self): self.protocol = ServerProtocol() self.transport = StringTransport() self.protocol.makeConnection(self.transport)
def setUp(self): self.transport = StringTransport()
def test_connection_made(self): """ Connection made events are passed on to the agent. """ self.client.makeConnection(StringTransport()) self.assertEqual(self.agent, FakeAgent(is_connected=True))
def test_onConnectionLost_fires_when_connection_is_lost(self): protocol = common.RPCProtocol() protocol.makeConnection(StringTransport()) protocol.connectionLost(connectionDone) self.assertThat(protocol.onConnectionLost, IsFiredDeferred())
def __init__(self): Client.__init__(self) self.transport = StringTransport() self.makeConnection(self.transport)
def __init__(self): self.t = StringTransport()
class StringTransportTests(TestCase): """ Tests for L{twisted.test.proto_helpers.StringTransport}. """ def setUp(self): self.transport = StringTransport() def test_interfaces(self): """ L{StringTransport} instances provide L{ITransport}, L{IPushProducer}, and L{IConsumer}. """ self.assertTrue(verifyObject(ITransport, self.transport)) self.assertTrue(verifyObject(IPushProducer, self.transport)) self.assertTrue(verifyObject(IConsumer, self.transport)) def test_registerProducer(self): """ L{StringTransport.registerProducer} records the arguments supplied to it as instance attributes. """ producer = object() streaming = object() self.transport.registerProducer(producer, streaming) self.assertIdentical(self.transport.producer, producer) self.assertIdentical(self.transport.streaming, streaming) def test_disallowedRegisterProducer(self): """ L{StringTransport.registerProducer} raises L{RuntimeError} if a producer is already registered. """ producer = object() self.transport.registerProducer(producer, True) self.assertRaises( RuntimeError, self.transport.registerProducer, object(), False) self.assertIdentical(self.transport.producer, producer) self.assertTrue(self.transport.streaming) def test_unregisterProducer(self): """ L{StringTransport.unregisterProducer} causes the transport to forget about the registered producer and makes it possible to register a new one. """ oldProducer = object() newProducer = object() self.transport.registerProducer(oldProducer, False) self.transport.unregisterProducer() self.assertIdentical(self.transport.producer, None) self.transport.registerProducer(newProducer, True) self.assertIdentical(self.transport.producer, newProducer) self.assertTrue(self.transport.streaming) def test_invalidUnregisterProducer(self): """ L{StringTransport.unregisterProducer} raises L{RuntimeError} if called when no producer is registered. """ self.assertRaises(RuntimeError, self.transport.unregisterProducer) def test_initialProducerState(self): """ L{StringTransport.producerState} is initially C{'producing'}. """ self.assertEqual(self.transport.producerState, 'producing') def test_pauseProducing(self): """ L{StringTransport.pauseProducing} changes the C{producerState} of the transport to C{'paused'}. """ self.transport.pauseProducing() self.assertEqual(self.transport.producerState, 'paused') def test_resumeProducing(self): """ L{StringTransport.resumeProducing} changes the C{producerState} of the transport to C{'producing'}. """ self.transport.pauseProducing() self.transport.resumeProducing() self.assertEqual(self.transport.producerState, 'producing') def test_stopProducing(self): """ L{StringTransport.stopProducing} changes the C{'producerState'} of the transport to C{'stopped'}. """ self.transport.stopProducing() self.assertEqual(self.transport.producerState, 'stopped') def test_stoppedTransportCannotPause(self): """ L{StringTransport.pauseProducing} raises L{RuntimeError} if the transport has been stopped. """ self.transport.stopProducing() self.assertRaises(RuntimeError, self.transport.pauseProducing) def test_stoppedTransportCannotResume(self): """ L{StringTransport.resumeProducing} raises L{RuntimeError} if the transport has been stopped. """ self.transport.stopProducing() self.assertRaises(RuntimeError, self.transport.resumeProducing) def test_disconnectingTransportCannotPause(self): """ L{StringTransport.pauseProducing} raises L{RuntimeError} if the transport is being disconnected. """ self.transport.loseConnection() self.assertRaises(RuntimeError, self.transport.pauseProducing) def test_disconnectingTransportCannotResume(self): """ L{StringTransport.resumeProducing} raises L{RuntimeError} if the transport is being disconnected. """ self.transport.loseConnection() self.assertRaises(RuntimeError, self.transport.resumeProducing) def test_loseConnectionSetsDisconnecting(self): """ L{StringTransport.loseConnection} toggles the C{disconnecting} instance variable to C{True}. """ self.assertFalse(self.transport.disconnecting) self.transport.loseConnection() self.assertTrue(self.transport.disconnecting) def test_specifiedHostAddress(self): """ If a host address is passed to L{StringTransport.__init__}, that value is returned from L{StringTransport.getHost}. """ address = object() self.assertIdentical(StringTransport(address).getHost(), address) def test_specifiedPeerAddress(self): """ If a peer address is passed to L{StringTransport.__init__}, that value is returned from L{StringTransport.getPeer}. """ address = object() self.assertIdentical( StringTransport(peerAddress=address).getPeer(), address) def test_defaultHostAddress(self): """ If no host address is passed to L{StringTransport.__init__}, an L{IPv4Address} is returned from L{StringTransport.getHost}. """ address = StringTransport().getHost() self.assertIsInstance(address, IPv4Address) def test_defaultPeerAddress(self): """ If no peer address is passed to L{StringTransport.__init__}, an L{IPv4Address} is returned from L{StringTransport.getPeer}. """ address = StringTransport().getPeer() self.assertIsInstance(address, IPv4Address)
def __init__(self, *args, **kwargs): self.aborted = False StringTransport.__init__(self, *args, **kwargs)
def build_testing_protocol(): protocol = TestingNetstringProtocol() transport = StringTransport() protocol.makeConnection(transport) return protocol, transport
def setUp(self): self.transport = StringTransport() self.handler = Handler() self.factory = WebSocketFactory(self.handler)
def setUp(self): self.account = IRCAccount( "Some account", False, "alice", None, "example.com", 6667) self.proto = IRCProto(self.account, StubChatUI(), None) self.transport = StringTransport()
def setUp(self): self.device_delegate = TestRegisterRequest.FakeDeviceDelegate() self.factory = TestRegisterRequest.FakeFactory(self.device_delegate) self.transport = StringTransport() self.protocol = HTTP11ClientProtocol() self.protocol.makeConnection(self.transport)
def write(self, bytes, addr=None): StringTransport.write(self, bytes)
class IRCProtoTests(TestCase): """ Tests for L{IRCProto}. """ def setUp(self): self.account = IRCAccount( "Some account", False, "alice", None, "example.com", 6667) self.proto = IRCProto(self.account, StubChatUI(), None) self.transport = StringTransport() def test_login(self): """ When L{IRCProto} is connected to a transport, it sends I{NICK} and I{USER} commands with the username from the account object. """ self.proto.makeConnection(self.transport) self.assertEqual( self.transport.value(), "NICK alice\r\n" "USER alice foo bar :Twisted-IM user\r\n") def test_authenticate(self): """ If created with an account with a password, L{IRCProto} sends a I{PASS} command before the I{NICK} and I{USER} commands. """ self.account.password = "******" self.proto.makeConnection(self.transport) self.assertEqual( self.transport.value(), "PASS secret\r\n" "NICK alice\r\n" "USER alice foo bar :Twisted-IM user\r\n") def test_channels(self): """ If created with an account with a list of channels, L{IRCProto} joins each of those channels after registering. """ self.account.channels = ['#foo', '#bar'] self.proto.makeConnection(self.transport) self.assertEqual( self.transport.value(), "NICK alice\r\n" "USER alice foo bar :Twisted-IM user\r\n" "JOIN #foo\r\n" "JOIN #bar\r\n") def test_isupport(self): """ L{IRCProto} can interpret I{ISUPPORT} (I{005}) messages from the server and reflect their information in its C{supported} attribute. """ self.proto.makeConnection(self.transport) self.proto.dataReceived( ":irc.example.com 005 alice MODES=4 CHANLIMIT=#:20\r\n") self.assertEqual(4, self.proto.supported.getFeature("MODES"))
def __init__(self, hostAddress=None, peerAddress=None): StringTransport.__init__(self, hostAddress, peerAddress) self._keepAlive = False
def __init__(self, client): self._client = client self._calls = [] self.transport = StringTransport()