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.
 
 
 
 

423 line
15 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading.Tasks;
  5. using Microsoft.VisualStudio.TestTools.UnitTesting;
  6. using MQTTnet.Core.Adapter;
  7. using MQTTnet.Core.Client;
  8. using MQTTnet.Core.Protocol;
  9. using MQTTnet.Core.Server;
  10. using Microsoft.Extensions.DependencyInjection;
  11. namespace MQTTnet.Core.Tests
  12. {
  13. [TestClass]
  14. public class MqttServerTests
  15. {
  16. [TestMethod]
  17. public void MqttServer_PublishSimple_AtMostOnce()
  18. {
  19. TestPublishAsync(
  20. "A/B/C",
  21. MqttQualityOfServiceLevel.AtMostOnce,
  22. "A/B/C",
  23. MqttQualityOfServiceLevel.AtMostOnce,
  24. 1).Wait();
  25. }
  26. [TestMethod]
  27. public void MqttServer_PublishSimple_AtLeastOnce()
  28. {
  29. TestPublishAsync(
  30. "A/B/C",
  31. MqttQualityOfServiceLevel.AtLeastOnce,
  32. "A/B/C",
  33. MqttQualityOfServiceLevel.AtLeastOnce,
  34. 1).Wait();
  35. }
  36. [TestMethod]
  37. public void MqttServer_PublishSimple_ExactlyOnce()
  38. {
  39. TestPublishAsync(
  40. "A/B/C",
  41. MqttQualityOfServiceLevel.ExactlyOnce,
  42. "A/B/C",
  43. MqttQualityOfServiceLevel.ExactlyOnce,
  44. 1).Wait();
  45. }
  46. [TestMethod]
  47. public async Task MqttServer_WillMessage()
  48. {
  49. var serverAdapter = new TestMqttServerAdapter();
  50. var services = new ServiceCollection()
  51. .AddLogging()
  52. .AddMqttServer()
  53. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  54. .BuildServiceProvider();
  55. var s = new MqttFactory(services).CreateMqttServer();
  56. var receivedMessagesCount = 0;
  57. try
  58. {
  59. await s.StartAsync();
  60. var willMessage = new MqttApplicationMessageBuilder().WithTopic("My/last/will").WithAtMostOnceQoS().Build();
  61. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  62. var c2 = await serverAdapter.ConnectTestClient(s, "c2", willMessage);
  63. c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  64. await c1.SubscribeAsync(new TopicFilter("#", MqttQualityOfServiceLevel.AtMostOnce));
  65. await c2.DisconnectAsync();
  66. await Task.Delay(1000);
  67. }
  68. finally
  69. {
  70. await s.StopAsync();
  71. }
  72. Assert.AreEqual(1, receivedMessagesCount);
  73. }
  74. [TestMethod]
  75. public async Task MqttServer_Unsubscribe()
  76. {
  77. var serverAdapter = new TestMqttServerAdapter();
  78. var services = new ServiceCollection()
  79. .AddLogging()
  80. .AddMqttServer()
  81. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  82. .BuildServiceProvider();
  83. var s = new MqttFactory(services).CreateMqttServer();
  84. var receivedMessagesCount = 0;
  85. try
  86. {
  87. await s.StartAsync();
  88. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  89. var c2 = await serverAdapter.ConnectTestClient(s, "c2");
  90. c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  91. var message = new MqttApplicationMessageBuilder().WithTopic("a").WithAtLeastOnceQoS().Build();
  92. await c2.PublishAsync(message);
  93. Assert.AreEqual(0, receivedMessagesCount);
  94. await c1.SubscribeAsync(new TopicFilter("a", MqttQualityOfServiceLevel.AtLeastOnce));
  95. await c2.PublishAsync(message);
  96. await Task.Delay(500);
  97. Assert.AreEqual(1, receivedMessagesCount);
  98. await c1.UnsubscribeAsync("a");
  99. await c2.PublishAsync(message);
  100. await Task.Delay(500);
  101. Assert.AreEqual(1, receivedMessagesCount);
  102. }
  103. finally
  104. {
  105. await s.StopAsync();
  106. }
  107. await Task.Delay(500);
  108. Assert.AreEqual(1, receivedMessagesCount);
  109. }
  110. [TestMethod]
  111. public async Task MqttServer_Publish()
  112. {
  113. var serverAdapter = new TestMqttServerAdapter();
  114. var services = new ServiceCollection()
  115. .AddLogging()
  116. .AddMqttServer()
  117. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  118. .BuildServiceProvider();
  119. var s = new MqttFactory(services).CreateMqttServer();
  120. var receivedMessagesCount = 0;
  121. try
  122. {
  123. await s.StartAsync();
  124. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  125. c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  126. var message = new MqttApplicationMessageBuilder().WithTopic("a").WithAtLeastOnceQoS().Build();
  127. await c1.SubscribeAsync(new TopicFilter("a", MqttQualityOfServiceLevel.AtLeastOnce));
  128. s.PublishAsync(message).Wait();
  129. await Task.Delay(500);
  130. }
  131. finally
  132. {
  133. await s.StopAsync();
  134. }
  135. Assert.AreEqual(1, receivedMessagesCount);
  136. }
  137. [TestMethod]
  138. public async Task MqttServer_NoRetainedMessage()
  139. {
  140. var serverAdapter = new TestMqttServerAdapter();
  141. var services = new ServiceCollection()
  142. .AddLogging()
  143. .AddMqttServer()
  144. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  145. .BuildServiceProvider();
  146. var s = new MqttFactory(services).CreateMqttServer();
  147. var receivedMessagesCount = 0;
  148. try
  149. {
  150. await s.StartAsync();
  151. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  152. await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).Build());
  153. await c1.DisconnectAsync();
  154. var c2 = await serverAdapter.ConnectTestClient(s, "c2");
  155. c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  156. await c2.SubscribeAsync(new TopicFilter("retained", MqttQualityOfServiceLevel.AtMostOnce));
  157. await Task.Delay(500);
  158. }
  159. finally
  160. {
  161. await s.StopAsync();
  162. }
  163. Assert.AreEqual(0, receivedMessagesCount);
  164. }
  165. [TestMethod]
  166. public async Task MqttServer_RetainedMessage()
  167. {
  168. var serverAdapter = new TestMqttServerAdapter();
  169. var services = new ServiceCollection()
  170. .AddLogging()
  171. .AddMqttServer()
  172. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  173. .BuildServiceProvider();
  174. var s = new MqttFactory(services).CreateMqttServer();
  175. var receivedMessagesCount = 0;
  176. try
  177. {
  178. await s.StartAsync();
  179. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  180. await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
  181. await c1.DisconnectAsync();
  182. var c2 = await serverAdapter.ConnectTestClient(s, "c2");
  183. c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  184. await c2.SubscribeAsync(new TopicFilter("retained", MqttQualityOfServiceLevel.AtMostOnce));
  185. await Task.Delay(500);
  186. }
  187. finally
  188. {
  189. await s.StopAsync();
  190. }
  191. Assert.AreEqual(1, receivedMessagesCount);
  192. }
  193. [TestMethod]
  194. public async Task MqttServer_ClearRetainedMessage()
  195. {
  196. var serverAdapter = new TestMqttServerAdapter();
  197. var services = new ServiceCollection()
  198. .AddLogging()
  199. .AddMqttServer()
  200. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  201. .BuildServiceProvider();
  202. var s = new MqttFactory(services).CreateMqttServer();
  203. var receivedMessagesCount = 0;
  204. try
  205. {
  206. await s.StartAsync();
  207. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  208. await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
  209. await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[0]).WithRetainFlag().Build());
  210. await c1.DisconnectAsync();
  211. var c2 = await serverAdapter.ConnectTestClient(s, "c2");
  212. c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  213. await c2.SubscribeAsync(new TopicFilter("retained", MqttQualityOfServiceLevel.AtMostOnce));
  214. await Task.Delay(500);
  215. }
  216. finally
  217. {
  218. await s.StopAsync();
  219. }
  220. Assert.AreEqual(0, receivedMessagesCount);
  221. }
  222. [TestMethod]
  223. public async Task MqttServer_PersistRetainedMessage()
  224. {
  225. var storage = new TestStorage();
  226. var serverAdapter = new TestMqttServerAdapter();
  227. var services = new ServiceCollection()
  228. .AddLogging()
  229. .AddMqttServer()
  230. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  231. .BuildServiceProvider();
  232. var s = new MqttFactory(services).CreateMqttServer(options => options.Storage = storage);
  233. try
  234. {
  235. await s.StartAsync();
  236. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  237. await c1.PublishAsync(new MqttApplicationMessageBuilder().WithTopic("retained").WithPayload(new byte[3]).WithRetainFlag().Build());
  238. await c1.DisconnectAsync();
  239. }
  240. finally
  241. {
  242. await s.StopAsync();
  243. }
  244. s = services.GetRequiredService<IMqttServer>();
  245. var receivedMessagesCount = 0;
  246. try
  247. {
  248. await s.StartAsync();
  249. var c2 = await serverAdapter.ConnectTestClient(s, "c2");
  250. c2.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  251. await c2.SubscribeAsync(new TopicFilter("retained", MqttQualityOfServiceLevel.AtMostOnce));
  252. await Task.Delay(500);
  253. }
  254. finally
  255. {
  256. await s.StopAsync();
  257. }
  258. Assert.AreEqual(1, receivedMessagesCount);
  259. }
  260. [TestMethod]
  261. public async Task MqttServer_InterceptMessage()
  262. {
  263. void Interceptor(MqttApplicationMessageInterceptorContext context)
  264. {
  265. context.ApplicationMessage.Payload = Encoding.ASCII.GetBytes("extended");
  266. }
  267. var serverAdapter = new TestMqttServerAdapter();
  268. var services = new ServiceCollection()
  269. .AddLogging()
  270. .AddMqttServer()
  271. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  272. .BuildServiceProvider();
  273. var s = new MqttFactory(services).CreateMqttServer(options => options.ApplicationMessageInterceptor = Interceptor);
  274. try
  275. {
  276. await s.StartAsync();
  277. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  278. var c2 = await serverAdapter.ConnectTestClient(s, "c2");
  279. await c2.SubscribeAsync(new TopicFilterBuilder().WithTopic("test").Build());
  280. var isIntercepted = false;
  281. c2.ApplicationMessageReceived += (sender, args) =>
  282. {
  283. isIntercepted = string.Compare("extended", Encoding.UTF8.GetString(args.ApplicationMessage.Payload), StringComparison.Ordinal) == 0;
  284. };
  285. var m = new MqttApplicationMessageBuilder().WithTopic("test").Build();
  286. await c1.PublishAsync(m);
  287. await c1.DisconnectAsync();
  288. await Task.Delay(500);
  289. Assert.IsTrue(isIntercepted);
  290. }
  291. finally
  292. {
  293. await s.StopAsync();
  294. }
  295. }
  296. private class TestStorage : IMqttServerStorage
  297. {
  298. private IList<MqttApplicationMessage> _messages = new List<MqttApplicationMessage>();
  299. public Task SaveRetainedMessagesAsync(IList<MqttApplicationMessage> messages)
  300. {
  301. _messages = messages;
  302. return Task.CompletedTask;
  303. }
  304. public Task<IList<MqttApplicationMessage>> LoadRetainedMessagesAsync()
  305. {
  306. return Task.FromResult(_messages);
  307. }
  308. }
  309. private static async Task TestPublishAsync(
  310. string topic,
  311. MqttQualityOfServiceLevel qualityOfServiceLevel,
  312. string topicFilter,
  313. MqttQualityOfServiceLevel filterQualityOfServiceLevel,
  314. int expectedReceivedMessagesCount)
  315. {
  316. var serverAdapter = new TestMqttServerAdapter();
  317. var services = new ServiceCollection()
  318. .AddMqttServer()
  319. .AddLogging()
  320. .AddSingleton<IMqttServerAdapter>(serverAdapter)
  321. .BuildServiceProvider();
  322. var s = services.GetRequiredService<IMqttServer>();
  323. var receivedMessagesCount = 0;
  324. try
  325. {
  326. await s.StartAsync();
  327. var c1 = await serverAdapter.ConnectTestClient(s, "c1");
  328. var c2 = await serverAdapter.ConnectTestClient(s, "c2");
  329. c1.ApplicationMessageReceived += (_, __) => receivedMessagesCount++;
  330. await c1.SubscribeAsync(new TopicFilterBuilder().WithTopic(topicFilter).WithQualityOfServiceLevel(filterQualityOfServiceLevel).Build());
  331. await c2.PublishAsync(new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload(new byte[0]).WithQualityOfServiceLevel(qualityOfServiceLevel).Build());
  332. await Task.Delay(500);
  333. await c1.UnsubscribeAsync(topicFilter);
  334. await Task.Delay(500);
  335. }
  336. finally
  337. {
  338. await s.StopAsync();
  339. }
  340. Assert.AreEqual(expectedReceivedMessagesCount, receivedMessagesCount);
  341. }
  342. }
  343. }