class TestElecraftProtocol(unittest.TestCase): """Test _ElecraftClientProtocol and _ElecraftRadio. This test uses those implementation classes rather than the public interface because the public interface is hardcoded to attempt to open a serial device.""" def setUp(self): self.clock = Clock() self.tr = StringTransport() self.protocol = _ElecraftClientProtocol(reactor=self.clock) self.proxy = self.protocol._proxy() self.protocol.makeConnection(self.tr) self.protocol.connectionMade() def test_state_smoke(self): state_smoke_test(self.proxy) def test_initial_send(self): self.assertIn('AI2;', self.tr.value()) self.assertIn('K31;', self.tr.value()) self.assertIn('IF;', self.tr.value()) def test_simple_receive(self): self.protocol.dataReceived('FA00000000012;') self.assertEqual(12.0, self.proxy.get_rx_main().state()['freq'].get()) def test_continues_after_bad_data(self): self.protocol.dataReceived('\x00\x00;;FA00000000012;') self.assertEqual(12.0, self.proxy.get_rx_main().state()['freq'].get()) def test_not_too_much_polling(self): self.tr.clear() self.assertEqual('', self.tr.value()) self.clock.pump([0.01] * 150) self.assertEqual('FA;', self.tr.value()) self.clock.pump([0.01] * 500) self.assertEqual('FA;FA;FA;FA;FA;FA;', self.tr.value())
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_incompleteUsername(self): """ Test that a login attempt using a username without a domain part results in a customized authentication failure message which points out that a domain part should be included in the username. """ mta = mail.MailTransferAgent(store=self.store) installOn(mta, self.store) factory = mta.getFactory() protocol = factory.buildProtocol(("192.168.1.1", 12345)) transport = StringTransport() transport.getHost = lambda: IPv4Address("TCP", "192.168.1.1", 54321) transport.getPeer = lambda: IPv4Address("TCP", "192.168.1.1", 12345) protocol.makeConnection(transport) protocol.dataReceived("EHLO example.net\r\n") protocol.dataReceived("AUTH LOGIN\r\n") protocol.dataReceived("testuser".encode("base64") + "\r\n") transport.clear() protocol.dataReceived("password".encode("base64") + "\r\n") written = transport.value() protocol.connectionLost(failure.Failure(error.ConnectionDone())) self.assertEquals( written, "535 Authentication failure [Username without domain name (ie " '"yourname" instead of "yourname@yourdomain") not allowed; try ' "with a domain name.]\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 test_incompleteUsername(self): """ Test that a login attempt using a username without a domain part results in a customized authentication failure message which points out that a domain part should be included in the username. """ mta = mail.MailTransferAgent(store=self.store) installOn(mta, self.store) factory = mta.getFactory() protocol = factory.buildProtocol(('192.168.1.1', 12345)) transport = StringTransport() transport.getHost = lambda: IPv4Address('TCP', '192.168.1.1', 54321) transport.getPeer = lambda: IPv4Address('TCP', '192.168.1.1', 12345) protocol.makeConnection(transport) protocol.dataReceived('EHLO example.net\r\n') protocol.dataReceived('AUTH LOGIN\r\n') protocol.dataReceived('testuser'.encode('base64') + '\r\n') transport.clear() protocol.dataReceived('password'.encode('base64') + '\r\n') written = transport.value() protocol.connectionLost(failure.Failure(error.ConnectionDone())) self.assertEquals( written, '535 Authentication failure [Username without domain name (ie ' '"yourname" instead of "yourname@yourdomain") not allowed; try ' 'with a domain name.]\r\n')
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_client_requires_trailing_slashes(self): """ If a connection is made to a client but the client rejects it due to requiring a trailing slash. We need to retry the request with a trailing slash. Workaround for Synapse <= v0.99.3, explained in #3622. """ d = defer.ensureDeferred( self.cl.get_json("testserv:8008", "foo/bar", try_trailing_slash_on_400=True) ) # Send the request self.pump() # there should have been a call to connectTCP clients = self.reactor.tcpClients self.assertEqual(len(clients), 1) (_host, _port, factory, _timeout, _bindAddress) = clients[0] # complete the connection and wire it up to a fake transport client = factory.buildProtocol(None) conn = StringTransport() client.makeConnection(conn) # that should have made it send the request to the connection self.assertRegex(conn.value(), b"^GET /foo/bar") # Clear the original request data before sending a response conn.clear() # Send the HTTP response client.dataReceived( b"HTTP/1.1 400 Bad Request\r\n" b"Content-Type: application/json\r\n" b"Content-Length: 59\r\n" b"\r\n" b'{"errcode":"M_UNRECOGNIZED","error":"Unrecognized request"}' ) # We should get another request with a trailing slash self.assertRegex(conn.value(), b"^GET /foo/bar/") # Send a happy response this time client.dataReceived( b"HTTP/1.1 200 OK\r\n" b"Content-Type: application/json\r\n" b"Content-Length: 2\r\n" b"\r\n" b"{}" ) # We should get a successful response r = self.successResultOf(d) self.assertEqual(r, {})
def _make_client(self) -> Tuple[IProtocol, StringTransport]: """Create a new direct TCP replication connection""" proto = self.factory.buildProtocol(("127.0.0.1", 0)) transport = StringTransport() proto.makeConnection(transport) # We can safely ignore the commands received during connection. self.pump() transport.clear() return proto, transport
def test_stop_pinging_on_connection_lost(self): """ When the protocol loses its connection, it stops trying to send ``NoOp`` commands. """ reactor = Clock() protocol = self.build_protocol(reactor) transport = StringTransport() protocol.makeConnection(transport) transport.clear() protocol.connectionLost(Failure(ConnectionDone("test, simulated"))) reactor.advance(PING_INTERVAL.total_seconds()) self.assertEqual(b"", transport.value())
def test_client_requires_trailing_slashes(self): """ If a connection is made to a client but the client rejects it due to requiring a trailing slash. We need to retry the request with a trailing slash. Workaround for Synapse <= v0.99.3, explained in #3622. """ d = self.cl.get_json("testserv:8008", "foo/bar", try_trailing_slash_on_400=True) # Send the request self.pump() # there should have been a call to connectTCP clients = self.reactor.tcpClients self.assertEqual(len(clients), 1) (_host, _port, factory, _timeout, _bindAddress) = clients[0] # complete the connection and wire it up to a fake transport client = factory.buildProtocol(None) conn = StringTransport() client.makeConnection(conn) # that should have made it send the request to the connection self.assertRegex(conn.value(), b"^GET /foo/bar") # Clear the original request data before sending a response conn.clear() # Send the HTTP response client.dataReceived( b"HTTP/1.1 400 Bad Request\r\n" b"Content-Type: application/json\r\n" b"Content-Length: 59\r\n" b"\r\n" b'{"errcode":"M_UNRECOGNIZED","error":"Unrecognized request"}' ) # We should get another request with a trailing slash self.assertRegex(conn.value(), b"^GET /foo/bar/") # Send a happy response this time client.dataReceived( b"HTTP/1.1 200 OK\r\n" b"Content-Type: application/json\r\n" b"Content-Length: 2\r\n" b"\r\n" b'{}' ) # We should get a successful response r = self.successResultOf(d) self.assertEqual(r, {})
def _versionTest(self, serverVersionResponse): """ Test L{NotificationClient} version negotiation. """ self.client.factory.userHandle = "foo" transport = StringTransport() self.client.makeConnection(transport) self.assertEqual(transport.value(), "VER 1 MSNP8 CVR0\r\n") transport.clear() self.client.dataReceived(serverVersionResponse) self.assertEqual( transport.value(), "CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS foo\r\n")
def _versionTest(self, serverVersionResponse): """ Test L{NotificationClient} version negotiation. """ self.client.factory.userHandle = "foo" transport = StringTransport() self.client.makeConnection(transport) self.assertEquals( transport.value(), "VER 1 MSNP8 CVR0\r\n") transport.clear() self.client.dataReceived(serverVersionResponse) self.assertEquals( transport.value(), "CVR 2 0x0409 win 4.10 i386 MSNMSGR 5.0.0544 MSMSGS foo\r\n")
def test_client_does_not_retry_on_400_plus(self): """ Another test for trailing slashes but now test that we don't retry on trailing slashes on a non-400/M_UNRECOGNIZED response. See test_client_requires_trailing_slashes() for context. """ d = defer.ensureDeferred( self.cl.get_json("testserv:8008", "foo/bar", try_trailing_slash_on_400=True) ) # Send the request self.pump() # there should have been a call to connectTCP clients = self.reactor.tcpClients self.assertEqual(len(clients), 1) (_host, _port, factory, _timeout, _bindAddress) = clients[0] # complete the connection and wire it up to a fake transport client = factory.buildProtocol(None) conn = StringTransport() client.makeConnection(conn) # that should have made it send the request to the connection self.assertRegex(conn.value(), b"^GET /foo/bar") # Clear the original request data before sending a response conn.clear() # Send the HTTP response client.dataReceived( b"HTTP/1.1 404 Not Found\r\n" b"Content-Type: application/json\r\n" b"Content-Length: 2\r\n" b"\r\n" b"{}" ) # We should not get another request self.assertEqual(conn.value(), b"") # We should get a 404 failure response self.failureResultOf(d)
class WorkerProtocolTests(TestCase): """ Tests for L{WorkerProtocol}. """ 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_run(self): """ Calling the L{workercommands.Run} command on the client returns a response with C{success} sets to C{True}. """ d = self.client.callRemote(workercommands.Run, testCase="doesntexist") def check(result): self.assertTrue(result['success']) d.addCallback(check) self.server.dataReceived(self.clientTransport.value()) self.clientTransport.clear() self.client.dataReceived(self.serverTransport.value()) self.serverTransport.clear() return d def test_start(self): """ The C{start} command changes the current path. """ curdir = os.path.realpath(os.path.curdir) self.addCleanup(os.chdir, curdir) self.server.start('..') self.assertNotEqual(os.path.realpath(os.path.curdir), curdir)
class WsClientSendingTestCase(unittest.TestCase): def setUp(self): self.transport = StringTransport() self.handler = Handler() self.factory = WebSocketFactory(self.handler) def test_buildProtocol(self): proto = self.factory.buildProtocol(None) self.assertIsInstance(proto, WebSocketDeviceHiveProtocol) def test_send_message(self): # testing headers sending # this should result in connected event proto = self.factory.buildProtocol(None) proto.makeConnection(self.transport) origin = ''.join(( 'GET /device HTTP/1.1\r\n', 'Host: localhost\r\n', 'Upgrade: websocket\r\n', 'Connection: Upgrade\r\n', 'Sec-WebSocket-Key: {0}\r\n'.format(proto.socket.security_key), 'Origin: http://localhost\r\n', 'Sec-WebSocket-Protocol: device-hive, devicehive\r\n', 'Sec-WebSocket-Version: 13\r\n\r\n', )) self.assertEquals(origin, self.transport.value()) proto.dataReceived('HTTP/1.1 101 OK\r\n\r\n') self.assertTrue(self.handler.is_connected) self.transport.clear() # testing message sending proto.socket.rand = Random(1) defer = self.factory.send_message({'test': True}) self.assertIsInstance(defer, Deferred) self.assertEquals('{{"test": true, "requestId": {0}}}'.format(max(proto.msg_callbacks.keys())), decode_ws_message(self.transport.value())) self.assertFalse(defer.called) # testing message response request_id = max(proto.msg_callbacks.keys()) proto.socket.frame_received(WS_OPCODE_TEXT_FRAME, '{{"requestId":{0},"done":1}}'.format(request_id)) self.assertTrue(defer.called)
def test_buffer(self): """ Exercise a lot of the SMTP client code. This is a "shotgun" style unit test. It does a lot of things and hopes that something will go really wrong if it is going to go wrong. This test should be replaced with a suite of nicer tests. """ transport = StringTransport() a = self.serverClass() class fooFactory: domain = 'foo.com' a.factory = fooFactory() a.makeConnection(transport) for (send, expect, msg, msgexpect) in self.data: if send: a.dataReceived(send) data = transport.value() transport.clear() if not re.match(expect, data): raise AssertionError, (send, expect, data) if data[:3] == '354': for line in msg.splitlines(): if line and line[0] == '.': line = '.' + line a.dataReceived(line + '\r\n') a.dataReceived('.\r\n') # Special case for DATA. Now we want a 250, and then # we compare the messages data = transport.value() transport.clear() resp, msgdata = msgexpect if not re.match(resp, data): raise AssertionError, (resp, data) for recip in msgdata[2]: expected = list(msgdata[:]) expected[2] = [recip] self.assertEquals( a.message[(recip,)], tuple(expected) ) a.setTimeout(None)
def test_client_does_not_retry_on_400_plus(self): """ Another test for trailing slashes but now test that we don't retry on trailing slashes on a non-400/M_UNRECOGNIZED response. See test_client_requires_trailing_slashes() for context. """ d = self.cl.get_json("testserv:8008", "foo/bar", try_trailing_slash_on_400=True) # Send the request self.pump() # there should have been a call to connectTCP clients = self.reactor.tcpClients self.assertEqual(len(clients), 1) (_host, _port, factory, _timeout, _bindAddress) = clients[0] # complete the connection and wire it up to a fake transport client = factory.buildProtocol(None) conn = StringTransport() client.makeConnection(conn) # that should have made it send the request to the connection self.assertRegex(conn.value(), b"^GET /foo/bar") # Clear the original request data before sending a response conn.clear() # Send the HTTP response client.dataReceived( b"HTTP/1.1 404 Not Found\r\n" b"Content-Type: application/json\r\n" b"Content-Length: 2\r\n" b"\r\n" b"{}" ) # We should not get another request self.assertEqual(conn.value(), b"") # We should get a 404 failure response self.failureResultOf(d)
def test_incompleteUsername(self): """ Test that a login attempt using a username without a domain part results in a customized authentication failure message which points out that a domain part should be included in the username. """ factory = POP3ServerFactory(self.portal) protocol = factory.buildProtocol(('192.168.1.1', 12345)) transport = StringTransport() protocol.makeConnection(transport) protocol.dataReceived("USER testuser\r\n") transport.clear() protocol.dataReceived("PASS password\r\n") written = transport.value() protocol.connectionLost(Failure(ConnectionDone())) self.assertEquals( written, '-ERR Username without domain name (ie "yourname" instead of ' '"yourname@yourdomain") not allowed; try with a domain name.\r\n')
def encode(bananaFactory, obj): """ Banana encode an object using L{banana.Banana.sendEncoded}. @param bananaFactory: A no-argument callable which will return a new, unconnected protocol instance to use to do the encoding (this should most likely be a L{banana.Banana} instance). @param obj: The object to encode. @type obj: Any type supported by Banana. @return: A L{bytes} instance giving the encoded form of C{obj}. """ transport = StringTransport() banana = bananaFactory() banana.makeConnection(transport) transport.clear() banana.sendEncoded(obj) return transport.value()
def test_challenge(self): """ L{NotificationClient} responds to a I{CHL} message by sending a I{QRY} back which included a hash based on the parameters of the I{CHL}. """ transport = StringTransport() self.client.makeConnection(transport) transport.clear() challenge = "15570131571988941333" self.client.dataReceived('CHL 0 ' + challenge + '\r\n') # md5 of the challenge and a magic string defined by the protocol response = "8f2f5a91b72102cd28355e9fc9000d6e" # Sanity check - the response is what the comment above says it is. self.assertEquals( response, md5(challenge + "Q1P7W2E4J9R8U3S5").hexdigest()) self.assertEquals( transport.value(), # 2 is the next transaction identifier. 32 is the length of the # response. "QRY 2 [email protected] 32\r\n" + response)
def test_portalRejectedSenderAddress(self): """ Test that a C{MAIL FROM} command with an address rejected by an L{smtp.SMTP} instance's portal is responded to with the correct error code. """ class DisallowAnonymousAccess(object): """ Checker for L{IAnonymous} which rejects authentication attempts. """ implements(ICredentialsChecker) credentialInterfaces = (IAnonymous,) def requestAvatarId(self, credentials): return defer.fail(UnauthorizedLogin()) realm = SingletonRealm(smtp.IMessageDelivery, NotImplementedDelivery()) portal = Portal(realm, [DisallowAnonymousAccess()]) 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 ' '<*****@*****.**>: Sender not acceptable\r\n')
def test_deferredChat(self): """ Test that I{get} and I{put} commands are responded to correctly by L{postfix.PostfixTCPMapServer} when its factory is an instance of L{postifx.PostfixTCPMapDeferringDictServerFactory}. """ factory = postfix.PostfixTCPMapDeferringDictServerFactory(self.data) transport = StringTransport() protocol = postfix.PostfixTCPMapServer() protocol.service = factory protocol.factory = factory protocol.makeConnection(transport) for input, expected_output in self.chat: protocol.lineReceived(input) self.assertEqual( transport.value(), expected_output, 'For %r, expected %r but got %r' % (input, expected_output, transport.value())) transport.clear() protocol.setTimeout(None)
def test_deferredChat(self): """ Test that I{get} and I{put} commands are responded to correctly by L{postfix.PostfixTCPMapServer} when its factory is an instance of L{postifx.PostfixTCPMapDeferringDictServerFactory}. """ factory = postfix.PostfixTCPMapDeferringDictServerFactory(self.data) transport = StringTransport() protocol = postfix.PostfixTCPMapServer() protocol.service = factory protocol.factory = factory protocol.makeConnection(transport) for input, expected_output in self.chat: protocol.lineReceived(input) self.assertEquals( transport.value(), expected_output, 'For %r, expected %r but got %r' % ( input, expected_output, transport.value())) transport.clear() protocol.setTimeout(None)
class SafelogTests(unittest.TestCase): """Tests for functions and attributes in :mod:`bridgedb.safelog`.""" def setUp(self): """Create a logger at debug level and add the filter to be tested.""" self.logfile = StringTransport() self.handler = safelog.logging.StreamHandler(self.logfile) self.logger = safelog.logging.getLogger(self.__class__.__name__) self.logger.setLevel(10) self.logger.addHandler(self.handler) self.sensitiveData = 'Nicholas Bourbaki' def tearDown(self): """Rewind and truncate the logfile so that we have an empty one.""" self.logfile.clear() def test_setSafeLogging_off(self): """Calls to ``logSafely()`` should return the original data when ``safe_logging`` is disabled. """ safelog.setSafeLogging(False) self.logger.warn("Got a connection from %s..." % safelog.logSafely(self.sensitiveData)) contents = self.logfile.value() self.assertIsNotNone(contents) #self.assertSubstring("Got a connection from", contents) #self.assertSubstring(self.sensitiveData, contents) #self.failIfSubstring("[scrubbed]", contents) def test_setSafeLogging_on(self): """Calls to ``logSafely()`` should return ``"[scrubbed]"`` for any arbitrary data when ``safe_logging`` is enabled. """ safelog.setSafeLogging(True) self.logger.warn("Got a connection from %s..." % safelog.logSafely(self.sensitiveData)) contents = self.logfile.value() self.assertIsNotNone(contents)
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 TestElecraftProtocol(unittest.TestCase): """Test _ElecraftClientProtocol and _ElecraftRadio. This test uses those implementation classes rather than the public interface because the public interface is hardcoded to attempt to open a serial device.""" def setUp(self): self.clock = Clock() self.tr = StringTransport() self.protocol = _ElecraftClientProtocol(reactor=self.clock) self.proxy = self.protocol._proxy() self.protocol.makeConnection(self.tr) self.protocol.connectionMade() def test_state_smoke(self): state_smoke_test(self.proxy) def test_initial_send(self): self.assertIn(b'AI2;', self.tr.value()) self.assertIn(b'K31;', self.tr.value()) self.assertIn(b'IF;', self.tr.value()) def test_simple_receive(self): self.protocol.dataReceived(b'FA00000000012;') self.assertEqual(12.0, self.proxy.get_rx_main().state()['freq'].get()) def test_continues_after_bad_data(self): self.protocol.dataReceived(b'\x00\x00;;FA00000000012;') self.assertEqual(12.0, self.proxy.get_rx_main().state()['freq'].get()) def test_not_too_much_polling(self): self.tr.clear() self.assertEqual(b'', self.tr.value()) self.clock.pump([0.01] * 150) self.assertEqual(b'FA;', self.tr.value()) self.clock.pump([0.01] * 500) self.assertEqual(b'FA;FA;FA;FA;FA;FA;', self.tr.value())
def clear(self): TStringTransport.clear(self) self.msgs = []
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. """ def newThing(color): it = objects.Thing(store=self.store, name=u'%s thing' % (color,)) it.moveTo(self.room) for color in [u'red', u'green']: newThing(color) self.player.parse(u"take thing") self.assertEquals(self.transport.value(), '> take thing\n' 'Could you be more specific? When you said "thing", ' 'did you mean a green thing or a red thing?\r\n') self.transport.clear() newThing(u'blue') self.player.parse(u"take thing") self.assertEquals(self.transport.value(), '> take thing\n' 'Could you be more specific? When you said "thing", ' 'did you mean a blue thing, a green thing, or a red ' 'thing?\r\n')
class ProtocolTestCase(TestCase): protocol_class = SSMIProtocol timeout = 1 def setUp(self): self.clock = Clock() self.patch(self.protocol_class, 'clock', self.clock) self.protocol = self.protocol_class() self.protocol.noisy = True self.transport = StringTransport() self.protocol.makeConnection(self.transport) def send(self, command): return self.protocol.lineReceived(str(command)) def receive(self, count, clear=True): d = Deferred() def check_for_input(): if not self.transport.value(): reactor.callLater(0, check_for_input) return lines = self.transport.value().split(self.protocol.delimiter) commands = map(SSMIRequest.parse, filter(None, lines)) if len(commands) == count: d.callback(commands) if clear: self.transport.clear() check_for_input() return d @inlineCallbacks def test_login(self): self.protocol.login('username', 'password') [cmd] = yield self.receive(1) self.assertEqual(cmd, Login(username='******', password='******')) @inlineCallbacks def test_authenticate(self): self.assertFalse(self.protocol.authenticated) d = self.protocol.authenticate('username', 'password') [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'LOGIN') yield self.send(Ack(ack_type='1')) self.assertTrue((yield d)) self.assertTrue(self.protocol.authenticated) @inlineCallbacks def test_send_message(self): self.protocol.send_message('2700000000', 'hi there!', validity='2') [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'SEND_SMS') self.assertEqual(cmd.msisdn, '2700000000') self.assertEqual(cmd.message, 'hi there!') self.assertEqual(cmd.validity, '2') @inlineCallbacks def test_send_message_with_comma(self): self.protocol.send_message('2700000000', 'foo, bar', validity='2') [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'SEND_SMS') self.assertEqual(cmd.msisdn, '2700000000') self.assertEqual(cmd.message, 'foo, bar') self.assertEqual(cmd.validity, '2') @inlineCallbacks def test_link_check(self): self.assertFalse(self.transport.value()) self.protocol.authenticated = False self.protocol.link_check.start(60) self.assertEqual(self.transport.value(), '') self.protocol.authenticated = True self.clock.advance(60) [check1] = yield self.receive(1) self.clock.advance(60) [check2] = yield self.receive(1) self.assertEqual(check1.command_name, 'LINK_CHECK') self.assertEqual(check2.command_name, 'LINK_CHECK') @inlineCallbacks def test_send_binary_message(self): self.protocol.send_binary_message( '2700000000', binascii.hexlify('hello world'), protocol_id=PROTOCOL_ENHANCED, coding=CODING_8BIT) [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'SEND_BINARY_SMS') self.assertEqual(binascii.unhexlify(cmd.hex_msg), 'hello world') self.assertEqual(cmd.msisdn, '2700000000') self.assertEqual(cmd.pid, PROTOCOL_ENHANCED) self.assertEqual(cmd.coding, CODING_8BIT) @inlineCallbacks def test_logout(self): self.protocol.logout() [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'LOGOUT') @inlineCallbacks def test_send_ussd_message(self): self.protocol.send_ussd_message( '2700000000', 'hello world', USSD_INITIATE) [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'SEND_USSD_MESSAGE') self.assertEqual(cmd.msisdn, '2700000000') self.assertEqual(cmd.type, USSD_INITIATE) self.assertEqual(cmd.message, 'hello world') @inlineCallbacks def test_wap_push_message(self): self.protocol.send_wap_push_message( '2700000000', 'foo', 'http://bar/baz.gif') [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'SEND_WAP_PUSH_MESSAGE') self.assertEqual(cmd.msisdn, '2700000000') self.assertEqual(cmd.subject, 'foo') self.assertEqual(cmd.url, 'http://bar/baz.gif') @inlineCallbacks def test_send_mms_message(self): self.protocol.send_mms_message( '2700000000', 'subject', 'name.gif', binascii.hexlify('hello world')) [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'SEND_MMS_MESSAGE') self.assertEqual(cmd.msisdn, '2700000000') self.assertEqual(cmd.subject, 'subject') self.assertEqual(cmd.name, 'name.gif') self.assertEqual(cmd.content, binascii.hexlify(u'hello world')) @inlineCallbacks def test_imsi_lookup(self): d = self.protocol.imsi_lookup('2700000000', imsi='12345') [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'IMSI_LOOKUP') self.assertEqual(cmd.msisdn, '2700000000') self.assertEqual(cmd.imsi, '12345') sequence = cmd.sequence reply_cmd = IMSILookupReply(sequence=sequence, msisdn=cmd.msisdn, imsi=cmd.imsi, spid='spid') yield self.send(reply_cmd) response = yield d self.assertEqual(response, reply_cmd) @inlineCallbacks def test_send_extended_ussd_message(self): self.protocol.send_extended_ussd_message( '2700000000', message='hello world', session_type=USSD_NEW, genfields=['foo', 'bar', 'baz']) [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'SEND_EXTENDED_USSD_MESSAGE') self.assertEqual(cmd.msisdn, '2700000000') self.assertEqual(cmd.message, 'hello world') self.assertEqual(cmd.type, USSD_NEW) self.assertEqual(cmd.genfields, 'foo:bar:baz') @inlineCallbacks def test_received_sequence_message(self): d = self.protocol.send_binary_message('2700000000', 'foo') [cmd] = yield self.receive(1) yield self.send(Seq(msisdn='2700000000', sequence='bar')) resp = yield d self.assertEqual(resp.sequence, 'bar') self.assertEqual(resp.msisdn, '2700000000') @inlineCallbacks def test_mo(self): calls = [] self.patch(self.protocol_class, 'handle_MO', calls.append) cmd = MoMessage(msisdn='2700000000', sequence='1', message='foo') yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_mo_with_comma(self): calls = [] self.patch(self.protocol_class, 'handle_MO', calls.append) cmd = MoMessage(msisdn='2700000000', sequence='1', message='foo, bar') yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_dr(self): calls = [] self.patch(self.protocol_class, 'handle_DR', calls.append) cmd = DrMessage(msisdn='2700000000', sequence='1', ret_code=DR_SUCCESS) yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_free_form(self): calls = [] self.patch(self.protocol_class, 'handle_FREE_FORM', calls.append) cmd = FFMessage(text='foo') yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_binary_mo(self): calls = [] self.patch(self.protocol_class, 'handle_BINARY_MO', calls.append) cmd = BMoMessage(msisdn='2700000000', sequence='1', coding=CODING_8BIT, pid=PROTOCOL_ENHANCED, hex_msg=binascii.hexlify('hello')) yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_premium_mo(self): calls = [] self.patch(self.protocol_class, 'handle_PREMIUM_MO', calls.append) cmd = PremiumMoMessage(msisdn='2700000000', sequence='1', destination='foo', message='bar') yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_premium_binary_mo(self): calls = [] self.patch(self.protocol_class, 'handle_PREMIUM_BINARY_MO', calls.append) cmd = PremiumBMoMessage(msisdn='2700000000', sequence='1', coding=CODING_8BIT, pid=PROTOCOL_ENHANCED, hex_msg=binascii.hexlify('hello'), destination='foo') yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_ussd_message(self): calls = [] self.patch(self.protocol_class, 'handle_USSD_MESSAGE', calls.append) cmd = USSDMessage(msisdn='2700000000', type=USSD_TIMEOUT, phase=USSD_PHASE_2, message='foo') yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_extended_ussd_message(self): calls = [] self.patch(self.protocol_class, 'handle_EXTENDED_USSD_MESSAGE', calls.append) cmd = ExtendedUSSDMessage(msisdn='2700000000', type=USSD_NEW, phase=USSD_PHASE_2, message='*100#', genfields='655011234567890:1::') yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_server_logout(self): calls = [] self.patch(self.protocol_class, 'handle_LOGOUT', calls.append) cmd = ServerLogout(ip='127.0.0.1') yield self.send(cmd) self.assertEqual([cmd], calls) @inlineCallbacks def test_nack(self): cmd = Nack(nack_type='1') yield self.send(cmd) nack = yield self.protocol.event_queue.get() self.assertEqual(str(cmd), 'SSMI,102,1')
class IRCProtoTests(IRCTestCase): """ 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.assertEqualBufferValue( 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.assertEqualBufferValue( 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.assertEqualBufferValue( 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 test_nick(self): """ IRC NICK command changes the nickname of a user. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice JOIN #group1\r\n") self.proto.dataReceived(":alice1 JOIN #group1\r\n") self.proto.dataReceived(":alice1 NICK newnick\r\n") self.proto.dataReceived(":alice3 NICK newnick3\r\n") self.assertIn("newnick", self.proto._ingroups) self.assertNotIn("alice1", self.proto._ingroups) def test_part(self): """ IRC PART command removes a user from an IRC channel. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 JOIN #group1\r\n") self.assertIn("group1", self.proto._ingroups["alice1"]) self.assertNotIn("group2", self.proto._ingroups["alice1"]) self.proto.dataReceived(":alice PART #group1\r\n") self.proto.dataReceived(":alice1 PART #group1\r\n") self.proto.dataReceived(":alice1 PART #group2\r\n") self.assertNotIn("group1", self.proto._ingroups["alice1"]) self.assertNotIn("group2", self.proto._ingroups["alice1"]) def test_quit(self): """ IRC QUIT command removes a user from all IRC channels. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 JOIN #group1\r\n") self.assertIn("group1", self.proto._ingroups["alice1"]) self.assertNotIn("group2", self.proto._ingroups["alice1"]) self.proto.dataReceived(":alice1 JOIN #group3\r\n") self.assertIn("group3", self.proto._ingroups["alice1"]) self.proto.dataReceived(":alice1 QUIT\r\n") self.assertTrue(len(self.proto._ingroups["alice1"]) == 0) self.proto.dataReceived(":alice3 QUIT\r\n") def test_topic(self): """ IRC TOPIC command changes the topic of an IRC channel. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 JOIN #group1\r\n") self.proto.dataReceived(":alice1 TOPIC #group1 newtopic\r\n") groupConversation = self.proto.getGroupConversation("group1") self.assertEqual(groupConversation.topic, "newtopic") self.assertEqual(groupConversation.topicSetBy, "alice1") def test_privmsg(self): """ PRIVMSG sends a private message to a user or channel. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 PRIVMSG t2 test_message_1\r\n") conversation = self.proto.chat.getConversation( self.proto.getPerson("alice1")) self.assertEqual(conversation.message, "test_message_1") self.proto.dataReceived(":alice1 PRIVMSG #group1 test_message_2\r\n") groupConversation = self.proto.getGroupConversation("group1") self.assertEqual(groupConversation.text, "test_message_2") self.proto.setNick("alice") self.proto.dataReceived(":alice PRIVMSG #foo test_message_3\r\n") groupConversation = self.proto.getGroupConversation("foo") self.assertFalse(hasattr(groupConversation, "text")) conversation = self.proto.chat.getConversation( self.proto.getPerson("alice")) self.assertFalse(hasattr(conversation, "message")) def test_action(self): """ CTCP ACTION to a user or channel. """ self.proto.makeConnection(self.transport) self.proto.dataReceived( ":alice1 PRIVMSG alice1 :\01ACTION smiles\01\r\n") conversation = self.proto.chat.getConversation( self.proto.getPerson("alice1")) self.assertEqual(conversation.message, "smiles") self.proto.dataReceived( ":alice1 PRIVMSG #group1 :\01ACTION laughs\01\r\n") groupConversation = self.proto.getGroupConversation("group1") self.assertEqual(groupConversation.text, "laughs") self.proto.setNick("alice") self.proto.dataReceived( ":alice PRIVMSG #group1 :\01ACTION cries\01\r\n") groupConversation = self.proto.getGroupConversation("foo") self.assertFalse(hasattr(groupConversation, "text")) conversation = self.proto.chat.getConversation( self.proto.getPerson("alice")) self.assertFalse(hasattr(conversation, "message")) def test_rplNamreply(self): """ RPL_NAMREPLY server response (353) lists all the users in a channel. RPL_ENDOFNAMES server response (363) is sent at the end of RPL_NAMREPLY to indicate that there are no more names. """ self.proto.makeConnection(self.transport) self.proto.dataReceived( ":example.com 353 z3p = #bnl :pSwede Dan- SkOyg @MrOp +MrPlus\r\n") expectedInGroups = { "Dan-": ["bnl"], "pSwede": ["bnl"], "SkOyg": ["bnl"], "MrOp": ["bnl"], "MrPlus": ["bnl"], } expectedNamReplies = { "bnl": ["pSwede", "Dan-", "SkOyg", "MrOp", "MrPlus"] } self.assertEqual(expectedInGroups, self.proto._ingroups) self.assertEqual(expectedNamReplies, self.proto._namreplies) self.proto.dataReceived( ":example.com 366 alice #bnl :End of /NAMES list\r\n") self.assertEqual({}, self.proto._namreplies) groupConversation = self.proto.getGroupConversation("bnl") self.assertEqual(expectedNamReplies["bnl"], groupConversation.members) def test_rplTopic(self): """ RPL_TOPIC server response (332) is sent when a channel's topic is changed """ self.proto.makeConnection(self.transport) self.proto.dataReceived( ":example.com 332 alice, #foo :Some random topic\r\n") self.assertEqual("Some random topic", self.proto._topics["foo"]) def test_sendMessage(self): """ L{IRCPerson.sendMessage} """ self.proto.makeConnection(self.transport) person = self.proto.getPerson("alice") self.assertRaises(OfflineError, person.sendMessage, "Some message") person.account.client = self.proto self.transport.clear() person.sendMessage("Some message 2") self.assertEqual(self.transport.io.getvalue(), b"PRIVMSG alice :Some message 2\r\n") self.transport.clear() person.sendMessage("smiles", {"style": "emote"}) self.assertEqual(self.transport.io.getvalue(), b"PRIVMSG alice :\x01ACTION smiles\x01\r\n") def test_sendGroupMessage(self): """ L{IRCGroup.sendGroupMessage} """ self.proto.makeConnection(self.transport) group = self.proto.chat.getGroup("#foo", self.proto) self.assertRaises(OfflineError, group.sendGroupMessage, "Some message") group.account.client = self.proto self.transport.clear() group.sendGroupMessage("Some message 2") self.assertEqual(self.transport.io.getvalue(), b"PRIVMSG #foo :Some message 2\r\n") self.transport.clear() group.sendGroupMessage("smiles", {"style": "emote"}) self.assertEqual(self.transport.io.getvalue(), b"PRIVMSG #foo :\x01ACTION smiles\x01\r\n")
class CommandTestCaseMixin: """ A mixin for TestCase classes which provides support for testing Imaginary environments via command-line transcripts. @ivar store: the L{store.Store} containing all the relevant game objects. @ivar location: The location where the test is taking place. @ivar world: The L{ImaginaryWorld} that created the player. @ivar player: The L{Thing} representing the main player. @ivar observer: The L{Thing} representing the observer who sees the main player's actions. """ genderForTest = language.Gender.FEMALE 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 tearDown(self): """ Disconnect the player and observer from their respective transports. """ for p in self.player, self.observer: try: p.destroy() except AttributeError: pass def watchCommand(self, command): """ Make C{self.player} run the given command and return the output both she and C{self.observer} receive. @param command: The textual command to run. @type command: C{unicode} @return: The player's output and the third-party observer's output. @rtype: Two-tuple of C{unicode} """ self.playerWrapper.parse(command) return ( self.transport.value().decode('utf-8'), self.otransport.value().decode('utf-8')) def assertCommandOutput(self, command, output, observed=()): """ Verify that when C{command} is executed by this L{CommandTestCaseMixin.playerWrapper}, C{output} is produced (to the actor) and C{observed} is produced (to the observer). @param command: The string for L{CommandTestCaseMixin.playerWrapper} to execute. @type command: L{str} @param output: The expected output of C{command} for L{CommandTestCaseMixin.player} to observe. @type output: iterable of L{str} @param observed: The expected output that L{CommandTestCaseMixin.observer} will observe. @type observed: iterable of L{str} """ if command is not None: # Deprecate this or something if not isinstance(command, unicode): command = unicode(command, 'ascii') self.playerWrapper.parse(command) output.insert(0, "> " + command) results = [] for perspective, xport, oput in ([ ('actor' ,self.transport, output), ('observer', self.otransport, observed)]): results.append([]) gotLines = xport.value().decode('utf-8').splitlines() for i, (got, expected) in enumerate(map(None, gotLines, oput)): got = got or '' expected = expected or '$^' m = compile(expected.rstrip() + '$').match(got.rstrip()) if m is None: s1 = pprint.pformat(gotLines) s2 = pprint.pformat(oput) raise unittest.FailTest( "\n%s %s\ndid not match expected\n%s\n(Line %d)" % ( repr(perspective), s1, s2, i)) results[-1].append(m) xport.clear() return results # Old alias. _test = assertCommandOutput def find(self, name): return [ th for th in self.player.findProviders(iimaginary.IThing, 1) if th.name == name][0]
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.transport.clear() defer = 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 test_device_save(self): class TestDev(object): implements(IDeviceInfo) id = 'td_id' key = 'td_key' name = 'td_name' equipment = [] status = None network = None device_class = None self.transport.clear() # minimal message info = TestDev() self.factory.device_save(info) s = decode_ws_message(self.transport.value()) self.assertEquals( { 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)) # with equipment self.transport.clear() 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.assertEquals( { 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)) # equipment with data self.transport.clear() 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.assertEquals( { 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)) # with network self.transport.clear() info.network = devicehive.Network(id='nid', key='nkey', name='nname', descr='ndesr') self.factory.device_save(info) s = decode_ws_message(self.transport.value()) self.assertEquals( { 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'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()) }, json.loads(s))
class IRCProtoTests(IRCTestCase): """ 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.assertEqualBufferValue( 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.assertEqualBufferValue( 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.assertEqualBufferValue( 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 test_nick(self): """ IRC NICK command changes the nickname of a user. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice JOIN #group1\r\n") self.proto.dataReceived(":alice1 JOIN #group1\r\n") self.proto.dataReceived(":alice1 NICK newnick\r\n") self.proto.dataReceived(":alice3 NICK newnick3\r\n") self.assertIn("newnick", self.proto._ingroups) self.assertNotIn("alice1", self.proto._ingroups) def test_part(self): """ IRC PART command removes a user from an IRC channel. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 JOIN #group1\r\n") self.assertIn("group1", self.proto._ingroups["alice1"]) self.assertNotIn("group2", self.proto._ingroups["alice1"]) self.proto.dataReceived(":alice PART #group1\r\n") self.proto.dataReceived(":alice1 PART #group1\r\n") self.proto.dataReceived(":alice1 PART #group2\r\n") self.assertNotIn("group1", self.proto._ingroups["alice1"]) self.assertNotIn("group2", self.proto._ingroups["alice1"]) def test_quit(self): """ IRC QUIT command removes a user from all IRC channels. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 JOIN #group1\r\n") self.assertIn("group1", self.proto._ingroups["alice1"]) self.assertNotIn("group2", self.proto._ingroups["alice1"]) self.proto.dataReceived(":alice1 JOIN #group3\r\n") self.assertIn("group3", self.proto._ingroups["alice1"]) self.proto.dataReceived(":alice1 QUIT\r\n") self.assertTrue(len(self.proto._ingroups["alice1"]) == 0) self.proto.dataReceived(":alice3 QUIT\r\n") def test_topic(self): """ IRC TOPIC command changes the topic of an IRC channel. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 JOIN #group1\r\n") self.proto.dataReceived(":alice1 TOPIC #group1 newtopic\r\n") groupConversation = self.proto.getGroupConversation("group1") self.assertEqual(groupConversation.topic, "newtopic") self.assertEqual(groupConversation.topicSetBy, "alice1") def test_privmsg(self): """ PRIVMSG sends a private message to a user or channel. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 PRIVMSG t2 test_message_1\r\n") conversation = self.proto.chat.getConversation( self.proto.getPerson("alice1")) self.assertEqual(conversation.message, "test_message_1") self.proto.dataReceived(":alice1 PRIVMSG #group1 test_message_2\r\n") groupConversation = self.proto.getGroupConversation("group1") self.assertEqual(groupConversation.text, "test_message_2") self.proto.setNick("alice") self.proto.dataReceived(":alice PRIVMSG #foo test_message_3\r\n") groupConversation = self.proto.getGroupConversation("foo") self.assertFalse(hasattr(groupConversation, "text")) conversation = self.proto.chat.getConversation( self.proto.getPerson("alice")) self.assertFalse(hasattr(conversation, "message")) def test_action(self): """ CTCP ACTION to a user or channel. """ self.proto.makeConnection(self.transport) self.proto.dataReceived(":alice1 PRIVMSG alice1 :\01ACTION smiles\01\r\n") conversation = self.proto.chat.getConversation( self.proto.getPerson("alice1")) self.assertEqual(conversation.message, "smiles") self.proto.dataReceived(":alice1 PRIVMSG #group1 :\01ACTION laughs\01\r\n") groupConversation = self.proto.getGroupConversation("group1") self.assertEqual(groupConversation.text, "laughs") self.proto.setNick("alice") self.proto.dataReceived(":alice PRIVMSG #group1 :\01ACTION cries\01\r\n") groupConversation = self.proto.getGroupConversation("foo") self.assertFalse(hasattr(groupConversation, "text")) conversation = self.proto.chat.getConversation( self.proto.getPerson("alice")) self.assertFalse(hasattr(conversation, "message")) def test_rplNamreply(self): """ RPL_NAMREPLY server response (353) lists all the users in a channel. RPL_ENDOFNAMES server response (363) is sent at the end of RPL_NAMREPLY to indicate that there are no more names. """ self.proto.makeConnection(self.transport) self.proto.dataReceived( ":example.com 353 z3p = #bnl :pSwede Dan- SkOyg @MrOp +MrPlus\r\n") expectedInGroups = {'Dan-': ['bnl'], 'pSwede': ['bnl'], 'SkOyg': ['bnl'], 'MrOp': ['bnl'], 'MrPlus': ['bnl']} expectedNamReplies = { 'bnl': ['pSwede', 'Dan-', 'SkOyg', 'MrOp', 'MrPlus']} self.assertEqual(expectedInGroups, self.proto._ingroups) self.assertEqual(expectedNamReplies, self.proto._namreplies) self.proto.dataReceived( ":example.com 366 alice #bnl :End of /NAMES list\r\n") self.assertEqual({}, self.proto._namreplies) groupConversation = self.proto.getGroupConversation("bnl") self.assertEqual(expectedNamReplies['bnl'], groupConversation.members) def test_rplTopic(self): """ RPL_TOPIC server response (332) is sent when a channel's topic is changed """ self.proto.makeConnection(self.transport) self.proto.dataReceived( ":example.com 332 alice, #foo :Some random topic\r\n") self.assertEqual("Some random topic", self.proto._topics["foo"]) def test_sendMessage(self): """ L{IRCPerson.sendMessage} """ self.proto.makeConnection(self.transport) person = self.proto.getPerson("alice") self.assertRaises(OfflineError, person.sendMessage, "Some message") person.account.client = self.proto self.transport.clear() person.sendMessage("Some message 2") self.assertEqual(self.transport.io.getvalue(), b'PRIVMSG alice :Some message 2\r\n') self.transport.clear() person.sendMessage("smiles", {"style": "emote"}) self.assertEqual(self.transport.io.getvalue(), b'PRIVMSG alice :\x01ACTION smiles\x01\r\n') def test_sendGroupMessage(self): """ L{IRCGroup.sendGroupMessage} """ self.proto.makeConnection(self.transport) group = self.proto.chat.getGroup("#foo", self.proto) self.assertRaises(OfflineError, group.sendGroupMessage, "Some message") group.account.client = self.proto self.transport.clear() group.sendGroupMessage("Some message 2") self.assertEqual(self.transport.io.getvalue(), b'PRIVMSG #foo :Some message 2\r\n') self.transport.clear() group.sendGroupMessage("smiles", {"style": "emote"}) self.assertEqual(self.transport.io.getvalue(), b'PRIVMSG #foo :\x01ACTION smiles\x01\r\n')
class LocalWorkerAMPTests(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 = [] errorClass = fullyQualifiedName(ValueError) d = self.worker.callRemote( managercommands.AddError, testName=self.testName, error="error", errorClass=errorClass, 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 = [] errorClass = fullyQualifiedName(ValueError) d = self.worker.callRemote( managercommands.AddError, testName=self.testName, error="error", errorClass=errorClass, 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 = [] failClass = fullyQualifiedName(RuntimeError) d = self.worker.callRemote( managercommands.AddFailure, testName=self.testName, fail="fail", failClass=failClass, 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) command = managercommands.TestWrite d = self.worker.callRemote(command, 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)
class LocalWorkerAMPTests(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)
class InfobobProtocolTestCase(TrialTestCase): def setUp(self): self.proto = None self.factory = FakeInfobobFactory() self.transport = StringTransport() def initProto(self, configStructure, stubTimer=True): conf = InfobobConfig() conf.load(io.BytesIO(json.dumps(configStructure))) conf.dbpool = None self.proto = Infobob(conf) self.proto.factory = self.factory self.proto.makeConnection(self.transport) if stubTimer: # Stub out startTimer to avoid unclean reactor self.proto.startTimer = lambda *a, **kw: None def clearWritten(self): self.transport.clear() def assertWritten(self, expectedBytes): self.assertEqual(self.transport.value(), expectedBytes) self.clearWritten() def test_autojoin_with_nickserv_pw_waits_for_identified(self): self.initProto({ 'irc': { 'nickname': 'testnick', 'password': '******', 'nickserv_pw': 'nickservpass', 'autojoin': ['#project', '##offtopic'], }, }) p = self.proto p.connectionMade() self.clearWritten() p.signedOn() self.assertWritten(b'PRIVMSG NickServ :identify nickservpass\r\n', ) p.noticed( b'NickServ!foo@host', b'testnick', b'You are now identified as "testnick"', ) self.assertWritten(b'JOIN #project\r\nJOIN ##offtopic\r\n') self.assertIs(p.identified, True) def test_autojoin_no_nickserv_pw(self): self.initProto({ 'irc': { 'nickname': 'testnick', 'password': '******', 'nickserv_pw': None, 'autojoin': ['#project', '##offtopic'], }, }) p = self.proto p.connectionMade() self.clearWritten() p.signedOn() self.assertWritten(b'JOIN #project\r\nJOIN ##offtopic\r\n') self.assertIs(p.identified, False)
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. """ def newThing(color): it = objects.Thing(store=self.store, name=u'%s thing' % (color, )) it.moveTo(self.room) for color in [u'red', u'green']: newThing(color) self.player.parse(u"take thing") self.assertEquals( self.transport.value(), '> take thing\n' 'Could you be more specific? When you said "thing", ' 'did you mean a green thing or a red thing?\r\n') self.transport.clear() newThing(u'blue') self.player.parse(u"take thing") self.assertEquals( self.transport.value(), '> take thing\n' 'Could you be more specific? When you said "thing", ' 'did you mean a blue thing, a green thing, or a red ' 'thing?\r\n')
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.transport.clear() defer = 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 test_device_save(self): class TestDev(object): implements(IDeviceInfo) id = 'td_id' key = 'td_key' name = 'td_name' equipment = [] status = None network = None device_class = None self.transport.clear() # minimal message info = TestDev() self.factory.device_save(info) s = decode_ws_message(self.transport.value()) self.assertEquals({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)) # with equipment self.transport.clear() 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.assertEquals({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)) # equipment with data self.transport.clear() 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.assertEquals({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)) # with network self.transport.clear() info.network = devicehive.Network(id = 'nid', key = 'nkey', name = 'nname', descr = 'ndesr') self.factory.device_save(info) s = decode_ws_message(self.transport.value()) self.assertEquals({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'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())}, json.loads(s))
class InfobobProtocolTestCase(TrialTestCase): def setUp(self): self.proto = None self.factory = FakeInfobobFactory() self.transport = StringTransport() def initProto(self, configStructure, stubTimer=True): conf = InfobobConfig() conf.load(io.BytesIO(json.dumps(configStructure))) conf.dbpool = None self.proto = Infobob(conf) self.proto.factory = self.factory self.proto.makeConnection(self.transport) if stubTimer: # Stub out startTimer to avoid unclean reactor self.proto.startTimer = lambda *a, **kw: None def clearWritten(self): self.transport.clear() def assertWritten(self, expectedBytes): self.assertEqual(self.transport.value(), expectedBytes) self.clearWritten() def test_autojoin_with_nickserv_pw_waits_for_identified(self): self.initProto({ 'irc': { 'nickname': 'testnick', 'password': '******', 'nickserv_pw': 'nickservpass', 'autojoin': ['#project', '##offtopic'], }, }) p = self.proto p.connectionMade() self.clearWritten() p.signedOn() self.assertWritten( b'PRIVMSG NickServ :identify nickservpass\r\n', ) p.noticed( b'NickServ!foo@host', b'testnick', b'You are now identified as "testnick"', ) self.assertWritten(b'JOIN #project\r\nJOIN ##offtopic\r\n') self.assertIs(p.identified, True) def test_autojoin_no_nickserv_pw(self): self.initProto({ 'irc': { 'nickname': 'testnick', 'password': '******', 'nickserv_pw': None, 'autojoin': ['#project', '##offtopic'], }, }) p = self.proto p.connectionMade() self.clearWritten() p.signedOn() self.assertWritten(b'JOIN #project\r\nJOIN ##offtopic\r\n') self.assertIs(p.identified, False)
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, [])