def test_thingsGetLogged(self): """ Check the output produced by L{policies.TrafficLoggingFactory}. """ wrappedFactory = Server() wrappedFactory.protocol = WriteSequenceEchoProtocol t = StringTransportWithDisconnection() f = TestLoggingFactory(wrappedFactory, 'test') p = f.buildProtocol(('1.2.3.4', 5678)) t.protocol = p p.makeConnection(t) v = f.openFile.getvalue() self.failUnless('*' in v, "* not found in %r" % (v,)) self.failIf(t.value()) p.dataReceived('here are some bytes') v = f.openFile.getvalue() self.assertIn("C 1: 'here are some bytes'", v) self.assertIn("S 1: 'here are some bytes'", v) self.assertEqual(t.value(), 'here are some bytes') t.clear() p.dataReceived('prepare for vector! to the extreme') v = f.openFile.getvalue() self.assertIn("SV 1: ['prepare for vector! to the extreme']", v) self.assertEqual(t.value(), 'prepare for vector! to the extreme') p.loseConnection() v = f.openFile.getvalue() self.assertIn('ConnectionDone', v)
def _testDataForward(self, data, method="GET", body=""): """ Build a fake proxy connection, and send C{data} over it, checking that it's forwarded to the originating request. """ # Connect everything clientTransport = StringTransportWithDisconnection() serverTransport = StringTransportWithDisconnection() channel = DummyChannel(serverTransport) parent = DummyParent(channel) serverTransport.protocol = channel client = ProxyClient(method, '/foo', 'HTTP/1.0', {"accept": "text/html"}, body, parent) clientTransport.protocol = client client.makeConnection(clientTransport) # Check data sent self.assertEquals(clientTransport.value(), "%s /foo HTTP/1.0\r\n" "connection: close\r\n" "accept: text/html\r\n\r\n%s" % (method, body)) # Fake an answer client.dataReceived(data) # Check that the data has been forwarded self.assertEquals(serverTransport.value(), data) clientTransport.loseConnection() self.assertIsInstance(channel.lostReason, ConnectionDone)
def test_thingsGetLogged(self): """ Check the output produced by L{policies.TrafficLoggingFactory}. """ wrappedFactory = Server() wrappedFactory.protocol = WriteSequenceEchoProtocol t = StringTransportWithDisconnection() f = TestLoggingFactory(wrappedFactory, "test") p = f.buildProtocol(("1.2.3.4", 5678)) t.protocol = p p.makeConnection(t) v = f.openFile.getvalue() self.assertIn("*", v) self.assertFalse(t.value()) p.dataReceived(b"here are some bytes") v = f.openFile.getvalue() self.assertIn("C 1: {!r}".format(b"here are some bytes"), v) self.assertIn("S 1: {!r}".format(b"here are some bytes"), v) self.assertEqual(t.value(), b"here are some bytes") t.clear() p.dataReceived(b"prepare for vector! to the extreme") v = f.openFile.getvalue() self.assertIn("SV 1: {!r}".format([b"prepare for vector! to the extreme"]), v) self.assertEqual(t.value(), b"prepare for vector! to the extreme") p.loseConnection() v = f.openFile.getvalue() self.assertIn("ConnectionDone", v)
class TestTXDistributeProtocol(TestCase): def setUp(self): self.p = TXDistributeProtocol() self.transport = StringTransportWithDisconnection() self.p.factory = MockFactory() self.p.makeConnection(self.transport) self.transport.protocol = self.p def test_sends_valid_version(self): self.assertEquals(ns("VERSION:1"), self.transport.value()) def test_valid_version(self): self.transport.clear() self.p.stringReceived("VERSION:1") self.assertEquals("", self.transport.value()) self.assertTrue(self.transport.connected) def test_invalid_version(self): self.transport.clear() self.p.stringReceived("VERSION:100") self.assertEquals(ns("QUIT"), self.transport.value()) self.assertFalse(self.transport.connected) def test_quit(self): self.p.stringReceived("QUIT") self.assertFalse(self.transport.connected) def test_send(self): self.p.stringReceived("SEND:1|('a', 'b')") self.assertEqual(self.p.factory.txs, [(1, 'a=b')]) def test_distribute(self): self.transport.clear() self.p.distribute((1, ('a', 'b'))) self.assertEqual(self.transport.value(), ns("SEND:1|('a', 'b')"))
def testThingsGetLogged(self): wrappedFactory = Server() wrappedFactory.protocol = WriteSequenceEchoProtocol t = StringTransportWithDisconnection() f = TestLoggingFactory(wrappedFactory, 'test') p = f.buildProtocol(('1.2.3.4', 5678)) t.protocol = p p.makeConnection(t) v = f.openFile.getvalue() self.failUnless('*' in v, "* not found in %r" % (v,)) self.failIf(t.value()) p.dataReceived('here are some bytes') v = f.openFile.getvalue() self.assertNotEqual(-1, v.find("C 1: 'here are some bytes'"), "Expected client string not found in %r" % (v,)) self.assertNotEqual(-1, v.find("S 1: 'here are some bytes'"), "Expected server string not found in %r" % (v,)) self.assertEquals(t.value(), 'here are some bytes') t.clear() p.dataReceived('prepare for vector! to the extreme') v = f.openFile.getvalue() self.assertNotEqual(-1, v.find("SV 1: ['prepare for vector! to the extreme']"), "Expected server string not found in %r" % (v,)) self.assertEquals(t.value(), 'prepare for vector! to the extreme') p.loseConnection() v = f.openFile.getvalue() self.assertNotEqual(-1, v.find('ConnectionDone'), "Connection done notification not found in %r" % (v,))
def _testDataForward(self, data, method="GET", body=""): """ Build a fake proxy connection, and send C{data} over it, checking that it's forwarded to the originating request. """ # Connect everything clientTransport = StringTransportWithDisconnection() serverTransport = StringTransportWithDisconnection() channel = DummyChannel(serverTransport) parent = DummyParent(channel) serverTransport.protocol = channel client = ProxyClient(method, '/foo', 'HTTP/1.0', {"accept": "text/html"}, body, parent) clientTransport.protocol = client client.makeConnection(clientTransport) # Check data sent self.assertEquals( clientTransport.value(), "%s /foo HTTP/1.0\r\n" "connection: close\r\n" "accept: text/html\r\n\r\n%s" % (method, body)) # Fake an answer client.dataReceived(data) # Check that the data has been forwarded self.assertEquals(serverTransport.value(), data) clientTransport.loseConnection() self.assertIsInstance(channel.lostReason, ConnectionDone)
def test_thingsGetLogged(self): """ Check the output produced by L{policies.TrafficLoggingFactory}. """ wrappedFactory = Server() wrappedFactory.protocol = WriteSequenceEchoProtocol t = StringTransportWithDisconnection() f = TestLoggingFactory(wrappedFactory, 'test') p = f.buildProtocol(('1.2.3.4', 5678)) t.protocol = p p.makeConnection(t) v = f.openFile.getvalue() self.assertIn('*', v) self.assertFalse(t.value()) p.dataReceived(b'here are some bytes') v = f.openFile.getvalue() self.assertIn("C 1: %r" % (b'here are some bytes',), v) self.assertIn("S 1: %r" % (b'here are some bytes',), v) self.assertEqual(t.value(), b'here are some bytes') t.clear() p.dataReceived(b'prepare for vector! to the extreme') v = f.openFile.getvalue() self.assertIn("SV 1: %r" % ([b'prepare for vector! to the extreme'],), v) self.assertEqual(t.value(), b'prepare for vector! to the extreme') p.loseConnection() v = f.openFile.getvalue() self.assertIn('ConnectionDone', v)
class ProtocolTestCase(unittest.TestCase): def setUp(self): self.proto = Redis() self.transport = StringTransportWithDisconnection() self.transport.protocol = self.proto self.proto.makeConnection(self.transport) def sendResponse(self, data): self.proto.dataReceived(data) def test_error_response(self): # pretending 'foo' is a set, so get is incorrect d = self.proto.get("foo") self.assertEquals( self.transport.value(), '*2\r\n$3\r\nGET\r\n$3\r\nfoo\r\n') msg = "Operation against a key holding the wrong kind of value" self.sendResponse("-%s\r\n" % msg) self.failUnlessFailure(d, ResponseError) def check_err(r): self.assertEquals(str(r), msg) return d @defer.inlineCallbacks def test_singleline_response(self): d = self.proto.ping() self.assertEquals(self.transport.value(), '*1\r\n$4\r\nPING\r\n') self.sendResponse("+PONG\r\n") r = yield d self.assertEquals(r, 'PONG') @defer.inlineCallbacks def test_bulk_response(self): d = self.proto.get("foo") self.assertEquals( self.transport.value(), '*2\r\n$3\r\nGET\r\n$3\r\nfoo\r\n') self.sendResponse("$3\r\nbar\r\n") r = yield d self.assertEquals(r, 'bar') @defer.inlineCallbacks def test_multibulk_response(self): d = self.proto.lrange("foo", 0, 1) expected = '*4\r\n$6\r\nLRANGE\r\n$3\r\nfoo\r\n$1\r\n0\r\n$1\r\n1\r\n' self.assertEquals(self.transport.value(), expected) self.sendResponse("*2\r\n$3\r\nbar\r\n$6\r\nlolwut\r\n") r = yield d self.assertEquals(r, ['bar', 'lolwut']) @defer.inlineCallbacks def test_integer_response(self): d = self.proto.dbsize() self.assertEquals(self.transport.value(), '*1\r\n$6\r\nDBSIZE\r\n') self.sendResponse(":1234\r\n") r = yield d self.assertEquals(r, 1234)
class TestWebSocketsProtocol(MAASTestCase): def setUp(self): super().setUp() self.receiver = SavingEchoReceiver() self.protocol = WebSocketsProtocol(self.receiver) self.factory = Factory.forProtocol(lambda: self.protocol) self.transport = StringTransportWithDisconnection() self.protocol.makeConnection(self.transport) self.transport.protocol = self.protocol def test_frameReceived(self): """ L{WebSocketsProtocol.dataReceived} translates bytes into frames, and then write it back encoded into frames. """ self.protocol.dataReceived( _makeFrame(b"Hello", CONTROLS.TEXT, True, mask=b"abcd") ) self.assertEqual(b"\x81\x05Hello", self.transport.value()) self.assertEqual( [(CONTROLS.TEXT, b"Hello", True)], self.receiver.received ) def test_ping(self): """ When a C{PING} frame is received, the frame is resent with a C{PONG}, and the application receiver is notified about it. """ self.protocol.dataReceived( _makeFrame(b"Hello", CONTROLS.PING, True, mask=b"abcd") ) self.assertEqual(b"\x8a\x05Hello", self.transport.value()) self.assertEqual( [(CONTROLS.PING, b"Hello", True)], self.receiver.received ) def test_close(self): """ When a C{CLOSE} frame is received, the protocol closes the connection and logs a message. """ with TwistedLoggerFixture() as logger: self.protocol.dataReceived( _makeFrame(b"", CONTROLS.CLOSE, True, mask=b"abcd") ) self.assertFalse(self.transport.connected) self.assertEqual( ["Closing connection: <STATUSES=NONE>"], logger.messages ) def test_invalidFrame(self): """ If an invalid frame is received, L{WebSocketsProtocol} closes the connection. """ self.protocol.dataReceived(b"\x72\x05") self.assertFalse(self.transport.connected)
class Protocol(unittest.TestCase): def setUp(self): self.proto = Redis() self.transport = StringTransportWithDisconnection() self.transport.protocol = self.proto self.proto.makeConnection(self.transport) def sendResponse(self, data): self.proto.dataReceived(data) def test_error_response(self): # pretending 'foo' is a set, so get is incorrect d = self.proto.get("foo") self.assertEquals(self.transport.value(), '*2\r\n$3\r\nGET\r\n$3\r\nfoo\r\n') msg = "Operation against a key holding the wrong kind of value" self.sendResponse("-%s\r\n" % msg) self.failUnlessFailure(d, ResponseError) def check_err(r): self.assertEquals(str(r), msg) return d @defer.inlineCallbacks def test_singleline_response(self): d = self.proto.ping() self.assertEquals(self.transport.value(), '*1\r\n$4\r\nPING\r\n') self.sendResponse("+PONG\r\n") r = yield d self.assertEquals(r, 'PONG') @defer.inlineCallbacks def test_bulk_response(self): d = self.proto.get("foo") self.assertEquals(self.transport.value(), '*2\r\n$3\r\nGET\r\n$3\r\nfoo\r\n') self.sendResponse("$3\r\nbar\r\n") r = yield d self.assertEquals(r, 'bar') @defer.inlineCallbacks def test_multibulk_response(self): d = self.proto.lrange("foo", 0, 1) expected = '*4\r\n$6\r\nLRANGE\r\n$3\r\nfoo\r\n$1\r\n0\r\n$1\r\n1\r\n' self.assertEquals(self.transport.value(), expected) self.sendResponse("*2\r\n$3\r\nbar\r\n$6\r\nlolwut\r\n") r = yield d self.assertEquals(r, ['bar', 'lolwut']) @defer.inlineCallbacks def test_integer_response(self): d = self.proto.dbsize() self.assertEquals(self.transport.value(), '*1\r\n$6\r\nDBSIZE\r\n') self.sendResponse(":1234\r\n") r = yield d self.assertEquals(r, 1234)
class Protocol(unittest.TestCase): def setUp(self): self.proto = Redis() self.transport = StringTransportWithDisconnection() self.transport.protocol = self.proto self.proto.makeConnection(self.transport) def sendResponse(self, data): self.proto.dataReceived(data) @defer.inlineCallbacks def test_error_response(self): # pretending 'foo' is a set, so get is incorrect d = self.proto.get("foo") self.assertEquals(self.transport.value(), "GET foo\r\n") msg = "Operation against a key holding the wrong kind of value" self.sendResponse("-%s\r\n" % msg) r = yield d self.assertEquals(str(r), msg) @defer.inlineCallbacks def test_singleline_response(self): d = self.proto.ping() self.assertEquals(self.transport.value(), "PING\r\n") self.sendResponse("+PONG\r\n") r = yield d self.assertEquals(r, 'PONG') @defer.inlineCallbacks def test_bulk_response(self): d = self.proto.get("foo") self.assertEquals(self.transport.value(), "GET foo\r\n") self.sendResponse("$3\r\nbar\r\n") r = yield d self.assertEquals(r, 'bar') @defer.inlineCallbacks def test_multibulk_response(self): d = self.proto.lrange("foo", 0, 1) self.assertEquals(self.transport.value(), "LRANGE foo 0 1\r\n") self.sendResponse("*2\r\n$3\r\nbar\r\n$6\r\nlolwut\r\n") r = yield d self.assertEquals(r, ['bar', 'lolwut']) @defer.inlineCallbacks def test_integer_response(self): d = self.proto.dbsize() self.assertEquals(self.transport.value(), "DBSIZE\r\n") self.sendResponse(":1234\r\n") r = yield d self.assertEquals(r, 1234)
class BaseStratumClientTest(unittest.TestCase): __test__ = False def setUp(self): super().setUp() from hathor.transaction.genesis import _get_genesis_transactions_unsafe self.block = next(x for x in _get_genesis_transactions_unsafe(None) if x.is_block) self.transport = StringTransportWithDisconnection() self.protocol = StratumClient() self.protocol.makeConnection(self.transport) self.job_request_params = { 'data': self.block.get_header_without_nonce().hex(), 'job_id': 'a734d03fe4b64739be2894742f3de20f', 'nonce_size': Block.SERIALIZATION_NONCE_SIZE, 'weight': self.block.weight, } def tearDown(self): super().tearDown() self.protocol.stop() @pytest.mark.skip(reason='hangs on some systems') def test_n_core_mining(self): self.protocol.start(self.clock) self.protocol.handle_request('job', self.job_request_params, None) # Ignore subscribe request and empty line after line break requests = self.transport.value().split(JSONRPC.delimiter)[1:-1] while len(requests) < 1: sleep(1) self.clock.advance(1) requests = self.transport.value().split(JSONRPC.delimiter)[1:-1] submits = [json_loads(request) for request in requests] submits_params = [submit['params'] for submit in submits] methods = [submit['method'] for submit in submits] jobs_id = [params['job_id'] for params in submits_params] nonces = [params['nonce'] for params in submits_params] self.assertTrue(all(method == 'submit' for method in methods)) self.assertTrue( all(job_id == self.job_request_params['job_id'] for job_id in jobs_id)) for nonce in nonces: self.block.nonce = int(nonce, 16) self.block.update_hash() self.block.verify_pow()
def test_getNodeConnection(self): """ L{Process._getNodeConnection}, if no connection is established, as a connection to a L{OneShotPortMapperFactory}. Once it gets a connection it sets the calls handler to the client factory to the process handler. """ d = self.process._getNodeConnection("egg@spam") epmd = self.process.oneShotEpmds["spam"] transport = StringTransportWithDisconnection() proto = epmd.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x04zegg") self.assertEqual(epmd.connect, [("spam", 4369, epmd)]) proto.dataReceived( "w\x00\x00\x09M\x01\x00\x05\x00\x05\x00\x03bar\x00") [factory] = epmd.factories self.assertEqual( epmd.factoriesArgs, [("foo@bar", "test_cookie", epmd.onConnectionLost)]) clientProto = TestableNodeProtocol() clientProto.factory = factory factory._connectDeferred.callback(clientProto) def check(proto): self.assertIdentical(proto, clientProto) self.assertIdentical(factory.handler, self.process.handler) return d.addCallback(check)
def test_writeLimit(self): """ Check the writeLimit parameter: write data, and check for the pause status. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server, writeLimit=10) port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0)) tr = StringTransportWithDisconnection() tr.protocol = port port.makeConnection(tr) port.producer = port.wrappedProtocol port.dataReceived("0123456789") port.dataReceived("abcdefghij") self.assertEqual(tr.value(), "0123456789abcdefghij") self.assertEqual(tServer.writtenThisSecond, 20) self.assertFalse(port.wrappedProtocol.paused) # at this point server should've written 20 bytes, 10 bytes # above the limit so writing should be paused around 1 second # from 'now', and resumed a second after that tServer.clock.advance(1.05) self.assertEqual(tServer.writtenThisSecond, 0) self.assertTrue(port.wrappedProtocol.paused) tServer.clock.advance(1.05) self.assertEqual(tServer.writtenThisSecond, 0) self.assertFalse(port.wrappedProtocol.paused)
class _BaseStratumTest(unittest.TestCase): __test__ = False def setUp(self): super().setUp() self.manager = self.create_peer('testnet') self.manager.allow_mining_without_peers() self.factory = StratumFactory(self.manager, port=8123, reactor=MemoryReactorClock()) self.factory.start() self.protocol = self.factory.buildProtocol('127.0.0.1') self.transport = StringTransportWithDisconnection() self.transport.protocol = self.protocol self.protocol.makeConnection(self.transport) # subscribe and ignore response _send_subscribe(self.protocol) self.job = self._get_latest_message()['params'] self.transport.clear() def tearDown(self): super().tearDown() self.factory.stop() def _get_latest_message(self): data = self.transport.value().split(JSONRPC.delimiter)[-2] return json_loads(data)
def test_web_with_factory(self): """ Speaking HTTP will pass it down to the HTTP factory. """ t = StringTransport() class MyResource(Resource): isLeaf = True def render_GET(self, request): return b"hi!" r = MyResource() s = Site(r) f = UniSocketServerFactory(web_factory=s) p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'GET / HTTP/1.1\r\nConnection: close\r\n\r\n') self.assertFalse(t.connected) self.assertIn(b"hi!", t.value())
def test_rawsocket_with_factory(self): """ Speaking RawSocket when the connection is made will make UniSocket create a new RawSocket protocol and send the data to it. """ t = StringTransport() class MyFakeRawSocket(Protocol): """ A fake RawSocket factory which just echos data back. """ def dataReceived(self, data): self.transport.write(data) fake_rawsocket = Factory.forProtocol(MyFakeRawSocket) f = UniSocketServerFactory(rawsocket_factory=fake_rawsocket) p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'\x7F0000000') p.dataReceived(b'moredata') self.assertTrue(t.connected) self.assertEqual(t.value(), b'\x7F0000000moredata')
def test_websocket_with_map(self): """ Speaking WebSocket when the connection is made will make UniSocket create a new WebSocket protocol and send the data to it. """ t = StringTransport() class MyFakeWebSocket(Protocol): """ A fake WebSocket factory which just echos data back. """ def dataReceived(self, data): self.transport.write(data) fake_websocket = Factory.forProtocol(MyFakeWebSocket) websocket_map = OrderedDict({u"baz": None}) websocket_map["ws"] = fake_websocket f = UniSocketServerFactory(websocket_factory_map=websocket_map) p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'GET /ws HTTP/1.1\r\nConnection: close\r\n\r\n') self.assertTrue(t.connected) self.assertEqual(t.value(), b'GET /ws HTTP/1.1\r\nConnection: close\r\n\r\n')
def test_writeLimit(self): """ Check the writeLimit parameter: write data, and check for the pause status. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server, writeLimit=10) port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0)) tr = StringTransportWithDisconnection() tr.protocol = port port.makeConnection(tr) port.producer = port.wrappedProtocol port.dataReceived(b"0123456789") port.dataReceived(b"abcdefghij") self.assertEqual(tr.value(), b"0123456789abcdefghij") self.assertEqual(tServer.writtenThisSecond, 20) self.assertFalse(port.wrappedProtocol.paused) # at this point server should've written 20 bytes, 10 bytes # above the limit so writing should be paused around 1 second # from 'now', and resumed a second after that tServer.clock.advance(1.05) self.assertEqual(tServer.writtenThisSecond, 0) self.assertTrue(port.wrappedProtocol.paused) tServer.clock.advance(1.05) self.assertEqual(tServer.writtenThisSecond, 0) self.assertFalse(port.wrappedProtocol.paused)
class TestLogin(TestCase): def setUp(self): self.sp = CredReceiver() self.sp.factory = CredAMPServerFactory() self.sp.factory.sUsername = '******' self.transport = StringTransportWithDisconnection() self.sp.makeConnection(self.transport) self.transport.protocol = self.sp self.testFrame = ("00:82:a0:00:00:53:45:52:50:2d:42:30:91:1d:1b:03:" + "8d:0b:5c:03:02:28:01:9c:01:ab:02:4c:02:98:01:da:" + "02:40:00:00:00:10:0a:46:58:10:00:c4:9d:cb:a2:21:39") def tearDown(self): self.sp.factory.active_protocols = {} self.sp.factory.active_connections = {} def test_serverSendsAnythingWhenReceiveFrame(self): self.sp.dataReceived(self.testFrame) return self.assertEquals('', self.transport.value()) @patch.object(CredReceiver, 'resetTimeout') def test_timeoutResetWhenReceivesMessage(self, resetTimeout): self.sp.dataReceived(self.testFrame) return self.assertEqual(resetTimeout.call_count, 1)
def test_connectToNode(self): """ L{OneShotPortMapperFactory.connectToNode} should return a L{Deferred} that will be called back with the instance of the protocol connected to the erlang node. """ clientFactory = DummyClientFactory() self.factory.nodeFactoryClass = lambda a, b, c: clientFactory d = self.factory.connectToNode("egg@spam") transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x04zegg") self.assertEqual( self.factory.connect, [("127.0.0.1", 4369, self.factory)]) proto.dataReceived( "w\x00\x00\x09M\x01\x00\x05\x00\x05\x00\x03bar\x00") clientProto = object() clientFactory._connectDeferred.callback(clientProto) self.assertEqual( self.factory.connect, [("127.0.0.1", 4369, self.factory), ("127.0.0.1", 9, clientFactory)]) return d.addCallback(self.assertIdentical, clientProto)
class TestProtocol(common.TestCase): def setUp(self): self.transport = StringTransportWithDisconnection() self.protocol = httpclient.Protocol(self, owner=None) self.protocol.factory = MockFactory() self.protocol.makeConnection(self.transport) self.transport.protocol = self.protocol self.addCleanup(self._disconnect_protocol) @defer.inlineCallbacks def testSimpleRequest(self): self.assertTrue(self.protocol.factory.onConnectionMade_called) self.assertTrue(self.protocol.is_idle()) d = self.protocol.request(http.Methods.GET, '/', headers={'accept': 'text/html'}) self.assertEqual('GET / HTTP/1.1\r\n' 'Accept: text/html\r\n\r\n', self.transport.value()) self.assertFalse(self.protocol.is_idle()) self.protocol.dataReceived( self.protocol.delimiter.join([ "HTTP/1.1 200 OK", "Content-Type: text/html", "Content-Length: 12", "", "This is body", ])) response = yield d self.assertIsInstance(response, httpclient.Response) self.assertEqual(200, response.status) self.assertEqual({'content-type': 'text/html', 'content-length': '12'}, response.headers) self.assertEqual('This is body', response.body) self.assertTrue(self.protocol.is_idle()) self.assertTrue(self.protocol.factory.onConnectionReset_called) @defer.inlineCallbacks def testCancelledRequest(self): d = self.protocol.request(http.Methods.GET, '/', headers={'accept': 'text/html'}) d.cancel() self.assertFalse(self.transport.connected) self.assertFailure(d, httpclient.RequestCancelled) f = yield d exp = ('GET to http://10.0.0.1:12345/ was cancelled ' '0.(\d+)s after it was sent.') self.assertTrue(re.match(exp, str(f)), str(f)) def _disconnect_protocol(self): if self.transport.connected: self.transport.loseConnection() self.assertTrue(self.protocol.factory.onConnectionLost_called)
def test_loseConnectionCodeAndReason(self): """ L{WebSocketsTransport.loseConnection} accepts a code and a reason which are used to build the closing frame. """ transport = StringTransportWithDisconnection() transport.protocol = Protocol() webSocketsTranport = WebSocketsTransport(transport) webSocketsTranport.loseConnection(STATUSES.GOING_AWAY, b"Going away") self.assertEqual(b"\x88\x0c\x03\xe9Going away", transport.value())
class TestPingPongProtocol(unittest.SynchronousTestCase): def setUp(self): self.maximum = 100 self.factory = PingPongClientFactory(self.maximum) self.protocol = self.factory.buildProtocol(address.IPv4Address('TCP', 'localhost', 1234)) self.transport = StringTransportWithDisconnection() self.protocol.makeConnection(self.transport) self.transport.protocol = self.protocol def test_first_byte_written(self): self.assertEqual(len(self.transport.value()), 1) def test_byte_written_for_byte(self): self.protocol.dataReceived(b'*') self.assertEqual(len(self.transport.value()), 2) def test_receiving_maximum_loses_connection(self): self.protocol.dataReceived(b'*' * self.maximum) self.assertFalse(self.transport.connected)
class TestHeartbeatProtocol(unittest.SynchronousTestCase): def setUp(self): self.clock = task.Clock() self.factory = HeartbeatProtocolFactory(self.clock) self.protocol = self.factory.buildProtocol(address.IPv4Address('TCP', 'localhost', 1234)) self.transport = StringTransportWithDisconnection() self.protocol.makeConnection(self.transport) self.transport.protocol = self.protocol def test_heartbeat_written(self): self.assertEqual(len(self.transport.value()), 1) self.clock.advance(60) self.assertEqual(len(self.transport.value()), 2) def test_lost_connection_stops_heartbeater(self): self.assertTrue(self.protocol._heartbeater.running) self.protocol.connectionLost(main.CONNECTION_DONE) self.assertFalse(self.protocol._heartbeater.running)
def test_loseConnectionCodeAndReason(self): """ L{WebSocketsTransport.loseConnection} accepts a code and a reason which are used to build the closing frame. """ transport = StringTransportWithDisconnection() transport.protocol = Protocol() webSocketsTranport = WebSocketsTransport(transport) webSocketsTranport.loseConnection(STATUSES.GOING_AWAY, "Going away") self.assertEqual("\x88\x0c\x03\xe9Going away", transport.value())
class TestProtocol(TestCase): def setUp(self): self.protocol = ChatProtocol() self.transport = StringTransportWithDisconnection() self.protocol.factory = ChatProtocolFactory() self.protocol.makeConnection(self.transport) self.transport.protocol = self.protocol fl = os.open(self.protocol.factory.filename, os.O_CREAT | os.O_RDWR) os.write(fl, 'hey ho\n') os.close(fl) def split_commands(self): return self.transport.value().splitlines() def assertCommands(self, args): commands = self.split_commands() cmd_list = [parsingCommand(cmd) for cmd in commands] arg_list = [parsingCommand(arg) for arg in args] for (cmd, arg) in zip(cmd_list, arg_list): self.assertEquals(arg[1], cmd[1]) if arg[2]: self.assertEquals(arg[2], cmd[2]) def test_connect_command(self): self.protocol.lineReceived("CONNECT hey ho") self.assertCommands(['OK', 'SERVICE', 'NAMES']) def test_new_command_error_incorrect_data(self): self.protocol.lineReceived("NEW gahhahjjkjsfkkfkk ho") self.assertCommands(["ERROR '%s'" % err_text['err_incorrect_data']]) def test_new_command_error_usr_exist(self): self.protocol.lineReceived("NEW hey ho") self.assertCommands(["ERROR '%s'" % err_text['err_user_exist']]) def test_msg_command(self): self.protocol.lineReceived("CONNECT hey ho") self.protocol.lineReceived("!hey MSG * 'message'") self.assertCommands(['OK', 'SERVICE', 'NAMES', 'MSG']) def test_nick_command(self): self.protocol.lineReceived("CONNECT hey ho") self.protocol.lineReceived("!hey NICK newnick") self.assertCommands(['OK', 'SERVICE', 'NAMES']*2) def tearDown(self): self.protocol.transport.loseConnection()
def _testDataForward(self, code, message, headers, body, method="GET", requestBody="", loseConnection=True): """ Build a fake proxy connection, and send C{data} over it, checking that it's forwarded to the originating request. """ request = DummyRequest(['foo']) # Connect a proxy client to a fake transport. clientTransport = StringTransportWithDisconnection() client = ProxyClient(method, '/foo', 'HTTP/1.0', {"accept": "text/html"}, requestBody, request) clientTransport.protocol = client client.makeConnection(clientTransport) # Check data sent self.assertEquals( clientTransport.value(), "%s /foo HTTP/1.0\r\n" "connection: close\r\n" "accept: text/html\r\n\r\n%s" % (method, requestBody)) # Fake an answer client.dataReceived("HTTP/1.0 %d %s\r\n" % (code, message)) for (header, values) in headers: for value in values: client.dataReceived("%s: %s\r\n" % (header, value)) client.dataReceived("\r\n" + body) # Check that the response data has been forwarded back to the original # requester. self.assertEquals(request.responseCode, code) self.assertEquals(request.responseMessage, message) receivedHeaders = list(request.responseHeaders.getAllRawHeaders()) receivedHeaders.sort() expectedHeaders = headers[:] expectedHeaders.sort() self.assertEquals(receivedHeaders, expectedHeaders) self.assertEquals(''.join(request.written), body) # Check that when the response is done, the request is finished. if loseConnection: clientTransport.loseConnection() # Even if we didn't call loseConnection, the transport should be # disconnected. This lets us not rely on the server to close our # sockets for us. self.assertFalse(clientTransport.connected) self.assertEquals(request.finished, 1)
def test_connection(self): """ On connection, the EPMD client should send an ALIVE2 request. """ self.factory.nodePortNumber = 1234 transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEquals(transport.value(), "\x00\x10x\x04\xd2H\x00\x00\x05\x00\x05\x00\x03foo\x00\x00")
class TestLineReciever(unittest.TestCase): S = six.b('TEST') def setUp(self): self.proto = LineReceiverSubclass() self.transport = StringTransportWithDisconnection() self.proto.makeConnection(self.transport) self.transport.protocol = self.proto self.proto.factory = MockFactory() def test_excess_line_length(self): self.assertTrue(self.transport.connected) self.proto.dataReceived(six.b('\x00') * (self.proto.MAX_LENGTH + 1)) self.assertFalse(self.transport.connected) def test_excess_delimited_line(self): self.assertTrue(self.transport.connected) self.proto.dataReceived(self.S + self.proto.delimiter) self.assertEqual(self.proto._rcvd_line, self.S.decode()) s = (six.b('\x00') * (self.proto.MAX_LENGTH + 1)) + self.proto.delimiter self.proto._rcvd_line = None self.proto.dataReceived(s) self.assertFalse(self.transport.connected) self.assertIs(self.proto._rcvd_line, None) def test_clear_line_buffer(self): self.proto.dataReceived(self.S) self.assertEqual(self.proto.clearLineBuffer(), self.S) def test_send_line(self): self.proto.dataReceived(self.S + self.proto.delimiter) self.assertEqual(self.proto._rcvd_line, self.S.decode()) def test_raw_data(self): clock = task.Clock() self.proto.callLater = clock.callLater self.proto.setRawMode() s = self.S + self.proto.delimiter self.proto.dataReceived(s) self.assertEqual(self.proto._rcvd_data, s) self.proto._rcvd_line = None self.proto.setLineMode(s) clock.advance(1) self.assertEqual(self.proto._rcvd_line, self.S.decode()) self.proto.dataReceived(s) self.assertEqual(self.proto._rcvd_line, self.S.decode()) def test_sendline(self): self.proto.sendLine(self.S) value = self.transport.value() self.assertEqual(value, self.S + self.proto.delimiter)
def test_readLimit(self): """ Check the readLimit parameter: read data and check for the pause status. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server, readLimit=10) port = tServer.buildProtocol(address.IPv4Address( "TCP", "127.0.0.1", 0)) tr = StringTransportWithDisconnection() tr.protocol = port port.makeConnection(tr) port.dataReceived(b"0123456789") port.dataReceived(b"abcdefghij") self.assertEqual(tr.value(), b"0123456789abcdefghij") self.assertEqual(tServer.readThisSecond, 20) tServer.clock.advance(1.05) self.assertEqual(tServer.readThisSecond, 0) self.assertEqual(tr.producerState, "paused") tServer.clock.advance(1.05) self.assertEqual(tServer.readThisSecond, 0) self.assertEqual(tr.producerState, "producing") tr.clear() port.dataReceived(b"0123456789") port.dataReceived(b"abcdefghij") self.assertEqual(tr.value(), b"0123456789abcdefghij") self.assertEqual(tServer.readThisSecond, 20) tServer.clock.advance(1.05) self.assertEqual(tServer.readThisSecond, 0) self.assertEqual(tr.producerState, "paused") tServer.clock.advance(1.05) self.assertEqual(tServer.readThisSecond, 0) self.assertEqual(tr.producerState, "producing")
def test_loseConnection(self): """ L{WebSocketsTransport.loseConnection} sends a close frame and closes the transport afterwards. """ transport = StringTransportWithDisconnection() transport.protocol = Protocol() webSocketsTranport = WebSocketsTransport(transport) webSocketsTranport.loseConnection() self.assertFalse(transport.connected) self.assertEqual(b"\x88\x02\x03\xe8", transport.value()) # We can call loseConnection again without side effects webSocketsTranport.loseConnection()
def test_loseConnection(self): """ L{WebSocketsTransport.loseConnection} sends a close frame and closes the transport afterwards. """ transport = StringTransportWithDisconnection() transport.protocol = Protocol() webSocketsTranport = WebSocketsTransport(transport) webSocketsTranport.loseConnection() self.assertFalse(transport.connected) self.assertEqual("\x88\x02\x03\xe8", transport.value()) # We can call loseConnection again without side effects webSocketsTranport.loseConnection()
def test_readLimit(self): """ Check the readLimit parameter: read data and check for the pause status. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server, readLimit=10) port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0)) tr = StringTransportWithDisconnection() tr.protocol = port port.makeConnection(tr) port.dataReceived("0123456789") port.dataReceived("abcdefghij") self.assertEqual(tr.value(), "0123456789abcdefghij") self.assertEqual(tServer.readThisSecond, 20) tServer.clock.advance(1.05) self.assertEqual(tServer.readThisSecond, 0) self.assertEqual(tr.producerState, 'paused') tServer.clock.advance(1.05) self.assertEqual(tServer.readThisSecond, 0) self.assertEqual(tr.producerState, 'producing') tr.clear() port.dataReceived("0123456789") port.dataReceived("abcdefghij") self.assertEqual(tr.value(), "0123456789abcdefghij") self.assertEqual(tServer.readThisSecond, 20) tServer.clock.advance(1.05) self.assertEqual(tServer.readThisSecond, 0) self.assertEqual(tr.producerState, 'paused') tServer.clock.advance(1.05) self.assertEqual(tServer.readThisSecond, 0) self.assertEqual(tr.producerState, 'producing')
def test_websocket_mechanics(): """ Shows that we can put our protocol (hey_joe._WayDownSouth) and factory (hey_joe.WebSocketService) together, along with a transport, and properly open a websocket connection. """ transport = StringTransportWithDisconnection() service = hey_joe.WebSocketService("127.0.0.1", 9000) protocol = service.buildProtocol(service._hey_joe_addr) protocol.transport = transport transport.protocol = protocol protocol.connectionMade() data_to_send = b'GET / HTTP/1.1\r\nHost: somewhere_in_the_world:9000\r\nConnection: keep-alive, Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: F76ObkF/aCKX8WkmAgx2OQ==\r\n\r\n' protocol.dataReceived(data_to_send) assert transport.value().startswith(b'HTTP/1.1 101 Switching Protocols\r\nServer: hendrix')
def test_kill(self): """ L{OneShotPortMapperFactory.kill} should return a L{Deferred} that will be called back when the kill request is complete. """ d = self.factory.kill() transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x01k") proto.dataReceived("OK") transport.loseConnection() return d.addCallback(self.assertEqual, "OK")
def test_writeSequence(self): """ L{ThrottlingProtocol.writeSequence} is called on the underlying factory. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server) protocol = tServer.buildProtocol(address.IPv4Address("TCP", "127.0.0.1", 0)) transport = StringTransportWithDisconnection() transport.protocol = protocol protocol.makeConnection(transport) protocol.writeSequence([b"bytes"] * 4) self.assertEqual(transport.value(), b"bytesbytesbytesbytes") self.assertEqual(tServer.writtenThisSecond, 20)
def test_names(self): """ L{OneShotPortMapperFactory.names} should return a L{Deferred} that will be called back when the names request is complete. """ d = self.factory.names() transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x01n") proto.dataReceived("\x00\x00\x00\x01") proto.dataReceived("name %s at port %s\n" % ("foo", 1234)) transport.loseConnection() return d.addCallback(self.assertEqual, [("foo", 1234)])
def test_writeSequence(self): """ L{ThrottlingProtocol.writeSequence} is called on the underlying factory. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server) protocol = tServer.buildProtocol( address.IPv4Address('TCP', '127.0.0.1', 0)) transport = StringTransportWithDisconnection() transport.protocol = protocol protocol.makeConnection(transport) protocol.writeSequence([b'bytes'] * 4) self.assertEqual(transport.value(), b"bytesbytesbytesbytes") self.assertEqual(tServer.writtenThisSecond, 20)
def _testDataForward(self, code, message, headers, body, method="GET", requestBody="", loseConnection=True): """ Build a fake proxy connection, and send C{data} over it, checking that it's forwarded to the originating request. """ request = DummyRequest(['foo']) # Connect a proxy client to a fake transport. clientTransport = StringTransportWithDisconnection() client = ProxyClient(method, '/foo', 'HTTP/1.0', {"accept": "text/html"}, requestBody, request) clientTransport.protocol = client client.makeConnection(clientTransport) # Check data sent self.assertEquals(clientTransport.value(), "%s /foo HTTP/1.0\r\n" "connection: close\r\n" "accept: text/html\r\n\r\n%s" % (method, requestBody)) # Fake an answer client.dataReceived("HTTP/1.0 %d %s\r\n" % (code, message)) for (header, values) in headers: for value in values: client.dataReceived("%s: %s\r\n" % (header, value)) client.dataReceived("\r\n" + body) # Check that the response data has been forwarded back to the original # requester. self.assertEquals(request.responseCode, code) self.assertEquals(request.responseMessage, message) receivedHeaders = list(request.responseHeaders.getAllRawHeaders()) receivedHeaders.sort() expectedHeaders = headers[:] expectedHeaders.sort() self.assertEquals(receivedHeaders, expectedHeaders) self.assertEquals(''.join(request.written), body) # Check that when the response is done, the request is finished. if loseConnection: clientTransport.loseConnection() # Even if we didn't call loseConnection, the transport should be # disconnected. This lets us not rely on the server to close our # sockets for us. self.assertFalse(clientTransport.connected) self.assertEquals(request.finished, 1)
def test_names(self): """ L{Process.names} returns the list of nodes on a particular host. """ d = self.process.names("spam") epmd = self.process.oneShotEpmds["spam"] transport = StringTransportWithDisconnection() proto = epmd.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x01n") proto.dataReceived("\x00\x00\x00\x01") proto.dataReceived("name %s at port %s\n" % ("foo", 1234)) proto.dataReceived("name %s at port %s\n" % ("egg", 4321)) transport.loseConnection() return d.addCallback(self.assertEqual, [("foo", 1234), ("egg", 4321)])
def test_dump(self): """ L{OneShotPortMapperFactory.dump} should return a L{Deferred} that will be called back when the dump request is complete. """ d = self.factory.dump() transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x01d") proto.dataReceived("\x00\x00\x00\x01") proto.dataReceived( "active name <%s> at port %s, fd = %s\n\x00" % ("foo", 1234, 3)) transport.loseConnection() return d.addCallback( self.assertEqual, {"active": [("foo", 1234, 3)], "old": []})
def test_subscribe(self): transport = StringTransportWithDisconnection() protocol = self.factory.buildProtocol('127.0.0.1') protocol.makeConnection(transport) id = uuid4() _send_subscribe(protocol, id) self.assertEqual(len(self.factory.miner_protocols), 2) data = transport.value().split(JSONRPC.delimiter) self.assertEqual(len(data), 3) response = json_loads(data[0]) self.assertEqual(response['id'], str(id)) self.assertEqual(response['result'], "ok") job = json_loads(data[1]) self.assertEqual(job['method'], 'job')
def test_connectionFailed(self): """ Check that L{ProxyClientFactory.clientConnectionFailed} produces a B{501} response to the parent request. """ serverTransport = StringTransportWithDisconnection() channel = DummyChannel(serverTransport) parent = DummyParent(channel) serverTransport.protocol = channel factory = ProxyClientFactory('GET', '/foo', 'HTTP/1.0', {"accept": "text/html"}, '', parent) factory.clientConnectionFailed(None, None) self.assertEquals(serverTransport.value(), "HTTP/1.0 501 Gateway error\r\n" "Content-Type: text/html\r\n\r\n" "<H1>Could not connect</H1>") self.assertIsInstance(channel.lostReason, ConnectionDone)
def test_portPlease2(self): """ L{OneShotPortMapperFactory.portPlease2Request} should create a connection to a new host, and set its initial action to B{portPlease2Request} with the nodeName given. """ d = self.factory.portPlease2Request("egg@spam") transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\tzegg@spam") self.assertEqual( self.factory.connect, [("127.0.0.1", 4369, self.factory)]) proto.dataReceived( "w\x00\x00\x09M\x01\x00\x05\x00\x05\x00\x03bar\x00") return d.addCallback(self.assertEqual, Node(9, 77, 1, (5, 5), "bar", ""))
def test_connectionFailed(self): """ Check that L{ProxyClientFactory.clientConnectionFailed} produces a B{501} response to the parent request. """ serverTransport = StringTransportWithDisconnection() channel = DummyChannel(serverTransport) parent = DummyParent(channel) serverTransport.protocol = channel factory = ProxyClientFactory('GET', '/foo', 'HTTP/1.0', {"accept": "text/html"}, '', parent) factory.clientConnectionFailed(None, None) self.assertEquals( serverTransport.value(), "HTTP/1.0 501 Gateway error\r\n" "Content-Type: text/html\r\n\r\n" "<H1>Could not connect</H1>") self.assertIsInstance(channel.lostReason, ConnectionDone)
def test_websocket_with_no_map(self): """ A web request that matches no WebSocket """ t = StringTransport() websocket_map = {u"x": None, u"y": None} f = UniSocketServerFactory(websocket_factory_map=websocket_map) p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'GET /ws HTTP/1.1\r\nConnection: close\r\n\r\n') self.assertFalse(t.connected) self.assertEqual(t.value(), b"")
def test_websocket_with_no_map(self): """ A web request that matches no WebSocket path will go to HTTP/1.1. """ t = StringTransport() websocket_map = {u"x": None, u"y": None} f = UniSocketServerFactory(websocket_factory_map=websocket_map) p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'GET /ws HTTP/1.1\r\nConnection: close\r\n\r\n') self.assertFalse(t.connected) self.assertEqual(t.value(), b"")
class WebSocketsProtocolWrapperTest(MAASTestCase): """ Tests for L{WebSocketsProtocolWrapper}. """ def setUp(self): super(WebSocketsProtocolWrapperTest, self).setUp() self.accumulatingProtocol = AccumulatingProtocol() self.protocol = WebSocketsProtocolWrapper(self.accumulatingProtocol) self.transport = StringTransportWithDisconnection() self.protocol.makeConnection(self.transport) self.transport.protocol = self.protocol def test_dataReceived(self): """ L{WebSocketsProtocolWrapper.dataReceived} forwards frame content to the underlying protocol. """ self.protocol.dataReceived( _makeFrame(b"Hello", CONTROLS.TEXT, True, mask=b"abcd")) self.assertEqual(b"Hello", self.accumulatingProtocol.data) def test_controlFrames(self): """ L{WebSocketsProtocolWrapper} doesn't forward data from control frames to the underlying protocol. """ self.protocol.dataReceived( _makeFrame(b"Hello", CONTROLS.PING, True, mask=b"abcd")) self.protocol.dataReceived( _makeFrame(b"Hello", CONTROLS.PONG, True, mask=b"abcd")) self.protocol.dataReceived( _makeFrame(b"", CONTROLS.CLOSE, True, mask=b"abcd")) self.assertEqual(b"", self.accumulatingProtocol.data) def test_loseConnection(self): """ L{WebSocketsProtocolWrapper.loseConnection} sends a close frame and disconnects the transport. """ self.protocol.loseConnection() self.assertFalse(self.transport.connected) self.assertEqual(b"\x88\x02\x03\xe8", self.transport.value()) def test_write(self): """ L{WebSocketsProtocolWrapper.write} creates and writes a frame from the payload passed. """ self.accumulatingProtocol.transport.write(b"Hello") self.assertEqual(b"\x81\x05Hello", self.transport.value()) def test_writeSequence(self): """ L{WebSocketsProtocolWrapper.writeSequence} writes a frame for every chunk passed. """ self.accumulatingProtocol.transport.writeSequence([b"Hello", b"World"]) self.assertEqual(b"\x81\x05Hello\x81\x05World", self.transport.value()) def test_getHost(self): """ L{WebSocketsProtocolWrapper.getHost} returns the transport C{getHost}. """ self.assertEqual(self.transport.getHost(), self.accumulatingProtocol.transport.getHost()) def test_getPeer(self): """ L{WebSocketsProtocolWrapper.getPeer} returns the transport C{getPeer}. """ self.assertEqual(self.transport.getPeer(), self.accumulatingProtocol.transport.getPeer()) def test_connectionLost(self): """ L{WebSocketsProtocolWrapper.connectionLost} forwards the connection lost call to the underlying protocol. """ self.transport.loseConnection() self.assertTrue(self.accumulatingProtocol.closed)
def test_subscribe_and_mine(self): import json from hashlib import sha256 # boilerplate needed to exchange bytes transport = StringTransportWithDisconnection() protocol = self.manager.stratum_factory.buildProtocol( IPv4Address('TCP', '127.0.0.1', 8123)) transport.protocol = protocol protocol.makeConnection(transport) # subscribe req = {'jsonrpc': '2.0', 'id': '1', 'method': 'subscribe'} protocol.lineReceived(json.dumps(req).encode()) res = transport.value().split(JSONRPC.delimiter) self.assertEqual(len(res), 3) # check if we have subscribed response = yield self.web.get('miners') data = response.json_value() self.assertIsInstance(data, list) self.assertEqual(len(data), 1) res = data[0] del res['connection_start_time'] del res['miner_id'] self.assertEqual( res, { 'address': '127.0.0.1:8123', 'blocks_found': 0, 'completed_jobs': 0, 'estimated_hash_rate': 0.0 }) # mine a block # TODO: use predictable work instead of always repeating this work job = json.loads(res[1])['params'] job_id = job['job_id'] job_hash1 = sha256(bytes.fromhex(job['data'])) job_nonce_size = job['nonce_size'] job_max_nonce = 1 << (8 * job_nonce_size) job_target = 2**(256 - job['weight']) - 1 nonce = 0 while nonce < job_max_nonce: job_hash2 = job_hash1.copy() job_hash2.update(nonce.to_bytes(job_nonce_size, 'big')) if int(sha256(job_hash2.digest()).digest()[::-1].hex(), 16) < job_target: break nonce += 1 # FIXME: assuming nonce was found: exited loop through break # submit our work req = {'job_id': job_id, 'nonce': nonce} protocol.lineReceived(json.dumps(req).encode()) res = transport.value().split(JSONRPC.delimiter) self.assertEqual(len(res), 4) self.assertTrue(False) # check if our work has updated the stats response = yield self.web.get('miners') data = response.json_value() self.assertIsInstance(data, list) self.assertEqual(len(data), 1) res = data[0] del res['connection_start_time'] del res['miner_id'] self.assertEqual( res, # TODO: what is the actual estimated hash rate? should we test it? { 'address': '127.0.0.1:8123', 'blocks_found': 1, 'completed_jobs': 1, 'estimated_hash_rate': 0.0 })
class NodeServerProtocolTestCase(TestCase): """ Tests for L{NodeServerProtocol}. """ def setUp(self): """ Create an instance of C{NodeClientProtocol} and connect it to a fake transport. """ self.factory = DummyServerFactory() self.proto = NodeServerProtocol() self.transport = StringTransportWithDisconnection() self.proto.factory = self.factory self.proto.makeConnection(self.transport) self.transport.protocol = self.proto self.clock = Clock() self.proto.callLater = self.clock.callLater def test_handshake(self): """ Test a handshake data received. """ remainData = self.proto.handle_handshake( "\x00\x0an\x00\x01\x00\x00\x00\x02foo") self.assertEqual(remainData, "") self.assertEqual(self.proto.state, "challenge") self.assertEqual( self.transport.value(), "\x00\x03sok" "\x00\x13n\x00\x05\x00\x00\x01\x0c\x00\x00\x00\x02spam@egg") def test_handshakeFragmented(self): """ Test a handshake data received in fragments. """ self.proto.dataReceived("\x00") self.proto.dataReceived("\x0a") self.proto.dataReceived("n\x00\x01\x00") self.proto.dataReceived("\x00\x00\x02foo") self.assertEqual(self.proto.state, "challenge") self.assertEqual( self.transport.value(), "\x00\x03sok" "\x00\x13n\x00\x05\x00\x00\x01\x0c\x00\x00\x00\x02spam@egg") def test_handshakeInvalidIdentifier(self): """ Test a handshake with an invalid indentifier. """ self.assertRaises( ValueError, self.proto.handle_handshake, "\x00\x0aN\x00\x01\x00\x00\x00\x02foo") def test_challenge(self): """ Test a challenge data received. """ self.proto.challenge = self.proto.generateChallenge() remainData = self.proto.handle_challenge( "\x00\x15r\x00\x00\x00\x05I\x14\xa6U'\xe0\x89\x14<\x1a\xdc\xf9" "(G&!") self.assertEqual(remainData, "") self.assertEqual(self.proto.state, "connected") self.assertEqual( self.transport.value(), "\x00\x11a\xe0\xdf2<\xe8\xbd\xa1o\xec\xe2\x12\xe5\x9c\xc6\xf7\x94") def test_challengeFragmented(self): """ Test a challenge data received in fragments. """ self.proto.challenge = self.proto.generateChallenge() self.proto.state = "challenge" self.proto.dataReceived("\x00") self.proto.dataReceived("\x15") self.proto.dataReceived("r\x00\x00\x00\x05I\x14\xa6U'\xe0") self.proto.dataReceived("\x89\x14<\x1a\xdc\xf9(G&!") self.assertEqual(self.proto.state, "connected") self.assertEqual( self.transport.value(), "\x00\x11a\xe0\xdf2<\xe8\xbd\xa1o\xec\xe2\x12\xe5\x9c\xc6\xf7\x94") def test_challengeInvalidIdentifier(self): """ Test a challenge with an invalid indentifier. """ self.proto.challenge = self.proto.generateChallenge() self.assertRaises( ValueError, self.proto.handle_challenge, "\x00\x15R\x00\x00\x00\x05SkH\x1f\xd8Z\xf0\"\xe2\xf5\xd6x2\xe9!" "\xe6") def test_challengeInvalidDigest(self): """ Test a challenge with a wrong digest. """ self.proto.challenge = self.proto.generateChallenge() self.assertRaises( ValueError, self.proto.handle_challenge, "\x00\x15r\x00\x00\x00\x05SkH\x1f\xd8Z\xf1\"\xe2\xf5\xd6x2\xe9!" "\xe6")
class MemCacheTests(CommandMixin, TestCase): """ Test client protocol class L{MemCacheProtocol}. """ def setUp(self): """ Create a memcache client, connect it to a string protocol, and make it use a deterministic clock. """ self.proto = MemCacheProtocol() self.clock = Clock() self.proto.callLater = self.clock.callLater self.transport = StringTransportWithDisconnection() self.transport.protocol = self.proto self.proto.makeConnection(self.transport) def _test(self, d, send, recv, result): """ Implementation of C{_test} which checks that the command sends C{send} data, and that upon reception of C{recv} the result is C{result}. @param d: the resulting deferred from the memcache command. @type d: C{Deferred} @param send: the expected data to be sent. @type send: C{bytes} @param recv: the data to simulate as reception. @type recv: C{bytes} @param result: the expected result. @type result: C{any} """ def cb(res): self.assertEqual(res, result) self.assertEqual(self.transport.value(), send) d.addCallback(cb) self.proto.dataReceived(recv) return d def test_invalidGetResponse(self): """ If the value returned doesn't match the expected key of the current C{get} command, an error is raised in L{MemCacheProtocol.dataReceived}. """ self.proto.get(b"foo") self.assertRaises( RuntimeError, self.proto.dataReceived, b"VALUE bar 0 7\r\nspamegg\r\nEND\r\n", ) def test_invalidMultipleGetResponse(self): """ If the value returned doesn't match one the expected keys of the current multiple C{get} command, an error is raised error in L{MemCacheProtocol.dataReceived}. """ self.proto.getMultiple([b"foo", b"bar"]) self.assertRaises( RuntimeError, self.proto.dataReceived, b"VALUE egg 0 7\r\nspamegg\r\nEND\r\n", ) def test_invalidEndResponse(self): """ If an END is received in response to an operation that isn't C{get}, C{gets}, or C{stats}, an error is raised in L{MemCacheProtocol.dataReceived}. """ self.proto.set(b"key", b"value") self.assertRaises(RuntimeError, self.proto.dataReceived, b"END\r\n") def test_timeOut(self): """ Test the timeout on outgoing requests: when timeout is detected, all current commands fail with a L{TimeoutError}, and the connection is closed. """ d1 = self.proto.get(b"foo") d2 = self.proto.get(b"bar") d3 = Deferred() self.proto.connectionLost = d3.callback self.clock.advance(self.proto.persistentTimeOut) self.assertFailure(d1, TimeoutError) self.assertFailure(d2, TimeoutError) def checkMessage(error): self.assertEqual(str(error), "Connection timeout") d1.addCallback(checkMessage) self.assertFailure(d3, ConnectionDone) return gatherResults([d1, d2, d3]) def test_timeoutRemoved(self): """ When a request gets a response, no pending timeout call remains around. """ d = self.proto.get(b"foo") self.clock.advance(self.proto.persistentTimeOut - 1) self.proto.dataReceived(b"VALUE foo 0 3\r\nbar\r\nEND\r\n") def check(result): self.assertEqual(result, (0, b"bar")) self.assertEqual(len(self.clock.calls), 0) d.addCallback(check) return d def test_timeOutRaw(self): """ Test the timeout when raw mode was started: the timeout is not reset until all the data has been received, so we can have a L{TimeoutError} when waiting for raw data. """ d1 = self.proto.get(b"foo") d2 = Deferred() self.proto.connectionLost = d2.callback self.proto.dataReceived(b"VALUE foo 0 10\r\n12345") self.clock.advance(self.proto.persistentTimeOut) self.assertFailure(d1, TimeoutError) self.assertFailure(d2, ConnectionDone) return gatherResults([d1, d2]) def test_timeOutStat(self): """ Test the timeout when stat command has started: the timeout is not reset until the final B{END} is received. """ d1 = self.proto.stats() d2 = Deferred() self.proto.connectionLost = d2.callback self.proto.dataReceived(b"STAT foo bar\r\n") self.clock.advance(self.proto.persistentTimeOut) self.assertFailure(d1, TimeoutError) self.assertFailure(d2, ConnectionDone) return gatherResults([d1, d2]) def test_timeoutPipelining(self): """ When two requests are sent, a timeout call remains around for the second request, and its timeout time is correct. """ d1 = self.proto.get(b"foo") d2 = self.proto.get(b"bar") d3 = Deferred() self.proto.connectionLost = d3.callback self.clock.advance(self.proto.persistentTimeOut - 1) self.proto.dataReceived(b"VALUE foo 0 3\r\nbar\r\nEND\r\n") def check(result): self.assertEqual(result, (0, b"bar")) self.assertEqual(len(self.clock.calls), 1) for i in range(self.proto.persistentTimeOut): self.clock.advance(1) return self.assertFailure(d2, TimeoutError).addCallback(checkTime) def checkTime(ignored): # Check that the timeout happened C{self.proto.persistentTimeOut} # after the last response self.assertEqual(self.clock.seconds(), 2 * self.proto.persistentTimeOut - 1) d1.addCallback(check) self.assertFailure(d3, ConnectionDone) return d1 def test_timeoutNotReset(self): """ Check that timeout is not resetted for every command, but keep the timeout from the first command without response. """ d1 = self.proto.get(b"foo") d3 = Deferred() self.proto.connectionLost = d3.callback self.clock.advance(self.proto.persistentTimeOut - 1) d2 = self.proto.get(b"bar") self.clock.advance(1) self.assertFailure(d1, TimeoutError) self.assertFailure(d2, TimeoutError) self.assertFailure(d3, ConnectionDone) return gatherResults([d1, d2, d3]) def test_timeoutCleanDeferreds(self): """ C{timeoutConnection} cleans the list of commands that it fires with C{TimeoutError}: C{connectionLost} doesn't try to fire them again, but sets the disconnected state so that future commands fail with a C{RuntimeError}. """ d1 = self.proto.get(b"foo") self.clock.advance(self.proto.persistentTimeOut) self.assertFailure(d1, TimeoutError) d2 = self.proto.get(b"bar") self.assertFailure(d2, RuntimeError) return gatherResults([d1, d2]) def test_connectionLost(self): """ When disconnection occurs while commands are still outstanding, the commands fail. """ d1 = self.proto.get(b"foo") d2 = self.proto.get(b"bar") self.transport.loseConnection() done = DeferredList([d1, d2], consumeErrors=True) def checkFailures(results): for success, result in results: self.assertFalse(success) result.trap(ConnectionDone) return done.addCallback(checkFailures) def test_tooLongKey(self): """ An error is raised when trying to use a too long key: the called command returns a L{Deferred} which fails with a L{ClientError}. """ d1 = self.assertFailure(self.proto.set(b"a" * 500, b"bar"), ClientError) d2 = self.assertFailure(self.proto.increment(b"a" * 500), ClientError) d3 = self.assertFailure(self.proto.get(b"a" * 500), ClientError) d4 = self.assertFailure(self.proto.append(b"a" * 500, b"bar"), ClientError) d5 = self.assertFailure(self.proto.prepend(b"a" * 500, b"bar"), ClientError) d6 = self.assertFailure(self.proto.getMultiple([b"foo", b"a" * 500]), ClientError) return gatherResults([d1, d2, d3, d4, d5, d6]) def test_invalidCommand(self): """ When an unknown command is sent directly (not through public API), the server answers with an B{ERROR} token, and the command fails with L{NoSuchCommand}. """ d = self.proto._set(b"egg", b"foo", b"bar", 0, 0, b"") self.assertEqual(self.transport.value(), b"egg foo 0 0 3\r\nbar\r\n") self.assertFailure(d, NoSuchCommand) self.proto.dataReceived(b"ERROR\r\n") return d def test_clientError(self): """ Test the L{ClientError} error: when the server sends a B{CLIENT_ERROR} token, the originating command fails with L{ClientError}, and the error contains the text sent by the server. """ a = b"eggspamm" d = self.proto.set(b"foo", a) self.assertEqual(self.transport.value(), b"set foo 0 0 8\r\neggspamm\r\n") self.assertFailure(d, ClientError) def check(err): self.assertEqual(str(err), repr(b"We don't like egg and spam")) d.addCallback(check) self.proto.dataReceived(b"CLIENT_ERROR We don't like egg and spam\r\n") return d def test_serverError(self): """ Test the L{ServerError} error: when the server sends a B{SERVER_ERROR} token, the originating command fails with L{ServerError}, and the error contains the text sent by the server. """ a = b"eggspamm" d = self.proto.set(b"foo", a) self.assertEqual(self.transport.value(), b"set foo 0 0 8\r\neggspamm\r\n") self.assertFailure(d, ServerError) def check(err): self.assertEqual(str(err), repr(b"zomg")) d.addCallback(check) self.proto.dataReceived(b"SERVER_ERROR zomg\r\n") return d def test_unicodeKey(self): """ Using a non-string key as argument to commands raises an error. """ d1 = self.assertFailure(self.proto.set("foo", b"bar"), ClientError) d2 = self.assertFailure(self.proto.increment("egg"), ClientError) d3 = self.assertFailure(self.proto.get(1), ClientError) d4 = self.assertFailure(self.proto.delete("bar"), ClientError) d5 = self.assertFailure(self.proto.append("foo", b"bar"), ClientError) d6 = self.assertFailure(self.proto.prepend("foo", b"bar"), ClientError) d7 = self.assertFailure(self.proto.getMultiple([b"egg", 1]), ClientError) return gatherResults([d1, d2, d3, d4, d5, d6, d7]) def test_unicodeValue(self): """ Using a non-string value raises an error. """ return self.assertFailure(self.proto.set(b"foo", "bar"), ClientError) def test_pipelining(self): """ Multiple requests can be sent subsequently to the server, and the protocol orders the responses correctly and dispatch to the corresponding client command. """ d1 = self.proto.get(b"foo") d1.addCallback(self.assertEqual, (0, b"bar")) d2 = self.proto.set(b"bar", b"spamspamspam") d2.addCallback(self.assertEqual, True) d3 = self.proto.get(b"egg") d3.addCallback(self.assertEqual, (0, b"spam")) self.assertEqual( self.transport.value(), b"get foo\r\nset bar 0 0 12\r\nspamspamspam\r\nget egg\r\n", ) self.proto.dataReceived(b"VALUE foo 0 3\r\nbar\r\nEND\r\n" b"STORED\r\n" b"VALUE egg 0 4\r\nspam\r\nEND\r\n") return gatherResults([d1, d2, d3]) def test_getInChunks(self): """ If the value retrieved by a C{get} arrive in chunks, the protocol is able to reconstruct it and to produce the good value. """ d = self.proto.get(b"foo") d.addCallback(self.assertEqual, (0, b"0123456789")) self.assertEqual(self.transport.value(), b"get foo\r\n") self.proto.dataReceived(b"VALUE foo 0 10\r\n0123456") self.proto.dataReceived(b"789") self.proto.dataReceived(b"\r\nEND") self.proto.dataReceived(b"\r\n") return d def test_append(self): """ L{MemCacheProtocol.append} behaves like a L{MemCacheProtocol.set} method: it returns a L{Deferred} which is called back with C{True} when the operation succeeds. """ return self._test( self.proto.append(b"foo", b"bar"), b"append foo 0 0 3\r\nbar\r\n", b"STORED\r\n", True, ) def test_prepend(self): """ L{MemCacheProtocol.prepend} behaves like a L{MemCacheProtocol.set} method: it returns a L{Deferred} which is called back with C{True} when the operation succeeds. """ return self._test( self.proto.prepend(b"foo", b"bar"), b"prepend foo 0 0 3\r\nbar\r\n", b"STORED\r\n", True, ) def test_gets(self): """ L{MemCacheProtocol.get} handles an additional cas result when C{withIdentifier} is C{True} and forward it in the resulting L{Deferred}. """ return self._test( self.proto.get(b"foo", True), b"gets foo\r\n", b"VALUE foo 0 3 1234\r\nbar\r\nEND\r\n", (0, b"1234", b"bar"), ) def test_emptyGets(self): """ Test getting a non-available key with gets: it succeeds but return L{None} as value, C{0} as flag and an empty cas value. """ return self._test(self.proto.get(b"foo", True), b"gets foo\r\n", b"END\r\n", (0, b"", None)) def test_getsMultiple(self): """ L{MemCacheProtocol.getMultiple} handles an additional cas field in the returned tuples if C{withIdentifier} is C{True}. """ return self._test( self.proto.getMultiple([b"foo", b"bar"], True), b"gets foo bar\r\n", b"VALUE foo 0 3 1234\r\negg\r\n" b"VALUE bar 0 4 2345\r\nspam\r\nEND\r\n", { b"bar": (0, b"2345", b"spam"), b"foo": (0, b"1234", b"egg") }, ) def test_getsMultipleIterableKeys(self): """ L{MemCacheProtocol.getMultiple} accepts any iterable of keys. """ return self._test( self.proto.getMultiple(iter([b"foo", b"bar"]), True), b"gets foo bar\r\n", b"VALUE foo 0 3 1234\r\negg\r\n" b"VALUE bar 0 4 2345\r\nspam\r\nEND\r\n", { b"bar": (0, b"2345", b"spam"), b"foo": (0, b"1234", b"egg") }, ) def test_getsMultipleWithEmpty(self): """ When getting a non-available key with L{MemCacheProtocol.getMultiple} when C{withIdentifier} is C{True}, the other keys are retrieved correctly, and the non-available key gets a tuple of C{0} as flag, L{None} as value, and an empty cas value. """ return self._test( self.proto.getMultiple([b"foo", b"bar"], True), b"gets foo bar\r\n", b"VALUE foo 0 3 1234\r\negg\r\nEND\r\n", { b"bar": (0, b"", None), b"foo": (0, b"1234", b"egg") }, ) def test_checkAndSet(self): """ L{MemCacheProtocol.checkAndSet} passes an additional cas identifier that the server handles to check if the data has to be updated. """ return self._test( self.proto.checkAndSet(b"foo", b"bar", cas=b"1234"), b"cas foo 0 0 3 1234\r\nbar\r\n", b"STORED\r\n", True, ) def test_casUnknowKey(self): """ When L{MemCacheProtocol.checkAndSet} response is C{EXISTS}, the resulting L{Deferred} fires with C{False}. """ return self._test( self.proto.checkAndSet(b"foo", b"bar", cas=b"1234"), b"cas foo 0 0 3 1234\r\nbar\r\n", b"EXISTS\r\n", False, )
class TestTruteqTransport(VumiTestCase): @inlineCallbacks def setUp(self): self.tx_helper = self.add_helper(TransportHelper(TruteqTransport)) self.config = { 'username': '******', 'password': '******', } self.string_transport = StringTransportWithDisconnection() # NOTE: pausing the transport before starting so we can # start the SSMIProtocol, which expects the vumi transport # as an argument. self.transport = yield self.tx_helper.get_transport(self.config, start=False) st_endpoint = StringTransportEndpoint(self._ste_connect_callback) def truteq_service_maker(endpoint, factory): return ReconnectingClientService(st_endpoint, factory) self.transport.service_class = truteq_service_maker yield self.transport.startWorker() yield self.process_login_commands('username', 'password') def _ste_connect_callback(self, protocol): self.protocol = protocol self.string_transport = protocol.transport @inlineCallbacks def process_login_commands(self, username, password): [cmd] = yield self.receive(1) self.assertEqual(cmd.command_name, 'LOGIN') self.assertEqual(cmd.username, username) self.assertEqual(cmd.password, password) self.send(Ack(ack_type='1')) [link_check] = yield self.receive(1) self.assertEqual(link_check.command_name, 'LINK_CHECK') returnValue(True) 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.string_transport.value(): reactor.callLater(0, check_for_input) return lines = self.string_transport.value().split( self.protocol.delimiter) commands = map(SSMIRequest.parse, filter(None, lines)) if len(commands) >= count: if clear: self.string_transport.clear() self.string_transport.write( self.protocol.delimiter.join(map( str, commands[count:]))) d.callback(commands[:count]) check_for_input() return d def incoming_ussd(self, msisdn="12345678", ussd_type=c.USSD_RESPONSE, phase="ignored", message="Hello"): self.send( USSDMessage(msisdn=msisdn, type=ussd_type, phase=c.USSD_PHASE_UNKNOWN, message=message)) @inlineCallbacks def start_ussd(self, message="*678#", **kw): kw.setdefault("msisdn", "12345678") kw.setdefault("phase", c.USSD_PHASE_UNKNOWN) yield self.transport.handle_raw_inbound_message( USSDMessage(type=c.USSD_NEW, message=message, **kw)) self.tx_helper.clear_dispatched_inbound() @inlineCallbacks def check_msg(self, from_addr="+12345678", to_addr="*678#", content=None, session_event=None, helper_metadata=None): default_hmd = {'truteq': {'genfields': {}}} [msg] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(msg['transport_name'], self.tx_helper.transport_name) self.assertEqual(msg['transport_type'], 'ussd') self.assertEqual(msg['transport_metadata'], {}) self.assertEqual(msg['helper_metadata'], helper_metadata or default_hmd) self.assertEqual(msg['from_addr'], from_addr) self.assertEqual(msg['to_addr'], to_addr) self.assertEqual(msg['content'], content) self.assertEqual(msg['session_event'], session_event) self.tx_helper.clear_dispatched_inbound() @inlineCallbacks def test_handle_inbound_ussd_new(self): yield self.send( USSDMessage(msisdn='27000000000', type=c.USSD_NEW, message='*678#', phase=c.USSD_PHASE_1)) [msg] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(msg['to_addr'], '*678#') self.assertEqual(msg['session_event'], SESSION_NEW) self.assertEqual(msg['transport_type'], 'ussd') @inlineCallbacks def test_handle_inbound_extended_ussd_new(self): yield self.send( ExtendedUSSDMessage(msisdn='27000000000', type=c.USSD_NEW, message='*678#', genfields='::3', phase=c.USSD_PHASE_1)) [msg] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(msg['from_addr'], '+27000000000') self.assertEqual(msg['to_addr'], '*678#') self.assertEqual( msg['helper_metadata'], { 'truteq': { 'genfields': { 'IMSI': '', 'OperatorID': '3', 'SessionID': '', 'Subscriber Type': '', 'ValiPort': '', } } }) @inlineCallbacks def test_handle_remote_logout(self): cmd = ServerLogout(ip='127.0.0.1') with LogCatcher() as logger: yield self.send(cmd) [warning] = logger.messages() self.assertEqual(warning, "Received remote logout command: %r" % (cmd, )) @inlineCallbacks def test_handle_inbound_ussd_resume(self): yield self.start_ussd() self.incoming_ussd(ussd_type=c.USSD_RESPONSE, message="Hello") yield self.check_msg(content="Hello", session_event=SESSION_RESUME) @inlineCallbacks def test_handle_inbound_ussd_close(self): yield self.start_ussd() self.incoming_ussd(ussd_type=c.USSD_END, message="Done") yield self.check_msg(content="Done", session_event=SESSION_CLOSE) @inlineCallbacks def test_handle_inbound_ussd_timeout(self): yield self.start_ussd() self.incoming_ussd(ussd_type=c.USSD_TIMEOUT, message="Timeout") yield self.check_msg(content="Timeout", session_event=SESSION_CLOSE) @inlineCallbacks def test_handle_inbound_ussd_non_ascii(self): yield self.start_ussd() self.incoming_ussd(ussd_type=c.USSD_TIMEOUT, message=u"föóbær".encode("iso-8859-1")) yield self.check_msg(content=u"föóbær", session_event=SESSION_CLOSE) @inlineCallbacks def test_handle_inbound_ussd_with_comma_in_content(self): yield self.start_ussd() self.incoming_ussd(ussd_type=c.USSD_TIMEOUT, message=u"foo, bar") yield self.check_msg(content=u"foo, bar", session_event=SESSION_CLOSE) @inlineCallbacks def _test_outbound_ussd(self, vumi_session_type, ssmi_session_type, content="Test", encoding="utf-8"): yield self.tx_helper.make_dispatch_outbound( content, to_addr=u"+1234", session_event=vumi_session_type) [ussd_call] = yield self.receive(1) data = content.encode(encoding) if content else "" self.assertEqual(ussd_call.message, data) self.assertTrue(isinstance(ussd_call.message, str)) self.assertEqual(ussd_call.msisdn, '1234') self.assertEqual(ussd_call.type, ssmi_session_type) def test_handle_outbound_ussd_no_session(self): return self._test_outbound_ussd(SESSION_NONE, c.USSD_RESPONSE) def test_handle_outbound_ussd_null_content(self): return self._test_outbound_ussd(SESSION_NONE, c.USSD_RESPONSE, content=None) def test_handle_outbound_ussd_resume(self): return self._test_outbound_ussd(SESSION_RESUME, c.USSD_RESPONSE) def test_handle_outbound_ussd_close(self): return self._test_outbound_ussd(SESSION_CLOSE, c.USSD_END) def test_handle_outbound_ussd_non_ascii(self): return self._test_outbound_ussd(SESSION_NONE, c.USSD_RESPONSE, content=u"föóbær", encoding='iso-8859-1') @inlineCallbacks def _test_content_wrangling(self, submitted, expected): yield self.tx_helper.make_dispatch_outbound(submitted, to_addr=u"+1234", session_event=SESSION_NONE) # Grab what was sent to Truteq [ussd_call] = yield self.receive(1) expected_msg = SendUSSDMessage(msisdn='1234', message=expected, type=c.USSD_RESPONSE) self.assertEqual(ussd_call, expected_msg) def test_handle_outbound_ussd_with_comma_in_content(self): return self._test_content_wrangling('hello world, universe', 'hello world, universe') def test_handle_outbound_ussd_with_crln_in_content(self): return self._test_content_wrangling('hello\r\nwindows\r\nworld', 'hello\nwindows\nworld') def test_handle_outbound_ussd_with_cr_in_content(self): return self._test_content_wrangling('hello\rold mac os\rworld', 'hello\nold mac os\nworld') @inlineCallbacks def test_ussd_addr_retains_asterisks_and_hashes(self): self.incoming_ussd(ussd_type=c.USSD_NEW, message="*6*7*8#") yield self.check_msg(to_addr="*6*7*8#", session_event=SESSION_NEW) @inlineCallbacks def test_ussd_addr_appends_hashes_if_missing(self): self.incoming_ussd(ussd_type=c.USSD_NEW, message="*6*7*8") yield self.check_msg(to_addr="*6*7*8#", session_event=SESSION_NEW) @inlineCallbacks def test_handle_inbound_sms(self): cmd = MoMessage(msisdn='foo', message='bar', sequence='1') with LogCatcher() as logger: yield self.send(cmd) [warning] = logger.messages() self.assertEqual( warning, "Received unsupported message, dropping: %r." % (cmd, )) @inlineCallbacks def test_reconnect(self): """ When disconnected, the transport should attempt to reconnect. We test this by stashing the current protocol instance, disconnecting it, and asserting that we get a new protocol instance with the usual login commands after reconnection. """ self.transport.client_service.delay = 0 old_protocol = self.protocol yield self.protocol.transport.loseConnection() yield deferLater(reactor, 0, lambda: None) # Let the reactor run. self.assertNotEqual(old_protocol, self.protocol) yield self.process_login_commands('username', 'password')