import asyncio import unittest import pytest from amqtt.adapters import BufferReader from amqtt.errors import AMQTTError from amqtt.mqtt.connect import ConnectPacket, ConnectPayload, ConnectVariableHeader from amqtt.mqtt.packet import CONNECT, MQTTFixedHeader, PUBLISH class ConnectPacketTest(unittest.TestCase): def setUp(self): self.loop = asyncio.new_event_loop() def test_decode_ok(self): data = ( b"\x10\x3e\x00\x04MQTT\x04\xce\x00\x00\x00\x0a0123456789" b"\x00\x09WillTopic\x00\x0bWillMessage\x00\x04user\x00\x08password" ) stream = BufferReader(data) message = self.loop.run_until_complete(ConnectPacket.from_stream(stream)) assert message.variable_header is not None assert message.variable_header.proto_name == "MQTT" assert message.variable_header.proto_level == 4 assert message.variable_header.username_flag assert message.variable_header.password_flag assert not message.variable_header.will_retain_flag assert message.variable_header.will_qos == 1 assert message.variable_header.will_flag assert message.variable_header.clean_session_flag assert not message.variable_header.reserved_flag assert message.payload is not None assert message.payload.client_id == "0123456789" assert message.payload.will_topic == "WillTopic" assert message.payload.will_message == b"WillMessage" assert message.payload.username == "user" assert message.payload.password == "password" def test_decode_ok_will_flag(self): data = b"\x10\x26\x00\x04MQTT\x04\xca\x00\x00\x00\x0a0123456789\x00\x04user\x00\x08password" stream = BufferReader(data) message = self.loop.run_until_complete(ConnectPacket.from_stream(stream)) assert message.variable_header is not None assert message.variable_header.proto_name == "MQTT" assert message.variable_header.proto_level == 4 assert message.variable_header.username_flag assert message.variable_header.password_flag assert not message.variable_header.will_retain_flag assert message.variable_header.will_qos == 1 assert not message.variable_header.will_flag assert message.variable_header.clean_session_flag assert not message.variable_header.reserved_flag assert message.payload is not None assert message.payload.client_id == "0123456789" assert message.payload.will_topic is None assert message.payload.will_message is None assert message.payload.username == "user" assert message.payload.password == "password" def test_decode_fail_reserved_flag(self): data = ( b"\x10\x3e\x00\x04MQTT\x04\xcf\x00\x00\x00\x0a0123456789" b"\x00\x09WillTopic\x00\x0bWillMessage\x00\x04user\x00\x08password" ) stream = BufferReader(data) message = self.loop.run_until_complete(ConnectPacket.from_stream(stream)) assert message.variable_header is not None assert message.variable_header.reserved_flag def test_decode_fail_miss_clientId(self): data = b"\x10\x0a\x00\x04MQTT\x04\xce\x00\x00" stream = BufferReader(data) message = self.loop.run_until_complete(ConnectPacket.from_stream(stream)) assert message.payload is not None assert message.payload.client_id is not None def test_decode_fail_miss_willtopic(self): data = b"\x10\x16\x00\x04MQTT\x04\xce\x00\x00\x00\x0a0123456789" stream = BufferReader(data) message = self.loop.run_until_complete(ConnectPacket.from_stream(stream)) assert message.payload is not None assert message.payload.will_topic is None def test_decode_fail_miss_username(self): data = b"\x10\x2e\x00\x04MQTT\x04\xce\x00\x00\x00\x0a0123456789\x00\x09WillTopic\x00\x0bWillMessage" stream = BufferReader(data) message = self.loop.run_until_complete(ConnectPacket.from_stream(stream)) assert message.payload is not None assert message.payload.username is None def test_decode_fail_miss_password(self): data = b"\x10\x34\x00\x04MQTT\x04\xce\x00\x00\x00\x0a0123456789\x00\x09WillTopic\x00\x0bWillMessage\x00\x04user" stream = BufferReader(data) message = self.loop.run_until_complete(ConnectPacket.from_stream(stream)) assert message.payload is not None assert message.payload.password is None def test_encode(self): header = MQTTFixedHeader(CONNECT, 0x00, 0) variable_header = ConnectVariableHeader(0xCE, 0, "MQTT", 4) payload = ConnectPayload( "0123456789", "WillTopic", b"WillMessage", "user", "password", ) message = ConnectPacket(header, variable_header, payload) encoded = message.to_bytes() assert ( encoded == b"\x10>\x00\x04MQTT\x04\xce\x00\x00\x00\n0123456789\x00\tWillTopic\x00\x0bWillMessage\x00\x04user\x00\x08password" ) def test_getattr_ok(self): data = ( b"\x10\x3e\x00\x04MQTT\x04\xce\x00\x00\x00\x0a0123456789" b"\x00\x09WillTopic\x00\x0bWillMessage\x00\x04user\x00\x08password" ) stream = BufferReader(data) message = self.loop.run_until_complete(ConnectPacket.from_stream(stream)) assert message.variable_header is not None assert message.variable_header.proto_name == "MQTT" assert message.proto_name == "MQTT" assert message.variable_header.proto_level == 4 assert message.proto_level == 4 assert message.variable_header.username_flag assert message.username_flag assert message.variable_header.password_flag assert message.password_flag assert not message.variable_header.will_retain_flag assert not message.will_retain_flag assert message.variable_header.will_qos == 1 assert message.will_qos == 1 assert message.variable_header.will_flag assert message.will_flag assert message.variable_header.clean_session_flag assert message.clean_session_flag assert not message.variable_header.reserved_flag assert not message.reserved_flag assert message.payload is not None assert message.payload.client_id == "0123456789" assert message.client_id == "0123456789" assert message.payload.will_topic == "WillTopic" assert message.will_topic == "WillTopic" assert message.payload.will_message == b"WillMessage" assert message.will_message == b"WillMessage" assert message.payload.username == "user" assert message.username == "user" assert message.payload.password == "password" assert message.password == "password" def test_incorrect_fixed_header(): header = MQTTFixedHeader(PUBLISH, 0x00) with pytest.raises(AMQTTError): _ = ConnectPacket(fixed=header) @pytest.mark.parametrize("prop", [ "proto_name", "proto_level", "username_flag", "password_flag", "clean_session_flag", "will_retain_flag", "will_qos", "will_flag", "reserved_flag", "client_id", "client_id_is_random", "will_topic", "will_message", "username", "password", "keep_alive", ]) def test_empty_variable_header(prop): packet = ConnectPacket() with pytest.raises(ValueError): assert getattr(packet, prop) is not None with pytest.raises(ValueError): assert setattr(packet, prop, "a value")