25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

610 lines
19 KiB

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