def test_publish_qos2_retry(self): @asyncio.coroutine def server_mock(reader, writer): try: packet = yield from PublishPacket.from_stream(reader) self.assertEqual(packet.topic_name, '/topic') self.assertEqual(packet.qos, QOS_2) self.assertIsNotNone(packet.packet_id) self.assertIn(packet.packet_id, self.session.inflight_out) self.assertIn(packet.packet_id, self.handler._pubrec_waiters) pubrec = PubrecPacket.build(packet.packet_id) yield from pubrec.to_stream(writer) pubrel = yield from PubrelPacket.from_stream(reader) self.assertIn(packet.packet_id, self.handler._pubcomp_waiters) pubcomp = PubcompPacket.build(packet.packet_id) yield from pubcomp.to_stream(writer) except Exception as ae: future.set_exception(ae) @asyncio.coroutine def test_coro(): try: reader, writer = yield from asyncio.open_connection( '127.0.0.1', 8888, loop=self.loop) reader_adapted, writer_adapted = adapt(reader, writer) self.handler = ProtocolHandler(self.plugin_manager, loop=self.loop) self.handler.attach(self.session, reader_adapted, writer_adapted) yield from self.handler.start() yield from self.stop_handler(self.handler, self.session) if not future.done(): future.set_result(True) except Exception as ae: future.set_exception(ae) self.handler = None self.session = Session() message = OutgoingApplicationMessage(1, '/topic', QOS_2, b'test_data', False) message.publish_packet = PublishPacket.build('/topic', b'test_data', rand_packet_id(), False, QOS_2, False) self.session.inflight_out[1] = message future = asyncio.Future(loop=self.loop) coro = asyncio.start_server(server_mock, '127.0.0.1', 8888, loop=self.loop) server = self.loop.run_until_complete(coro) self.loop.run_until_complete(test_coro()) server.close() self.loop.run_until_complete(server.wait_closed()) if future.exception(): raise future.exception()
def test_publish_qos1_retry(self): async def server_mock(reader, writer): packet = await PublishPacket.from_stream(reader) try: self.assertEqual(packet.topic_name, "/topic") self.assertEqual(packet.qos, QOS_1) self.assertIsNotNone(packet.packet_id) self.assertIn(packet.packet_id, self.session.inflight_out) self.assertIn(packet.packet_id, self.handler._puback_waiters) puback = PubackPacket.build(packet.packet_id) await puback.to_stream(writer) except Exception as ae: future.set_exception(ae) async def test_coro(): try: reader, writer = await asyncio.open_connection("127.0.0.1", 8888, loop=self.loop) reader_adapted, writer_adapted = adapt(reader, writer) self.handler = ProtocolHandler(self.plugin_manager, loop=self.loop) self.handler.attach(self.session, reader_adapted, writer_adapted) await self.handler.start() await self.stop_handler(self.handler, self.session) if not future.done(): future.set_result(True) except Exception as ae: future.set_exception(ae) self.handler = None self.session = Session() message = OutgoingApplicationMessage(1, "/topic", QOS_1, b"test_data", False) message.publish_packet = PublishPacket.build("/topic", b"test_data", rand_packet_id(), False, QOS_1, False) self.session.inflight_out[1] = message future = asyncio.Future(loop=self.loop) coro = asyncio.start_server(server_mock, "127.0.0.1", 8888, loop=self.loop) server = self.loop.run_until_complete(coro) self.loop.run_until_complete(test_coro()) server.close() self.loop.run_until_complete(server.wait_closed()) if future.exception(): raise future.exception()
async def test_coro(stream_adapted): self.session = Session(None) message = OutgoingApplicationMessage(1, '/topic', QOS_2, b'test_data', False) message.publish_packet = PublishPacket.build( '/topic', b'test_data', rand_packet_id(), False, QOS_2, False) self.session.inflight_out[1] = message try: self.handler = ProtocolHandler(self.plugin_manager) self.handler.attach(self.session, stream_adapted) await self.handler.start() await self.stop_handler(self.handler, self.session) except Exception as ae: raise
def test_publish_qos2_retry(self): @asyncio.coroutine def server_mock(reader, writer): try: packet = yield from PublishPacket.from_stream(reader) self.assertEquals(packet.topic_name, "/topic") self.assertEquals(packet.qos, QOS_2) self.assertIsNotNone(packet.packet_id) self.assertIn(packet.packet_id, self.session.inflight_out) self.assertIn(packet.packet_id, self.handler._pubrec_waiters) pubrec = PubrecPacket.build(packet.packet_id) yield from pubrec.to_stream(writer) pubrel = yield from PubrelPacket.from_stream(reader) self.assertIn(packet.packet_id, self.handler._pubcomp_waiters) pubcomp = PubcompPacket.build(packet.packet_id) yield from pubcomp.to_stream(writer) except Exception as ae: future.set_exception(ae) @asyncio.coroutine def test_coro(): try: reader, writer = yield from asyncio.open_connection("127.0.0.1", 8888, loop=self.loop) reader_adapted, writer_adapted = adapt(reader, writer) self.handler = ProtocolHandler(self.plugin_manager, loop=self.loop) self.handler.attach(self.session, reader_adapted, writer_adapted) yield from self.handler.start() yield from self.stop_handler(self.handler, self.session) if not future.done(): future.set_result(True) except Exception as ae: future.set_exception(ae) self.handler = None self.session = Session() message = OutgoingApplicationMessage(1, "/topic", QOS_2, b"test_data", False) message.publish_packet = PublishPacket.build("/topic", b"test_data", rand_packet_id(), False, QOS_2, False) self.session.inflight_out[1] = message future = asyncio.Future(loop=self.loop) coro = asyncio.start_server(server_mock, "127.0.0.1", 8888, loop=self.loop) server = self.loop.run_until_complete(coro) self.loop.run_until_complete(test_coro()) server.close() self.loop.run_until_complete(server.wait_closed()) if future.exception(): raise future.exception()
def mqtt_publish(self, topic, data, qos, retain, ack_timeout=None): """ Sends a MQTT publish message and manages messages flows. This methods doesn't return until the message has been acknowledged by receiver or timeout occur :param topic: MQTT topic to publish :param data: data to send on topic :param qos: quality of service to use for message flow. Can be QOS_0, QOS_1 or QOS_2 :param retain: retain message flag :param ack_timeout: acknowledge timeout. If set, this method will return a TimeOut error if the acknowledgment is not completed before ack_timeout second :return: ApplicationMessage used during inflight operations """ if qos in (QOS_1, QOS_2): packet_id = self.session.next_packet_id if packet_id in self.session.inflight_out: raise HBMQTTException( "A message with the same packet ID '%d' is already in flight" % packet_id) else: packet_id = None message = OutgoingApplicationMessage(packet_id, topic, qos, data, retain) # Handle message flow if ack_timeout is not None and ack_timeout > 0: yield from asyncio.wait_for(self._handle_message_flow(message), ack_timeout, loop=self._loop) else: yield from self._handle_message_flow(message) return message