You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

527 lines
16 KiB

  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using System.Threading;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. using MQTTnet.Adapter;
  7. using MQTTnet.Internal;
  8. using MQTTnet.Packets;
  9. using MQTTnet.Protocol;
  10. using MQTTnet.Serializer;
  11. namespace MQTTnet.Core.Tests
  12. {
  13. [TestClass]
  14. public class MqttPacketSerializerTests
  15. {
  16. [TestMethod]
  17. public void SerializeV310_MqttConnectPacket()
  18. {
  19. var p = new MqttConnectPacket
  20. {
  21. ClientId = "XYZ",
  22. Password = "PASS",
  23. Username = "USER",
  24. KeepAlivePeriod = 123,
  25. CleanSession = true
  26. };
  27. SerializeAndCompare(p, "EB0ABk1RSXNkcAPCAHsAA1hZWgAEVVNFUgAEUEFTUw==", MqttProtocolVersion.V310);
  28. }
  29. [TestMethod]
  30. public void SerializeV311_MqttConnectPacket()
  31. {
  32. var p = new MqttConnectPacket
  33. {
  34. ClientId = "XYZ",
  35. Password = "PASS",
  36. Username = "USER",
  37. KeepAlivePeriod = 123,
  38. CleanSession = true
  39. };
  40. SerializeAndCompare(p, "EBsABE1RVFQEwgB7AANYWVoABFVTRVIABFBBU1M=");
  41. }
  42. [TestMethod]
  43. public void SerializeV311_MqttConnectPacketWithWillMessage()
  44. {
  45. var p = new MqttConnectPacket
  46. {
  47. ClientId = "XYZ",
  48. Password = "PASS",
  49. Username = "USER",
  50. KeepAlivePeriod = 123,
  51. CleanSession = true,
  52. WillMessage = new MqttApplicationMessage
  53. {
  54. Topic = "My/last/will",
  55. Payload = Encoding.UTF8.GetBytes("Good byte."),
  56. QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce,
  57. Retain = true
  58. }
  59. };
  60. SerializeAndCompare(p, "EDUABE1RVFQE7gB7AANYWVoADE15L2xhc3Qvd2lsbAAKR29vZCBieXRlLgAEVVNFUgAEUEFTUw==");
  61. }
  62. [TestMethod]
  63. public void DeserializeV311_MqttConnectPacket()
  64. {
  65. var p = new MqttConnectPacket
  66. {
  67. ClientId = "XYZ",
  68. Password = "PASS",
  69. Username = "USER",
  70. KeepAlivePeriod = 123,
  71. CleanSession = true
  72. };
  73. DeserializeAndCompare(p, "EBsABE1RVFQEwgB7AANYWVoABFVTRVIABFBBU1M=");
  74. }
  75. [TestMethod]
  76. public void DeserializeV311_MqttConnectPacketWithWillMessage()
  77. {
  78. var p = new MqttConnectPacket
  79. {
  80. ClientId = "XYZ",
  81. Password = "PASS",
  82. Username = "USER",
  83. KeepAlivePeriod = 123,
  84. CleanSession = true,
  85. WillMessage = new MqttApplicationMessage
  86. {
  87. Topic = "My/last/will",
  88. Payload = Encoding.UTF8.GetBytes("Good byte."),
  89. QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce,
  90. Retain = true
  91. }
  92. };
  93. DeserializeAndCompare(p, "EDUABE1RVFQE7gB7AANYWVoADE15L2xhc3Qvd2lsbAAKR29vZCBieXRlLgAEVVNFUgAEUEFTUw==");
  94. }
  95. [TestMethod]
  96. public void SerializeV311_MqttConnAckPacket()
  97. {
  98. var p = new MqttConnAckPacket
  99. {
  100. IsSessionPresent = true,
  101. ConnectReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized
  102. };
  103. SerializeAndCompare(p, "IAIBBQ==");
  104. }
  105. [TestMethod]
  106. public void SerializeV310_MqttConnAckPacket()
  107. {
  108. var p = new MqttConnAckPacket
  109. {
  110. ConnectReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized
  111. };
  112. SerializeAndCompare(p, "IAIABQ==", MqttProtocolVersion.V310);
  113. }
  114. [TestMethod]
  115. public void DeserializeV311_MqttConnAckPacket()
  116. {
  117. var p = new MqttConnAckPacket
  118. {
  119. IsSessionPresent = true,
  120. ConnectReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized
  121. };
  122. DeserializeAndCompare(p, "IAIBBQ==");
  123. }
  124. [TestMethod]
  125. public void DeserializeV310_MqttConnAckPacket()
  126. {
  127. var p = new MqttConnAckPacket
  128. {
  129. ConnectReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized
  130. };
  131. DeserializeAndCompare(p, "IAIABQ==", MqttProtocolVersion.V310);
  132. }
  133. [TestMethod]
  134. public void SerializeV311_MqttDisconnectPacket()
  135. {
  136. SerializeAndCompare(new MqttDisconnectPacket(), "4AA=");
  137. }
  138. [TestMethod]
  139. public void SerializeV311_MqttPingReqPacket()
  140. {
  141. SerializeAndCompare(new MqttPingReqPacket(), "wAA=");
  142. }
  143. [TestMethod]
  144. public void SerializeV311_MqttPingRespPacket()
  145. {
  146. SerializeAndCompare(new MqttPingRespPacket(), "0AA=");
  147. }
  148. [TestMethod]
  149. public void SerializeV311_MqttPublishPacket()
  150. {
  151. var p = new MqttPublishPacket
  152. {
  153. PacketIdentifier = 123,
  154. Dup = true,
  155. Retain = true,
  156. Payload = Encoding.ASCII.GetBytes("HELLO"),
  157. QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce,
  158. Topic = "A/B/C"
  159. };
  160. SerializeAndCompare(p, "Ow4ABUEvQi9DAHtIRUxMTw==");
  161. }
  162. [TestMethod]
  163. public void DeserializeV311_MqttPublishPacket()
  164. {
  165. var p = new MqttPublishPacket
  166. {
  167. PacketIdentifier = 123,
  168. Dup = true,
  169. Retain = true,
  170. Payload = Encoding.ASCII.GetBytes("HELLO"),
  171. QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce,
  172. Topic = "A/B/C"
  173. };
  174. DeserializeAndCompare(p, "Ow4ABUEvQi9DAHtIRUxMTw==");
  175. }
  176. [TestMethod]
  177. public void DeserializeV311_MqttPublishPacket_Qos1()
  178. {
  179. var p = new MqttPublishPacket
  180. {
  181. QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce,
  182. };
  183. var p2 = Roundtrip(p);
  184. Assert.AreEqual(p.QualityOfServiceLevel, p2.QualityOfServiceLevel);
  185. Assert.AreEqual(p.Dup, p2.Dup);
  186. }
  187. [TestMethod]
  188. public void DeserializeV311_MqttPublishPacket_Qos2()
  189. {
  190. var p = new MqttPublishPacket
  191. {
  192. QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce,
  193. PacketIdentifier = 1
  194. };
  195. var p2 = Roundtrip(p);
  196. Assert.AreEqual(p.QualityOfServiceLevel, p2.QualityOfServiceLevel);
  197. Assert.AreEqual(p.Dup, p2.Dup);
  198. }
  199. [TestMethod]
  200. public void DeserializeV311_MqttPublishPacket_Qos3()
  201. {
  202. var p = new MqttPublishPacket
  203. {
  204. QualityOfServiceLevel = MqttQualityOfServiceLevel.ExactlyOnce,
  205. PacketIdentifier = 1
  206. };
  207. var p2 = Roundtrip(p);
  208. Assert.AreEqual(p.QualityOfServiceLevel, p2.QualityOfServiceLevel);
  209. Assert.AreEqual(p.Dup, p2.Dup);
  210. }
  211. [TestMethod]
  212. public void DeserializeV311_MqttPublishPacket_DupFalse()
  213. {
  214. var p = new MqttPublishPacket
  215. {
  216. Dup = false,
  217. };
  218. var p2 = Roundtrip(p);
  219. Assert.AreEqual(p.Dup, p2.Dup);
  220. }
  221. [TestMethod]
  222. public void SerializeV311_MqttPubAckPacket()
  223. {
  224. var p = new MqttPubAckPacket
  225. {
  226. PacketIdentifier = 123
  227. };
  228. SerializeAndCompare(p, "QAIAew==");
  229. }
  230. [TestMethod]
  231. public void DeserializeV311_MqttPubAckPacket()
  232. {
  233. var p = new MqttPubAckPacket
  234. {
  235. PacketIdentifier = 123
  236. };
  237. DeserializeAndCompare(p, "QAIAew==");
  238. }
  239. [TestMethod]
  240. public void SerializeV311_MqttPubRecPacket()
  241. {
  242. var p = new MqttPubRecPacket
  243. {
  244. PacketIdentifier = 123
  245. };
  246. SerializeAndCompare(p, "UAIAew==");
  247. }
  248. [TestMethod]
  249. public void DeserializeV311_MqttPubRecPacket()
  250. {
  251. var p = new MqttPubRecPacket
  252. {
  253. PacketIdentifier = 123
  254. };
  255. DeserializeAndCompare(p, "UAIAew==");
  256. }
  257. [TestMethod]
  258. public void SerializeV311_MqttPubRelPacket()
  259. {
  260. var p = new MqttPubRelPacket
  261. {
  262. PacketIdentifier = 123
  263. };
  264. SerializeAndCompare(p, "YgIAew==");
  265. }
  266. [TestMethod]
  267. public void DeserializeV311_MqttPubRelPacket()
  268. {
  269. var p = new MqttPubRelPacket
  270. {
  271. PacketIdentifier = 123
  272. };
  273. DeserializeAndCompare(p, "YgIAew==");
  274. }
  275. [TestMethod]
  276. public void SerializeV311_MqttPubCompPacket()
  277. {
  278. var p = new MqttPubCompPacket
  279. {
  280. PacketIdentifier = 123
  281. };
  282. SerializeAndCompare(p, "cAIAew==");
  283. }
  284. [TestMethod]
  285. public void DeserializeV311_MqttPubCompPacket()
  286. {
  287. var p = new MqttPubCompPacket
  288. {
  289. PacketIdentifier = 123
  290. };
  291. DeserializeAndCompare(p, "cAIAew==");
  292. }
  293. [TestMethod]
  294. public void SerializeV311_MqttSubscribePacket()
  295. {
  296. var p = new MqttSubscribePacket
  297. {
  298. PacketIdentifier = 123
  299. };
  300. p.TopicFilters.Add(new TopicFilter("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce));
  301. p.TopicFilters.Add(new TopicFilter("1/2/3", MqttQualityOfServiceLevel.AtLeastOnce));
  302. p.TopicFilters.Add(new TopicFilter("x/y/z", MqttQualityOfServiceLevel.AtMostOnce));
  303. SerializeAndCompare(p, "ghoAewAFQS9CL0MCAAUxLzIvMwEABXgveS96AA==");
  304. }
  305. [TestMethod]
  306. public void DeserializeV311_MqttSubscribePacket()
  307. {
  308. var p = new MqttSubscribePacket
  309. {
  310. PacketIdentifier = 123
  311. };
  312. p.TopicFilters.Add(new TopicFilter("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce));
  313. p.TopicFilters.Add(new TopicFilter("1/2/3", MqttQualityOfServiceLevel.AtLeastOnce));
  314. p.TopicFilters.Add(new TopicFilter("x/y/z", MqttQualityOfServiceLevel.AtMostOnce));
  315. DeserializeAndCompare(p, "ghoAewAFQS9CL0MCAAUxLzIvMwEABXgveS96AA==");
  316. }
  317. [TestMethod]
  318. public void SerializeV311_MqttSubAckPacket()
  319. {
  320. var p = new MqttSubAckPacket
  321. {
  322. PacketIdentifier = 123
  323. };
  324. p.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.SuccessMaximumQoS0);
  325. p.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.SuccessMaximumQoS1);
  326. p.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.SuccessMaximumQoS2);
  327. p.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.Failure);
  328. SerializeAndCompare(p, "kAYAewABAoA=");
  329. }
  330. [TestMethod]
  331. public void DeserializeV311_MqttSubAckPacket()
  332. {
  333. var p = new MqttSubAckPacket
  334. {
  335. PacketIdentifier = 123
  336. };
  337. p.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.SuccessMaximumQoS0);
  338. p.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.SuccessMaximumQoS1);
  339. p.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.SuccessMaximumQoS2);
  340. p.SubscribeReturnCodes.Add(MqttSubscribeReturnCode.Failure);
  341. DeserializeAndCompare(p, "kAYAewABAoA=");
  342. }
  343. [TestMethod]
  344. public void SerializeV311_MqttUnsubscribePacket()
  345. {
  346. var p = new MqttUnsubscribePacket
  347. {
  348. PacketIdentifier = 123
  349. };
  350. p.TopicFilters.Add("A/B/C");
  351. p.TopicFilters.Add("1/2/3");
  352. p.TopicFilters.Add("x/y/z");
  353. SerializeAndCompare(p, "ohcAewAFQS9CL0MABTEvMi8zAAV4L3kveg==");
  354. }
  355. [TestMethod]
  356. public void DeserializeV311_MqttUnsubscribePacket()
  357. {
  358. var p = new MqttUnsubscribePacket
  359. {
  360. PacketIdentifier = 123
  361. };
  362. p.TopicFilters.Add("A/B/C");
  363. p.TopicFilters.Add("1/2/3");
  364. p.TopicFilters.Add("x/y/z");
  365. DeserializeAndCompare(p, "ohcAewAFQS9CL0MABTEvMi8zAAV4L3kveg==");
  366. }
  367. [TestMethod]
  368. public void SerializeV311_MqttUnsubAckPacket()
  369. {
  370. var p = new MqttUnsubAckPacket
  371. {
  372. PacketIdentifier = 123
  373. };
  374. SerializeAndCompare(p, "sAIAew==");
  375. }
  376. [TestMethod]
  377. public void DeserializeV311_MqttUnsubAckPacket()
  378. {
  379. var p = new MqttUnsubAckPacket
  380. {
  381. PacketIdentifier = 123
  382. };
  383. DeserializeAndCompare(p, "sAIAew==");
  384. }
  385. private static void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
  386. {
  387. var serializer = new MqttPacketSerializer { ProtocolVersion = protocolVersion };
  388. var data = serializer.Serialize(packet);
  389. Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(data)));
  390. }
  391. private static void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
  392. {
  393. var serializer = new MqttPacketSerializer { ProtocolVersion = protocolVersion };
  394. var buffer1 = serializer.Serialize(packet);
  395. using (var headerStream = new MemoryStream(Join(buffer1)))
  396. {
  397. var channel = new TestMqttChannel(headerStream);
  398. var fixedHeader = new byte[2];
  399. var singleByteBuffer = new byte[1];
  400. var header = MqttPacketReader.ReadFixedHeaderAsync(channel, fixedHeader, singleByteBuffer, CancellationToken.None).GetAwaiter().GetResult();
  401. using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
  402. {
  403. var deserializedPacket = serializer.Deserialize(new ReceivedMqttPacket(header.Flags, new MqttPacketBodyReader(bodyStream.ToArray(), 0)));
  404. var buffer2 = serializer.Serialize(deserializedPacket);
  405. Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
  406. }
  407. }
  408. }
  409. private static T Roundtrip<T>(T packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
  410. where T : MqttBasePacket
  411. {
  412. var serializer = new MqttPacketSerializer { ProtocolVersion = protocolVersion };
  413. var buffer1 = serializer.Serialize(packet);
  414. using (var headerStream = new MemoryStream(Join(buffer1)))
  415. {
  416. var channel = new TestMqttChannel(headerStream);
  417. var fixedHeader = new byte[2];
  418. var singleByteBuffer = new byte[1];
  419. var header = MqttPacketReader.ReadFixedHeaderAsync(channel, fixedHeader, singleByteBuffer, CancellationToken.None).GetAwaiter().GetResult();
  420. using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
  421. {
  422. return (T)serializer.Deserialize(new ReceivedMqttPacket(header.Flags, new MqttPacketBodyReader(bodyStream.ToArray(), 0)));
  423. }
  424. }
  425. }
  426. private static byte[] Join(params ArraySegment<byte>[] chunks)
  427. {
  428. var buffer = new MemoryStream();
  429. foreach (var chunk in chunks)
  430. {
  431. buffer.Write(chunk.Array, chunk.Offset, chunk.Count);
  432. }
  433. return buffer.ToArray();
  434. }
  435. }
  436. }