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.
 
 
 
 

220 lines
8.8 KiB

  1. using System;
  2. using System.Text;
  3. using System.Threading.Tasks;
  4. using Microsoft.VisualStudio.TestTools.UnitTesting;
  5. using MQTTnet.Tests.Mockups;
  6. using MQTTnet.Client;
  7. using MQTTnet.Client.Receiving;
  8. using MQTTnet.Exceptions;
  9. using MQTTnet.Extensions.Rpc;
  10. using MQTTnet.Protocol;
  11. using MQTTnet.Client.Options;
  12. using MQTTnet.Formatter;
  13. using MQTTnet.Extensions.Rpc.Options;
  14. using MQTTnet.Extensions.Rpc.Options.TopicGeneration;
  15. namespace MQTTnet.Tests
  16. {
  17. [TestClass]
  18. public class RPC_Tests
  19. {
  20. public TestContext TestContext { get; set; }
  21. [TestMethod]
  22. public Task Execute_Success_With_QoS_0()
  23. {
  24. return Execute_Success(MqttQualityOfServiceLevel.AtMostOnce, MqttProtocolVersion.V311);
  25. }
  26. [TestMethod]
  27. public Task Execute_Success_With_QoS_1()
  28. {
  29. return Execute_Success(MqttQualityOfServiceLevel.AtLeastOnce, MqttProtocolVersion.V311);
  30. }
  31. [TestMethod]
  32. public Task Execute_Success_With_QoS_2()
  33. {
  34. return Execute_Success(MqttQualityOfServiceLevel.ExactlyOnce, MqttProtocolVersion.V311);
  35. }
  36. [TestMethod]
  37. public Task Execute_Success_With_QoS_0_MQTT_V5()
  38. {
  39. return Execute_Success(MqttQualityOfServiceLevel.AtMostOnce, MqttProtocolVersion.V500);
  40. }
  41. [TestMethod]
  42. public Task Execute_Success_With_QoS_1_MQTT_V5()
  43. {
  44. return Execute_Success(MqttQualityOfServiceLevel.AtLeastOnce, MqttProtocolVersion.V500);
  45. }
  46. [TestMethod]
  47. public Task Execute_Success_With_QoS_2_MQTT_V5()
  48. {
  49. return Execute_Success(MqttQualityOfServiceLevel.ExactlyOnce, MqttProtocolVersion.V500);
  50. }
  51. [TestMethod]
  52. public Task Execute_Success_With_QoS_0_MQTT_V5_Use_ResponseTopic()
  53. {
  54. return Execute_Success_MQTT_V5(MqttQualityOfServiceLevel.AtMostOnce);
  55. }
  56. [TestMethod]
  57. public Task Execute_Success_With_QoS_1_MQTT_V5_Use_ResponseTopic()
  58. {
  59. return Execute_Success_MQTT_V5(MqttQualityOfServiceLevel.AtLeastOnce);
  60. }
  61. [TestMethod]
  62. public Task Execute_Success_With_QoS_2_MQTT_V5_Use_ResponseTopic()
  63. {
  64. return Execute_Success_MQTT_V5(MqttQualityOfServiceLevel.ExactlyOnce);
  65. }
  66. [TestMethod]
  67. [ExpectedException(typeof(MqttCommunicationTimedOutException))]
  68. public async Task Execute_Timeout()
  69. {
  70. using (var testEnvironment = new TestEnvironment(TestContext))
  71. {
  72. await testEnvironment.StartServer();
  73. var requestSender = await testEnvironment.ConnectClient();
  74. var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build());
  75. await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
  76. }
  77. }
  78. [TestMethod]
  79. [ExpectedException(typeof(MqttCommunicationTimedOutException))]
  80. public async Task Execute_With_Custom_Topic_Names()
  81. {
  82. using (var testEnvironment = new TestEnvironment(TestContext))
  83. {
  84. await testEnvironment.StartServer();
  85. var requestSender = await testEnvironment.ConnectClient();
  86. var rpcClient = await testEnvironment.ConnectRpcClient(new MqttRpcClientOptionsBuilder().WithTopicGenerationStrategy(new TestTopicStrategy()).Build());
  87. await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
  88. }
  89. }
  90. async Task Execute_Success(MqttQualityOfServiceLevel qosLevel, MqttProtocolVersion protocolVersion)
  91. {
  92. using (var testEnvironment = new TestEnvironment(TestContext))
  93. {
  94. await testEnvironment.StartServer();
  95. var responseSender = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(protocolVersion));
  96. await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping", qosLevel);
  97. responseSender.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(async e =>
  98. {
  99. await responseSender.PublishAsync(e.ApplicationMessage.Topic + "/response", "pong");
  100. });
  101. var requestSender = await testEnvironment.ConnectClient();
  102. using (var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build()))
  103. {
  104. var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), "ping", "", qosLevel);
  105. Assert.AreEqual("pong", Encoding.UTF8.GetString(response));
  106. }
  107. }
  108. }
  109. async Task Execute_Success_MQTT_V5(MqttQualityOfServiceLevel qosLevel)
  110. {
  111. using (var testEnvironment = new TestEnvironment(TestContext))
  112. {
  113. await testEnvironment.StartServer();
  114. var responseSender = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
  115. await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping", qosLevel);
  116. responseSender.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(async e =>
  117. {
  118. await responseSender.PublishAsync(e.ApplicationMessage.ResponseTopic, "pong");
  119. });
  120. var requestSender = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
  121. using (var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build()))
  122. {
  123. var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), "ping", "", qosLevel);
  124. Assert.AreEqual("pong", Encoding.UTF8.GetString(response));
  125. }
  126. }
  127. }
  128. [TestMethod]
  129. public async Task Execute_Success_MQTT_V5_Mixed_Clients()
  130. {
  131. using (var testEnvironment = new TestEnvironment(TestContext))
  132. {
  133. await testEnvironment.StartServer();
  134. var responseSender = await testEnvironment.ConnectClient();
  135. await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping", MqttQualityOfServiceLevel.AtMostOnce);
  136. responseSender.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(async e =>
  137. {
  138. Assert.IsNull(e.ApplicationMessage.ResponseTopic);
  139. await responseSender.PublishAsync(e.ApplicationMessage.Topic + "/response", "pong");
  140. });
  141. var requestSender = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
  142. using (var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build()))
  143. {
  144. var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
  145. Assert.AreEqual("pong", Encoding.UTF8.GetString(response));
  146. }
  147. }
  148. }
  149. [TestMethod]
  150. [ExpectedException(typeof(MqttCommunicationTimedOutException))]
  151. public async Task Execute_Timeout_MQTT_V5_Mixed_Clients()
  152. {
  153. using (var testEnvironment = new TestEnvironment(TestContext))
  154. {
  155. await testEnvironment.StartServer();
  156. var responseSender = await testEnvironment.ConnectClient();
  157. await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping", MqttQualityOfServiceLevel.AtMostOnce);
  158. responseSender.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(async e =>
  159. {
  160. Assert.IsNull(e.ApplicationMessage.ResponseTopic);
  161. });
  162. var requestSender = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
  163. using (var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build()))
  164. {
  165. var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
  166. }
  167. }
  168. }
  169. class TestTopicStrategy : IMqttRpcClientTopicGenerationStrategy
  170. {
  171. public MqttRpcTopicPair CreateRpcTopics(TopicGenerationContext context)
  172. {
  173. return new MqttRpcTopicPair
  174. {
  175. RequestTopic = "a",
  176. ResponseTopic = "b"
  177. };
  178. }
  179. }
  180. }
  181. }