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())
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="mqtt", controller=MockContainer())) client_transport.write( Connect(client_id="testclient", username="******", password="******", flags=ConnectFlags(clean_session=False, username=True, password=True)).serialise()) client_transport.write( Subscribe(packet_identifier=1, topic_requests=[ SubscriptionTopicRequest( topic_filter="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("com.test.wamp", "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="com/test/wamp", payload=b'{"args":["bar"]}').serialise())
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 """ class SubHandler(BasicHandler): @inlineCallbacks def process_subscribe(self, event): raise Exception("boom!") h = SubHandler() r, t, p, cp = make_test_items(h) 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("MQ501") 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()