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.
 
 
 
 

190 lines
7.3 KiB

  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. // See the LICENSE file in the project root for more information.
  4. using Microsoft.VisualStudio.TestTools.UnitTesting;
  5. using MQTTnet.Client;
  6. using MQTTnet.Formatter;
  7. using MQTTnet.Tests.Mockups;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. using MQTTnet.Implementations;
  11. using MQTTnet.Protocol;
  12. namespace MQTTnet.Tests.MQTTv5
  13. {
  14. [TestClass]
  15. public sealed class Server_Tests : BaseTestClass
  16. {
  17. [TestMethod]
  18. public async Task Will_Message_Send()
  19. {
  20. using (var testEnvironment = CreateTestEnvironment())
  21. {
  22. await testEnvironment.StartServer();
  23. var clientOptions = new MqttClientOptionsBuilder().WithWillTopic("My/last/will").WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).WithProtocolVersion(MqttProtocolVersion.V500);
  24. var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
  25. var receivedMessagesCount = 0;
  26. c1.ApplicationMessageReceivedAsync += e =>
  27. {
  28. Interlocked.Increment(ref receivedMessagesCount);
  29. return PlatformAbstractionLayer.CompletedTask;
  30. };
  31. await c1.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("#").Build());
  32. var c2 = await testEnvironment.ConnectClient(clientOptions);
  33. c2.Dispose(); // Dispose will not send a DISCONNECT pattern first so the will message must be sent.
  34. await Task.Delay(1000);
  35. Assert.AreEqual(1, receivedMessagesCount);
  36. }
  37. }
  38. [TestMethod]
  39. public async Task Validate_IsSessionPresent()
  40. {
  41. using (var testEnvironment = CreateTestEnvironment())
  42. {
  43. // Create server with persistent sessions enabled
  44. await testEnvironment.StartServer(o => o.WithPersistentSessions());
  45. const string ClientId = "Client1";
  46. // Create client without clean session and long session expiry interval
  47. var options1 = CreateClientOptions(testEnvironment, ClientId, false, 9999);
  48. var client1 = await testEnvironment.ConnectClient(options1);
  49. // Disconnect; empty session should remain on server
  50. await client1.DisconnectAsync();
  51. // Simulate some time delay between connections
  52. await Task.Delay(1000);
  53. // Reconnect the same client ID to existing session
  54. var client2 = testEnvironment.CreateClient();
  55. var options2 = CreateClientOptions(testEnvironment, ClientId, false, 9999);
  56. var result = await client2.ConnectAsync(options2).ConfigureAwait(false);
  57. await client2.DisconnectAsync();
  58. // Session should be present
  59. Assert.IsTrue(result.IsSessionPresent, "Session not present");
  60. }
  61. }
  62. [TestMethod]
  63. public async Task Connect_with_Undefined_SessionExpiryInterval()
  64. {
  65. using (var testEnvironment = CreateTestEnvironment())
  66. {
  67. // Create server with persistent sessions enabled
  68. await testEnvironment.StartServer(o => o.WithPersistentSessions());
  69. const string ClientId = "Client1";
  70. // Create client without clean session and NO session expiry interval,
  71. // that means, the session should not persist
  72. var options1 = CreateClientOptions(testEnvironment, ClientId, false, 0);
  73. var client1 = await testEnvironment.ConnectClient(options1);
  74. // Disconnect; no session should remain on server because the session expiry interval was undefined
  75. await client1.DisconnectAsync();
  76. // Simulate some time delay between connections
  77. await Task.Delay(1000);
  78. // Reconnect the same client ID to existing session
  79. var client2 = testEnvironment.CreateClient();
  80. var options2 = CreateClientOptions(testEnvironment, ClientId, false, 9999);
  81. var result = await client2.ConnectAsync(options2).ConfigureAwait(false);
  82. await client2.DisconnectAsync();
  83. // Session should not be present
  84. Assert.IsTrue(!result.IsSessionPresent, "Session is present when it should not");
  85. }
  86. }
  87. [TestMethod]
  88. public async Task Reconnect_with_different_SessionExpiryInterval()
  89. {
  90. using (var testEnvironment = CreateTestEnvironment())
  91. {
  92. // Create server with persistent sessions enabled
  93. await testEnvironment.StartServer(o => o.WithPersistentSessions());
  94. const string ClientId = "Client1";
  95. // Create client with clean session and session expiry interval > 0
  96. var options = CreateClientOptions(testEnvironment, ClientId, true, 9999);
  97. var client1 = await testEnvironment.ConnectClient(options);
  98. // Disconnect; session should remain on server
  99. await client1.DisconnectAsync();
  100. await Task.Delay(1000);
  101. // Reconnect the same client ID to the existing session but leave session expiry interval undefined this time.
  102. // Session should be present because the client1 connection had SessionExpiryInterval > 0
  103. var client2 = testEnvironment.CreateClient();
  104. var options2 = CreateClientOptions(testEnvironment, ClientId, false, 0);
  105. var result2 = await client2.ConnectAsync(options2).ConfigureAwait(false);
  106. await client2.DisconnectAsync();
  107. Assert.IsTrue(result2.IsSessionPresent, "Session is not present when it should");
  108. // Simulate some time delay between connections
  109. await Task.Delay(1000);
  110. // Reconnect the same client ID.
  111. // No session should be present because the previous session expiry interval was undefined for the client2 connection
  112. var client3 = testEnvironment.CreateClient();
  113. var options3 = CreateClientOptions(testEnvironment, ClientId, false, 0);
  114. var result3 = await client2.ConnectAsync(options3).ConfigureAwait(false);
  115. await client3.DisconnectAsync();
  116. // Session should be present
  117. Assert.IsTrue(!result3.IsSessionPresent, "Session is present when it should not");
  118. }
  119. }
  120. MqttClientOptions CreateClientOptions(TestEnvironment testEnvironment, string clientId, bool cleanSession, uint sessionExpiryInterval)
  121. {
  122. return testEnvironment.Factory.CreateClientOptionsBuilder()
  123. .WithProtocolVersion(MqttProtocolVersion.V500)
  124. .WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
  125. .WithSessionExpiryInterval(sessionExpiryInterval)
  126. .WithCleanSession(cleanSession)
  127. .WithClientId(clientId)
  128. .Build();
  129. }
  130. }
  131. }