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.
 
 
 
 

347 lines
14 KiB

  1. using System.Collections.Generic;
  2. using System.Threading;
  3. using System.Threading.Tasks;
  4. using Microsoft.VisualStudio.TestTools.UnitTesting;
  5. using MQTTnet.Client;
  6. using MQTTnet.Client.Options;
  7. using MQTTnet.Client.Publishing;
  8. using MQTTnet.Client.Receiving;
  9. using MQTTnet.Client.Subscribing;
  10. using MQTTnet.Client.Unsubscribing;
  11. using MQTTnet.Formatter;
  12. using MQTTnet.Protocol;
  13. using MQTTnet.Server;
  14. using MQTTnet.Tests.Mockups;
  15. namespace MQTTnet.Tests.MQTTv5
  16. {
  17. [TestClass]
  18. public class Client_Tests
  19. {
  20. public TestContext TestContext { get; set; }
  21. [TestMethod]
  22. public async Task Connect_With_New_Mqtt_Features()
  23. {
  24. using (var testEnvironment = new TestEnvironment(TestContext))
  25. {
  26. await testEnvironment.StartServerAsync();
  27. // This test can be also executed against "broker.hivemq.com" to validate package format.
  28. var client = await testEnvironment.ConnectClientAsync(
  29. new MqttClientOptionsBuilder()
  30. //.WithTcpServer("broker.hivemq.com")
  31. .WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
  32. .WithProtocolVersion(MqttProtocolVersion.V500)
  33. .WithTopicAliasMaximum(20)
  34. .WithReceiveMaximum(20)
  35. .WithWillMessage(new MqttApplicationMessageBuilder().WithTopic("abc").Build())
  36. .WithWillDelayInterval(20)
  37. .Build());
  38. MqttApplicationMessage receivedMessage = null;
  39. await client.SubscribeAsync("a");
  40. client.UseApplicationMessageReceivedHandler(context => { receivedMessage = context.ApplicationMessage; });
  41. await client.PublishAsync(new MqttApplicationMessageBuilder()
  42. .WithTopic("a")
  43. .WithPayload("x")
  44. .WithUserProperty("a", "1")
  45. .WithUserProperty("b", "2")
  46. .WithPayloadFormatIndicator(MqttPayloadFormatIndicator.CharacterData)
  47. .WithAtLeastOnceQoS()
  48. .Build());
  49. await Task.Delay(500);
  50. Assert.IsNotNull(receivedMessage);
  51. Assert.AreEqual(2, receivedMessage.UserProperties.Count);
  52. }
  53. }
  54. [TestMethod]
  55. public async Task Connect_With_AssignedClientId()
  56. {
  57. using (var testEnvironment = new TestEnvironment(TestContext))
  58. {
  59. string serverConnectedClientId = null;
  60. string serverDisconnectedClientId = null;
  61. string clientAssignedClientId = null;
  62. // Arrange server
  63. var disconnectedMre = new ManualResetEventSlim();
  64. var serverOptions = new MqttServerOptionsBuilder()
  65. .WithConnectionValidator((context) =>
  66. {
  67. if (string.IsNullOrEmpty(context.ClientId))
  68. {
  69. context.AssignedClientIdentifier = "test123";
  70. context.ReasonCode = MqttConnectReasonCode.Success;
  71. }
  72. });
  73. await testEnvironment.StartServerAsync(serverOptions);
  74. testEnvironment.Server.UseClientConnectedHandler((args) =>
  75. {
  76. serverConnectedClientId = args.ClientId;
  77. });
  78. testEnvironment.Server.UseClientDisconnectedHandler((args) =>
  79. {
  80. serverDisconnectedClientId = args.ClientId;
  81. disconnectedMre.Set();
  82. });
  83. // Arrange client
  84. var client = testEnvironment.CreateClient();
  85. client.UseConnectedHandler((args) =>
  86. {
  87. clientAssignedClientId = args.AuthenticateResult.AssignedClientIdentifier;
  88. });
  89. // Act
  90. await client.ConnectAsync(new MqttClientOptionsBuilder()
  91. .WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
  92. .WithProtocolVersion(MqttProtocolVersion.V500)
  93. .WithClientId(null)
  94. .Build());
  95. await client.DisconnectAsync();
  96. // Wait for ClientDisconnectedHandler to trigger
  97. disconnectedMre.Wait(500);
  98. // Assert
  99. Assert.IsNotNull(serverConnectedClientId);
  100. Assert.IsNotNull(serverDisconnectedClientId);
  101. Assert.IsNotNull(clientAssignedClientId);
  102. Assert.AreEqual("test123", serverConnectedClientId);
  103. Assert.AreEqual("test123", serverDisconnectedClientId);
  104. Assert.AreEqual("test123", clientAssignedClientId);
  105. }
  106. }
  107. [TestMethod]
  108. public async Task Connect()
  109. {
  110. using (var testEnvironment = new TestEnvironment())
  111. {
  112. await testEnvironment.StartServerAsync();
  113. await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500).Build());
  114. }
  115. }
  116. [TestMethod]
  117. public async Task Connect_And_Disconnect()
  118. {
  119. using (var testEnvironment = new TestEnvironment())
  120. {
  121. await testEnvironment.StartServerAsync();
  122. var client = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  123. await client.DisconnectAsync();
  124. }
  125. }
  126. [TestMethod]
  127. public async Task Subscribe()
  128. {
  129. using (var testEnvironment = new TestEnvironment())
  130. {
  131. await testEnvironment.StartServerAsync();
  132. var client =
  133. await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  134. var result = await client.SubscribeAsync(new MqttClientSubscribeOptions()
  135. {
  136. SubscriptionIdentifier = 1,
  137. TopicFilters = new List<MqttTopicFilter>
  138. {
  139. new MqttTopicFilter {Topic = "a", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce}
  140. }
  141. });
  142. await client.DisconnectAsync();
  143. Assert.AreEqual(1, result.Items.Count);
  144. Assert.AreEqual(MqttClientSubscribeResultCode.GrantedQoS1, result.Items[0].ResultCode);
  145. }
  146. }
  147. [TestMethod]
  148. public async Task Unsubscribe()
  149. {
  150. using (var testEnvironment = new TestEnvironment())
  151. {
  152. await testEnvironment.StartServerAsync();
  153. var client = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  154. await client.SubscribeAsync("a");
  155. var result = await client.UnsubscribeAsync("a");
  156. await client.DisconnectAsync();
  157. Assert.AreEqual(1, result.Items.Count);
  158. Assert.AreEqual(MqttClientUnsubscribeResultCode.Success, result.Items[0].ReasonCode);
  159. }
  160. }
  161. [TestMethod]
  162. public async Task Publish_QoS_0()
  163. {
  164. using (var testEnvironment = new TestEnvironment())
  165. {
  166. await testEnvironment.StartServerAsync();
  167. var client = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  168. var result = await client.PublishAsync("a", "b");
  169. await client.DisconnectAsync();
  170. Assert.AreEqual(MqttClientPublishReasonCode.Success, result.ReasonCode);
  171. }
  172. }
  173. [TestMethod]
  174. public async Task Publish_QoS_1()
  175. {
  176. using (var testEnvironment = new TestEnvironment())
  177. {
  178. await testEnvironment.StartServerAsync();
  179. var client = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  180. var result = await client.PublishAsync("a", "b", MqttQualityOfServiceLevel.AtLeastOnce);
  181. await client.DisconnectAsync();
  182. Assert.AreEqual(MqttClientPublishReasonCode.Success, result.ReasonCode);
  183. }
  184. }
  185. [TestMethod]
  186. public async Task Publish_QoS_2()
  187. {
  188. using (var testEnvironment = new TestEnvironment())
  189. {
  190. await testEnvironment.StartServerAsync();
  191. var client = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  192. var result = await client.PublishAsync("a", "b", MqttQualityOfServiceLevel.ExactlyOnce);
  193. await client.DisconnectAsync();
  194. Assert.AreEqual(MqttClientPublishReasonCode.Success, result.ReasonCode);
  195. }
  196. }
  197. [TestMethod]
  198. public async Task Publish_With_Properties()
  199. {
  200. using (var testEnvironment = new TestEnvironment())
  201. {
  202. await testEnvironment.StartServerAsync();
  203. var client = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
  204. var applicationMessage = new MqttApplicationMessageBuilder()
  205. .WithTopic("Hello")
  206. .WithPayload("World")
  207. .WithAtMostOnceQoS()
  208. .WithUserProperty("x", "1")
  209. .WithUserProperty("y", "2")
  210. .WithResponseTopic("response")
  211. .WithContentType("text")
  212. .WithMessageExpiryInterval(50)
  213. .WithCorrelationData(new byte[12])
  214. .WithTopicAlias(2)
  215. .Build();
  216. var result = await client.PublishAsync(applicationMessage);
  217. await client.DisconnectAsync();
  218. Assert.AreEqual(MqttClientPublishReasonCode.Success, result.ReasonCode);
  219. }
  220. }
  221. [TestMethod]
  222. public async Task Subscribe_And_Publish()
  223. {
  224. using (var testEnvironment = new TestEnvironment())
  225. {
  226. await testEnvironment.StartServerAsync();
  227. var receivedMessages = new List<MqttApplicationMessageReceivedEventArgs>();
  228. var client1 = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500).WithClientId("client1"));
  229. client1.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(e =>
  230. {
  231. lock (receivedMessages)
  232. {
  233. receivedMessages.Add(e);
  234. }
  235. });
  236. await client1.SubscribeAsync("a");
  237. var client2 = await testEnvironment.ConnectClientAsync(o => o.WithProtocolVersion(MqttProtocolVersion.V500).WithClientId("client2"));
  238. await client2.PublishAsync("a", "b");
  239. await Task.Delay(500);
  240. await client2.DisconnectAsync();
  241. await client1.DisconnectAsync();
  242. Assert.AreEqual(1, receivedMessages.Count);
  243. Assert.AreEqual("client1", receivedMessages[0].ClientId);
  244. Assert.AreEqual("a", receivedMessages[0].ApplicationMessage.Topic);
  245. Assert.AreEqual("b", receivedMessages[0].ApplicationMessage.ConvertPayloadToString());
  246. }
  247. }
  248. [TestMethod]
  249. public async Task Publish_And_Receive_New_Properties()
  250. {
  251. using (var testEnvironment = new TestEnvironment(TestContext))
  252. {
  253. await testEnvironment.StartServerAsync();
  254. var receiver = await testEnvironment.ConnectClientAsync(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
  255. await receiver.SubscribeAsync("#");
  256. MqttApplicationMessage receivedMessage = null;
  257. receiver.UseApplicationMessageReceivedHandler(c =>
  258. {
  259. receivedMessage = c.ApplicationMessage;
  260. });
  261. var sender = await testEnvironment.ConnectClientAsync(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
  262. var applicationMessage = new MqttApplicationMessageBuilder()
  263. .WithTopic("Hello")
  264. .WithPayload("World")
  265. .WithAtMostOnceQoS()
  266. .WithUserProperty("x", "1")
  267. .WithUserProperty("y", "2")
  268. .WithResponseTopic("response")
  269. .WithContentType("text")
  270. .WithMessageExpiryInterval(50)
  271. .WithCorrelationData(new byte[12])
  272. .WithTopicAlias(2)
  273. .Build();
  274. await sender.PublishAsync(applicationMessage);
  275. await Task.Delay(500);
  276. Assert.IsNotNull(receivedMessage);
  277. Assert.AreEqual(applicationMessage.Topic, receivedMessage.Topic);
  278. Assert.AreEqual(applicationMessage.TopicAlias, receivedMessage.TopicAlias);
  279. Assert.AreEqual(applicationMessage.ContentType, receivedMessage.ContentType);
  280. Assert.AreEqual(applicationMessage.ResponseTopic, receivedMessage.ResponseTopic);
  281. Assert.AreEqual(applicationMessage.MessageExpiryInterval, receivedMessage.MessageExpiryInterval);
  282. CollectionAssert.AreEqual(applicationMessage.CorrelationData, receivedMessage.CorrelationData);
  283. CollectionAssert.AreEqual(applicationMessage.Payload, receivedMessage.Payload);
  284. CollectionAssert.AreEqual(applicationMessage.UserProperties, receivedMessage.UserProperties);
  285. }
  286. }
  287. }
  288. }