mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-11-02 12:12:38 +08:00
Implement new managed client.
This commit is contained in:
+62
-143
@@ -13,121 +13,67 @@ using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Extensions.ManagedClient;
|
||||
using MQTTnet.Implementations;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
using MqttClient = MQTTnet.Client.MqttClient;
|
||||
|
||||
namespace MQTTnet.Tests.Client
|
||||
namespace MQTTnet.Tests.ManagedMqttClient
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class ManagedMqttClient_Tests : BaseTestClass
|
||||
public sealed class ManagedMqttClient_Connection_Tests : BaseTestClass
|
||||
{
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Connect_To_Invalid_Server()
|
||||
public async Task Connect_To_Valid_Server()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
await testEnvironment.StartServer();
|
||||
var managedClient = await testEnvironment.StartManagedClient();
|
||||
|
||||
var mqttClient = testEnvironment.CreateClient();
|
||||
await LongTestDelay();
|
||||
|
||||
var managedClient = testEnvironment.Factory.CreateManagedMqttClient(mqttClient);
|
||||
|
||||
ConnectingFailedEventArgs connectingFailedEventArgs = null;
|
||||
|
||||
managedClient.ConnectingFailedAsync += args =>
|
||||
{
|
||||
connectingFailedEventArgs = args;
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
await managedClient.StartAsync(
|
||||
new ManagedMqttClientOptions
|
||||
{
|
||||
ClientOptions = testEnvironment.Factory.CreateClientOptionsBuilder().WithTimeout(TimeSpan.FromSeconds(2)).WithTcpServer("wrong_server", 1234).Build()
|
||||
});
|
||||
|
||||
await managedClient.EnqueueAsync("test_topic_2");
|
||||
|
||||
SpinWait.SpinUntil(() => connectingFailedEventArgs != null, 10000);
|
||||
|
||||
// The wrong server must be reported in general.
|
||||
Assert.IsNotNull(connectingFailedEventArgs);
|
||||
Assert.IsNotNull(connectingFailedEventArgs.Exception);
|
||||
Assert.IsNull(connectingFailedEventArgs.ConnectResult);
|
||||
Assert.IsTrue(managedClient.IsStarted);
|
||||
Assert.IsTrue(managedClient.IsConnected);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Drop_New_Messages_On_Full_Queue()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var managedClient = factory.CreateManagedMqttClient();
|
||||
try
|
||||
{
|
||||
var clientOptions = new ManagedMqttClientOptionsBuilder().WithMaxPendingMessages(5)
|
||||
.WithPendingMessagesOverflowStrategy(MqttPendingMessagesOverflowStrategy.DropNewMessage);
|
||||
|
||||
clientOptions.WithClientOptions(o => o.WithTcpServer("localhost"));
|
||||
|
||||
await managedClient.StartAsync(clientOptions.Build());
|
||||
|
||||
await managedClient.EnqueueAsync("1");
|
||||
await managedClient.EnqueueAsync("2");
|
||||
await managedClient.EnqueueAsync("3");
|
||||
await managedClient.EnqueueAsync("4");
|
||||
await managedClient.EnqueueAsync("5");
|
||||
await managedClient.EnqueueAsync("6");
|
||||
await managedClient.EnqueueAsync("7");
|
||||
await managedClient.EnqueueAsync("8");
|
||||
|
||||
Assert.AreEqual(5, managedClient.PendingApplicationMessagesCount);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await managedClient.StopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ManagedClients_Will_Message_Send()
|
||||
public async Task Will_Message_Send()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
// Prepare the receiving client.
|
||||
var receivedMessagesCount = 0;
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.WithWillTopic("My/last/will")
|
||||
.WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce)
|
||||
.Build();
|
||||
|
||||
var dyingClient = testEnvironment.CreateClient();
|
||||
var dyingManagedClient = new ManagedMqttClient(dyingClient, testEnvironment.ClientLogger);
|
||||
|
||||
await dyingManagedClient.StartAsync(new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).Build());
|
||||
|
||||
// Wait until the managed client is fully set up and running.
|
||||
await Task.Delay(1000);
|
||||
|
||||
var receivingClient = await testEnvironment.ConnectClient();
|
||||
|
||||
receivingClient.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
Interlocked.Increment(ref receivedMessagesCount);
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
|
||||
await receivingClient.SubscribeAsync("My/last/will");
|
||||
|
||||
// Prepare the managed client.
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.WithWillTopic("My/last/will")
|
||||
.Build();
|
||||
|
||||
var dyingClient = testEnvironment.CreateClient();
|
||||
var dyingManagedClient = testEnvironment.CreateManagedMqttClient(dyingClient);
|
||||
await dyingManagedClient.StartAsync(new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).Build());
|
||||
|
||||
// Wait until the managed client is fully set up and running.
|
||||
await LongTestDelay();
|
||||
|
||||
// Disposing the client will not sent a DISCONNECT packet so that connection is terminated
|
||||
// which will lead to the will publish.
|
||||
dyingManagedClient.Dispose();
|
||||
|
||||
// Wait for arrival of the will message at the receiver.
|
||||
await Task.Delay(5000);
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.AreEqual(1, receivedMessagesCount);
|
||||
}
|
||||
@@ -140,18 +86,17 @@ namespace MQTTnet.Tests.Client
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = new ManagedMqttClient(testEnvironment.CreateClient(), new MqttNetEventLogger());
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost", testEnvironment.ServerPort);
|
||||
var managedClient = testEnvironment.CreateManagedClient();
|
||||
|
||||
var connected = GetConnectedTask(managedClient);
|
||||
|
||||
await managedClient.StartAsync(new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).Build());
|
||||
await managedClient.StartAsync(testEnvironment.CreateDefaultManagedMqttClientOptions());
|
||||
|
||||
await connected;
|
||||
|
||||
await managedClient.StopAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.AreEqual(0, (await server.GetClientsAsync()).Count);
|
||||
}
|
||||
@@ -167,7 +112,7 @@ namespace MQTTnet.Tests.Client
|
||||
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = new ManagedMqttClient(testEnvironment.CreateClient(), new MqttNetEventLogger());
|
||||
var managedClient = testEnvironment.CreateManagedClient();
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost", testEnvironment.ServerPort);
|
||||
var storage = new ManagedMqttClientTestStorage();
|
||||
|
||||
@@ -207,6 +152,8 @@ namespace MQTTnet.Tests.Client
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var unmanagedClient = testEnvironment.CreateClient();
|
||||
var managedClient = await CreateManagedClientAsync(testEnvironment, unmanagedClient);
|
||||
|
||||
@@ -223,7 +170,7 @@ namespace MQTTnet.Tests.Client
|
||||
await managedClient.SubscribeAsync("unsubscribedThenSubscribed");
|
||||
|
||||
//wait a bit for the subscriptions to become established before the messages are published
|
||||
await Task.Delay(500);
|
||||
await LongTestDelay();
|
||||
|
||||
var sendingClient = await testEnvironment.ConnectClient();
|
||||
|
||||
@@ -253,7 +200,7 @@ namespace MQTTnet.Tests.Client
|
||||
await connected;
|
||||
|
||||
// wait a bit so that the managed client can reestablish the subscriptions
|
||||
await Task.Delay(500);
|
||||
await LongTestDelay();
|
||||
|
||||
received = SetupReceivingOfMessages(managedClient, 2);
|
||||
|
||||
@@ -269,28 +216,14 @@ namespace MQTTnet.Tests.Client
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer().ConfigureAwait(false);
|
||||
|
||||
var sendingClient = await testEnvironment.ConnectClient().ConfigureAwait(false);
|
||||
await sendingClient.PublishAsync(
|
||||
new MqttApplicationMessage
|
||||
{
|
||||
Topic = "topic",
|
||||
Payload = new byte[] { 1 },
|
||||
Retain = true
|
||||
});
|
||||
|
||||
// Wait a bit for the retained message to be available
|
||||
await Task.Delay(1000);
|
||||
|
||||
await sendingClient.DisconnectAsync();
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
// Prepare retained messages.
|
||||
await server.InjectApplicationMessage(testEnvironment.Factory.CreateApplicationMessageBuilder().WithTopic("topic").WithPayload("payload").WithRetainFlag().Build());
|
||||
|
||||
// Now use the managed client and check if subscriptions get cleared properly.
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort);
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedMqttClient();
|
||||
var receivedManagedMessages = new List<MqttApplicationMessage>();
|
||||
var managedClient = new ManagedMqttClient(testEnvironment.CreateClient(), new MqttNetEventLogger());
|
||||
managedClient.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
receivedManagedMessages.Add(e.ApplicationMessage);
|
||||
@@ -299,19 +232,21 @@ namespace MQTTnet.Tests.Client
|
||||
|
||||
await managedClient.SubscribeAsync("topic");
|
||||
|
||||
await managedClient.StartAsync(new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).WithAutoReconnectDelay(TimeSpan.FromSeconds(1)).Build());
|
||||
var managedClientOptions = testEnvironment.CreateDefaultManagedMqttClientOptions();
|
||||
managedClientOptions.ClientOptions.CleanSession = false;
|
||||
await managedClient.StartAsync(managedClientOptions);
|
||||
|
||||
await Task.Delay(1000);
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.AreEqual(1, receivedManagedMessages.Count);
|
||||
|
||||
await managedClient.StopAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
await LongTestDelay();
|
||||
|
||||
await managedClient.StartAsync(new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).WithAutoReconnectDelay(TimeSpan.FromSeconds(1)).Build());
|
||||
await managedClient.StartAsync(managedClientOptions);
|
||||
|
||||
await Task.Delay(1000);
|
||||
await LongTestDelay();
|
||||
|
||||
// After reconnect and then some delay, the retained message must not be received,
|
||||
// showing that the subscriptions were cleared
|
||||
@@ -319,7 +254,9 @@ namespace MQTTnet.Tests.Client
|
||||
|
||||
// Make sure that it gets received after subscribing again.
|
||||
await managedClient.SubscribeAsync("topic");
|
||||
await Task.Delay(500);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.AreEqual(2, receivedManagedMessages.Count);
|
||||
}
|
||||
}
|
||||
@@ -331,6 +268,8 @@ namespace MQTTnet.Tests.Client
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
// Use a long connection check interval to verify that the subscriptions
|
||||
// do not depend on the connection check interval anymore
|
||||
var connectionCheckInterval = TimeSpan.FromSeconds(10);
|
||||
@@ -361,6 +300,8 @@ namespace MQTTnet.Tests.Client
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = await CreateManagedClientAsync(testEnvironment);
|
||||
|
||||
var sendingClient = await testEnvironment.ConnectClient();
|
||||
@@ -387,14 +328,12 @@ namespace MQTTnet.Tests.Client
|
||||
}
|
||||
}
|
||||
|
||||
async Task<ManagedMqttClient> CreateManagedClientAsync(
|
||||
async Task<IManagedMqttClient> CreateManagedClientAsync(
|
||||
TestEnvironment testEnvironment,
|
||||
IMqttClient underlyingClient = null,
|
||||
TimeSpan? connectionCheckInterval = null,
|
||||
string host = "localhost")
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer(host, testEnvironment.ServerPort);
|
||||
|
||||
var managedOptions = new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).Build();
|
||||
@@ -404,46 +343,31 @@ namespace MQTTnet.Tests.Client
|
||||
// at connection check intervals
|
||||
managedOptions.ConnectionCheckInterval = connectionCheckInterval ?? TimeSpan.FromSeconds(0.1);
|
||||
|
||||
var managedClient = new ManagedMqttClient(underlyingClient ?? testEnvironment.CreateClient(), new MqttNetEventLogger());
|
||||
var managedClient = testEnvironment.CreateManagedMqttClient(underlyingClient ?? testEnvironment.CreateClient());
|
||||
|
||||
var connected = GetConnectedTask(managedClient);
|
||||
|
||||
await managedClient.StartAsync(managedOptions);
|
||||
|
||||
|
||||
await connected;
|
||||
|
||||
return managedClient;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a task that will finish when the
|
||||
/// <paramref
|
||||
/// name="managedClient" />
|
||||
/// has connected
|
||||
/// </summary>
|
||||
Task GetConnectedTask(ManagedMqttClient managedClient)
|
||||
static Task GetConnectedTask(IManagedMqttClient managedClient)
|
||||
{
|
||||
var connected = new TaskCompletionSource<bool>();
|
||||
var promise = new TaskCompletionSource<bool>();
|
||||
|
||||
managedClient.ConnectedAsync += e =>
|
||||
{
|
||||
connected.TrySetResult(true);
|
||||
promise.TrySetResult(true);
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
return connected.Task;
|
||||
return promise.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a task that will return the messages received on
|
||||
/// <paramref
|
||||
/// name="managedClient" />
|
||||
/// when
|
||||
/// <paramref
|
||||
/// name="expectedNumberOfMessages" />
|
||||
/// have been received
|
||||
/// </summary>
|
||||
Task<List<MqttApplicationMessage>> SetupReceivingOfMessages(ManagedMqttClient managedClient, int expectedNumberOfMessages)
|
||||
Task<List<MqttApplicationMessage>> SetupReceivingOfMessages(IManagedMqttClient managedClient, int expectedNumberOfMessages)
|
||||
{
|
||||
var receivedMessages = new List<MqttApplicationMessage>();
|
||||
var result = new AsyncTaskCompletionSource<List<MqttApplicationMessage>>();
|
||||
@@ -466,7 +390,7 @@ namespace MQTTnet.Tests.Client
|
||||
|
||||
public class ManagedMqttClientTestStorage : IManagedMqttClientStorage
|
||||
{
|
||||
IList<ManagedMqttApplicationMessage> _messages;
|
||||
IList<ManagedMqttApplicationMessage> _messages = new List<ManagedMqttApplicationMessage>();
|
||||
|
||||
public int GetMessageCount()
|
||||
{
|
||||
@@ -475,11 +399,6 @@ namespace MQTTnet.Tests.Client
|
||||
|
||||
public Task<IList<ManagedMqttApplicationMessage>> LoadQueuedMessagesAsync()
|
||||
{
|
||||
if (_messages == null)
|
||||
{
|
||||
_messages = new List<ManagedMqttApplicationMessage>();
|
||||
}
|
||||
|
||||
return Task.FromResult(_messages);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Extensions.ManagedClient;
|
||||
using MQTTnet.Implementations;
|
||||
|
||||
namespace MQTTnet.Tests.ManagedMqttClient
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class ManagedMqttClient_Event_Tests : BaseTestClass
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task Connecting_Should_Fire_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedClient();
|
||||
|
||||
var eventFired = false;
|
||||
managedClient.ConnectedAsync += e =>
|
||||
{
|
||||
eventFired = true;
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
await managedClient.StartAsync(testEnvironment.CreateDefaultManagedMqttClientOptions());
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.IsTrue(eventFired);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Connecting_To_Invalid_Server_Should_Fire_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedMqttClient();
|
||||
|
||||
ConnectingFailedEventArgs connectingFailedEventArgs = null;
|
||||
managedClient.ConnectingFailedAsync += args =>
|
||||
{
|
||||
connectingFailedEventArgs = args;
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
await managedClient.StartAsync(
|
||||
new ManagedMqttClientOptions
|
||||
{
|
||||
ClientOptions = testEnvironment.Factory.CreateClientOptionsBuilder().WithTimeout(TimeSpan.FromSeconds(2)).WithTcpServer("wrong_server", 1234).Build()
|
||||
});
|
||||
|
||||
SpinWait.SpinUntil(() => connectingFailedEventArgs != null, 10000);
|
||||
|
||||
// The wrong server must be reported in general.
|
||||
Assert.IsNotNull(connectingFailedEventArgs);
|
||||
Assert.IsNotNull(connectingFailedEventArgs.Exception);
|
||||
Assert.IsNull(connectingFailedEventArgs.ConnectResult);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Disconnect_Should_Fire_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedClient();
|
||||
|
||||
var eventFired = false;
|
||||
managedClient.DisconnectedAsync += e =>
|
||||
{
|
||||
eventFired = true;
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
await managedClient.StartAsync(testEnvironment.CreateDefaultManagedMqttClientOptions());
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
await server.StopAsync();
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.IsTrue(eventFired);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Enqueueing_Should_Fire_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedClient();
|
||||
|
||||
var eventFired = false;
|
||||
managedClient.ApplicationMessageEnqueueingAsync += e =>
|
||||
{
|
||||
eventFired = true;
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
await managedClient.EnqueueAsync("A");
|
||||
|
||||
Assert.IsTrue(eventFired);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Subscription_Should_Fire_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedClient();
|
||||
|
||||
await managedClient.SubscribeAsync("A");
|
||||
|
||||
var eventFired = false;
|
||||
managedClient.SubscribeProcessedAsync += e =>
|
||||
{
|
||||
eventFired = e.Options.TopicFilters[0].Topic == "A";
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
await managedClient.StartAsync(testEnvironment.CreateDefaultManagedMqttClientOptions());
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.IsTrue(eventFired);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Unsubscription_Should_Fire_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedClient();
|
||||
|
||||
await managedClient.SubscribeAsync("A");
|
||||
|
||||
var eventFired = false;
|
||||
managedClient.UnsubscribeProcessedAsync += e =>
|
||||
{
|
||||
eventFired = e.Options.TopicFilters[0] == "A";
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
await managedClient.StartAsync(testEnvironment.CreateDefaultManagedMqttClientOptions());
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
await managedClient.UnsubscribeAsync("A");
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.IsTrue(eventFired);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Extensions.ManagedClient;
|
||||
using MQTTnet.Implementations;
|
||||
using MQTTnet.Server;
|
||||
|
||||
namespace MQTTnet.Tests.ManagedMqttClient
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class ManagedMqttClient_Messages_Tests : BaseTestClass
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task Drop_New_Messages_On_Full_Queue()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedMqttClient();
|
||||
|
||||
var clientOptions = new ManagedMqttClientOptionsBuilder().WithClientOptions(o => o.WithTcpServer("localhost"))
|
||||
.WithMaxPendingMessages(5)
|
||||
.WithPendingMessagesOverflowStrategy(MqttPendingMessagesOverflowStrategy.DropNewMessage);
|
||||
|
||||
await managedClient.StartAsync(clientOptions.Build());
|
||||
|
||||
await managedClient.EnqueueAsync("1");
|
||||
await managedClient.EnqueueAsync("2");
|
||||
await managedClient.EnqueueAsync("3");
|
||||
await managedClient.EnqueueAsync("4");
|
||||
await managedClient.EnqueueAsync("5");
|
||||
await managedClient.EnqueueAsync("6");
|
||||
await managedClient.EnqueueAsync("7");
|
||||
await managedClient.EnqueueAsync("8");
|
||||
|
||||
Assert.AreEqual(5, managedClient.EnqueuedApplicationMessagesCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Drop_Old_Messages_On_Full_Queue()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = testEnvironment.CreateManagedMqttClient();
|
||||
|
||||
var clientOptions = new ManagedMqttClientOptionsBuilder().WithClientOptions(o => o.WithTcpServer("localhost"))
|
||||
.WithMaxPendingMessages(5)
|
||||
.WithPendingMessagesOverflowStrategy(MqttPendingMessagesOverflowStrategy.DropOldestQueuedMessage);
|
||||
|
||||
await managedClient.StartAsync(clientOptions.Build());
|
||||
|
||||
await managedClient.EnqueueAsync("1");
|
||||
await managedClient.EnqueueAsync("2");
|
||||
await managedClient.EnqueueAsync("3");
|
||||
await managedClient.EnqueueAsync("4");
|
||||
await managedClient.EnqueueAsync("5");
|
||||
await managedClient.EnqueueAsync("6");
|
||||
await managedClient.EnqueueAsync("7");
|
||||
await managedClient.EnqueueAsync("8");
|
||||
|
||||
Assert.AreEqual(5, managedClient.EnqueuedApplicationMessagesCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Preserve_Order_Of_Subscriptions()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
// Prepare the retained messages.
|
||||
await server.InjectApplicationMessage(testEnvironment.Factory.CreateApplicationMessageBuilder().WithTopic("A").WithPayload("P").WithRetainFlag().Build());
|
||||
await server.InjectApplicationMessage(testEnvironment.Factory.CreateApplicationMessageBuilder().WithTopic("B").WithPayload("P").WithRetainFlag().Build());
|
||||
await server.InjectApplicationMessage(testEnvironment.Factory.CreateApplicationMessageBuilder().WithTopic("C").WithPayload("P").WithRetainFlag().Build());
|
||||
await server.InjectApplicationMessage(testEnvironment.Factory.CreateApplicationMessageBuilder().WithTopic("3").WithPayload("P").WithRetainFlag().Build());
|
||||
await server.InjectApplicationMessage(testEnvironment.Factory.CreateApplicationMessageBuilder().WithTopic("2").WithPayload("P").WithRetainFlag().Build());
|
||||
await server.InjectApplicationMessage(testEnvironment.Factory.CreateApplicationMessageBuilder().WithTopic("1").WithPayload("P").WithRetainFlag().Build());
|
||||
|
||||
// Subscribe to the retained messages in a defined order.
|
||||
var managedClient = testEnvironment.CreateManagedMqttClient();
|
||||
|
||||
var applicationMessages = new List<MqttApplicationMessage>();
|
||||
managedClient.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
applicationMessages.Add(e.ApplicationMessage);
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
};
|
||||
|
||||
await managedClient.SubscribeAsync("B");
|
||||
await managedClient.SubscribeAsync("C");
|
||||
await managedClient.SubscribeAsync("A");
|
||||
await managedClient.SubscribeAsync("2");
|
||||
await managedClient.SubscribeAsync("1");
|
||||
await managedClient.SubscribeAsync("3");
|
||||
|
||||
await managedClient.StartAsync(testEnvironment.CreateDefaultManagedMqttClientOptions()).ConfigureAwait(false);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
var order = string.Join(string.Empty, applicationMessages.Select(a => a.Topic));
|
||||
|
||||
Assert.AreEqual("BCA213", order);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
testEnvironment.TrackServerReceivedApplicationMessages = true;
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = await testEnvironment.StartManagedClient();
|
||||
|
||||
await managedClient.EnqueueAsync(testEnvironment.Factory.CreateApplicationMessageBuilder().WithTopic("TEST").Build());
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.AreEqual(1, testEnvironment.ServerReceivedApplicationMessages.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#region
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -11,6 +13,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Extensions.ManagedClient;
|
||||
using MQTTnet.Extensions.Rpc;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Implementations;
|
||||
@@ -18,6 +21,8 @@ using MQTTnet.LowLevelClient;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace MQTTnet.Tests.Mockups
|
||||
{
|
||||
public sealed class TestEnvironment : IDisposable
|
||||
@@ -27,6 +32,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
readonly List<Exception> _exceptions = new List<Exception>();
|
||||
readonly List<ILowLevelMqttClient> _lowLevelClients = new List<ILowLevelMqttClient>();
|
||||
readonly List<IManagedMqttClient> _managedClients = new List<IManagedMqttClient>();
|
||||
readonly MqttProtocolVersion _protocolVersion;
|
||||
readonly List<string> _serverErrors = new List<string>();
|
||||
|
||||
@@ -88,8 +94,12 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
public int ServerPort { get; set; }
|
||||
|
||||
public List<MqttApplicationMessage> ServerReceivedApplicationMessages { get; } = new List<MqttApplicationMessage>();
|
||||
|
||||
public TestContext TestContext { get; }
|
||||
|
||||
public bool TrackServerReceivedApplicationMessages { get; set; }
|
||||
|
||||
public Task<IMqttClient> ConnectClient()
|
||||
{
|
||||
return ConnectClient(Factory.CreateClientOptionsBuilder().WithProtocolVersion(_protocolVersion));
|
||||
@@ -109,7 +119,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
configureOptions.Invoke(optionsBuilder);
|
||||
|
||||
var options = optionsBuilder.Build();
|
||||
|
||||
|
||||
var client = CreateClient();
|
||||
|
||||
if (timeout == TimeSpan.Zero)
|
||||
@@ -137,7 +147,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
options = options.WithTcpServer("127.0.0.1", ServerPort);
|
||||
|
||||
var client = CreateClient();
|
||||
|
||||
|
||||
if (timeout == TimeSpan.Zero)
|
||||
{
|
||||
await client.ConnectAsync(options.Build()).ConfigureAwait(false);
|
||||
@@ -161,7 +171,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
}
|
||||
|
||||
var client = CreateClient();
|
||||
|
||||
|
||||
if (timeout == TimeSpan.Zero)
|
||||
{
|
||||
await client.ConnectAsync(options).ConfigureAwait(false);
|
||||
@@ -227,6 +237,11 @@ namespace MQTTnet.Tests.Mockups
|
||||
}
|
||||
}
|
||||
|
||||
public ManagedMqttClientOptions CreateDefaultManagedMqttClientOptions()
|
||||
{
|
||||
return Factory.CreateManagedMqttClientOptionsBuilder().WithClientOptions(Factory.CreateClientOptionsBuilder().WithTcpServer("localhost", ServerPort).Build()).Build();
|
||||
}
|
||||
|
||||
public ILowLevelMqttClient CreateLowLevelClient()
|
||||
{
|
||||
lock (_clients)
|
||||
@@ -238,6 +253,21 @@ namespace MQTTnet.Tests.Mockups
|
||||
}
|
||||
}
|
||||
|
||||
public IManagedMqttClient CreateManagedClient()
|
||||
{
|
||||
return Factory.CreateManagedMqttClient(CreateClient());
|
||||
}
|
||||
|
||||
public IManagedMqttClient CreateManagedMqttClient()
|
||||
{
|
||||
return Factory.CreateManagedMqttClient(CreateClient(), ClientLogger);
|
||||
}
|
||||
|
||||
public IManagedMqttClient CreateManagedMqttClient(IMqttClient client)
|
||||
{
|
||||
return Factory.CreateManagedMqttClient(client, ClientLogger);
|
||||
}
|
||||
|
||||
public MqttServer CreateServer(MqttServerOptions options)
|
||||
{
|
||||
if (Server != null)
|
||||
@@ -249,6 +279,11 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
Server = Factory.CreateMqttServer(options, logger);
|
||||
|
||||
if (TrackServerReceivedApplicationMessages)
|
||||
{
|
||||
Server.InterceptingPublishAsync += ServerOnInterceptingPublishAsync;
|
||||
}
|
||||
|
||||
Server.ValidatingConnectionAsync += e =>
|
||||
{
|
||||
if (TestContext != null)
|
||||
@@ -285,6 +320,18 @@ namespace MQTTnet.Tests.Mockups
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var managedMqttClient in _managedClients)
|
||||
{
|
||||
try
|
||||
{
|
||||
managedMqttClient.StopAsync().Wait();
|
||||
}
|
||||
finally
|
||||
{
|
||||
managedMqttClient.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var lowLevelMqttClient in _lowLevelClients)
|
||||
{
|
||||
lowLevelMqttClient.Dispose();
|
||||
@@ -311,6 +358,13 @@ namespace MQTTnet.Tests.Mockups
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IManagedMqttClient> StartManagedClient()
|
||||
{
|
||||
var managedClient = Factory.CreateManagedMqttClient(CreateClient());
|
||||
await managedClient.StartAsync(CreateDefaultManagedMqttClientOptions());
|
||||
return managedClient;
|
||||
}
|
||||
|
||||
public Task<MqttServer> StartServer()
|
||||
{
|
||||
return StartServer(Factory.CreateServerOptionsBuilder());
|
||||
@@ -325,7 +379,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
var options = optionsBuilder.Build();
|
||||
var server = CreateServer(options);
|
||||
await server.StartAsync();
|
||||
|
||||
|
||||
// The OS has chosen the port to we have to properly expose it to the tests.
|
||||
ServerPort = options.DefaultEndpointOptions.Port;
|
||||
return server;
|
||||
@@ -344,7 +398,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
var options = optionsBuilder.Build();
|
||||
var server = CreateServer(options);
|
||||
await server.StartAsync();
|
||||
|
||||
|
||||
// The OS has chosen the port to we have to properly expose it to the tests.
|
||||
ServerPort = options.DefaultEndpointOptions.Port;
|
||||
return server;
|
||||
@@ -380,5 +434,15 @@ namespace MQTTnet.Tests.Mockups
|
||||
_exceptions.Add(exception);
|
||||
}
|
||||
}
|
||||
|
||||
Task ServerOnInterceptingPublishAsync(InterceptingPublishEventArgs arg)
|
||||
{
|
||||
lock (ServerReceivedApplicationMessages)
|
||||
{
|
||||
ServerReceivedApplicationMessages.Add(arg.ApplicationMessage);
|
||||
}
|
||||
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user