예제 #1
0
    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)
예제 #2
0
    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)
예제 #4
0
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')"))
예제 #5
0
    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,))
예제 #6
0
    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,))
예제 #7
0
    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)
예제 #8
0
    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)
예제 #9
0
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)
예제 #10
0
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)
예제 #11
0
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)
예제 #12
0
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)
예제 #13
0
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()
예제 #14
0
    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)
예제 #15
0
    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)
예제 #16
0
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)
예제 #17
0
    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())
예제 #18
0
    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')
예제 #19
0
    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')
예제 #20
0
    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)
예제 #21
0
    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')
예제 #22
0
    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())
예제 #23
0
    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')
예제 #24
0
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)
예제 #25
0
파일: test_epmd.py 프로젝트: gbour/twotp
 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)
예제 #26
0
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)
예제 #27
0
 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())
예제 #28
0
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)
예제 #29
0
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)
예제 #30
0
 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())
예제 #31
0
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()
예제 #32
0
    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)
예제 #33
0
 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")
예제 #34
0
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)
예제 #35
0
    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")
예제 #36
0
 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()
예제 #37
0
 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()
예제 #38
0
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)
예제 #39
0
    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')
예제 #40
0
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')
예제 #41
0
파일: test_epmd.py 프로젝트: gbour/twotp
 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)
예제 #43
0
파일: test_epmd.py 프로젝트: gbour/twotp
 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)])
예제 #44
0
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')"))
예제 #45
0
    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)
예제 #46
0
파일: test_proxy.py 프로젝트: Almad/twisted
    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)
예제 #47
0
 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)])
예제 #48
0
파일: test_epmd.py 프로젝트: gbour/twotp
 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": []})
예제 #49
0
    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')
예제 #50
0
    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)
예제 #51
0
파일: test_epmd.py 프로젝트: gbour/twotp
 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", ""))
예제 #52
0
    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)
예제 #53
0
    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"")
예제 #54
0
    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"")
예제 #55
0
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)
예제 #56
0
    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
            })
예제 #57
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")
예제 #58
0
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,
        )
예제 #59
0
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')