From e480dff9fa3adff39f404bf63ce617528f0e5b0f Mon Sep 17 00:00:00 2001 From: sosowang Date: Mon, 25 Nov 2013 17:39:54 +0800 Subject: [PATCH 1/3] test command:connect --- tests/test_commands.py | 86 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tests/test_commands.py diff --git a/tests/test_commands.py b/tests/test_commands.py new file mode 100644 index 0000000..21815cd --- /dev/null +++ b/tests/test_commands.py @@ -0,0 +1,86 @@ +from StringIO import StringIO +from twisted.trial import unittest +from twisted.test import proto_helpers +from twisted.internet.protocol import ClientFactory +from MQTT import MQTTClient + + +class MQTTClientFactory(ClientFactory): + def buildProtocol(self, addr): + return MQTTClient() + +class CommandsTestCase(unittest.TestCase): + def setUp(self): + factory = MQTTClientFactory() + self.proto = factory.buildProtocol(('127.0.0.1', 0)) + self.tr = proto_helpers.StringTransport() + self.proto.makeConnection(self.tr) + + def _make_fixed_header(self, command, dup, qos, retain, remainning_length): + header = bytearray() + header.append(command << 4 | dup << 3 | qos << 1 | retain) + header.extend(remainning_length) + return header + + def _make_variable_header_connect(self, + protocol_name, + version, + user_name_flag, + password_flag, + will_retain, + will_qos, + will_flag, + clean_session, + keep_alive_timer): + header = bytearray() + header.extend(self.proto._encodeString(protocol_name)) + header.append(version) + + header.append(user_name_flag << 7 | + password_flag << 6 | + will_retain << 5 | + will_qos << 4 | + will_flag << 2 | + clean_session << 1 | + 0) + header.extend(self.proto._encodeValue(keep_alive_timer / 1000)) + return header + + def _make_payload_connect(self, + client_id, + will_topic, + will_message, + user_name, + password): + payload = bytearray() + + if client_id: + payload.extend(self.proto._encodeString(client_id)) + + if will_message and will_topic: + payload.extend(self.proto._encodeString(will_topic)) + payload.extend(self.proto._encodeString(will_message)) + + if user_name and password: + payload.extend(self.proto._encodeString(user_name)) + payload.extend(self.proto._encodeString(password)) + + return payload + + def test_connect(self): + """ + test connect command + """ + + """ when default parameters """ + + variable_header = self._make_variable_header_connect("MQIsdp", 3, 0, 0, 0, 0, 0, 1, 3000) + payload = self._make_payload_connect(self.proto.clientId, None, None, None, None) + fixed_header = self._make_fixed_header(0x01, 0, 0, 0, self.proto._encodeLength(len(variable_header) + len(payload))) + + st = StringIO() + st.write(fixed_header) + st.write(variable_header) + st.write(payload) + self.assertEqual(self.proto.transport.value(), "".join( + map(lambda x: str(x), [fixed_header, variable_header, payload]))) From c9f26a8ce4db32d21c60423a18b3c05b2b8f1e58 Mon Sep 17 00:00:00 2001 From: sosowang Date: Tue, 26 Nov 2013 09:56:20 +0800 Subject: [PATCH 2/3] user/pwd supports --- MQTT.py | 57 ++++++++++++++++++++++++++++++++++-------- tests/test_commands.py | 9 ++++--- 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/MQTT.py b/MQTT.py index ab0f119..ae81d42 100644 --- a/MQTT.py +++ b/MQTT.py @@ -232,7 +232,7 @@ def connectionLost(self, reason): pass def connectReceived(self, clientID, keepalive, willTopic, - willMessage, willQoS, willRetain, cleanStart): + willMessage, willQos, willRetain, cleanStart): pass def connackReceived(self, status): @@ -276,8 +276,8 @@ def disconnectReceived(self): pass def connect(self, clientID, keepalive=3000, willTopic=None, - willMessage=None, willQoS=0, willRetain=False, - cleanStart=True): + willMessage=None, willQos=0, willRetain=0, + cleanStart=0, username=None, password=None): header = bytearray() varHeader = bytearray() payload = bytearray() @@ -285,12 +285,25 @@ def connect(self, clientID, keepalive=3000, willTopic=None, varHeader.extend(self._encodeString("MQIsdp")) varHeader.append(3) - if willMessage is None or willTopic is None: - # Clean start, no will message - varHeader.append(0 << 2 | cleanStart << 1) + if username and password: + username_flag = 1 + password_flag = 1 else: - varHeader.append(willRetain << 5 | willQoS << 3 - | 1 << 2 | cleanStart << 1) + username_flag = 0 + password_flag = 0 + + if willQos and willRetain and willTopic and willMessage: + will_flag = 1 + else: + will_flag = 0 + + varHeader.append(username_flag << 7 | + password_flag << 6 | + willRetain << 5 | + willQos << 4 | + will_flag << 2 | + cleanStart << 1 | + 0) varHeader.extend(self._encodeValue(keepalive/1000)) @@ -299,6 +312,10 @@ def connect(self, clientID, keepalive=3000, willTopic=None, payload.extend(self._encodeString(willTopic)) payload.extend(self._encodeString(willMessage)) + if username_flag and password_flag: + payload.extend(self._encodeString(username)) + payload.extend(self._encodeString(password)) + header.append(0x01 << 4) header.extend(self._encodeLength(len(varHeader) + len(payload))) @@ -546,7 +563,17 @@ def _decodeValue(self, valueArray): class MQTTClient(MQTTProtocol): def __init__(self, clientId=None, keepalive=None, willQos=0, - willTopic=None, willMessage=None, willRetain=False): + willTopic=None, willMessage=None, willRetain=False, + username=None, password=None): + + if username and password: + self.username = username + self.password = password + self.username_flag = 1 + self.password_flag = 1 + else: + self.username_flag = 0 + self.password_flag = 0 if clientId is not None: self.clientId = clientId @@ -564,8 +591,16 @@ def __init__(self, clientId=None, keepalive=None, willQos=0, self.willRetain = willRetain def connectionMade(self): - self.connect(self.clientId, self.keepalive, self.willTopic, - self.willMessage, self.willQos, self.willRetain, True) + self.connect(clientID=self.clientId, + keepalive=self.keepalive, + willTopic=self.willTopic, + willMessage=self.willMessage, + willQos=self.willQos, + willRetain=self.willRetain, + cleanStart=True, + username=self.username, + password=self.password) + def connackReceived(self, status): if status == 0: diff --git a/tests/test_commands.py b/tests/test_commands.py index 21815cd..a355e3e 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -6,8 +6,11 @@ class MQTTClientFactory(ClientFactory): + username = "testuser" + password = "testpwd" + def buildProtocol(self, addr): - return MQTTClient() + return MQTTClient(username=self.username, password=self.password) class CommandsTestCase(unittest.TestCase): def setUp(self): @@ -74,8 +77,8 @@ def test_connect(self): """ when default parameters """ - variable_header = self._make_variable_header_connect("MQIsdp", 3, 0, 0, 0, 0, 0, 1, 3000) - payload = self._make_payload_connect(self.proto.clientId, None, None, None, None) + variable_header = self._make_variable_header_connect("MQIsdp", 3, 1, 1, 0, 0, 0, 1, 3000) + payload = self._make_payload_connect(self.proto.clientId, None, None, "testuser", "testpwd") fixed_header = self._make_fixed_header(0x01, 0, 0, 0, self.proto._encodeLength(len(variable_header) + len(payload))) st = StringIO() From 70e8b6643b2bb81b6fa7e08f46904dc38002e325 Mon Sep 17 00:00:00 2001 From: sosowang Date: Tue, 26 Nov 2013 10:28:26 +0800 Subject: [PATCH 3/3] resolve error username passed, --- MQTT.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MQTT.py b/MQTT.py index ae81d42..5f9e04a 100644 --- a/MQTT.py +++ b/MQTT.py @@ -566,9 +566,10 @@ def __init__(self, clientId=None, keepalive=None, willQos=0, willTopic=None, willMessage=None, willRetain=False, username=None, password=None): + self.username = username + self.password = password + if username and password: - self.username = username - self.password = password self.username_flag = 1 self.password_flag = 1 else: