Esempio n. 1
0
    def test_subscribe_same_id(self):
        """
        SubACKs have the same packet IDs as the Subscription that it is
        replying to.

        Compliance statements MQTT-3.8.4-2
        """
        sessions = {}

        class SubHandler(BasicHandler):
            def process_subscribe(self, event):
                return succeed([0])

        h = SubHandler()
        r = Clock()
        t = StringTransport()
        p = MQTTServerTwistedProtocol(h, r, sessions)
        cp = MQTTClientParser()

        p.makeConnection(t)

        data = (Connect(client_id=u"test123",
                        flags=ConnectFlags(clean_session=True)).serialise() +
                Subscribe(packet_identifier=1234,
                          topic_requests=[SubscriptionTopicRequest(u"a", 0)
                                          ]).serialise())

        for x in iterbytes(data):
            p.dataReceived(x)

        events = cp.data_received(t.value())
        self.assertEqual(len(events), 2)
        self.assertEqual(events[1].return_codes, [0])
        self.assertEqual(events[1].packet_identifier, 1234)
Esempio n. 2
0
    def test_subscribe_always_gets_packet(self):
        """
        Subscriptions always get a ConnACK, even if none of the subscriptions
        were successful.

        Compliance statements MQTT-3.8.4-1
        """
        sessions = {}

        class SubHandler(BasicHandler):
            def process_subscribe(self, event):
                return succeed([128])

        h = SubHandler()
        r = Clock()
        t = StringTransport()
        p = MQTTServerTwistedProtocol(h, r, sessions)
        cp = MQTTClientParser()

        p.makeConnection(t)

        data = (Connect(client_id=u"test123",
                        flags=ConnectFlags(clean_session=True)).serialise() +
                Subscribe(packet_identifier=1234,
                          topic_requests=[SubscriptionTopicRequest(u"a", 0)
                                          ]).serialise())

        for x in iterbytes(data):
            p.dataReceived(x)

        events = cp.data_received(t.value())
        self.assertEqual(len(events), 2)
        self.assertEqual(events[1].return_codes, [128])
Esempio n. 3
0
def test_self_subscribe(host, port):
    record = [
        Frame(send=True,
              data=Connect(client_id=u"test_selfsub",
                           flags=ConnectFlags(clean_session=True))),
        Frame(send=False, data=ConnACK(session_present=False, return_code=0)),
        Frame(send=True,
              data=Subscribe(
                  packet_identifier=1234,
                  topic_requests=[SubscriptionTopicRequest(u"foo", 2)])),
        Frame(send=False,
              data=SubACK(packet_identifier=1234, return_codes=[2])),
        Frame(send=True,
              data=Publish(duplicate=False,
                           qos_level=0,
                           topic_name=u"foo",
                           payload=b"abc",
                           retain=False)),
        Frame(send=False,
              data=Publish(duplicate=False,
                           qos_level=0,
                           topic_name=u"foo",
                           payload=b"abc",
                           retain=False)),
        Frame(send=True, data=Disconnect()),
        ConnectionLoss(),
    ]

    r = SelectReactor()
    f = ReplayClientFactory(r, record)
    e = TCP4ClientEndpoint(r, host, port)
    e.connect(f)
    r.run()

    return Result("self_subscribe", f.success, f.reason, f.client_transcript)
Esempio n. 4
0
    def _test_retained(self):
        """
        The MQTT client can set and receive retained messages.
        """
        reactor, router, server_factory, session_factory = build_mqtt_server()
        client_transport, client_protocol, mqtt_pump = connect_mqtt_server(
            server_factory)

        client_transport.write(
            Connect(client_id=u"testclient",
                    username=u"test123",
                    password=u"password",
                    flags=ConnectFlags(clean_session=False,
                                       username=True,
                                       password=True)).serialise())

        client_transport.write(
            Publish(duplicate=False,
                    qos_level=1,
                    retain=True,
                    topic_name=u"com/test/wamp",
                    packet_identifier=123,
                    payload=b'{}').serialise())

        mqtt_pump.flush()

        self.assertEqual(
            client_protocol.data,
            (ConnACK(session_present=False, return_code=0).serialise() +
             PubACK(packet_identifier=123).serialise()))
        client_protocol.data = b""

        client_transport.write(
            Subscribe(packet_identifier=1,
                      topic_requests=[
                          SubscriptionTopicRequest(
                              topic_filter=u"com/test/wamp", max_qos=0)
                      ]).serialise())

        mqtt_pump.flush()

        self.assertEqual(
            client_protocol.data,
            SubACK(packet_identifier=1, return_codes=[0]).serialise())
        client_protocol.data = b""

        reactor.advance(0.1)
        mqtt_pump.flush()

        # This needs to be replaced with the real deal, see https://github.com/crossbario/crossbar/issues/885
        self.assertEqual(
            client_protocol.data,
            Publish(duplicate=False,
                    qos_level=0,
                    retain=True,
                    topic_name=u"com/test/wamp",
                    payload=json.dumps(
                        {}, sort_keys=True).encode('utf8')).serialise())
Esempio n. 5
0
    def _test_basic_subscribe(self):
        """
        The MQTT client can subscribe to a WAMP topic and get messages.
        """
        reactor, router, server_factory, session_factory = build_mqtt_server()
        client_transport, client_protocol, mqtt_pump = connect_mqtt_server(
            server_factory)

        session, pump = connect_application_session(
            server_factory,
            ApplicationSession,
            component_config=ComponentConfig(realm=u"mqtt"))

        client_transport.write(
            Connect(client_id=u"testclient",
                    username=u"test123",
                    password=u"password",
                    flags=ConnectFlags(clean_session=False,
                                       username=True,
                                       password=True)).serialise())
        client_transport.write(
            Subscribe(packet_identifier=1,
                      topic_requests=[
                          SubscriptionTopicRequest(
                              topic_filter=u"com/test/wamp", max_qos=0)
                      ]).serialise())

        mqtt_pump.flush()

        self.assertEqual(
            client_protocol.data,
            (ConnACK(session_present=False, return_code=0).serialise() +
             SubACK(packet_identifier=1, return_codes=[0]).serialise()))
        client_protocol.data = b""

        session.publish(u"com.test.wamp", u"bar")
        pump.flush()

        reactor.advance(0.1)
        mqtt_pump.flush()

        self.assertEqual(
            client_protocol.data,
            Publish(duplicate=False,
                    qos_level=0,
                    retain=False,
                    topic_name=u"com/test/wamp",
                    payload=b'{"args":["bar"]}').serialise())
Esempio n. 6
0
def test_qos1_send_wrong_confirm(host, port):
    record = [
        Frame(send=True,
              data=Connect(client_id=u"test_wrong_confirm_qos1",
                           flags=ConnectFlags(clean_session=True))),
        Frame(send=False, data=ConnACK(session_present=False, return_code=0)),
        Frame(send=True,
              data=Subscribe(
                  packet_identifier=1234,
                  topic_requests=[SubscriptionTopicRequest(u"foo", 2)])),
        Frame(send=False,
              data=SubACK(packet_identifier=1234, return_codes=[2])),
        Frame(send=True,
              data=Publish(duplicate=False,
                           qos_level=1,
                           topic_name=u"foo",
                           payload=b"abc",
                           retain=False,
                           packet_identifier=12)),
        Frame(send=False,
              data=[
                  PubACK(packet_identifier=12),
                  Publish(duplicate=False,
                          qos_level=1,
                          topic_name=u"foo",
                          payload=b"abc",
                          retain=False,
                          packet_identifier=1)
              ]),
        # We send a pubrel to the packet_id expecting a puback
        Frame(send=True, data=PubREL(packet_identifier=1)),
        # ..aaaaand we get a pubcomp back (even though mosquitto warns).
        Frame(send=False, data=PubCOMP(packet_identifier=1)),
        Frame(send=True, data=Disconnect()),
        ConnectionLoss(),
    ]

    r = SelectReactor()
    f = ReplayClientFactory(r, record)
    e = TCP4ClientEndpoint(r, host, port)
    e.connect(f)
    r.run()

    return Result("qos1_wrong_confirm", f.success, f.reason,
                  f.client_transcript)
Esempio n. 7
0
    def test_exception_in_subscribe_drops_connection(self):
        """
        Transient failures (like an exception from handler.process_subscribe)
        will cause the connection it happened on to be dropped.

        Compliance statement MQTT-4.8.0-2
        """
        sessions = {}

        class SubHandler(BasicHandler):
            @inlineCallbacks
            def process_subscribe(self, event):
                raise Exception("boom!")

        h = SubHandler()
        r = Clock()
        t = StringTransport()
        p = MQTTServerTwistedProtocol(h, r, sessions)
        cp = MQTTClientParser()

        p.makeConnection(t)

        data = (Connect(client_id=u"test123",
                        flags=ConnectFlags(clean_session=True)).serialise() +
                Subscribe(packet_identifier=1234,
                          topic_requests=[SubscriptionTopicRequest(u"a", 0)
                                          ]).serialise())

        with LogCapturer("trace") as logs:
            for x in iterbytes(data):
                p.dataReceived(x)

        sent_logs = logs.get_category("MQ500")
        self.assertEqual(len(sent_logs), 1)
        self.assertEqual(sent_logs[0]["log_level"], LogLevel.critical)
        self.assertEqual(sent_logs[0]["log_failure"].value.args[0], "boom!")

        events = cp.data_received(t.value())
        self.assertEqual(len(events), 1)
        self.assertTrue(t.disconnecting)

        # We got the error, we need to flush it so it doesn't make the test
        # error
        self.flushLoggedErrors()