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.
 
 
 
 

201 lines
7.8 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.Connecting;
  7. using MQTTnet.Client.Options;
  8. using MQTTnet.Diagnostics;
  9. using MQTTnet.Extensions.ManagedClient;
  10. using MQTTnet.Server;
  11. using MQTTnet.Tests.Mockups;
  12. namespace MQTTnet.Tests
  13. {
  14. [TestClass]
  15. public class ManagedMqttClient_Tests
  16. {
  17. [TestMethod]
  18. public async Task Drop_New_Messages_On_Full_Queue()
  19. {
  20. var factory = new MqttFactory();
  21. var managedClient = factory.CreateManagedMqttClient();
  22. try
  23. {
  24. var clientOptions = new ManagedMqttClientOptionsBuilder()
  25. .WithMaxPendingMessages(5)
  26. .WithPendingMessagesOverflowStrategy(MqttPendingMessagesOverflowStrategy.DropNewMessage);
  27. clientOptions.WithClientOptions(o => o.WithTcpServer("localhost"));
  28. await managedClient.StartAsync(clientOptions.Build());
  29. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "1" });
  30. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "2" });
  31. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "3" });
  32. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "4" });
  33. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "5" });
  34. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "6" });
  35. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "7" });
  36. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "8" });
  37. Assert.AreEqual(5, managedClient.PendingApplicationMessagesCount);
  38. }
  39. finally
  40. {
  41. await managedClient.StopAsync();
  42. }
  43. }
  44. [TestMethod]
  45. public async Task ManagedClients_Will_Message_Send()
  46. {
  47. using (var testEnvironment = new TestEnvironment())
  48. {
  49. var receivedMessagesCount = 0;
  50. var factory = new MqttFactory();
  51. await testEnvironment.StartServerAsync();
  52. var willMessage = new MqttApplicationMessageBuilder().WithTopic("My/last/will").WithAtMostOnceQoS().Build();
  53. var clientOptions = new MqttClientOptionsBuilder()
  54. .WithTcpServer("localhost", testEnvironment.ServerPort)
  55. .WithWillMessage(willMessage);
  56. var dyingClient = testEnvironment.CreateClient();
  57. var dyingManagedClient = new ManagedMqttClient(dyingClient, testEnvironment.ClientLogger.CreateChildLogger());
  58. await dyingManagedClient.StartAsync(new ManagedMqttClientOptionsBuilder()
  59. .WithClientOptions(clientOptions)
  60. .Build());
  61. var recievingClient = await testEnvironment.ConnectClientAsync();
  62. await recievingClient.SubscribeAsync("My/last/will");
  63. recievingClient.UseApplicationMessageReceivedHandler(context => Interlocked.Increment(ref receivedMessagesCount));
  64. dyingManagedClient.Dispose();
  65. await Task.Delay(1000);
  66. Assert.AreEqual(1, receivedMessagesCount);
  67. }
  68. }
  69. [TestMethod]
  70. public async Task Start_Stop()
  71. {
  72. using (var testEnvironment = new TestEnvironment())
  73. {
  74. var factory = new MqttFactory();
  75. var server = await testEnvironment.StartServerAsync();
  76. var managedClient = new ManagedMqttClient(testEnvironment.CreateClient(), new MqttNetLogger().CreateChildLogger());
  77. var clientOptions = new MqttClientOptionsBuilder()
  78. .WithTcpServer("localhost", testEnvironment.ServerPort);
  79. TaskCompletionSource<bool> connected = new TaskCompletionSource<bool>();
  80. managedClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(e => { connected.SetResult(true);});
  81. await managedClient.StartAsync(new ManagedMqttClientOptionsBuilder()
  82. .WithClientOptions(clientOptions)
  83. .Build());
  84. await connected.Task;
  85. await managedClient.StopAsync();
  86. Assert.AreEqual(0, (await server.GetClientStatusAsync()).Count);
  87. }
  88. }
  89. [TestMethod]
  90. public async Task Storage_Queue_Drains()
  91. {
  92. using (var testEnvironment = new TestEnvironment())
  93. {
  94. testEnvironment.IgnoreClientLogErrors = true;
  95. testEnvironment.IgnoreServerLogErrors = true;
  96. var factory = new MqttFactory();
  97. var server = await testEnvironment.StartServerAsync();
  98. var managedClient = new ManagedMqttClient(testEnvironment.CreateClient(), new MqttNetLogger().CreateChildLogger());
  99. var clientOptions = new MqttClientOptionsBuilder()
  100. .WithTcpServer("localhost", testEnvironment.ServerPort);
  101. var storage = new ManagedMqttClientTestStorage();
  102. TaskCompletionSource<bool> connected = new TaskCompletionSource<bool>();
  103. managedClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(e =>
  104. {
  105. managedClient.ConnectedHandler = null;
  106. connected.SetResult(true);
  107. });
  108. await managedClient.StartAsync(new ManagedMqttClientOptionsBuilder()
  109. .WithClientOptions(clientOptions)
  110. .WithStorage(storage)
  111. .WithAutoReconnectDelay(System.TimeSpan.FromSeconds(5))
  112. .Build());
  113. await connected.Task;
  114. await testEnvironment.Server.StopAsync();
  115. await managedClient.PublishAsync(new MqttApplicationMessage { Topic = "1" });
  116. //Message should have been added to the storage queue in PublishAsync,
  117. //and we are awaiting PublishAsync, so the message should already be
  118. //in storage at this point (i.e. no waiting).
  119. Assert.AreEqual(1, storage.GetMessageCount());
  120. connected = new TaskCompletionSource<bool>();
  121. managedClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(e =>
  122. {
  123. managedClient.ConnectedHandler = null;
  124. connected.SetResult(true);
  125. });
  126. await testEnvironment.Server.StartAsync(new MqttServerOptionsBuilder()
  127. .WithDefaultEndpointPort(testEnvironment.ServerPort).Build());
  128. await connected.Task;
  129. //Wait 500ms here so the client has time to publish the queued message
  130. await Task.Delay(500);
  131. Assert.AreEqual(0, storage.GetMessageCount());
  132. await managedClient.StopAsync();
  133. }
  134. }
  135. }
  136. public class ManagedMqttClientTestStorage : IManagedMqttClientStorage
  137. {
  138. private IList<ManagedMqttApplicationMessage> _messages = null;
  139. public Task<IList<ManagedMqttApplicationMessage>> LoadQueuedMessagesAsync()
  140. {
  141. if (_messages == null)
  142. {
  143. _messages = new List<ManagedMqttApplicationMessage>();
  144. }
  145. return Task.FromResult(_messages);
  146. }
  147. public Task SaveQueuedMessagesAsync(IList<ManagedMqttApplicationMessage> messages)
  148. {
  149. _messages = messages;
  150. return Task.FromResult(0);
  151. }
  152. public int GetMessageCount()
  153. {
  154. return _messages.Count;
  155. }
  156. }
  157. }