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.
 
 
 
 

170 lines
5.1 KiB

  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using MQTTnet.Client;
  3. using MQTTnet.Client.Options;
  4. using MQTTnet.Diagnostics;
  5. using MQTTnet.Server;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. namespace MQTTnet.Tests.Mockups
  11. {
  12. public sealed class TestEnvironment : IDisposable
  13. {
  14. readonly MqttFactory _mqttFactory = new MqttFactory();
  15. readonly List<IMqttClient> _clients = new List<IMqttClient>();
  16. readonly List<string> _serverErrors = new List<string>();
  17. readonly List<string> _clientErrors = new List<string>();
  18. readonly List<Exception> _exceptions = new List<Exception>();
  19. public IMqttServer Server { get; private set; }
  20. public bool IgnoreClientLogErrors { get; set; }
  21. public bool IgnoreServerLogErrors { get; set; }
  22. public int ServerPort { get; set; } = 1888;
  23. public IMqttNetLogger ServerLogger { get; } = new MqttNetLogger("server");
  24. public IMqttNetLogger ClientLogger { get; } = new MqttNetLogger("client");
  25. public TestContext TestContext { get; }
  26. public TestEnvironment() : this(null)
  27. {
  28. }
  29. public TestEnvironment(TestContext testContext)
  30. {
  31. TestContext = testContext;
  32. ServerLogger.LogMessagePublished += (s, e) =>
  33. {
  34. if (e.LogMessage.Level == MqttNetLogLevel.Error)
  35. {
  36. lock (_serverErrors)
  37. {
  38. _serverErrors.Add(e.LogMessage.ToString());
  39. }
  40. }
  41. };
  42. ClientLogger.LogMessagePublished += (s, e) =>
  43. {
  44. if (e.LogMessage.Level == MqttNetLogLevel.Error)
  45. {
  46. lock (_clientErrors)
  47. {
  48. _clientErrors.Add(e.LogMessage.ToString());
  49. }
  50. }
  51. };
  52. }
  53. public IMqttClient CreateClient()
  54. {
  55. var client = _mqttFactory.CreateMqttClient(ClientLogger);
  56. _clients.Add(client);
  57. return new TestClientWrapper(client, TestContext);
  58. }
  59. public Task<IMqttServer> StartServerAsync()
  60. {
  61. return StartServerAsync(new MqttServerOptionsBuilder());
  62. }
  63. public async Task<IMqttServer> StartServerAsync(MqttServerOptionsBuilder options)
  64. {
  65. if (options == null) throw new ArgumentNullException(nameof(options));
  66. if (Server != null)
  67. {
  68. throw new InvalidOperationException("Server already started.");
  69. }
  70. Server = new TestServerWrapper(_mqttFactory.CreateMqttServer(ServerLogger), TestContext, this);
  71. options.WithDefaultEndpointPort(ServerPort);
  72. await Server.StartAsync(options.Build()).ConfigureAwait(false);
  73. return Server;
  74. }
  75. public Task<IMqttClient> ConnectClientAsync()
  76. {
  77. return ConnectClientAsync(new MqttClientOptionsBuilder());
  78. }
  79. public async Task<IMqttClient> ConnectClientAsync(MqttClientOptionsBuilder options)
  80. {
  81. if (options == null) throw new ArgumentNullException(nameof(options));
  82. options = options.WithTcpServer("localhost", ServerPort);
  83. var client = CreateClient();
  84. await client.ConnectAsync(options.Build()).ConfigureAwait(false);
  85. return client;
  86. }
  87. public async Task<IMqttClient> ConnectClientAsync(IMqttClientOptions options)
  88. {
  89. if (options == null) throw new ArgumentNullException(nameof(options));
  90. var client = CreateClient();
  91. await client.ConnectAsync(options).ConfigureAwait(false);
  92. return client;
  93. }
  94. public void ThrowIfLogErrors()
  95. {
  96. lock (_serverErrors)
  97. {
  98. if (!IgnoreServerLogErrors && _serverErrors.Count > 0)
  99. {
  100. throw new Exception($"Server had {_serverErrors.Count} errors (${string.Join(Environment.NewLine, _serverErrors)}).");
  101. }
  102. }
  103. lock (_clientErrors)
  104. {
  105. if (!IgnoreClientLogErrors && _clientErrors.Count > 0)
  106. {
  107. throw new Exception($"Client(s) had {_clientErrors.Count} errors (${string.Join(Environment.NewLine, _clientErrors)}).");
  108. }
  109. }
  110. }
  111. public void Dispose()
  112. {
  113. foreach (var mqttClient in _clients)
  114. {
  115. mqttClient?.Dispose();
  116. }
  117. Server?.StopAsync().GetAwaiter().GetResult();
  118. Server?.Dispose();
  119. ThrowIfLogErrors();
  120. if (_exceptions.Any())
  121. {
  122. throw new Exception($"{_exceptions.Count} exceptions tracked.\r\n" + string.Join(Environment.NewLine, _exceptions));
  123. }
  124. }
  125. public void TrackException(Exception exception)
  126. {
  127. lock (_exceptions)
  128. {
  129. _exceptions.Add(exception);
  130. }
  131. }
  132. }
  133. }