mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-11-05 22:16:32 +08:00
Improve performance and drop support for old frameworks (#2068)
* Remove WebSocket4Net extension library * Remove UWP support * Drop support for all old frameworks * Update CI * Update CI * Update CI * Update CI * Remove obsolete code * Set default protocol version to 5.0.0 * Remove obsolete tests * Remove old dependencies * Reset release notes * Move server to dedicated project * Fix unit tests * Update and cleanup nuget packages * Fix unit tests Refactor code * No longer throw exception when receiving non success CONNACK * Enable nuget signing * Enable nuget signing * Enable nuget signing * Enable nuget signing * Enable nuget signing * Enable nuget signing * Enable nuget signing * Enable nuget signing * Enable code signing * Enable code signing * Enable code signing * Fix client endpoint handling * Improve CI * Fix CI * Fix CI * Fix CI * Fix CI * Import changes from version 4 * Cleanup target frameworks and remove obsolete code * Drop support for dotnet7.0 * Remove managed client * Version5 auditmode (#2016) Added NuGet audit mode and some other settings to get informed about security issues. * Address warnings from analyzers * Support for ReadOnlySequence as payload (#2046) * use ReadOnlySequence as payload * fix build * fix build * skip sign in forks * remove unnecessary owner * tests and extensions * remove test * simplify WritePacketBuffer, remove unused helper * Adjust namespaces * Fix build errors * Import latest fixes from main branch * Adjust namespaces --------- Co-authored-by: SeppPenner <HansM2013@gmx.de> Co-authored-by: Martin Regen <mregen@microsoft.com>
This commit is contained in:
co-authored by
SeppPenner
Martin Regen
parent
e18a91a4b5
commit
980a5d0a6d
@@ -0,0 +1,50 @@
|
||||
// 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.Tasks;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
using MQTTnet.Adapter;
|
||||
using MQTTnet.AspNetCore;
|
||||
using MQTTnet.Diagnostics.Logger;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Server;
|
||||
|
||||
namespace MQTTnet.Tests.ASP.Mockups;
|
||||
|
||||
public sealed class ConnectionHandlerMockup : IMqttServerAdapter
|
||||
{
|
||||
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
|
||||
public TaskCompletionSource<MqttConnectionContext> Context { get; } = new();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public async Task OnConnectedAsync(ConnectionContext connection)
|
||||
{
|
||||
try
|
||||
{
|
||||
var formatter = new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535));
|
||||
var context = new MqttConnectionContext(formatter, connection);
|
||||
Context.TrySetResult(context);
|
||||
|
||||
await ClientHandler(context);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Context.TrySetException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public Task StartAsync(MqttServerOptions options, IMqttNetLogger logger)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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.IO.Pipelines;
|
||||
|
||||
namespace MQTTnet.Tests.ASP.Mockups
|
||||
{
|
||||
public sealed class DuplexPipeMockup : IDuplexPipe
|
||||
{
|
||||
public DuplexPipeMockup()
|
||||
{
|
||||
var pool = new LimitedMemoryPool();
|
||||
var pipeOptions = new PipeOptions(pool);
|
||||
Receive = new Pipe(pipeOptions);
|
||||
Send = new Pipe(pipeOptions);
|
||||
}
|
||||
|
||||
PipeReader IDuplexPipe.Input => Receive.Reader;
|
||||
|
||||
PipeWriter IDuplexPipe.Output => Send.Writer;
|
||||
|
||||
public Pipe Receive { get; }
|
||||
|
||||
public Pipe Send { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// 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.Buffers;
|
||||
|
||||
namespace MQTTnet.Tests.ASP.Mockups
|
||||
{
|
||||
public sealed class LimitedMemoryPool : MemoryPool<byte>
|
||||
{
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
}
|
||||
|
||||
public override IMemoryOwner<byte> Rent(int minBufferSize = -1)
|
||||
{
|
||||
return new MemoryOwner(minBufferSize);
|
||||
}
|
||||
|
||||
public override int MaxBufferSize { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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.Buffers;
|
||||
|
||||
namespace MQTTnet.Tests.ASP.Mockups
|
||||
{
|
||||
public sealed class MemoryOwner : IMemoryOwner<byte>
|
||||
{
|
||||
readonly byte[] _raw;
|
||||
|
||||
public MemoryOwner(int size)
|
||||
{
|
||||
if (size <= 0)
|
||||
{
|
||||
size = 1024;
|
||||
}
|
||||
|
||||
if (size > 4096)
|
||||
{
|
||||
size = 4096;
|
||||
}
|
||||
|
||||
_raw = ArrayPool<byte>.Shared.Rent(size);
|
||||
Memory = _raw;
|
||||
}
|
||||
|
||||
public Memory<byte> Memory { get; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(_raw);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// 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.Buffers;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.AspNetCore;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Tests.ASP.Mockups;
|
||||
using MQTTnet.Tests.Helpers;
|
||||
|
||||
namespace MQTTnet.Tests.ASP
|
||||
{
|
||||
[TestClass]
|
||||
public class MqttConnectionContextTest
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task TestCorruptedConnectPacket()
|
||||
{
|
||||
var writer = new MqttBufferWriter(4096, 65535);
|
||||
var serializer = new MqttPacketFormatterAdapter(writer);
|
||||
var pipe = new DuplexPipeMockup();
|
||||
var connection = new DefaultConnectionContext();
|
||||
connection.Transport = pipe;
|
||||
var ctx = new MqttConnectionContext(serializer, connection);
|
||||
|
||||
await pipe.Receive.Writer.WriteAsync(writer.AddMqttHeader(MqttControlPacketType.Connect, Array.Empty<byte>()));
|
||||
|
||||
await Assert.ThrowsExceptionAsync<MqttProtocolViolationException>(() => ctx.ReceivePacketAsync(CancellationToken.None));
|
||||
|
||||
// the first exception should complete the pipes so if someone tries to use the connection after that it should throw immidiatly
|
||||
await Assert.ThrowsExceptionAsync<InvalidOperationException>(() => ctx.ReceivePacketAsync(CancellationToken.None));
|
||||
}
|
||||
|
||||
// TODO: Fix test
|
||||
// [TestMethod]
|
||||
// public async Task TestEndpoint()
|
||||
// {
|
||||
// var mockup = new ConnectionHandlerMockup();
|
||||
//
|
||||
// using (var host = new WebHostBuilder().UseKestrel(kestrel => kestrel.ListenLocalhost(1883, listener => listener.Use((ctx, next) => mockup.OnConnectedAsync(ctx))))
|
||||
// .UseStartup<Startup>()
|
||||
// .ConfigureServices(
|
||||
// (hostContext, services) =>
|
||||
// {
|
||||
// services.AddHostedMqttServer(o => o.WithoutDefaultEndpoint());
|
||||
// services.AddSingleton<IMqttServerAdapter>(mockup);
|
||||
// })
|
||||
// .Build())
|
||||
//
|
||||
// using (var client = new MqttFactory().CreateMqttClient())
|
||||
// {
|
||||
// host.Start();
|
||||
// await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("localhost").Build(), CancellationToken.None);
|
||||
//
|
||||
// var ctx = await mockup.Context.Task;
|
||||
//
|
||||
// var ep = IPEndPoint.Parse(ctx.Endpoint);
|
||||
// Assert.IsNotNull(ep);
|
||||
//
|
||||
// Assert.IsNotNull(ctx);
|
||||
// }
|
||||
// }
|
||||
|
||||
// COMMENTED OUT DUE TO DEAD LOCK? OR VERY VERY SLOW PERFORMANCE ON LOCAL DEV MACHINE. TEST WAS STILL RUNNING AFTER SEVERAL MINUTES!
|
||||
//[TestMethod]
|
||||
//public async Task TestParallelWrites()
|
||||
//{
|
||||
// var serializer = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311);
|
||||
// var pipe = new DuplexPipeMockup();
|
||||
// var connection = new DefaultConnectionContext();
|
||||
// connection.Transport = pipe;
|
||||
// var ctx = new MqttConnectionContext(serializer, connection);
|
||||
|
||||
// var tasks = Enumerable.Range(1, 100).Select(_ => Task.Run(async () =>
|
||||
// {
|
||||
// for (int i = 0; i < 100; i++)
|
||||
// {
|
||||
// await ctx.SendPacketAsync(new MqttPublishPacket(), TimeSpan.Zero, CancellationToken.None).ConfigureAwait(false);
|
||||
// }
|
||||
// }));
|
||||
|
||||
// await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
//}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestLargePacket()
|
||||
{
|
||||
var serializer = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311, new MqttBufferWriter(4096, 65535));
|
||||
var pipe = new DuplexPipeMockup();
|
||||
var connection = new DefaultConnectionContext();
|
||||
connection.Transport = pipe;
|
||||
var ctx = new MqttConnectionContext(serializer, connection);
|
||||
|
||||
await ctx.SendPacketAsync(new MqttPublishPacket { PayloadSegment = new byte[20_000] }, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var readResult = await pipe.Send.Reader.ReadAsync();
|
||||
Assert.IsTrue(readResult.Buffer.Length > 20000);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestReceivePacketAsyncThrowsWhenReaderCompleted()
|
||||
{
|
||||
var serializer = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311, new MqttBufferWriter(4096, 65535));
|
||||
var pipe = new DuplexPipeMockup();
|
||||
var connection = new DefaultConnectionContext();
|
||||
connection.Transport = pipe;
|
||||
var ctx = new MqttConnectionContext(serializer, connection);
|
||||
|
||||
pipe.Receive.Writer.Complete();
|
||||
|
||||
await Assert.ThrowsExceptionAsync<MqttCommunicationException>(() => ctx.ReceivePacketAsync(CancellationToken.None));
|
||||
}
|
||||
|
||||
class Startup
|
||||
{
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// 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.Buffers;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.AspNetCore;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Packets;
|
||||
|
||||
namespace MQTTnet.Tests.ASP;
|
||||
|
||||
[TestClass]
|
||||
public sealed class ReaderExtensionsTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestTryDeserialize()
|
||||
{
|
||||
var serializer = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311, new MqttBufferWriter(4096, 65535));
|
||||
|
||||
var buffer = serializer.Encode(new MqttPublishPacket { Topic = "a", PayloadSegment = new byte[5] }).Join();
|
||||
|
||||
var sequence = new ReadOnlySequence<byte>(buffer.Array, buffer.Offset, buffer.Count);
|
||||
|
||||
var part = sequence;
|
||||
var consumed = part.Start;
|
||||
var observed = part.Start;
|
||||
var read = 0;
|
||||
|
||||
part = sequence.Slice(sequence.Start, 0); // empty message should fail
|
||||
var result = serializer.TryDecode(part, out _, out consumed, out observed, out read);
|
||||
Assert.IsFalse(result);
|
||||
|
||||
part = sequence.Slice(sequence.Start, 1); // partial fixed header should fail
|
||||
result = serializer.TryDecode(part, out _, out consumed, out observed, out read);
|
||||
Assert.IsFalse(result);
|
||||
|
||||
part = sequence.Slice(sequence.Start, 4); // partial body should fail
|
||||
result = serializer.TryDecode(part, out _, out consumed, out observed, out read);
|
||||
Assert.IsFalse(result);
|
||||
|
||||
part = sequence; // complete msg should work
|
||||
result = serializer.TryDecode(part, out _, out consumed, out observed, out read);
|
||||
Assert.IsTrue(result);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.LowLevelClient;
|
||||
using MQTTnet.Packets;
|
||||
@@ -27,7 +26,7 @@ namespace MQTTnet.Tests.Clients.LowLevelMqttClient
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var lowLevelClient = factory.CreateLowLevelMqttClient();
|
||||
|
||||
await lowLevelClient.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build(), CancellationToken.None);
|
||||
@@ -48,7 +47,7 @@ namespace MQTTnet.Tests.Clients.LowLevelMqttClient
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var lowLevelClient = testEnvironment.Factory.CreateLowLevelMqttClient();
|
||||
var lowLevelClient = testEnvironment.ClientFactory.CreateLowLevelMqttClient();
|
||||
|
||||
await lowLevelClient.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build(), CancellationToken.None);
|
||||
|
||||
@@ -60,7 +59,7 @@ namespace MQTTnet.Tests.Clients.LowLevelMqttClient
|
||||
[ExpectedException(typeof(MqttCommunicationException))]
|
||||
public async Task Connect_To_Not_Existing_Broker()
|
||||
{
|
||||
var client = new MqttFactory().CreateLowLevelMqttClient();
|
||||
var client = new MqttClientFactory().CreateLowLevelMqttClient();
|
||||
var options = new MqttClientOptionsBuilder().WithTcpServer("localhost").Build();
|
||||
|
||||
await client.ConnectAsync(options, CancellationToken.None).ConfigureAwait(false);
|
||||
@@ -70,7 +69,7 @@ namespace MQTTnet.Tests.Clients.LowLevelMqttClient
|
||||
[ExpectedException(typeof(MqttCommunicationException))]
|
||||
public async Task Connect_To_Wrong_Host()
|
||||
{
|
||||
var client = new MqttFactory().CreateLowLevelMqttClient();
|
||||
var client = new MqttClientFactory().CreateLowLevelMqttClient();
|
||||
var options = new MqttClientOptionsBuilder().WithTcpServer("123.456.789.10").Build();
|
||||
|
||||
await client.ConnectAsync(options, CancellationToken.None).ConfigureAwait(false);
|
||||
@@ -166,7 +165,7 @@ namespace MQTTnet.Tests.Clients.LowLevelMqttClient
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var lowLevelClient = factory.CreateLowLevelMqttClient();
|
||||
|
||||
await lowLevelClient.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build(), CancellationToken.None);
|
||||
|
||||
@@ -1,818 +0,0 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Extensions.ManagedClient;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
|
||||
namespace MQTTnet.Tests.Clients.ManagedMqttClient
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class ManagedMqttClient_Tests : BaseTestClass
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task Connect_To_Invalid_Server()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
|
||||
var mqttClient = testEnvironment.CreateClient();
|
||||
|
||||
var managedClient = testEnvironment.Factory.CreateManagedMqttClient(mqttClient);
|
||||
|
||||
ConnectingFailedEventArgs connectingFailedEventArgs = null;
|
||||
managedClient.ConnectingFailedAsync += args =>
|
||||
{
|
||||
connectingFailedEventArgs = args;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
[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 Expose_Custom_Connection_Error()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
server.ValidatingConnectionAsync += args =>
|
||||
{
|
||||
args.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
var managedClient = testEnvironment.Factory.CreateManagedMqttClient();
|
||||
|
||||
MqttClientDisconnectedEventArgs disconnectedArgs = null;
|
||||
managedClient.DisconnectedAsync += args =>
|
||||
{
|
||||
disconnectedArgs = args;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
var clientOptions = testEnvironment.Factory.CreateManagedMqttClientOptionsBuilder().WithClientOptions(testEnvironment.CreateDefaultClientOptions()).Build();
|
||||
await managedClient.StartAsync(clientOptions);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.IsNotNull(disconnectedArgs);
|
||||
Assert.AreEqual(MqttClientConnectResultCode.BadUserNameOrPassword, disconnectedArgs.ConnectResult.ResultCode);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ManagedClients_Will_Message_Send()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
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 MQTTnet.Extensions.ManagedClient.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 CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await receivingClient.SubscribeAsync("My/last/will");
|
||||
|
||||
// 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);
|
||||
|
||||
Assert.AreEqual(1, receivedMessagesCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Receive_While_Not_Cleanly_Disconnected()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment(MqttProtocolVersion.V500))
|
||||
{
|
||||
await testEnvironment.StartServer(o => o.WithPersistentSessions());
|
||||
|
||||
var senderClient = await testEnvironment.ConnectClient();
|
||||
|
||||
// Prepare managed client.
|
||||
var managedClient = testEnvironment.Factory.CreateManagedMqttClient();
|
||||
await managedClient.SubscribeAsync("#");
|
||||
var receivedMessages = testEnvironment.CreateApplicationMessageHandler(managedClient);
|
||||
|
||||
var managedClientOptions = new ManagedMqttClientOptions
|
||||
{
|
||||
ClientOptions = testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.WithClientId(nameof(Receive_While_Not_Cleanly_Disconnected) + "_managed")
|
||||
.WithCleanSession(false)
|
||||
.Build()
|
||||
};
|
||||
|
||||
await managedClient.StartAsync(managedClientOptions);
|
||||
await LongTestDelay();
|
||||
await LongTestDelay();
|
||||
|
||||
// Send test data.
|
||||
await senderClient.PublishStringAsync("topic1");
|
||||
await LongTestDelay();
|
||||
await LongTestDelay();
|
||||
|
||||
receivedMessages.AssertReceivedCountEquals(1);
|
||||
|
||||
// Stop the managed client but keep session at server (not clean disconnect required).
|
||||
await managedClient.StopAsync(false);
|
||||
await LongTestDelay();
|
||||
|
||||
// Send new messages in the meantime.
|
||||
await senderClient.PublishStringAsync("topic2", qualityOfServiceLevel: MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
await LongTestDelay();
|
||||
|
||||
// Start the managed client, it should receive the new message.
|
||||
await managedClient.StartAsync(managedClientOptions);
|
||||
await LongTestDelay();
|
||||
|
||||
receivedMessages.AssertReceivedCountEquals(2);
|
||||
|
||||
// Stop and start again, no new message should be received.
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
await managedClient.StopAsync(false);
|
||||
await LongTestDelay();
|
||||
await managedClient.StartAsync(managedClientOptions);
|
||||
await LongTestDelay();
|
||||
}
|
||||
|
||||
receivedMessages.AssertReceivedCountEquals(2);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Start_Stop()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = new MQTTnet.Extensions.ManagedClient.ManagedMqttClient(testEnvironment.CreateClient(), new MqttNetEventLogger());
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost", testEnvironment.ServerPort);
|
||||
|
||||
var connected = GetConnectedTask(managedClient);
|
||||
|
||||
await managedClient.StartAsync(new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).Build());
|
||||
|
||||
await connected;
|
||||
|
||||
await managedClient.StopAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
Assert.AreEqual(0, (await server.GetClientsAsync()).Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Storage_Queue_Drains()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
testEnvironment.IgnoreServerLogErrors = true;
|
||||
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var managedClient = new MQTTnet.Extensions.ManagedClient.ManagedMqttClient(testEnvironment.CreateClient(), new MqttNetEventLogger());
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost", testEnvironment.ServerPort);
|
||||
var storage = new ManagedMqttClientTestStorage();
|
||||
|
||||
var connected = GetConnectedTask(managedClient);
|
||||
|
||||
await managedClient.StartAsync(
|
||||
new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).WithStorage(storage).WithAutoReconnectDelay(TimeSpan.FromSeconds(5)).Build());
|
||||
|
||||
await connected;
|
||||
|
||||
await testEnvironment.Server.StopAsync();
|
||||
|
||||
await managedClient.EnqueueAsync("1");
|
||||
|
||||
//Message should have been added to the storage queue in PublishAsync,
|
||||
//and we are awaiting PublishAsync, so the message should already be
|
||||
//in storage at this point (i.e. no waiting).
|
||||
Assert.AreEqual(1, storage.GetMessageCount());
|
||||
|
||||
connected = GetConnectedTask(managedClient);
|
||||
|
||||
await testEnvironment.Server.StartAsync();
|
||||
|
||||
await connected;
|
||||
|
||||
//Wait 500ms here so the client has time to publish the queued message
|
||||
await Task.Delay(500);
|
||||
|
||||
Assert.AreEqual(0, storage.GetMessageCount());
|
||||
|
||||
await managedClient.StopAsync();
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Subscriptions_And_Unsubscriptions_Are_Made_And_Reestablished_At_Reconnect()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var unmanagedClient = testEnvironment.CreateClient();
|
||||
var managedClient = await CreateManagedClientAsync(testEnvironment, unmanagedClient);
|
||||
|
||||
var received = SetupReceivingOfMessages(managedClient, 2);
|
||||
|
||||
// Perform some opposing subscriptions and unsubscriptions to verify
|
||||
// that these conflicting subscriptions are handled correctly
|
||||
await managedClient.SubscribeAsync("keptSubscribed");
|
||||
await managedClient.SubscribeAsync("subscribedThenUnsubscribed");
|
||||
|
||||
await managedClient.UnsubscribeAsync("subscribedThenUnsubscribed");
|
||||
await managedClient.UnsubscribeAsync("unsubscribedThenSubscribed");
|
||||
|
||||
await managedClient.SubscribeAsync("unsubscribedThenSubscribed");
|
||||
|
||||
//wait a bit for the subscriptions to become established before the messages are published
|
||||
await Task.Delay(500);
|
||||
|
||||
var sendingClient = await testEnvironment.ConnectClient();
|
||||
|
||||
async Task PublishMessages()
|
||||
{
|
||||
await sendingClient.PublishBinaryAsync("keptSubscribed", new byte[] { 1 });
|
||||
await sendingClient.PublishBinaryAsync("subscribedThenUnsubscribed", new byte[] { 1 });
|
||||
await sendingClient.PublishBinaryAsync("unsubscribedThenSubscribed", new byte[] { 1 });
|
||||
}
|
||||
|
||||
await PublishMessages();
|
||||
|
||||
async Task AssertMessagesReceived()
|
||||
{
|
||||
var messages = await received;
|
||||
Assert.AreEqual("keptSubscribed", messages[0].Topic);
|
||||
Assert.AreEqual("unsubscribedThenSubscribed", messages[1].Topic);
|
||||
}
|
||||
|
||||
await AssertMessagesReceived();
|
||||
|
||||
var connected = GetConnectedTask(managedClient);
|
||||
|
||||
await unmanagedClient.DisconnectAsync();
|
||||
|
||||
// the managed client has to reconnect by itself
|
||||
await connected;
|
||||
|
||||
// wait a bit so that the managed client can reestablish the subscriptions
|
||||
await Task.Delay(500);
|
||||
|
||||
received = SetupReceivingOfMessages(managedClient, 2);
|
||||
|
||||
await PublishMessages();
|
||||
|
||||
// and then the same subscriptions need to exist again
|
||||
await AssertMessagesReceived();
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Subscriptions_Are_Cleared_At_Logout()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer().ConfigureAwait(false);
|
||||
|
||||
var sendingClient = await testEnvironment.ConnectClient().ConfigureAwait(false);
|
||||
await sendingClient.PublishStringAsync("topic", "A", retain: true);
|
||||
|
||||
// Wait a bit for the retained message to be available
|
||||
await LongTestDelay();
|
||||
|
||||
await sendingClient.DisconnectAsync();
|
||||
|
||||
// Now use the managed client and check if subscriptions get cleared properly.
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort);
|
||||
|
||||
var receivedManagedMessages = new List<MqttApplicationMessage>();
|
||||
|
||||
var managedClient = testEnvironment.Factory.CreateManagedMqttClient(testEnvironment.CreateClient());
|
||||
managedClient.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
receivedManagedMessages.Add(e.ApplicationMessage);
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await managedClient.SubscribeAsync("topic");
|
||||
|
||||
await managedClient.StartAsync(new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).WithAutoReconnectDelay(TimeSpan.FromSeconds(0.5)).Build());
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.AreEqual(1, receivedManagedMessages.Count);
|
||||
|
||||
await managedClient.StopAsync();
|
||||
await LongTestDelay();
|
||||
|
||||
await managedClient.StartAsync(new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).WithAutoReconnectDelay(TimeSpan.FromSeconds(0.5)).Build());
|
||||
await LongTestDelay();
|
||||
|
||||
// After reconnect and then some delay, the retained message must not be received,
|
||||
// showing that the subscriptions were cleared
|
||||
Assert.AreEqual(1, receivedManagedMessages.Count);
|
||||
|
||||
// Make sure that it gets received after subscribing again.
|
||||
await managedClient.SubscribeAsync("topic");
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.AreEqual(2, receivedManagedMessages.Count);
|
||||
}
|
||||
}
|
||||
|
||||
// This case also serves as a regression test for the previous behavior
|
||||
// that subscriptions were only published at the ConnectionCheckInterval
|
||||
[TestMethod]
|
||||
public async Task Subscriptions_Are_Published_Immediately()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
// 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);
|
||||
var receivingClient = await CreateManagedClientAsync(testEnvironment, null, connectionCheckInterval);
|
||||
var sendingClient = await testEnvironment.ConnectClient();
|
||||
|
||||
await sendingClient.PublishAsync(new MqttApplicationMessage { Topic = "topic", PayloadSegment = new ArraySegment<byte>(new byte[] { 1 }), Retain = true });
|
||||
|
||||
var subscribeTime = DateTime.UtcNow;
|
||||
|
||||
var messagesTask = SetupReceivingOfMessages(receivingClient, 1);
|
||||
|
||||
await receivingClient.SubscribeAsync("topic");
|
||||
|
||||
var messages = await messagesTask;
|
||||
|
||||
var elapsed = DateTime.UtcNow - subscribeTime;
|
||||
Assert.IsTrue(elapsed < TimeSpan.FromSeconds(1), $"Subscriptions must be activated immediately, this one took {elapsed}");
|
||||
Assert.AreEqual(messages.Single().Topic, "topic");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task ManagedClients_CanInterceptPublishedMessage_PreventingPublish()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var receivedMessagesCount = 0;
|
||||
var interceptedMessagesCount = 0;
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder()
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.Build();
|
||||
|
||||
var sendingClient = testEnvironment.CreateClient();
|
||||
var sendingManagedClient = new MQTTnet.Extensions.ManagedClient.ManagedMqttClient(sendingClient, testEnvironment.ClientLogger);
|
||||
|
||||
await sendingManagedClient.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 CompletedTask.Instance;
|
||||
};
|
||||
sendingManagedClient.InterceptPublishMessageAsync += e =>
|
||||
{
|
||||
Interlocked.Increment(ref interceptedMessagesCount);
|
||||
e.AcceptPublish = false;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await receivingClient.SubscribeAsync("My/last/will");
|
||||
|
||||
// Wait for arrival of the will message at the receiver.
|
||||
await Task.Delay(5000);
|
||||
|
||||
await sendingManagedClient.EnqueueAsync("My/last/will", "hello world");
|
||||
|
||||
// Wait for arrival of the will message at the receiver.
|
||||
await Task.Delay(5000);
|
||||
|
||||
Assert.AreEqual(0, receivedMessagesCount);
|
||||
Assert.AreEqual(1, interceptedMessagesCount);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ManagedClients_CanInterceptPublishedMessage_AllowingPublish()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var receivedMessagesCount = 0;
|
||||
var interceptedMessagesCount = 0;
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder()
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.Build();
|
||||
|
||||
var sendingClient = testEnvironment.CreateClient();
|
||||
var sendingManagedClient = new MQTTnet.Extensions.ManagedClient.ManagedMqttClient(sendingClient, testEnvironment.ClientLogger);
|
||||
|
||||
await sendingManagedClient.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 CompletedTask.Instance;
|
||||
};
|
||||
sendingManagedClient.InterceptPublishMessageAsync += e =>
|
||||
{
|
||||
Interlocked.Increment(ref interceptedMessagesCount);
|
||||
e.AcceptPublish = true;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await receivingClient.SubscribeAsync("My/last/will");
|
||||
|
||||
// Wait for arrival of the will message at the receiver.
|
||||
await Task.Delay(5000);
|
||||
|
||||
await sendingManagedClient.EnqueueAsync("My/last/will", "hello world");
|
||||
|
||||
// Wait for arrival of the will message at the receiver.
|
||||
await Task.Delay(5000);
|
||||
|
||||
Assert.AreEqual(1, receivedMessagesCount);
|
||||
Assert.AreEqual(1, interceptedMessagesCount);
|
||||
}
|
||||
}
|
||||
|
||||
// This case also serves as a regression test for the previous behavior which re-published
|
||||
// each and every existing subscriptions with every new subscription that was made
|
||||
// (causing performance problems and having the visible symptom of retained messages being received again)
|
||||
[TestMethod]
|
||||
public async Task Subscriptions_Subscribe_Only_New_Subscriptions()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var managedClient = await CreateManagedClientAsync(testEnvironment);
|
||||
|
||||
var sendingClient = await testEnvironment.ConnectClient();
|
||||
|
||||
await managedClient.SubscribeAsync("topic");
|
||||
|
||||
//wait a bit for the subscription to become established
|
||||
await Task.Delay(500);
|
||||
|
||||
await sendingClient.PublishAsync(new MqttApplicationMessage { Topic = "topic", PayloadSegment = new ArraySegment<byte>(new byte[] { 1 }), Retain = true });
|
||||
|
||||
var messages = await SetupReceivingOfMessages(managedClient, 1);
|
||||
|
||||
Assert.AreEqual(1, messages.Count);
|
||||
Assert.AreEqual("topic", messages.Single().Topic);
|
||||
|
||||
await managedClient.SubscribeAsync("anotherTopic");
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
// The subscription of the other topic must not trigger a re-subscription of the existing topic
|
||||
// (and thus renewed receiving of the retained message)
|
||||
Assert.AreEqual(1, messages.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Subscribe_Does_Not_Hang_On_Server_Stop()
|
||||
{
|
||||
var timeout = TimeSpan.FromSeconds(2);
|
||||
var testTimeout = TimeSpan.FromSeconds(timeout.TotalSeconds * 2);
|
||||
const string topic = "test_topic_2";
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
using (var managedClient = await CreateManagedClientAsync(testEnvironment, timeout: timeout))
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
bool reject = true;
|
||||
var receivedOnServer = new SemaphoreSlim(0, 1);
|
||||
var failedOnClient = new SemaphoreSlim(0, 1);
|
||||
testEnvironment.Server.InterceptingInboundPacketAsync += e =>
|
||||
{
|
||||
if (e.Packet is MqttSubscribePacket)
|
||||
{
|
||||
if (reject)
|
||||
{
|
||||
e.ProcessPacket = false;
|
||||
}
|
||||
receivedOnServer.Release();
|
||||
}
|
||||
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
managedClient.SynchronizingSubscriptionsFailedAsync += e =>
|
||||
{
|
||||
failedOnClient.Release();
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await managedClient.SubscribeAsync(topic);
|
||||
Assert.IsTrue(await receivedOnServer.WaitAsync(testTimeout));
|
||||
Assert.IsTrue(await failedOnClient.WaitAsync(testTimeout));
|
||||
|
||||
reject = false;
|
||||
await managedClient.SubscribeAsync(topic);
|
||||
Assert.IsTrue(await receivedOnServer.WaitAsync(testTimeout));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Unsubscribe_Does_Not_Hang_On_Server_Stop()
|
||||
{
|
||||
var timeout = TimeSpan.FromSeconds(2);
|
||||
var testTimeout = TimeSpan.FromSeconds(timeout.TotalSeconds * 2);
|
||||
const string topic = "test_topic_2";
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
using (var managedClient = await CreateManagedClientAsync(testEnvironment, timeout: timeout))
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
bool reject = true;
|
||||
var receivedOnServer = new SemaphoreSlim(0, 1);
|
||||
var failedOnClient = new SemaphoreSlim(0, 1);
|
||||
testEnvironment.Server.InterceptingInboundPacketAsync += e =>
|
||||
{
|
||||
if (e.Packet is MqttUnsubscribePacket)
|
||||
{
|
||||
if (reject)
|
||||
{
|
||||
e.ProcessPacket = false;
|
||||
}
|
||||
receivedOnServer.Release();
|
||||
}
|
||||
else if (e.Packet is MqttSubscribePacket)
|
||||
{
|
||||
receivedOnServer.Release();
|
||||
}
|
||||
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
managedClient.SynchronizingSubscriptionsFailedAsync += e =>
|
||||
{
|
||||
failedOnClient.Release();
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await managedClient.SubscribeAsync(topic);
|
||||
Assert.IsTrue(await receivedOnServer.WaitAsync(testTimeout));
|
||||
|
||||
await managedClient.UnsubscribeAsync(topic);
|
||||
Assert.IsTrue(await receivedOnServer.WaitAsync(testTimeout));
|
||||
Assert.IsTrue(await failedOnClient.WaitAsync(testTimeout));
|
||||
|
||||
reject = false;
|
||||
await managedClient.UnsubscribeAsync(topic);
|
||||
Assert.IsTrue(await receivedOnServer.WaitAsync(testTimeout));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish_Does_Not_Hang_On_Server_Error()
|
||||
{
|
||||
var timeout = TimeSpan.FromSeconds(2);
|
||||
var testTimeout = TimeSpan.FromSeconds(timeout.TotalSeconds * 2);
|
||||
|
||||
const string topic = "test_topic_42";
|
||||
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
using (var managedClient = await CreateManagedClientAsync(testEnvironment, timeout: timeout))
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
bool reject = true;
|
||||
var receivedOnServer = new TaskCompletionSource<object>();
|
||||
managedClient.ApplicationMessageProcessedAsync += e => Task.FromResult(reject &= e.Exception is null);
|
||||
testEnvironment.Server.InterceptingInboundPacketAsync += e =>
|
||||
{
|
||||
if (e.Packet is MqttPublishPacket)
|
||||
{
|
||||
if (reject)
|
||||
{
|
||||
e.ProcessPacket = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
receivedOnServer.TrySetResult(null);
|
||||
}
|
||||
}
|
||||
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await managedClient.EnqueueAsync(new MqttApplicationMessage { Topic = topic, PayloadSegment = new ArraySegment<byte>(new byte[] { 1 }), Retain = true, QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce });
|
||||
|
||||
var timeoutTask = Task.Delay(testTimeout);
|
||||
|
||||
var firstDone = await Task.WhenAny(receivedOnServer.Task, timeoutTask);
|
||||
Assert.AreEqual(receivedOnServer.Task, firstDone, "Client is hung on publish!");
|
||||
}
|
||||
}
|
||||
|
||||
async Task<MQTTnet.Extensions.ManagedClient.ManagedMqttClient> CreateManagedClientAsync(
|
||||
TestEnvironment testEnvironment,
|
||||
IMqttClient underlyingClient = null,
|
||||
TimeSpan? connectionCheckInterval = null,
|
||||
string host = "localhost",
|
||||
TimeSpan? timeout = null)
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer(host, testEnvironment.ServerPort);
|
||||
|
||||
if (timeout != null)
|
||||
{
|
||||
clientOptions.WithTimeout(timeout.Value);
|
||||
}
|
||||
|
||||
var managedOptions = new ManagedMqttClientOptionsBuilder().WithClientOptions(clientOptions).Build();
|
||||
|
||||
// Use a short connection check interval so that subscription operations are performed quickly
|
||||
// in order to verify against a previous implementation that performed subscriptions only
|
||||
// at connection check intervals
|
||||
managedOptions.ConnectionCheckInterval = connectionCheckInterval ?? TimeSpan.FromSeconds(0.1);
|
||||
|
||||
var managedClient = new MQTTnet.Extensions.ManagedClient.ManagedMqttClient(underlyingClient ?? testEnvironment.CreateClient(), new MqttNetEventLogger());
|
||||
|
||||
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(MQTTnet.Extensions.ManagedClient.ManagedMqttClient managedClient)
|
||||
{
|
||||
var connected = new TaskCompletionSource<bool>();
|
||||
|
||||
managedClient.ConnectedAsync += e =>
|
||||
{
|
||||
connected.TrySetResult(true);
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
return connected.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(MQTTnet.Extensions.ManagedClient.ManagedMqttClient managedClient, int expectedNumberOfMessages)
|
||||
{
|
||||
var receivedMessages = new List<MqttApplicationMessage>();
|
||||
var result = new AsyncTaskCompletionSource<List<MqttApplicationMessage>>();
|
||||
|
||||
managedClient.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
receivedMessages.Add(e.ApplicationMessage);
|
||||
|
||||
if (receivedMessages.Count == expectedNumberOfMessages)
|
||||
{
|
||||
result.TrySetResult(receivedMessages);
|
||||
}
|
||||
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
return result.Task;
|
||||
}
|
||||
}
|
||||
|
||||
public class ManagedMqttClientTestStorage : IManagedMqttClientStorage
|
||||
{
|
||||
IList<ManagedMqttApplicationMessage> _messages;
|
||||
|
||||
public int GetMessageCount()
|
||||
{
|
||||
return _messages.Count;
|
||||
}
|
||||
|
||||
public Task<IList<ManagedMqttApplicationMessage>> LoadQueuedMessagesAsync()
|
||||
{
|
||||
if (_messages == null)
|
||||
{
|
||||
_messages = new List<ManagedMqttApplicationMessage>();
|
||||
}
|
||||
|
||||
return Task.FromResult(_messages);
|
||||
}
|
||||
|
||||
public Task SaveQueuedMessagesAsync(IList<ManagedMqttApplicationMessage> messages)
|
||||
{
|
||||
_messages = messages;
|
||||
return CompletedTask.Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
@@ -24,7 +23,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
[ExpectedException(typeof(MqttCommunicationException))]
|
||||
public async Task Connect_To_Invalid_Server_Port_Not_Opened()
|
||||
{
|
||||
var client = new MqttFactory().CreateMqttClient();
|
||||
var client = new MqttClientFactory().CreateMqttClient();
|
||||
using (var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
|
||||
{
|
||||
await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", 12345).Build(), timeout.Token);
|
||||
@@ -35,7 +34,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
[ExpectedException(typeof(OperationCanceledException))]
|
||||
public async Task Connect_To_Invalid_Server_Wrong_IP()
|
||||
{
|
||||
var client = new MqttFactory().CreateMqttClient();
|
||||
var client = new MqttClientFactory().CreateMqttClient();
|
||||
using (var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(2)))
|
||||
{
|
||||
await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("1.2.3.4").Build(), timeout.Token);
|
||||
@@ -46,14 +45,14 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
[ExpectedException(typeof(MqttCommunicationException))]
|
||||
public async Task Connect_To_Invalid_Server_Wrong_Protocol()
|
||||
{
|
||||
var client = new MqttFactory().CreateMqttClient();
|
||||
var client = new MqttClientFactory().CreateMqttClient();
|
||||
await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("http://127.0.0.1", 12345).WithTimeout(TimeSpan.FromSeconds(2)).Build());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ConnectTimeout_Throws_Exception()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
using (var client = factory.CreateMqttClient())
|
||||
{
|
||||
var disconnectHandlerCalled = false;
|
||||
@@ -96,7 +95,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
|
||||
var client = await testEnvironment.ConnectClient();
|
||||
|
||||
var disconnectOptions = testEnvironment.Factory.CreateClientDisconnectOptionsBuilder().WithReason(MqttClientDisconnectOptionsReason.MessageRateTooHigh).Build();
|
||||
var disconnectOptions = testEnvironment.ClientFactory.CreateClientDisconnectOptionsBuilder().WithReason(MqttClientDisconnectOptionsReason.MessageRateTooHigh).Build();
|
||||
|
||||
// Perform a clean disconnect.
|
||||
await client.DisconnectAsync(disconnectOptions);
|
||||
@@ -124,7 +123,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
|
||||
var client = await testEnvironment.ConnectClient();
|
||||
|
||||
var disconnectOptions = testEnvironment.Factory.CreateClientDisconnectOptionsBuilder().WithReason(MqttClientDisconnectOptionsReason.MessageRateTooHigh).Build();
|
||||
var disconnectOptions = testEnvironment.ClientFactory.CreateClientDisconnectOptionsBuilder().WithReason(MqttClientDisconnectOptionsReason.MessageRateTooHigh).Build();
|
||||
|
||||
// Perform a clean disconnect.
|
||||
await client.DisconnectAsync(disconnectOptions);
|
||||
@@ -152,7 +151,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
|
||||
var client = await testEnvironment.ConnectClient();
|
||||
|
||||
var disconnectOptions = testEnvironment.Factory.CreateClientDisconnectOptionsBuilder().WithUserProperty("test_name", "test_value").Build();
|
||||
var disconnectOptions = testEnvironment.ClientFactory.CreateClientDisconnectOptionsBuilder().WithUserProperty("test_name", "test_value").Build();
|
||||
|
||||
// Perform a clean disconnect.
|
||||
await client.DisconnectAsync(disconnectOptions);
|
||||
@@ -220,7 +219,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
|
||||
var client = testEnvironment.CreateClient();
|
||||
|
||||
var response = await client.ConnectAsync(testEnvironment.CreateDefaultClientOptionsBuilder().WithoutThrowOnNonSuccessfulConnectResponse().Build());
|
||||
var response = await client.ConnectAsync(testEnvironment.CreateDefaultClientOptionsBuilder().Build());
|
||||
|
||||
Assert.IsNotNull(response);
|
||||
Assert.AreEqual(MqttClientConnectResultCode.QuotaExceeded, response.ResultCode);
|
||||
@@ -234,7 +233,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
{
|
||||
try
|
||||
{
|
||||
var mqttFactory = new MqttFactory();
|
||||
var mqttFactory = new MqttClientFactory();
|
||||
using (var mqttClient = mqttFactory.CreateMqttClient())
|
||||
{
|
||||
await mqttClient.SubscribeAsync("test", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
@@ -3,16 +3,15 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
@@ -107,7 +106,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
[TestMethod]
|
||||
public async Task Disconnect_Event_Contains_Exception()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
using (var client = factory.CreateMqttClient())
|
||||
{
|
||||
Exception ex = null;
|
||||
@@ -248,7 +247,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
[TestMethod]
|
||||
public async Task Invalid_Connect_Throws_Exception()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
using (var client = factory.CreateMqttClient())
|
||||
{
|
||||
try
|
||||
@@ -298,7 +297,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
|
||||
Assert.IsNotNull(receivedMessage);
|
||||
Assert.AreEqual("A", receivedMessage.Topic);
|
||||
Assert.AreEqual(null, receivedMessage.PayloadSegment.Array);
|
||||
Assert.AreEqual(0, receivedMessage.Payload.Length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,7 +508,7 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
|
||||
client2.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
client2TopicResults.Add(Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment.ToArray()));
|
||||
client2TopicResults.Add(Encoding.UTF8.GetString(e.ApplicationMessage.Payload.ToArray()));
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
@@ -926,54 +925,5 @@ namespace MQTTnet.Tests.Clients.MqttClient
|
||||
Assert.IsFalse(disconnectedFired);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Backward_compatible_TCP_options()
|
||||
{
|
||||
var options = new MqttClientOptionsBuilder().WithTcpServer("host", 3).Build();
|
||||
|
||||
Assert.AreEqual("host", ((MqttClientTcpOptions)options.ChannelOptions).Server);
|
||||
Assert.AreEqual(3, ((MqttClientTcpOptions)options.ChannelOptions).Port);
|
||||
|
||||
options = new MqttClientOptions
|
||||
{
|
||||
ChannelOptions = new MqttClientTcpOptions
|
||||
{
|
||||
Server = "host",
|
||||
Port = 3
|
||||
}
|
||||
};
|
||||
|
||||
Assert.AreEqual("host:3", options.ChannelOptions.ToString());
|
||||
Assert.AreEqual("host", ((MqttClientTcpOptions)options.ChannelOptions).Server);
|
||||
Assert.AreEqual(3, ((MqttClientTcpOptions)options.ChannelOptions).Port);
|
||||
|
||||
options = new MqttClientOptionsBuilder().WithEndPoint(new DnsEndPoint("host", 3)).Build();
|
||||
Assert.AreEqual("Unspecified/host:3", options.ChannelOptions.ToString());
|
||||
Assert.AreEqual("host", ((MqttClientTcpOptions)options.ChannelOptions).Server);
|
||||
Assert.AreEqual(3, ((MqttClientTcpOptions)options.ChannelOptions).Port);
|
||||
|
||||
options = new MqttClientOptionsBuilder().WithTcpServer("host").Build();
|
||||
|
||||
Assert.AreEqual("host", ((MqttClientTcpOptions)options.ChannelOptions).Server);
|
||||
Assert.AreEqual(1883, ((MqttClientTcpOptions)options.ChannelOptions).Port);
|
||||
Assert.AreEqual("Unspecified/host:1883", options.ChannelOptions.ToString());
|
||||
|
||||
options = new MqttClientOptionsBuilder().WithTlsOptions(o => o.UseTls()).WithTcpServer("host").Build();
|
||||
|
||||
Assert.AreEqual("host", ((MqttClientTcpOptions)options.ChannelOptions).Server);
|
||||
Assert.AreEqual(8883, ((MqttClientTcpOptions)options.ChannelOptions).Port);
|
||||
|
||||
options = new MqttClientOptions
|
||||
{
|
||||
ChannelOptions = new MqttClientTcpOptions
|
||||
{
|
||||
Server = "host"
|
||||
}
|
||||
};
|
||||
|
||||
Assert.AreEqual("host", ((MqttClientTcpOptions)options.ChannelOptions).Server);
|
||||
Assert.AreEqual(null, ((MqttClientTcpOptions)options.ChannelOptions).Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
|
||||
namespace MQTTnet.Tests.Clients
|
||||
{
|
||||
@@ -18,7 +17,7 @@ namespace MQTTnet.Tests.Clients
|
||||
var options = new MqttClientOptionsBuilder()
|
||||
.WithConnectionUri("mqtt://user:password@127.0.0.1")
|
||||
.Build();
|
||||
|
||||
|
||||
Assert.AreEqual("user", options.Credentials.GetUserName(null));
|
||||
Assert.IsTrue(Encoding.UTF8.GetBytes("password").SequenceEqual(options.Credentials.GetPassword(null)));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Diagnostics.Logger;
|
||||
|
||||
namespace MQTTnet.Tests.Diagnostics
|
||||
{
|
||||
@@ -44,7 +44,7 @@ namespace MQTTnet.Tests.Diagnostics
|
||||
|
||||
Assert.AreEqual(4, logMessagesCount);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void Use_Custom_Log_Id()
|
||||
{
|
||||
@@ -56,7 +56,7 @@ namespace MQTTnet.Tests.Diagnostics
|
||||
Assert.AreEqual("logId", e.LogMessage.LogId);
|
||||
Assert.AreEqual("Source1", e.LogMessage.Source);
|
||||
};
|
||||
|
||||
|
||||
childLogger.Verbose("Verbose");
|
||||
childLogger.Info("Info");
|
||||
childLogger.Warning((Exception)null, "Warning");
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
|
||||
namespace MQTTnet.Tests.Diagnostics
|
||||
@@ -20,24 +21,25 @@ namespace MQTTnet.Tests.Diagnostics
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
using (var mqttClient = testEnvironment.CreateClient())
|
||||
{
|
||||
var mqttClientOptions = testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
var mqttClientOptions = testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithClientId("CLIENT_ID") // Must be fixed.
|
||||
.WithProtocolVersion(MqttProtocolVersion.V311)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.Build();
|
||||
|
||||
var packets = new List<string>();
|
||||
|
||||
|
||||
mqttClient.InspectPacketAsync += eventArgs =>
|
||||
{
|
||||
packets.Add(eventArgs.Direction + ":" + Convert.ToBase64String(eventArgs.Buffer));
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
|
||||
|
||||
|
||||
Assert.AreEqual(2, packets.Count);
|
||||
Assert.AreEqual("Outbound:ECwABE1RVFQEAgAPACBJbnNwZWN0X0NsaWVudF9QYWNrZXRzX0NMSUVOVF9JRA==", packets[0]); // CONNECT
|
||||
Assert.AreEqual("Inbound:IAIAAA==", packets[1]); // CONNACK
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
using MQTTnet.Diagnostics.Logger;
|
||||
|
||||
namespace MQTTnet.Tests.Diagnostics
|
||||
{
|
||||
@@ -14,16 +15,16 @@ namespace MQTTnet.Tests.Diagnostics
|
||||
public void Log_With_Source()
|
||||
{
|
||||
MqttNetLogMessage logMessage = null;
|
||||
|
||||
|
||||
var logger = new MqttNetEventLogger();
|
||||
logger.LogMessagePublished += (s, e) =>
|
||||
{
|
||||
logMessage = e.LogMessage;
|
||||
};
|
||||
|
||||
|
||||
var sourceLogger = logger.WithSource("The_Source");
|
||||
sourceLogger.Info("MESSAGE", (object)null, (object)null);
|
||||
|
||||
|
||||
Assert.AreEqual("The_Source", logMessage.Source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,21 +61,21 @@ namespace MQTTnet.Tests.Extensions
|
||||
var template = new MqttTopicTemplate("A/B/{foo}/D");
|
||||
template.WithParameter("foo", "a/b");
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void AcceptsEmptyValue()
|
||||
{
|
||||
var template = new MqttTopicTemplate("A/B/{foo}/D");
|
||||
template.WithParameter("foo", "");
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(MqttProtocolViolationException))]
|
||||
public void RejectsEmptyTemplate()
|
||||
{
|
||||
var _ = new MqttTopicTemplate("");
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(ArgumentNullException))]
|
||||
public void RejectsNullTemplate()
|
||||
@@ -83,14 +83,13 @@ namespace MQTTnet.Tests.Extensions
|
||||
var _ = new MqttTopicTemplate(null);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void IgnoresEmptyParameters()
|
||||
{
|
||||
var template = new MqttTopicTemplate("A/B/{}/D");
|
||||
Assert.IsFalse(template.Parameters.Any());
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void AcceptsValidTopics()
|
||||
{
|
||||
@@ -127,6 +126,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
.WithAtLeastOnceQoS()
|
||||
.WithNoLocal()
|
||||
.Build();
|
||||
|
||||
Assert.AreEqual("A/v1/+/F", filter.Topic);
|
||||
}
|
||||
|
||||
@@ -134,11 +134,12 @@ namespace MQTTnet.Tests.Extensions
|
||||
public void SubscriptionSupport2()
|
||||
{
|
||||
var template = new MqttTopicTemplate("A/v1/{param}/F");
|
||||
|
||||
var subscribeOptions = new MqttFactory().CreateSubscribeOptionsBuilder()
|
||||
|
||||
var subscribeOptions = new MqttClientFactory().CreateSubscribeOptionsBuilder()
|
||||
.WithTopicTemplate(template)
|
||||
.WithSubscriptionIdentifier(5)
|
||||
.Build();
|
||||
|
||||
Assert.AreEqual("A/v1/+/F", subscribeOptions.TopicFilters[0].Topic);
|
||||
}
|
||||
|
||||
@@ -170,7 +171,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
public void SendAndSubscribeSupport2()
|
||||
{
|
||||
var template = new MqttTopicTemplate("App/v1/{sender}/message");
|
||||
Assert.ThrowsException<ArgumentException>(() =>
|
||||
Assert.ThrowsException<ArgumentException>(() =>
|
||||
template.BuildMessage());
|
||||
}
|
||||
|
||||
@@ -184,7 +185,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
// possible improvement: Assert.AreEqual("A/v1/+/F", canonicalFilter.TopicFilter);
|
||||
Assert.AreEqual("A/v1/+", canonicalFilter.TopicFilter);
|
||||
Assert.AreEqual("A/v1/+/#", canonicalFilter.TopicTreeRootFilter);
|
||||
|
||||
|
||||
var template2b = new MqttTopicTemplate("A/v1/E/X");
|
||||
canonicalFilter = MqttTopicTemplate.FindCanonicalPrefix(new[] { template1, template2, template3, template2b });
|
||||
Assert.AreEqual("A/v1/+", canonicalFilter.Template);
|
||||
@@ -197,7 +198,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
Assert.AreEqual("A/+", canonicalFilter2.TopicFilter);
|
||||
Assert.AreEqual("A/+/#", canonicalFilter2.TopicTreeRootFilter);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void CanonicalPrefixFilterSimple1()
|
||||
{
|
||||
@@ -209,7 +210,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
Assert.AreEqual("#", template.TopicFilter);
|
||||
Assert.AreEqual("#", template.Template);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void CanonicalPrefixFilterSimple2()
|
||||
{
|
||||
@@ -220,7 +221,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
});
|
||||
Assert.AreEqual("A/v1/+", template.TopicFilter);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void CanonicalPrefixFilterSimple3()
|
||||
{
|
||||
@@ -232,7 +233,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
Assert.AreEqual("A/v1/+/+", template.TopicFilter);
|
||||
Assert.AreEqual("A/v1/{param}/+", template.Template);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void CanonicalPrefixFilterSimple4()
|
||||
{
|
||||
@@ -244,8 +245,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
Assert.AreEqual("A/v1/+/+", template.TopicFilter);
|
||||
Assert.AreEqual("A/v1/{param}/+", template.Template);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void CanonicalPrefixFilterSimple5()
|
||||
{
|
||||
@@ -257,7 +257,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
Assert.AreEqual("A/+", template.TopicFilter);
|
||||
Assert.AreEqual("A/+/#", template.TopicTreeRootFilter);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void CanonicalPrefixFilterSimple6()
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Extensions.Rpc;
|
||||
using MQTTnet.Formatter;
|
||||
@@ -186,7 +185,7 @@ namespace MQTTnet.Tests.Extensions
|
||||
[TestMethod]
|
||||
public void Use_Factory()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
using (var client = factory.CreateMqttClient())
|
||||
{
|
||||
var rpcClient = factory.CreateMqttRpcClient(client);
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// 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.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Extensions.WebSocket4Net;
|
||||
using MQTTnet.Tests.Helpers;
|
||||
|
||||
namespace MQTTnet.Tests.Extensions
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class WebSocket4Net_Tests
|
||||
{
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(MqttCommunicationException))]
|
||||
public async Task Connect_Failed_With_Invalid_Server()
|
||||
{
|
||||
var factory = new MqttFactory().UseWebSocket4Net();
|
||||
|
||||
using (var client = factory.CreateMqttClient())
|
||||
{
|
||||
var options = new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("ws://a.b/mqtt")).WithTimeout(TimeSpan.FromSeconds(2)).Build();
|
||||
await client.ConnectAsync(options).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Use_Correct_Adapter()
|
||||
{
|
||||
// Should not throw exception
|
||||
var factory = new MqttFactory().UseWebSocket4Net();
|
||||
using (var client = factory.CreateMqttClient())
|
||||
{
|
||||
var adapterFactory = client.GetFieldValue("_adapterFactory");
|
||||
|
||||
Assert.IsInstanceOfType(adapterFactory, typeof(WebSocket4NetMqttClientAdapterFactory));
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Use_WebSocket4Net()
|
||||
{
|
||||
// Should not throw exception
|
||||
new MqttFactory().UseWebSocket4Net();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,7 @@
|
||||
// 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.Diagnostics;
|
||||
using MQTTnet.Extensions.ManagedClient;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Server;
|
||||
|
||||
namespace MQTTnet.Tests.Factory
|
||||
@@ -16,66 +10,11 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestClass]
|
||||
public sealed class MqttFactory_Tests : BaseTestClass
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task Create_Managed_Client_With_Logger()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
|
||||
// This test compares
|
||||
// 1. correct logID
|
||||
var logId = "logId";
|
||||
var hasInvalidLogId = false;
|
||||
|
||||
// 2. if the total log calls are the same for global and local
|
||||
//var globalLogCount = 0;
|
||||
var localLogCount = 0;
|
||||
|
||||
var logger = new MqttNetEventLogger(logId);
|
||||
logger.LogMessagePublished += (s, e) =>
|
||||
{
|
||||
if (e.LogMessage.LogId != logId)
|
||||
{
|
||||
hasInvalidLogId = true;
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref localLogCount);
|
||||
};
|
||||
|
||||
var managedClient = factory.CreateManagedMqttClient(logger);
|
||||
try
|
||||
{
|
||||
var clientOptions = new ManagedMqttClientOptionsBuilder();
|
||||
|
||||
clientOptions.WithClientOptions(o => o.WithTcpServer("this_is_an_invalid_host").WithTimeout(TimeSpan.FromSeconds(1)));
|
||||
|
||||
// try connect to get some log entries
|
||||
await managedClient.StartAsync(clientOptions.Build());
|
||||
|
||||
// wait at least connect timeout or we have some log messages
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
managedClient.ConnectingFailedAsync += e =>
|
||||
{
|
||||
tcs.TrySetResult(null);
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await Task.WhenAny(Task.Delay(managedClient.Options.ClientOptions.Timeout), tcs.Task);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await managedClient.StopAsync();
|
||||
}
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
Assert.IsFalse(hasInvalidLogId);
|
||||
Assert.AreNotEqual(0, localLogCount);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Create_ApplicationMessageBuilder()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var builder = factory.CreateApplicationMessageBuilder();
|
||||
|
||||
Assert.IsNotNull(builder);
|
||||
@@ -84,7 +23,7 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestMethod]
|
||||
public void Create_ClientOptionsBuilder()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var builder = factory.CreateClientOptionsBuilder();
|
||||
|
||||
Assert.IsNotNull(builder);
|
||||
@@ -93,7 +32,7 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestMethod]
|
||||
public void Create_ServerOptionsBuilder()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttServerFactory();
|
||||
var builder = factory.CreateServerOptionsBuilder();
|
||||
|
||||
Assert.IsNotNull(builder);
|
||||
@@ -102,7 +41,7 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestMethod]
|
||||
public void Create_SubscribeOptionsBuilder()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var builder = factory.CreateSubscribeOptionsBuilder();
|
||||
|
||||
Assert.IsNotNull(builder);
|
||||
@@ -111,7 +50,7 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestMethod]
|
||||
public void Create_UnsubscribeOptionsBuilder()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var builder = factory.CreateUnsubscribeOptionsBuilder();
|
||||
|
||||
Assert.IsNotNull(builder);
|
||||
@@ -120,7 +59,7 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestMethod]
|
||||
public void Create_TopicFilterBuilder()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var builder = factory.CreateTopicFilterBuilder();
|
||||
|
||||
Assert.IsNotNull(builder);
|
||||
@@ -129,7 +68,7 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestMethod]
|
||||
public void Create_MqttServer()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttServerFactory();
|
||||
var server = factory.CreateMqttServer(new MqttServerOptionsBuilder().Build());
|
||||
|
||||
Assert.IsNotNull(server);
|
||||
@@ -138,7 +77,7 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestMethod]
|
||||
public void Create_MqttClient()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var client = factory.CreateMqttClient();
|
||||
|
||||
Assert.IsNotNull(client);
|
||||
@@ -147,19 +86,10 @@ namespace MQTTnet.Tests.Factory
|
||||
[TestMethod]
|
||||
public void Create_LowLevelMqttClient()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var client = factory.CreateLowLevelMqttClient();
|
||||
|
||||
Assert.IsNotNull(client);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Create_ManagedMqttClient()
|
||||
{
|
||||
var factory = new MqttFactory();
|
||||
var client = factory.CreateManagedMqttClient();
|
||||
|
||||
Assert.IsNotNull(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,7 @@ namespace MQTTnet.Tests.Formatter
|
||||
Assert.AreEqual(5, remainingData.Length);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void Read_Various_Positions_and_Offsets()
|
||||
{
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Adapter;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Diagnostics.Logger;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Packets;
|
||||
@@ -213,7 +213,7 @@ namespace MQTTnet.Tests.Formatter
|
||||
MqttSubscribeReasonCode.UnspecifiedError
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
DeserializeAndCompare(p, "kAYAewABAoA=");
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ namespace MQTTnet.Tests.Formatter
|
||||
|
||||
Assert.IsNotNull(publishPacketCopy);
|
||||
Assert.AreEqual(publishPacket.Topic, publishPacketCopy.Topic);
|
||||
CollectionAssert.AreEqual(publishPacket.PayloadSegment.ToArray(), publishPacketCopy.PayloadSegment.ToArray());
|
||||
CollectionAssert.AreEqual(publishPacket.Payload.ToArray(), publishPacketCopy.Payload.ToArray());
|
||||
|
||||
// Now modify the payload and test again.
|
||||
publishPacket.PayloadSegment = new ArraySegment<byte>(Encoding.UTF8.GetBytes("MQTT"));
|
||||
@@ -338,7 +338,7 @@ namespace MQTTnet.Tests.Formatter
|
||||
|
||||
Assert.IsNotNull(publishPacketCopy2);
|
||||
Assert.AreEqual(publishPacket.Topic, publishPacketCopy2.Topic);
|
||||
CollectionAssert.AreEqual(publishPacket.PayloadSegment.ToArray(), publishPacketCopy2.PayloadSegment.ToArray());
|
||||
CollectionAssert.AreEqual(publishPacket.Payload.ToArray(), publishPacketCopy2.Payload.ToArray());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -506,7 +506,7 @@ namespace MQTTnet.Tests.Formatter
|
||||
MqttSubscribeReasonCode.UnspecifiedError
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SerializeAndCompare(p, "kAYAewABAoA=");
|
||||
}
|
||||
|
||||
@@ -587,7 +587,7 @@ namespace MQTTnet.Tests.Formatter
|
||||
return packetFormatterAdapter.ProtocolVersion;
|
||||
}
|
||||
|
||||
TPacket Roundtrip<TPacket>(TPacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311, MqttBufferWriter bufferWriter = null) where TPacket : MqttPacket
|
||||
TPacket Roundtrip<TPacket>(TPacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311, MqttBufferReader bufferReader = null, MqttBufferWriter bufferWriter = null) where TPacket : MqttPacket
|
||||
{
|
||||
var writer = bufferWriter ?? WriterFactory();
|
||||
var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -322,7 +323,7 @@ namespace MQTTnet.Tests.Formatter
|
||||
Assert.AreEqual(publishPacket.PacketIdentifier, deserialized.PacketIdentifier);
|
||||
Assert.AreEqual(publishPacket.Dup, deserialized.Dup);
|
||||
Assert.AreEqual(publishPacket.Retain, deserialized.Retain);
|
||||
CollectionAssert.AreEqual(publishPacket.PayloadSegment.ToArray(), deserialized.PayloadSegment.ToArray());
|
||||
CollectionAssert.AreEqual(publishPacket.Payload.ToArray(), deserialized.Payload.ToArray());
|
||||
Assert.AreEqual(publishPacket.QualityOfServiceLevel, deserialized.QualityOfServiceLevel);
|
||||
Assert.AreEqual(publishPacket.Topic, deserialized.Topic);
|
||||
Assert.AreEqual(null, deserialized.ResponseTopic); // Not supported in v3.1.1.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -283,7 +284,7 @@ namespace MQTTnet.Tests.Formatter
|
||||
Assert.AreEqual(publishPacket.PacketIdentifier, deserialized.PacketIdentifier);
|
||||
Assert.AreEqual(publishPacket.Dup, deserialized.Dup);
|
||||
Assert.AreEqual(publishPacket.Retain, deserialized.Retain);
|
||||
CollectionAssert.AreEqual(publishPacket.PayloadSegment.ToArray(), deserialized.PayloadSegment.ToArray());
|
||||
CollectionAssert.AreEqual(publishPacket.Payload.ToArray(), deserialized.Payload.ToArray());
|
||||
Assert.AreEqual(publishPacket.QualityOfServiceLevel, deserialized.QualityOfServiceLevel);
|
||||
Assert.AreEqual(publishPacket.Topic, deserialized.Topic);
|
||||
Assert.AreEqual(publishPacket.ResponseTopic, deserialized.ResponseTopic);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
|
||||
namespace MQTTnet.Tests.Helpers
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -19,7 +20,7 @@ namespace MQTTnet.Tests.Internal
|
||||
public async Task Connect_Send_Receive()
|
||||
{
|
||||
var crossPlatformSocket = new CrossPlatformSocket(ProtocolType.Tcp);
|
||||
await crossPlatformSocket.ConnectAsync("www.google.de", 80, CancellationToken.None);
|
||||
await crossPlatformSocket.ConnectAsync(new DnsEndPoint("www.google.de", 80), CancellationToken.None);
|
||||
|
||||
var requestBuffer = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\nHost: www.google.de\r\n\r\n");
|
||||
await crossPlatformSocket.SendAsync(new ArraySegment<byte>(requestBuffer), System.Net.Sockets.SocketFlags.None);
|
||||
@@ -42,7 +43,7 @@ namespace MQTTnet.Tests.Internal
|
||||
var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(5));
|
||||
cancellationToken.Token.Register(() => crossPlatformSocket.Dispose());
|
||||
|
||||
await crossPlatformSocket.ConnectAsync("www.google.de", 54321, cancellationToken.Token);
|
||||
await crossPlatformSocket.ConnectAsync(new DnsEndPoint("www.google.de", 54321), cancellationToken.Token);
|
||||
}
|
||||
|
||||
//[TestMethod]
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;net7.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net452;net48</TargetFrameworks>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<IsPackable>false</IsPackable>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<EnableNETAnalyzers>false</EnableNETAnalyzers>
|
||||
<EnforceCodeStyleInBuild>false</EnforceCodeStyleInBuild>
|
||||
<DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers>
|
||||
<NoWarn>1591;NETSDK1138</NoWarn>
|
||||
<NoWarn>1591;NETSDK1138;NU1803;NU1901;NU1902</NoWarn>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<NuGetAuditMode>all</NuGetAuditMode>
|
||||
<NuGetAudit>true</NuGetAudit>
|
||||
<AnalysisLevel>latest-Recommended</AnalysisLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
|
||||
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj" />
|
||||
<ProjectReference Include="..\..\Source\MQTTnet.Server\MQTTnet.Server.csproj" />
|
||||
<ProjectReference Include="..\..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj" />
|
||||
<ProjectReference Include="..\..\Source\MQTTnet\MQTTnet.csproj" />
|
||||
<ProjectReference Include="..\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj" />
|
||||
<ProjectReference Include="..\MQTTnet.Extensions.TopicTemplate\MQTTnet.Extensions.TopicTemplate.csproj" />
|
||||
<ProjectReference Include="..\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -2,11 +2,12 @@
|
||||
// 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.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.IO;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Packets;
|
||||
@@ -61,7 +62,7 @@ namespace MQTTnet.Tests.MQTTv5
|
||||
Assert.AreEqual(2, receivedMessage.UserProperties.Count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Connect()
|
||||
{
|
||||
@@ -128,6 +129,54 @@ namespace MQTTnet.Tests.MQTTv5
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish_QoS_0_LargeBuffer()
|
||||
{
|
||||
using var recyclableMemoryStream = GetLargePayload();
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var client = await testEnvironment.ConnectClient(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
|
||||
var result = await client.PublishSequenceAsync("a", recyclableMemoryStream.GetReadOnlySequence());
|
||||
await client.DisconnectAsync();
|
||||
|
||||
Assert.AreEqual(MqttClientPublishReasonCode.Success, result.ReasonCode);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish_QoS_1_LargeBuffer()
|
||||
{
|
||||
using var recyclableMemoryStream = GetLargePayload();
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var client = await testEnvironment.ConnectClient(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
|
||||
var result = await client.PublishSequenceAsync("a", recyclableMemoryStream.GetReadOnlySequence(), MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await client.DisconnectAsync();
|
||||
|
||||
Assert.AreEqual(MqttClientPublishReasonCode.NoMatchingSubscribers, result.ReasonCode);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish_QoS_2_LargeBuffer()
|
||||
{
|
||||
using var recyclableMemoryStream = GetLargePayload();
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var client = await testEnvironment.ConnectClient(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
|
||||
var result = await client.PublishSequenceAsync("a", recyclableMemoryStream.GetReadOnlySequence(), MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
await client.DisconnectAsync();
|
||||
|
||||
Assert.AreEqual(MqttClientPublishReasonCode.NoMatchingSubscribers, result.ReasonCode);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish_QoS_0()
|
||||
{
|
||||
@@ -173,6 +222,45 @@ namespace MQTTnet.Tests.MQTTv5
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish_With_RecyclableMemoryStream()
|
||||
{
|
||||
var memoryManager = new RecyclableMemoryStreamManager(options: new RecyclableMemoryStreamManager.Options { BlockSize = 4096 });
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var client = await testEnvironment.ConnectClient(o => o.WithProtocolVersion(MqttProtocolVersion.V500));
|
||||
|
||||
const int payloadSize = 100000;
|
||||
using var memoryStream = memoryManager.GetStream();
|
||||
|
||||
byte testValue = 0;
|
||||
while (memoryStream.Length < payloadSize)
|
||||
{
|
||||
memoryStream.WriteByte(testValue++);
|
||||
}
|
||||
|
||||
var applicationMessage = new MqttApplicationMessageBuilder()
|
||||
.WithTopic("Hello")
|
||||
.WithPayload(memoryStream.GetReadOnlySequence())
|
||||
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce)
|
||||
.WithUserProperty("x", "1")
|
||||
.WithUserProperty("y", "2")
|
||||
.WithResponseTopic("response")
|
||||
.WithContentType("text")
|
||||
.WithMessageExpiryInterval(50)
|
||||
.WithCorrelationData(new byte[12])
|
||||
.WithTopicAlias(2)
|
||||
.Build();
|
||||
|
||||
var result = await client.PublishAsync(applicationMessage);
|
||||
await client.DisconnectAsync();
|
||||
|
||||
Assert.AreEqual(MqttClientPublishReasonCode.Success, result.ReasonCode);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish_With_Properties()
|
||||
{
|
||||
@@ -208,7 +296,7 @@ namespace MQTTnet.Tests.MQTTv5
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var client1 = await testEnvironment.ConnectClient(o => o.WithProtocolVersion(MqttProtocolVersion.V500).WithClientId("client1"));
|
||||
|
||||
var testMessageHandler = testEnvironment.CreateApplicationMessageHandler(client1);
|
||||
@@ -273,9 +361,22 @@ namespace MQTTnet.Tests.MQTTv5
|
||||
Assert.AreEqual(applicationMessage.ResponseTopic, receivedMessage.ResponseTopic);
|
||||
Assert.AreEqual(applicationMessage.MessageExpiryInterval, receivedMessage.MessageExpiryInterval);
|
||||
CollectionAssert.AreEqual(applicationMessage.CorrelationData, receivedMessage.CorrelationData);
|
||||
CollectionAssert.AreEqual(applicationMessage.PayloadSegment.ToArray(), receivedMessage.PayloadSegment.ToArray());
|
||||
CollectionAssert.AreEqual(applicationMessage.Payload.ToArray(), receivedMessage.Payload.ToArray());
|
||||
CollectionAssert.AreEqual(applicationMessage.UserProperties, receivedMessage.UserProperties);
|
||||
}
|
||||
}
|
||||
|
||||
private RecyclableMemoryStream GetLargePayload()
|
||||
{
|
||||
var memoryManager = new RecyclableMemoryStreamManager();
|
||||
var memoryStream = memoryManager.GetStream();
|
||||
for (var i = 0; i < 100000; i++)
|
||||
{
|
||||
memoryStream.WriteByte((byte)i);
|
||||
}
|
||||
|
||||
memoryStream.Position = 0;
|
||||
return memoryStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
using System.Threading;
|
||||
@@ -23,18 +22,18 @@ namespace MQTTnet.Tests.MQTTv5
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithWillTopic("My/last/will").WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce).WithProtocolVersion(MqttProtocolVersion.V500);
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
|
||||
|
||||
|
||||
var receivedMessagesCount = 0;
|
||||
c1.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
Interlocked.Increment(ref receivedMessagesCount);
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
await c1.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("#").Build());
|
||||
|
||||
var c2 = await testEnvironment.ConnectClient(clientOptions);
|
||||
@@ -220,7 +219,7 @@ namespace MQTTnet.Tests.MQTTv5
|
||||
|
||||
static MqttClientOptions CreateClientOptions(TestEnvironment testEnvironment, string clientId, bool cleanSession, uint sessionExpiryInterval)
|
||||
{
|
||||
return testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
return testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V500)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.WithSessionExpiryInterval(sessionExpiryInterval)
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
// 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 MQTTnet.Channel;
|
||||
using MQTTnet.Internal;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Channel;
|
||||
using MQTTnet.Internal;
|
||||
|
||||
namespace MQTTnet.Tests.Mockups
|
||||
{
|
||||
@@ -47,9 +47,12 @@ namespace MQTTnet.Tests.Mockups
|
||||
return _stream.ReadAsync(buffer, offset, count, cancellationToken);
|
||||
}
|
||||
|
||||
public Task WriteAsync(ArraySegment<byte> buffer, bool isEndOfPacket, CancellationToken cancellationToken)
|
||||
public async Task WriteAsync(ReadOnlySequence<byte> buffer, bool isEndOfPacket, CancellationToken cancellationToken)
|
||||
{
|
||||
return _stream.WriteAsync(buffer.Array, buffer.Offset, buffer.Count, cancellationToken);
|
||||
foreach (var segment in buffer)
|
||||
{
|
||||
await _stream.WriteAsync(segment, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -8,7 +8,6 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Internal;
|
||||
|
||||
namespace MQTTnet.Tests.Mockups
|
||||
|
||||
@@ -9,9 +9,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Extensions.ManagedClient;
|
||||
using MQTTnet.Diagnostics.Logger;
|
||||
using MQTTnet.Extensions.Rpc;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
@@ -23,12 +21,12 @@ namespace MQTTnet.Tests.Mockups
|
||||
{
|
||||
public sealed class TestEnvironment : IDisposable
|
||||
{
|
||||
readonly List<string> _clientErrors = new List<string>();
|
||||
readonly List<IMqttClient> _clients = new List<IMqttClient>();
|
||||
readonly List<Exception> _exceptions = new List<Exception>();
|
||||
readonly List<ILowLevelMqttClient> _lowLevelClients = new List<ILowLevelMqttClient>();
|
||||
readonly List<string> _clientErrors = new();
|
||||
readonly List<IMqttClient> _clients = new();
|
||||
readonly List<Exception> _exceptions = new();
|
||||
readonly List<ILowLevelMqttClient> _lowLevelClients = new();
|
||||
readonly MqttProtocolVersion _protocolVersion;
|
||||
readonly List<string> _serverErrors = new List<string>();
|
||||
readonly List<string> _serverErrors = new();
|
||||
|
||||
public TestEnvironment() : this(null)
|
||||
{
|
||||
@@ -77,11 +75,13 @@ namespace MQTTnet.Tests.Mockups
|
||||
};
|
||||
}
|
||||
|
||||
public MqttNetEventLogger ClientLogger { get; } = new MqttNetEventLogger("client");
|
||||
public MqttNetEventLogger ClientLogger { get; } = new("client");
|
||||
|
||||
public static bool EnableLogger { get; set; } = true;
|
||||
|
||||
public MqttFactory Factory { get; } = new MqttFactory();
|
||||
public MqttClientFactory ClientFactory { get; } = new();
|
||||
|
||||
public MqttServerFactory ServerFactory { get; } = new();
|
||||
|
||||
public bool IgnoreClientLogErrors { get; set; }
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
public MqttServer Server { get; private set; }
|
||||
|
||||
public MqttNetEventLogger ServerLogger { get; } = new MqttNetEventLogger("server");
|
||||
public MqttNetEventLogger ServerLogger { get; } = new("server");
|
||||
|
||||
public int ServerPort { get; set; }
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
public Task<IMqttClient> ConnectClient()
|
||||
{
|
||||
return ConnectClient(Factory.CreateClientOptionsBuilder().WithProtocolVersion(_protocolVersion));
|
||||
return ConnectClient(ClientFactory.CreateClientOptionsBuilder().WithProtocolVersion(_protocolVersion));
|
||||
}
|
||||
|
||||
public async Task<IMqttClient> ConnectClient(Action<MqttClientOptionsBuilder> configureOptions, TimeSpan timeout = default)
|
||||
@@ -108,7 +108,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
}
|
||||
|
||||
// Start with initial default values.
|
||||
var optionsBuilder = Factory.CreateClientOptionsBuilder().WithProtocolVersion(_protocolVersion).WithTcpServer("127.0.0.1", ServerPort);
|
||||
var optionsBuilder = ClientFactory.CreateClientOptionsBuilder().WithProtocolVersion(_protocolVersion).WithTcpServer("127.0.0.1", ServerPort);
|
||||
|
||||
// Let the caller override settings. Do not touch the options after this.
|
||||
configureOptions.Invoke(optionsBuilder);
|
||||
@@ -204,21 +204,11 @@ namespace MQTTnet.Tests.Mockups
|
||||
return new TestApplicationMessageReceivedHandler(mqttClient);
|
||||
}
|
||||
|
||||
public TestApplicationMessageReceivedHandler CreateApplicationMessageHandler(IManagedMqttClient managedClient)
|
||||
{
|
||||
if (managedClient == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(managedClient));
|
||||
}
|
||||
|
||||
return new TestApplicationMessageReceivedHandler(managedClient.InternalClient);
|
||||
}
|
||||
|
||||
public IMqttClient CreateClient()
|
||||
{
|
||||
var logger = EnableLogger ? (IMqttNetLogger)ClientLogger : MqttNetNullLogger.Instance;
|
||||
|
||||
var client = Factory.CreateMqttClient(logger);
|
||||
var client = ClientFactory.CreateMqttClient(logger);
|
||||
|
||||
client.ConnectingAsync += e =>
|
||||
{
|
||||
@@ -250,7 +240,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
public MqttClientOptionsBuilder CreateDefaultClientOptionsBuilder()
|
||||
{
|
||||
return Factory.CreateClientOptionsBuilder()
|
||||
return ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(_protocolVersion)
|
||||
.WithTcpServer("127.0.0.1", ServerPort)
|
||||
.WithClientId(TestContext.TestName + "_" + Guid.NewGuid());
|
||||
@@ -258,7 +248,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
public ILowLevelMqttClient CreateLowLevelClient()
|
||||
{
|
||||
var client = Factory.CreateLowLevelMqttClient(ClientLogger);
|
||||
var client = ClientFactory.CreateLowLevelMqttClient(ClientLogger);
|
||||
|
||||
lock (_lowLevelClients)
|
||||
{
|
||||
@@ -277,7 +267,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
var logger = EnableLogger ? (IMqttNetLogger)ServerLogger : new MqttNetNullLogger();
|
||||
|
||||
Server = Factory.CreateMqttServer(options, logger);
|
||||
Server = ServerFactory.CreateMqttServer(options, logger);
|
||||
|
||||
Server.ValidatingConnectionAsync += e =>
|
||||
{
|
||||
@@ -352,7 +342,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
GC.Collect();
|
||||
GC.WaitForFullGCComplete();
|
||||
GC.WaitForPendingFinalizers();
|
||||
|
||||
|
||||
if (_exceptions.Any())
|
||||
{
|
||||
throw new Exception($"{_exceptions.Count} exceptions tracked.\r\n" + string.Join(Environment.NewLine, _exceptions));
|
||||
@@ -366,7 +356,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
public Task<MqttServer> StartServer()
|
||||
{
|
||||
return StartServer(Factory.CreateServerOptionsBuilder());
|
||||
return StartServer(ServerFactory.CreateServerOptionsBuilder());
|
||||
}
|
||||
|
||||
public async Task<MqttServer> StartServer(MqttServerOptionsBuilder optionsBuilder)
|
||||
@@ -386,7 +376,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
public async Task<MqttServer> StartServer(Action<MqttServerOptionsBuilder> configure)
|
||||
{
|
||||
var optionsBuilder = Factory.CreateServerOptionsBuilder();
|
||||
var optionsBuilder = ServerFactory.CreateServerOptionsBuilder();
|
||||
|
||||
optionsBuilder.WithDefaultEndpoint();
|
||||
optionsBuilder.WithDefaultEndpointPort(ServerPort);
|
||||
@@ -396,7 +386,7 @@ namespace MQTTnet.Tests.Mockups
|
||||
|
||||
var options = optionsBuilder.Build();
|
||||
var server = CreateServer(options);
|
||||
await server.StartAsync();
|
||||
await server.StartAsync().ConfigureAwait(false);
|
||||
|
||||
// The OS has chosen the port to we have to properly expose it to the tests.
|
||||
ServerPort = options.DefaultEndpointOptions.Port;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Diagnostics.Logger;
|
||||
|
||||
namespace MQTTnet.Tests.Mockups
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -30,7 +29,7 @@ namespace MQTTnet.Tests
|
||||
Assert.AreEqual("xyz", message.Topic);
|
||||
Assert.IsFalse(message.Retain);
|
||||
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, message.QualityOfServiceLevel);
|
||||
Assert.AreEqual(Encoding.UTF8.GetString(message.PayloadSegment.ToArray()), "00:06:00");
|
||||
Assert.AreEqual(Encoding.UTF8.GetString(message.Payload), "00:06:00");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
@@ -42,7 +41,7 @@ namespace MQTTnet.Tests
|
||||
Assert.AreEqual("123", message.Topic);
|
||||
Assert.IsFalse(message.Retain);
|
||||
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, message.QualityOfServiceLevel);
|
||||
Assert.AreEqual(Encoding.UTF8.GetString(message.PayloadSegment.ToArray()), "Hello");
|
||||
Assert.AreEqual(Encoding.UTF8.GetString(message.Payload), "Hello");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MQTTnet.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class MqttApplicationMessageTest
|
||||
{
|
||||
[TestMethod]
|
||||
public void PayloadSegment()
|
||||
{
|
||||
var message = new MqttApplicationMessage();
|
||||
Assert.AreEqual(0, message.Payload.Length);
|
||||
Assert.AreEqual(0, message.PayloadSegment.Count);
|
||||
|
||||
Assert.IsTrue(ReferenceEquals(message.Payload, message.PayloadSegment.Array));
|
||||
|
||||
message.Payload = new byte[] { 1, 2 };
|
||||
Assert.AreEqual(2, message.Payload.Length);
|
||||
Assert.AreEqual(2, message.PayloadSegment.Count);
|
||||
Assert.IsTrue(ReferenceEquals(message.Payload, message.PayloadSegment.Array));
|
||||
|
||||
message.Payload = new byte[] { 1, 2, 3 };
|
||||
Assert.AreEqual(3, message.Payload.Length);
|
||||
Assert.AreEqual(3, message.PayloadSegment.Count);
|
||||
Assert.IsTrue(ReferenceEquals(message.Payload, message.PayloadSegment.Array));
|
||||
|
||||
message.PayloadSegment = new ArraySegment<byte>(new byte[] { 1, 2, 3 });
|
||||
Assert.AreEqual(3, message.Payload.Length);
|
||||
Assert.AreEqual(3, message.PayloadSegment.Count);
|
||||
Assert.IsTrue(ReferenceEquals(message.Payload, message.PayloadSegment.Array));
|
||||
|
||||
message.PayloadSegment = new ArraySegment<byte>(new byte[] { 1, 2, 3 }, 1, 1);
|
||||
Assert.AreEqual(1, message.Payload.Length);
|
||||
Assert.AreEqual(1, message.PayloadSegment.Count);
|
||||
Assert.IsFalse(ReferenceEquals(message.Payload, message.PayloadSegment.Array));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
|
||||
namespace MQTTnet.Tests
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
|
||||
namespace MQTTnet.Tests
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using MQTTnet.Adapter;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Diagnostics.Logger;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace MQTTnet.Tests
|
||||
}, ct.Token);
|
||||
|
||||
var clientSocket = new CrossPlatformSocket(AddressFamily.InterNetwork, ProtocolType.Tcp);
|
||||
await clientSocket.ConnectAsync("localhost", 50001, CancellationToken.None);
|
||||
await clientSocket.ConnectAsync(new DnsEndPoint("localhost", 50001), CancellationToken.None);
|
||||
|
||||
var tcpChannel = new MqttTcpChannel(clientSocket.GetStream(), "test", null);
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
|
||||
@@ -24,20 +23,20 @@ namespace MQTTnet.Tests
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var receiverClient = await testEnvironment.ConnectClient();
|
||||
var senderClient = await testEnvironment.ConnectClient();
|
||||
|
||||
TaskCompletionSource<string> response = null;
|
||||
|
||||
receiverClient.ApplicationMessageReceivedAsync += e =>
|
||||
receiverClient.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
response?.TrySetResult(e.ApplicationMessage.ConvertPayloadToString());
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
await receiverClient.SubscribeAsync("#");
|
||||
|
||||
|
||||
var times = new List<TimeSpan>();
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -49,7 +48,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
testEnvironment.Server.ClientConnectedAsync += args =>
|
||||
{
|
||||
serverConnectedClientId = args.ClientId;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -24,7 +25,7 @@ namespace MQTTnet.Tests.Server
|
||||
await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithDefaultCommunicationTimeout(TimeSpan.FromSeconds(1)));
|
||||
|
||||
var client = new CrossPlatformSocket(AddressFamily.InterNetwork, ProtocolType.Tcp);
|
||||
await client.ConnectAsync("localhost", testEnvironment.ServerPort, CancellationToken.None);
|
||||
await client.ConnectAsync(new DnsEndPoint("localhost", testEnvironment.ServerPort), CancellationToken.None);
|
||||
|
||||
// Don't send anything. The server should close the connection.
|
||||
await Task.Delay(TimeSpan.FromSeconds(3));
|
||||
@@ -55,7 +56,7 @@ namespace MQTTnet.Tests.Server
|
||||
// Send an invalid packet and ensure that the server will close the connection and stay in a waiting state
|
||||
// forever. This is security related.
|
||||
var client = new CrossPlatformSocket(AddressFamily.InterNetwork, ProtocolType.Tcp);
|
||||
await client.ConnectAsync("localhost", testEnvironment.ServerPort, CancellationToken.None);
|
||||
await client.ConnectAsync(new DnsEndPoint("localhost", testEnvironment.ServerPort), CancellationToken.None);
|
||||
|
||||
var buffer = Encoding.UTF8.GetBytes("Garbage");
|
||||
await client.SendAsync(new ArraySegment<byte>(buffer), SocketFlags.None);
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
@@ -44,7 +43,7 @@ namespace MQTTnet.Tests.Server
|
||||
var receiver = await testEnvironment.ConnectClient(o => o.WithProtocolVersion(MqttProtocolVersion.V311));
|
||||
var receivedApplicationMessages = testEnvironment.CreateApplicationMessageHandler(receiver);
|
||||
await receiver.SubscribeAsync("#");
|
||||
|
||||
|
||||
var sender = await testEnvironment.ConnectClient();
|
||||
|
||||
var applicationMessage = new MqttApplicationMessageBuilder().WithTopic("My/Message")
|
||||
@@ -53,7 +52,7 @@ namespace MQTTnet.Tests.Server
|
||||
.WithResponseTopic("Response")
|
||||
.WithCorrelationData(Encoding.UTF8.GetBytes("Correlation"))
|
||||
.Build();
|
||||
|
||||
|
||||
await sender.PublishAsync(applicationMessage);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -31,11 +30,11 @@ namespace MQTTnet.Tests.Server
|
||||
};
|
||||
|
||||
await testEnvironment.ConnectClient(o => o.WithCredentials("TheUser"));
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
Assert.IsNotNull(eventArgs);
|
||||
|
||||
|
||||
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Connected_Event)));
|
||||
Assert.IsTrue(eventArgs.Endpoint.Contains("127.0.0.1"));
|
||||
Assert.AreEqual(MqttProtocolVersion.V311, eventArgs.ProtocolVersion);
|
||||
@@ -59,17 +58,17 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
var client = await testEnvironment.ConnectClient(o => o.WithCredentials("TheUser"));
|
||||
await client.DisconnectAsync();
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
Assert.IsNotNull(eventArgs);
|
||||
|
||||
|
||||
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Disconnected_Event)));
|
||||
Assert.IsTrue(eventArgs.Endpoint.Contains("127.0.0.1"));
|
||||
Assert.AreEqual(MqttClientDisconnectType.Clean, eventArgs.DisconnectType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Client_Subscribed_Event()
|
||||
{
|
||||
@@ -86,70 +85,70 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
var client = await testEnvironment.ConnectClient();
|
||||
await client.SubscribeAsync("The/Topic", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
Assert.IsNotNull(eventArgs);
|
||||
|
||||
|
||||
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Subscribed_Event)));
|
||||
Assert.AreEqual("The/Topic", eventArgs.TopicFilter.Topic);
|
||||
Assert.AreEqual(MqttQualityOfServiceLevel.AtLeastOnce, eventArgs.TopicFilter.QualityOfServiceLevel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Client_Unsubscribed_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
|
||||
ClientUnsubscribedTopicEventArgs eventArgs = null;
|
||||
server.ClientUnsubscribedTopicAsync += e =>
|
||||
{
|
||||
eventArgs = e;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
var client = await testEnvironment.ConnectClient();
|
||||
await client.UnsubscribeAsync("The/Topic");
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
Assert.IsNotNull(eventArgs);
|
||||
|
||||
|
||||
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Unsubscribed_Event)));
|
||||
Assert.AreEqual("The/Topic", eventArgs.TopicFilter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Application_Message_Received_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
|
||||
InterceptingPublishEventArgs eventArgs = null;
|
||||
server.InterceptingPublishAsync += e =>
|
||||
{
|
||||
eventArgs = e;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
var client = await testEnvironment.ConnectClient();
|
||||
await client.PublishStringAsync("The_Topic", "The_Payload");
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
Assert.IsNotNull(eventArgs);
|
||||
|
||||
|
||||
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Application_Message_Received_Event)));
|
||||
Assert.AreEqual("The_Topic", eventArgs.ApplicationMessage.Topic);
|
||||
Assert.AreEqual("The_Payload", eventArgs.ApplicationMessage.ConvertPayloadToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Started_Event()
|
||||
{
|
||||
@@ -163,22 +162,22 @@ namespace MQTTnet.Tests.Server
|
||||
eventArgs = e;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
await server.StartAsync();
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
Assert.IsNotNull(eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Stopped_Event()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
|
||||
EventArgs eventArgs = null;
|
||||
server.StoppedAsync += e =>
|
||||
{
|
||||
@@ -187,9 +186,9 @@ namespace MQTTnet.Tests.Server
|
||||
};
|
||||
|
||||
await server.StopAsync();
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
Assert.IsNotNull(eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,19 +2,18 @@
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Adapter;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
{
|
||||
@@ -60,7 +59,7 @@ namespace MQTTnet.Tests.Server
|
||||
var server = await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithPersistentSessions());
|
||||
|
||||
// Create the session including the subscription.
|
||||
var client1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("a").WithCleanSession(false));
|
||||
var client1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("a").WithCleanSession(false).WithSessionExpiryInterval(60));
|
||||
await client1.SubscribeAsync("x");
|
||||
await client1.DisconnectAsync();
|
||||
await Task.Delay(500);
|
||||
@@ -68,7 +67,7 @@ namespace MQTTnet.Tests.Server
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
Assert.AreEqual(0, clientStatus.Count);
|
||||
|
||||
var client2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("b").WithCleanSession(false));
|
||||
var client2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("b").WithCleanSession(false).WithSessionExpiryInterval(60));
|
||||
await client2.PublishStringAsync("x", "1");
|
||||
await client2.PublishStringAsync("x", "2");
|
||||
await client2.PublishStringAsync("x", "3");
|
||||
@@ -101,8 +100,10 @@ namespace MQTTnet.Tests.Server
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
var connectingFailedException = await Assert.ThrowsExceptionAsync<MqttConnectingFailedException>(() => testEnvironment.ConnectClient());
|
||||
Assert.AreEqual(MqttClientConnectResultCode.NotAuthorized, connectingFailedException.ResultCode);
|
||||
var client = testEnvironment.CreateClient();
|
||||
var response = await client.ConnectAsync(testEnvironment.CreateDefaultClientOptions());
|
||||
|
||||
Assert.AreEqual(MqttClientConnectResultCode.NotAuthorized, response.ResultCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +315,7 @@ namespace MQTTnet.Tests.Server
|
||||
var isIntercepted = false;
|
||||
c2.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
isIntercepted = string.Compare("extended", Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment.ToArray()), StringComparison.Ordinal) == 0;
|
||||
isIntercepted = string.Compare("extended", Encoding.UTF8.GetString(e.ApplicationMessage.Payload), StringComparison.Ordinal) == 0;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
@@ -780,7 +781,7 @@ namespace MQTTnet.Tests.Server
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
client1.ApplicationMessageReceivedAsync += e =>
|
||||
{
|
||||
receivedBody = e.ApplicationMessage.PayloadSegment.ToArray();
|
||||
receivedBody = e.ApplicationMessage.Payload.ToArray();
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
@@ -794,7 +795,7 @@ namespace MQTTnet.Tests.Server
|
||||
Assert.IsTrue(longBody.SequenceEqual(receivedBody ?? new byte[0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Set_Subscription_At_Server()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if !(NET452 || NET461 || NET48)
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
@@ -12,7 +11,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Certificates;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
@@ -239,7 +237,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
var mqttClientOptions = optionsBuilder.Build();
|
||||
|
||||
var factory = new MqttFactory();
|
||||
var factory = new MqttClientFactory();
|
||||
var mqttClient = factory.CreateMqttClient();
|
||||
_client = mqttClient;
|
||||
|
||||
@@ -295,7 +293,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
public Task StartServer()
|
||||
{
|
||||
var mqttFactory = new MqttFactory();
|
||||
var mqttServerFactory = new MqttServerFactory();
|
||||
|
||||
var mqttServerOptions = new MqttServerOptionsBuilder().WithEncryptionCertificate(_hotSwapServer)
|
||||
.WithRemoteCertificateValidationCallback(_hotSwapServer.RemoteCertificateValidationCallback)
|
||||
@@ -304,7 +302,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
mqttServerOptions.TlsEndpointOptions.ClientCertificateRequired = true;
|
||||
|
||||
_server = mqttFactory.CreateMqttServer(mqttServerOptions);
|
||||
_server = mqttServerFactory.CreateMqttServer(mqttServerOptions);
|
||||
return _server.StartAsync();
|
||||
}
|
||||
}
|
||||
@@ -318,16 +316,14 @@ namespace MQTTnet.Tests.Server
|
||||
{
|
||||
_certificates = new X509Certificate2Collection(CreateSelfSignedCertificate("1.3.6.1.5.5.7.3.2"));
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_certificates != null)
|
||||
{
|
||||
foreach (var certs in _certificates)
|
||||
{
|
||||
#if !NET452
|
||||
certs.Dispose();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,9 +374,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
#if !NET452
|
||||
_certificate.Dispose();
|
||||
#endif
|
||||
}
|
||||
|
||||
public X509Certificate2 GetCertificate()
|
||||
@@ -392,9 +386,8 @@ namespace MQTTnet.Tests.Server
|
||||
{
|
||||
var newCert = CreateSelfSignedCertificate("1.3.6.1.5.5.7.3.1");
|
||||
var oldCert = Interlocked.Exchange(ref _certificate, newCert);
|
||||
#if !NET452
|
||||
|
||||
oldCert.Dispose();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void InstallNewClientCert(X509Certificate2 certificate)
|
||||
@@ -422,5 +415,3 @@ namespace MQTTnet.Tests.Server
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Server;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -76,7 +75,7 @@ namespace MQTTnet.Tests.Server
|
||||
Interlocked.Increment(ref receivedMessages);
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
for (var i = 0; i < 100; i++)
|
||||
{
|
||||
_ = Task.Run(
|
||||
@@ -95,12 +94,12 @@ namespace MQTTnet.Tests.Server
|
||||
var packet = await client.ReceiveAsync(CancellationToken.None);
|
||||
|
||||
var connAckPacket = packet as MqttConnAckPacket;
|
||||
|
||||
|
||||
Assert.IsTrue(connAckPacket != null);
|
||||
Assert.AreEqual(MqttConnectReasonCode.Success, connAckPacket.ReasonCode);
|
||||
|
||||
|
||||
var publishPacket = new MqttPublishPacket();
|
||||
|
||||
|
||||
for (var j = 0; j < 1000; j++)
|
||||
{
|
||||
publishPacket.Topic = j.ToString();
|
||||
@@ -108,7 +107,7 @@ namespace MQTTnet.Tests.Server
|
||||
await client.SendAsync(publishPacket, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
await client.DisconnectAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
||||
@@ -124,7 +123,7 @@ namespace MQTTnet.Tests.Server
|
||||
Assert.AreEqual(100000, receivedMessages);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Handle_100_000_Messages_In_Server()
|
||||
{
|
||||
@@ -148,7 +147,7 @@ namespace MQTTnet.Tests.Server
|
||||
using (var client = await testEnvironment.ConnectClient())
|
||||
{
|
||||
var applicationMessageBuilder = new MqttApplicationMessageBuilder();
|
||||
|
||||
|
||||
for (var j = 0; j < 1000; j++)
|
||||
{
|
||||
var message = applicationMessageBuilder.WithTopic(j.ToString())
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Server.Internal;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
{
|
||||
@@ -14,8 +15,8 @@ namespace MQTTnet.Tests.Server
|
||||
public async Task MqttRetainedMessageManager_GetUndefinedTopic()
|
||||
{
|
||||
var logger = new Mockups.TestLogger();
|
||||
var eventContainer = new MQTTnet.Server.MqttServerEventContainer();
|
||||
var retainedMessagesManager = new MQTTnet.Server.MqttRetainedMessagesManager(eventContainer, logger);
|
||||
var eventContainer = new MqttServerEventContainer();
|
||||
var retainedMessagesManager = new MqttRetainedMessagesManager(eventContainer, logger);
|
||||
var task = retainedMessagesManager.GetMessage("undefined");
|
||||
Assert.IsNotNull(task, "Task should not be null");
|
||||
var result = await task;
|
||||
|
||||
@@ -10,6 +10,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
using MQTTnet.Server.Internal;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
@@ -17,7 +16,7 @@ namespace MQTTnet.Tests.Server
|
||||
{
|
||||
return ExecuteTest(true, 0);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public Task Subscribe_Without_No_Local()
|
||||
{
|
||||
@@ -31,19 +30,19 @@ namespace MQTTnet.Tests.Server
|
||||
using (var testEnvironment = CreateTestEnvironment(MqttProtocolVersion.V500))
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
var applicationMessageHandler = testEnvironment.CreateApplicationMessageHandler(client1);
|
||||
var topicFilter = testEnvironment.Factory.CreateTopicFilterBuilder().WithTopic("Topic").WithNoLocal(noLocal).Build();
|
||||
var topicFilter = testEnvironment.ClientFactory.CreateTopicFilterBuilder().WithTopic("Topic").WithNoLocal(noLocal).Build();
|
||||
await client1.SubscribeAsync(topicFilter);
|
||||
await LongTestDelay();
|
||||
|
||||
applicationMessageHandler.AssertReceivedCountEquals(0);
|
||||
|
||||
|
||||
// The client will publish a message where it is itself subscribing to.
|
||||
await client1.PublishStringAsync("Topic", "Payload", retain: true);
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
applicationMessageHandler.AssertReceivedCountEquals(expectedCountAfterPublish);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -79,29 +79,29 @@ namespace MQTTnet.Tests.Server
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var sender = await testEnvironment.ConnectClient();
|
||||
|
||||
|
||||
var receiver = await testEnvironment.ConnectClient();
|
||||
await receiver.SubscribeAsync("A");
|
||||
var receivedMessages = testEnvironment.CreateApplicationMessageHandler(receiver);
|
||||
|
||||
|
||||
await sender.PublishStringAsync("A", "Payload", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
receivedMessages.AssertReceivedCountEquals(1);
|
||||
|
||||
|
||||
server.InterceptingClientEnqueueAsync += e =>
|
||||
{
|
||||
e.AcceptEnqueue = false;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
await sender.PublishStringAsync("A", "Payload", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
// Do not increase because the internal enqueue to the target client is not accepted!
|
||||
receivedMessages.AssertReceivedCountEquals(1);
|
||||
}
|
||||
|
||||
@@ -5,165 +5,163 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
namespace MQTTnet.Tests.Server;
|
||||
|
||||
[TestClass]
|
||||
public sealed class QoS_Tests : BaseTestClass
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class QoS_Tests : BaseTestClass
|
||||
[TestMethod]
|
||||
public async Task Fire_Event_On_Client_Acknowledges_QoS_0()
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task Preserve_Message_Order_For_Queued_Messages()
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
ClientAcknowledgedPublishPacketEventArgs eventArgs = null;
|
||||
server.ClientAcknowledgedPublishPacketAsync += args =>
|
||||
{
|
||||
var server = await testEnvironment.StartServer(o => o.WithPersistentSessions());
|
||||
eventArgs = args;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
// Create a session which will contain the messages.
|
||||
var dummyClient = await testEnvironment.ConnectClient(o => o.WithClientId("A").WithCleanSession(false));
|
||||
await dummyClient.SubscribeAsync("#", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
dummyClient.Dispose();
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
await client1.SubscribeAsync("A");
|
||||
|
||||
await LongTestDelay();
|
||||
await LongTestDelay();
|
||||
|
||||
// Now inject messages which are appended to the queue of the client.
|
||||
await server.InjectApplicationMessage("T", "0", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await server.InjectApplicationMessage("T", "2", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await server.InjectApplicationMessage("T", "1", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await server.InjectApplicationMessage("T", "4", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await server.InjectApplicationMessage("T", "3", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await server.InjectApplicationMessage("T", "6", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await server.InjectApplicationMessage("T", "5", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await server.InjectApplicationMessage("T", "8", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await server.InjectApplicationMessage("T", "7", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await server.InjectApplicationMessage("T", "9", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
// Create a new client for the existing message.
|
||||
var client = await testEnvironment.ConnectClient(o => o.WithClientId("A").WithCleanSession(false));
|
||||
var messages = testEnvironment.CreateApplicationMessageHandler(client);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
var payloadSequence = messages.GeneratePayloadSequence();
|
||||
Assert.AreEqual("0214365879", payloadSequence);
|
||||
var client2 = await testEnvironment.ConnectClient();
|
||||
await client2.PublishStringAsync("A");
|
||||
|
||||
// Disconnect and reconnect to make sure that the server will not send the messages twice.
|
||||
await client.DisconnectAsync();
|
||||
await LongTestDelay();
|
||||
await client.ReconnectAsync();
|
||||
await LongTestDelay();
|
||||
|
||||
payloadSequence = messages.GeneratePayloadSequence();
|
||||
Assert.AreEqual("0214365879", payloadSequence);
|
||||
}
|
||||
await LongTestDelay();
|
||||
|
||||
// Must be null because no event should be fired for QoS 0.
|
||||
Assert.IsNull(eventArgs);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Event_On_Client_Acknowledges_QoS_0()
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Event_On_Client_Acknowledges_QoS_1()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
ClientAcknowledgedPublishPacketEventArgs eventArgs = null;
|
||||
server.ClientAcknowledgedPublishPacketAsync += args =>
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
eventArgs = args;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
ClientAcknowledgedPublishPacketEventArgs eventArgs = null;
|
||||
server.ClientAcknowledgedPublishPacketAsync += args =>
|
||||
{
|
||||
eventArgs = args;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
await client1.SubscribeAsync("A", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
await client1.SubscribeAsync("A");
|
||||
var client2 = await testEnvironment.ConnectClient();
|
||||
await client2.PublishStringAsync("A", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
var client2 = await testEnvironment.ConnectClient();
|
||||
await client2.PublishStringAsync("A");
|
||||
await LongTestDelay();
|
||||
|
||||
await LongTestDelay();
|
||||
Assert.IsNotNull(eventArgs);
|
||||
Assert.IsNotNull(eventArgs.PublishPacket);
|
||||
Assert.IsNotNull(eventArgs.AcknowledgePacket);
|
||||
Assert.IsTrue(eventArgs.IsCompleted);
|
||||
|
||||
// Must be null because no event should be fired for QoS 0.
|
||||
Assert.IsNull(eventArgs);
|
||||
}
|
||||
Assert.AreEqual("A", eventArgs.PublishPacket.Topic);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Event_On_Client_Acknowledges_QoS_1()
|
||||
[TestMethod]
|
||||
public async Task Fire_Event_On_Client_Acknowledges_QoS_2()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
var eventArgs = new List<ClientAcknowledgedPublishPacketEventArgs>();
|
||||
server.ClientAcknowledgedPublishPacketAsync += args =>
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
ClientAcknowledgedPublishPacketEventArgs eventArgs = null;
|
||||
server.ClientAcknowledgedPublishPacketAsync += args =>
|
||||
lock (eventArgs)
|
||||
{
|
||||
eventArgs = args;
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
eventArgs.Add(args);
|
||||
}
|
||||
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
await client1.SubscribeAsync("A", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
var client2 = await testEnvironment.ConnectClient();
|
||||
await client2.PublishStringAsync("A", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
await client1.SubscribeAsync("A", MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
|
||||
await LongTestDelay();
|
||||
var client2 = await testEnvironment.ConnectClient();
|
||||
await client2.PublishStringAsync("A", qualityOfServiceLevel: MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
|
||||
Assert.IsNotNull(eventArgs);
|
||||
Assert.IsNotNull(eventArgs.PublishPacket);
|
||||
Assert.IsNotNull(eventArgs.AcknowledgePacket);
|
||||
Assert.IsTrue(eventArgs.IsCompleted);
|
||||
await LongTestDelay();
|
||||
|
||||
Assert.AreEqual("A", eventArgs.PublishPacket.Topic);
|
||||
}
|
||||
Assert.AreEqual(1, eventArgs.Count);
|
||||
|
||||
var firstEvent = eventArgs[0];
|
||||
|
||||
Assert.IsNotNull(firstEvent);
|
||||
Assert.IsNotNull(firstEvent.PublishPacket);
|
||||
Assert.IsNotNull(firstEvent.AcknowledgePacket);
|
||||
Assert.IsTrue(firstEvent.IsCompleted);
|
||||
|
||||
Assert.AreEqual("A", firstEvent.PublishPacket.Topic);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Fire_Event_On_Client_Acknowledges_QoS_2()
|
||||
[TestMethod]
|
||||
public async Task Preserve_Message_Order_For_Queued_Messages()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
var server = await testEnvironment.StartServer(o => o.WithPersistentSessions());
|
||||
|
||||
var eventArgs = new List<ClientAcknowledgedPublishPacketEventArgs>();
|
||||
server.ClientAcknowledgedPublishPacketAsync += args =>
|
||||
{
|
||||
lock (eventArgs)
|
||||
{
|
||||
eventArgs.Add(args);
|
||||
}
|
||||
// Create a session which will contain the messages.
|
||||
var dummyClient = await testEnvironment.ConnectClient(o => o.WithClientId("A").WithCleanSession(false));
|
||||
await dummyClient.SubscribeAsync("#", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
dummyClient.Dispose();
|
||||
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
await LongTestDelay();
|
||||
await LongTestDelay();
|
||||
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
await client1.SubscribeAsync("A", MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
// Now inject messages which are appended to the queue of the client.
|
||||
await server.InjectApplicationMessage("T", "0", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
var client2 = await testEnvironment.ConnectClient();
|
||||
await client2.PublishStringAsync("A", qualityOfServiceLevel: MqttQualityOfServiceLevel.ExactlyOnce);
|
||||
await server.InjectApplicationMessage("T", "2", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await server.InjectApplicationMessage("T", "1", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await LongTestDelay();
|
||||
await server.InjectApplicationMessage("T", "4", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await server.InjectApplicationMessage("T", "3", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
Assert.AreEqual(1, eventArgs.Count);
|
||||
await server.InjectApplicationMessage("T", "6", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await server.InjectApplicationMessage("T", "5", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
var firstEvent = eventArgs[0];
|
||||
await server.InjectApplicationMessage("T", "8", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
await server.InjectApplicationMessage("T", "7", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
Assert.IsNotNull(firstEvent);
|
||||
Assert.IsNotNull(firstEvent.PublishPacket);
|
||||
Assert.IsNotNull(firstEvent.AcknowledgePacket);
|
||||
Assert.IsTrue(firstEvent.IsCompleted);
|
||||
await server.InjectApplicationMessage("T", "9", MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
Assert.AreEqual("A", firstEvent.PublishPacket.Topic);
|
||||
}
|
||||
await LongTestDelay();
|
||||
|
||||
// Create a new client for the existing message.
|
||||
var client = await testEnvironment.ConnectClient(o => o.WithClientId("A").WithCleanSession(false));
|
||||
var messages = testEnvironment.CreateApplicationMessageHandler(client);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
var payloadSequence = messages.GeneratePayloadSequence();
|
||||
Assert.AreEqual("0214365879", payloadSequence);
|
||||
|
||||
// Disconnect and reconnect to make sure that the server will not send the messages twice.
|
||||
await client.DisconnectAsync();
|
||||
await LongTestDelay();
|
||||
await client.ReconnectAsync();
|
||||
await LongTestDelay();
|
||||
|
||||
payloadSequence = messages.GeneratePayloadSequence();
|
||||
Assert.AreEqual("0214365879", payloadSequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Client;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
{
|
||||
@@ -32,7 +31,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
var applicationMessageHandler = testEnvironment.CreateApplicationMessageHandler(client1);
|
||||
var topicFilter = testEnvironment.Factory.CreateTopicFilterBuilder().WithTopic("Topic").WithRetainAsPublished(retainAsPublished).Build();
|
||||
var topicFilter = testEnvironment.ClientFactory.CreateTopicFilterBuilder().WithTopic("Topic").WithRetainAsPublished(retainAsPublished).Build();
|
||||
await client1.SubscribeAsync(topicFilter);
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Protocol;
|
||||
|
||||
@@ -18,13 +17,13 @@ namespace MQTTnet.Tests.Server
|
||||
{
|
||||
return ExecuteTest(MqttRetainHandling.SendAtSubscribe, 1, 2, 3);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public Task Do_Not_Send_On_Subscribe()
|
||||
{
|
||||
return ExecuteTest(MqttRetainHandling.DoNotSendOnSubscribe, 0, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public Task Send_At_Subscribe_If_New_Subscription_Only()
|
||||
{
|
||||
@@ -45,21 +44,21 @@ namespace MQTTnet.Tests.Server
|
||||
await client1.PublishStringAsync("Topic", "Payload", retain: true);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
var client2 = await testEnvironment.ConnectClient();
|
||||
var applicationMessageHandler = testEnvironment.CreateApplicationMessageHandler(client2);
|
||||
|
||||
var topicFilter = testEnvironment.Factory.CreateTopicFilterBuilder().WithTopic("Topic").WithRetainHandling(retainHandling).Build();
|
||||
|
||||
var topicFilter = testEnvironment.ClientFactory.CreateTopicFilterBuilder().WithTopic("Topic").WithRetainHandling(retainHandling).Build();
|
||||
await client2.SubscribeAsync(topicFilter);
|
||||
await LongTestDelay();
|
||||
|
||||
applicationMessageHandler.AssertReceivedCountEquals(expectedCountAfterSubscribe);
|
||||
|
||||
|
||||
await client1.PublishStringAsync("Topic", "Payload", retain: true);
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
applicationMessageHandler.AssertReceivedCountEquals(expectedCountAfterSecondPublish);
|
||||
|
||||
|
||||
await client2.SubscribeAsync(topicFilter);
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -242,7 +241,7 @@ namespace MQTTnet.Tests.Server
|
||||
var client = testEnvironment.CreateClient();
|
||||
|
||||
var connectResult = await client.ConnectAsync(
|
||||
testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V311)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.Build());
|
||||
@@ -260,7 +259,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
var client = testEnvironment.CreateClient();
|
||||
var connectResult = await client.ConnectAsync(
|
||||
testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V500)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.Build());
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Adapter;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -22,7 +21,7 @@ namespace MQTTnet.Tests.Server
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
|
||||
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var publishedApplicationMessages = new List<MqttApplicationMessage>();
|
||||
@@ -53,7 +52,7 @@ namespace MQTTnet.Tests.Server
|
||||
using (var validClient = testEnvironment.CreateClient())
|
||||
{
|
||||
await validClient.ConnectAsync(
|
||||
testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithTcpServer("localhost", testEnvironment.ServerPort)
|
||||
.WithCredentials("SECRET")
|
||||
.WithClientId("CLIENT")
|
||||
@@ -68,7 +67,7 @@ namespace MQTTnet.Tests.Server
|
||||
using (var invalidClient = testEnvironment.CreateClient())
|
||||
{
|
||||
await invalidClient.ConnectAsync(
|
||||
testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithTcpServer("localhost", testEnvironment.ServerPort)
|
||||
.WithCredentials("???")
|
||||
.WithClientId("CLIENT")
|
||||
@@ -81,15 +80,15 @@ namespace MQTTnet.Tests.Server
|
||||
}
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
await validClient.PublishStringAsync("HELLO 2");
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
await validClient.PublishStringAsync("HELLO 3");
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
|
||||
Assert.AreEqual(3, publishedApplicationMessages.Count);
|
||||
Assert.AreEqual(1, testEnvironment.Server.GetClientsAsync().GetAwaiter().GetResult().Count);
|
||||
}
|
||||
@@ -133,7 +132,6 @@ namespace MQTTnet.Tests.Server
|
||||
var ex = await Assert.ThrowsExceptionAsync<MqttConnectingFailedException>(async () => await client.ConnectAsync(clientOptions));
|
||||
Assert.IsInstanceOfType(ex.InnerException, typeof(MqttProtocolViolationException));
|
||||
Assert.AreEqual("Error while authenticating. If the User Name Flag is set to 0, the Password Flag MUST be set to 0 [MQTT-3.1.2-22].", ex.Message, false);
|
||||
Assert.AreEqual(MqttClientConnectResultCode.UnspecifiedError, ex.ResultCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +162,8 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).WithCredentials(userName, password).Build();
|
||||
|
||||
var ex = await Assert.ThrowsExceptionAsync<MqttConnectingFailedException>(() => client.ConnectAsync(clientOptions));
|
||||
Assert.AreEqual(MqttClientConnectResultCode.BadUserNameOrPassword, ex.Result.ResultCode);
|
||||
var response = await client.ConnectAsync(clientOptions);
|
||||
Assert.AreEqual(MqttClientConnectResultCode.BadUserNameOrPassword, response.ResultCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,51 +4,38 @@
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Adapter;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Implementations;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
namespace MQTTnet.Tests.Server;
|
||||
|
||||
[TestClass]
|
||||
public sealed class Server_Reference_Tests : BaseTestClass
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class Server_Reference_Tests : BaseTestClass
|
||||
[TestMethod]
|
||||
public async Task Server_Reports_With_Reference_Server()
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task Server_Reports_With_Reference_Server()
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
server.ValidatingConnectionAsync += e =>
|
||||
{
|
||||
testEnvironment.IgnoreClientLogErrors = true;
|
||||
|
||||
var server = await testEnvironment.StartServer();
|
||||
e.ReasonCode = MqttConnectReasonCode.ServerMoved;
|
||||
e.ServerReference = "new_server";
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
server.ValidatingConnectionAsync += e =>
|
||||
{
|
||||
e.ReasonCode = MqttConnectReasonCode.ServerMoved;
|
||||
e.ServerReference = "new_server";
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
var client = testEnvironment.CreateClient();
|
||||
|
||||
try
|
||||
{
|
||||
var client = testEnvironment.CreateClient();
|
||||
|
||||
await client.ConnectAsync(new MqttClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V500)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.Build());
|
||||
|
||||
Assert.Fail();
|
||||
}
|
||||
catch (MqttConnectingFailedException e)
|
||||
{
|
||||
Assert.AreEqual(MqttClientConnectResultCode.ServerMoved, e.ResultCode);
|
||||
Assert.AreEqual("new_server", e.Result.ServerReference);
|
||||
}
|
||||
}
|
||||
var response = await client.ConnectAsync(
|
||||
new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500).WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
|
||||
|
||||
Assert.AreEqual(MqttClientConnectResultCode.ServerMoved, response.ResultCode);
|
||||
Assert.AreEqual("new_server", response.ServerReference);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -51,7 +50,7 @@ namespace MQTTnet.Tests.Server
|
||||
// Reconnect the same client ID without clean session
|
||||
|
||||
var client2 = testEnvironment.CreateClient();
|
||||
var options = testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
var options = testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V311)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.WithSessionExpiryInterval(9999) // not relevant for v311 but testing impact
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
@@ -21,14 +20,14 @@ namespace MQTTnet.Tests.Server
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var client = testEnvironment.CreateClient();
|
||||
var connectResult = await client.ConnectAsync(testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
var connectResult = await client.ConnectAsync(testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V500)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
|
||||
|
||||
Assert.IsFalse(connectResult.SharedSubscriptionAvailable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Subscription_Of_Shared_Subscription_Is_Denied()
|
||||
{
|
||||
@@ -37,12 +36,12 @@ namespace MQTTnet.Tests.Server
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var client = testEnvironment.CreateClient();
|
||||
await client.ConnectAsync(testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
await client.ConnectAsync(testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V500)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
|
||||
|
||||
var subscribeResult = await client.SubscribeAsync("$share/A");
|
||||
|
||||
|
||||
Assert.AreEqual(MqttClientSubscribeResultCode.SharedSubscriptionsNotSupported, subscribeResult.Items.First().ResultCode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,159 +5,196 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
namespace MQTTnet.Tests.Server;
|
||||
|
||||
[TestClass]
|
||||
public sealed class Status_Tests : BaseTestClass
|
||||
{
|
||||
[TestClass]
|
||||
public sealed class Status_Tests : BaseTestClass
|
||||
[TestMethod]
|
||||
public async Task Disconnect_Client()
|
||||
{
|
||||
[TestMethod]
|
||||
public async Task Show_Client_And_Session_Statistics()
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client1"));
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
|
||||
Assert.AreEqual(1, clientStatus.Count);
|
||||
Assert.IsTrue(clientStatus.Any(s => s.Id == c1.Options.ClientId));
|
||||
|
||||
await clientStatus.First().DisconnectAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
Assert.IsFalse(c1.IsConnected);
|
||||
|
||||
clientStatus = await server.GetClientsAsync();
|
||||
|
||||
Assert.AreEqual(0, clientStatus.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Keep_Persistent_Session_Version311()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer(o => o.WithPersistentSessions());
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(
|
||||
new MqttClientOptionsBuilder().WithClientId("client1").WithCleanSession(false).WithProtocolVersion(MqttProtocolVersion.V311));
|
||||
var c2 = await testEnvironment.ConnectClient(
|
||||
new MqttClientOptionsBuilder().WithClientId("client2").WithCleanSession(false).WithProtocolVersion(MqttProtocolVersion.V311));
|
||||
|
||||
await c1.DisconnectAsync();
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
var sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(1, clientStatus.Count);
|
||||
Assert.AreEqual(2, sessionStatus.Count);
|
||||
|
||||
await c2.DisconnectAsync();
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
clientStatus = await server.GetClientsAsync();
|
||||
sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(0, clientStatus.Count);
|
||||
Assert.AreEqual(2, sessionStatus.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Keep_Persistent_Session_Version500()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer(o => o.WithPersistentSessions());
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(
|
||||
new MqttClientOptionsBuilder().WithClientId("client1").WithCleanSession(false).WithProtocolVersion(MqttProtocolVersion.V500));
|
||||
var c2 = await testEnvironment.ConnectClient(
|
||||
new MqttClientOptionsBuilder().WithClientId("client2").WithCleanSession(false).WithProtocolVersion(MqttProtocolVersion.V500));
|
||||
|
||||
// The session expiry interval is mandatory for MQTT5.0.0 in order keep session!
|
||||
await c1.DisconnectAsync(sessionExpiryInterval: 60);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
var sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(1, clientStatus.Count);
|
||||
Assert.AreEqual(2, sessionStatus.Count);
|
||||
|
||||
// The session expiry interval is mandatory for MQTT5.0.0 in order keep session!
|
||||
await c2.DisconnectAsync(sessionExpiryInterval: 60);
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
clientStatus = await server.GetClientsAsync();
|
||||
sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(0, clientStatus.Count);
|
||||
Assert.AreEqual(2, sessionStatus.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Show_Client_And_Session_Statistics()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client1"));
|
||||
var c2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client2"));
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
var sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(2, clientStatus.Count);
|
||||
Assert.AreEqual(2, sessionStatus.Count);
|
||||
|
||||
Assert.IsTrue(clientStatus.Any(s => s.Id == c1.Options.ClientId));
|
||||
Assert.IsTrue(clientStatus.Any(s => s.Id == c2.Options.ClientId));
|
||||
|
||||
await c1.DisconnectAsync();
|
||||
await c2.DisconnectAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
clientStatus = await server.GetClientsAsync();
|
||||
sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(0, clientStatus.Count);
|
||||
Assert.AreEqual(0, sessionStatus.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Track_Sent_Application_Messages()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithPersistentSessions());
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient();
|
||||
|
||||
for (var i = 1; i < 25; i++)
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client1"));
|
||||
var c2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client2"));
|
||||
|
||||
await Task.Delay(500);
|
||||
await c1.PublishStringAsync("a");
|
||||
await Task.Delay(50);
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
var sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(2, clientStatus.Count);
|
||||
Assert.AreEqual(2, sessionStatus.Count);
|
||||
|
||||
Assert.IsTrue(clientStatus.Any(s => s.Id == c1.Options.ClientId));
|
||||
Assert.IsTrue(clientStatus.Any(s => s.Id == c2.Options.ClientId));
|
||||
|
||||
await c1.DisconnectAsync();
|
||||
await c2.DisconnectAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
clientStatus = await server.GetClientsAsync();
|
||||
sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(0, clientStatus.Count);
|
||||
Assert.AreEqual(0, sessionStatus.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Disconnect_Client()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer();
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client1"));
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
|
||||
Assert.AreEqual(1, clientStatus.Count);
|
||||
Assert.IsTrue(clientStatus.Any(s => s.Id == c1.Options.ClientId));
|
||||
|
||||
await clientStatus.First().DisconnectAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
Assert.IsFalse(c1.IsConnected);
|
||||
|
||||
clientStatus = await server.GetClientsAsync();
|
||||
|
||||
Assert.AreEqual(0, clientStatus.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Keep_Persistent_Session()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithPersistentSessions());
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client1").WithCleanSession(false));
|
||||
var c2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("client2").WithCleanSession(false));
|
||||
|
||||
await c1.DisconnectAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
var sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(1, clientStatus.Count);
|
||||
Assert.AreEqual(2, sessionStatus.Count);
|
||||
|
||||
await c2.DisconnectAsync();
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
clientStatus = await server.GetClientsAsync();
|
||||
sessionStatus = await server.GetSessionsAsync();
|
||||
|
||||
Assert.AreEqual(0, clientStatus.Count);
|
||||
Assert.AreEqual(2, sessionStatus.Count);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Track_Sent_Application_Messages()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithPersistentSessions());
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient();
|
||||
|
||||
for (var i = 1; i < 25; i++)
|
||||
{
|
||||
await c1.PublishStringAsync("a");
|
||||
await Task.Delay(50);
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
Assert.AreEqual(i, clientStatus.First().SentApplicationMessagesCount);
|
||||
Assert.AreEqual(0, clientStatus.First().ReceivedApplicationMessagesCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Track_Sent_Packets()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithPersistentSessions());
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithNoKeepAlive());
|
||||
|
||||
for (var i = 1; i < 25; i++)
|
||||
{
|
||||
// At most once will send one packet to the client and the server will reply
|
||||
// with an additional ACK packet.
|
||||
await c1.PublishStringAsync("a", string.Empty, MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
|
||||
Assert.AreEqual(i, clientStatus.First().SentApplicationMessagesCount, "SAMC invalid!");
|
||||
|
||||
// + 1 because CONNECT is also counted.
|
||||
Assert.AreEqual(i + 1, clientStatus.First().SentPacketsCount, "SPC invalid!");
|
||||
|
||||
// +2 because ConnACK + PubAck package is already counted.
|
||||
Assert.AreEqual(i + 2, clientStatus.First().ReceivedPacketsCount, "RPC invalid!");
|
||||
}
|
||||
Assert.AreEqual(i, clientStatus.First().SentApplicationMessagesCount);
|
||||
Assert.AreEqual(0, clientStatus.First().ReceivedApplicationMessagesCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task Track_Sent_Packets()
|
||||
{
|
||||
using (var testEnvironment = new TestEnvironment(TestContext))
|
||||
{
|
||||
var server = await testEnvironment.StartServer(new MqttServerOptionsBuilder().WithPersistentSessions());
|
||||
|
||||
var c1 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithNoKeepAlive());
|
||||
|
||||
for (var i = 1; i < 25; i++)
|
||||
{
|
||||
// At most once will send one packet to the client and the server will reply
|
||||
// with an additional ACK packet.
|
||||
await c1.PublishStringAsync("a", string.Empty, MqttQualityOfServiceLevel.AtLeastOnce);
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
var clientStatus = await server.GetClientsAsync();
|
||||
|
||||
Assert.AreEqual(i, clientStatus.First().SentApplicationMessagesCount, "SAMC invalid!");
|
||||
|
||||
// + 1 because CONNECT is also counted.
|
||||
Assert.AreEqual(i + 1, clientStatus.First().SentPacketsCount, "SPC invalid!");
|
||||
|
||||
// +2 because ConnACK + PubAck package is already counted.
|
||||
Assert.AreEqual(i + 2, clientStatus.First().ReceivedPacketsCount, "RPC invalid!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Packets;
|
||||
@@ -106,7 +106,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
var client = await testEnvironment.ConnectClient();
|
||||
|
||||
var subscribeOptions = testEnvironment.Factory.CreateSubscribeOptionsBuilder().WithTopicFilter("X").WithUserProperty("A", "1").Build();
|
||||
var subscribeOptions = testEnvironment.ClientFactory.CreateSubscribeOptionsBuilder().WithTopicFilter("X").WithUserProperty("A", "1").Build();
|
||||
await client.SubscribeAsync(subscribeOptions);
|
||||
|
||||
CollectionAssert.AreEqual(subscribeOptions.UserProperties.ToList(), eventArgs.UserProperties);
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
@@ -18,33 +17,33 @@ namespace MQTTnet.Tests.Server
|
||||
using (var testEnvironment = CreateTestEnvironment(MqttProtocolVersion.V500))
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var client = testEnvironment.CreateClient();
|
||||
var connectResult = await client.ConnectAsync(testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
var connectResult = await client.ConnectAsync(testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V500)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
|
||||
|
||||
Assert.IsTrue(connectResult.SubscriptionIdentifiersAvailable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Subscribe_With_Subscription_Identifier()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment(MqttProtocolVersion.V500))
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
var applicationMessageHandler = testEnvironment.CreateApplicationMessageHandler(client1);
|
||||
var topicFilter = testEnvironment.Factory.CreateTopicFilterBuilder().WithTopic("Topic").Build();
|
||||
var subscribeOptions = testEnvironment.Factory.CreateSubscribeOptionsBuilder().WithSubscriptionIdentifier(456).WithTopicFilter(topicFilter).Build();
|
||||
|
||||
var topicFilter = testEnvironment.ClientFactory.CreateTopicFilterBuilder().WithTopic("Topic").Build();
|
||||
var subscribeOptions = testEnvironment.ClientFactory.CreateSubscribeOptionsBuilder().WithSubscriptionIdentifier(456).WithTopicFilter(topicFilter).Build();
|
||||
|
||||
await client1.SubscribeAsync(subscribeOptions);
|
||||
await LongTestDelay();
|
||||
|
||||
applicationMessageHandler.AssertReceivedCountEquals(0);
|
||||
|
||||
|
||||
// The client will publish a message where it is itself subscribing to.
|
||||
await client1.PublishStringAsync("Topic", "Payload", retain: true);
|
||||
await LongTestDelay();
|
||||
@@ -54,31 +53,31 @@ namespace MQTTnet.Tests.Server
|
||||
applicationMessageHandler.ReceivedEventArgs[0].ApplicationMessage.SubscriptionIdentifiers.Contains(456);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Subscribe_With_Multiple_Subscription_Identifiers()
|
||||
{
|
||||
using (var testEnvironment = CreateTestEnvironment(MqttProtocolVersion.V500))
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var client1 = await testEnvironment.ConnectClient();
|
||||
var applicationMessageHandler = testEnvironment.CreateApplicationMessageHandler(client1);
|
||||
|
||||
var topicFilter = testEnvironment.Factory.CreateTopicFilterBuilder().WithTopic("Topic/A").Build();
|
||||
var subscribeOptions = testEnvironment.Factory.CreateSubscribeOptionsBuilder().WithSubscriptionIdentifier(456).WithTopicFilter(topicFilter).Build();
|
||||
|
||||
var topicFilter = testEnvironment.ClientFactory.CreateTopicFilterBuilder().WithTopic("Topic/A").Build();
|
||||
var subscribeOptions = testEnvironment.ClientFactory.CreateSubscribeOptionsBuilder().WithSubscriptionIdentifier(456).WithTopicFilter(topicFilter).Build();
|
||||
await client1.SubscribeAsync(subscribeOptions);
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
topicFilter = testEnvironment.Factory.CreateTopicFilterBuilder().WithTopic("Topic/+").Build();
|
||||
subscribeOptions = testEnvironment.Factory.CreateSubscribeOptionsBuilder().WithSubscriptionIdentifier(789).WithTopicFilter(topicFilter).Build();
|
||||
|
||||
topicFilter = testEnvironment.ClientFactory.CreateTopicFilterBuilder().WithTopic("Topic/+").Build();
|
||||
subscribeOptions = testEnvironment.ClientFactory.CreateSubscribeOptionsBuilder().WithSubscriptionIdentifier(789).WithTopicFilter(topicFilter).Build();
|
||||
await client1.SubscribeAsync(subscribeOptions);
|
||||
|
||||
|
||||
await LongTestDelay();
|
||||
|
||||
applicationMessageHandler.AssertReceivedCountEquals(0);
|
||||
|
||||
|
||||
// The client will publish a message where it is itself subscribing to.
|
||||
await client1.PublishStringAsync("Topic/A", "Payload", retain: true);
|
||||
await LongTestDelay();
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Packets;
|
||||
using MQTTnet.Protocol;
|
||||
using MQTTnet.Server;
|
||||
using MQTTnet.Server.Internal;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#if !WINDOWS_UWP && (NET48_OR_GREATER || NET5_0_OR_GREATER)
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
@@ -9,7 +8,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Certificates;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Server;
|
||||
using MQTTnet.Tests.Mockups;
|
||||
@@ -25,7 +23,7 @@ namespace MQTTnet.Tests.Server
|
||||
sanBuilder.AddIpAddress(IPAddress.Loopback);
|
||||
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
|
||||
sanBuilder.AddDnsName("localhost");
|
||||
|
||||
|
||||
using (var rsa = RSA.Create())
|
||||
{
|
||||
var certRequest = new CertificateRequest("CN=localhost", rsa, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
|
||||
@@ -53,7 +51,7 @@ namespace MQTTnet.Tests.Server
|
||||
public async Task Tls_Swap_Test()
|
||||
{
|
||||
var testEnvironment = CreateTestEnvironment(MqttProtocolVersion.V500);
|
||||
var serverOptionsBuilder = testEnvironment.Factory.CreateServerOptionsBuilder();
|
||||
var serverOptionsBuilder = testEnvironment.ServerFactory.CreateServerOptionsBuilder();
|
||||
|
||||
var firstOid = "1.3.6.1.5.5.7.3.1";
|
||||
var secondOid = "1.3.6.1.5.5.7.3.2";
|
||||
@@ -175,7 +173,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
static async Task<IMqttClient> ConnectClientAsync(TestEnvironment testEnvironment, Func<MqttClientCertificateValidationEventArgs, bool> certValidator)
|
||||
{
|
||||
var clientOptionsBuilder = testEnvironment.Factory.CreateClientOptionsBuilder();
|
||||
var clientOptionsBuilder = testEnvironment.ClientFactory.CreateClientOptionsBuilder();
|
||||
clientOptionsBuilder.WithClientId(Guid.NewGuid().ToString())
|
||||
.WithTcpServer("localhost", 8883)
|
||||
.WithTlsOptions(
|
||||
@@ -187,7 +185,7 @@ namespace MQTTnet.Tests.Server
|
||||
var clientOptions = clientOptionsBuilder.Build();
|
||||
return await testEnvironment.ConnectClient(clientOptions);
|
||||
}
|
||||
|
||||
|
||||
sealed class CertificateProvider : ICertificateProvider
|
||||
{
|
||||
public X509Certificate2 CurrentCertificate { get; set; }
|
||||
@@ -199,4 +197,3 @@ namespace MQTTnet.Tests.Server
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
|
||||
@@ -21,18 +20,18 @@ namespace MQTTnet.Tests.Server
|
||||
using (var testEnvironment = CreateTestEnvironment())
|
||||
{
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
|
||||
var client = testEnvironment.CreateClient();
|
||||
|
||||
|
||||
var connectResult = await client.ConnectAsync(new MqttClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V500)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
|
||||
.Build());
|
||||
|
||||
|
||||
Assert.AreEqual(connectResult.TopicAliasMaximum, ushort.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Publish_With_Topic_Alias()
|
||||
{
|
||||
@@ -49,7 +48,7 @@ namespace MQTTnet.Tests.Server
|
||||
{
|
||||
receivedTopics.Add(e.ApplicationMessage.Topic);
|
||||
}
|
||||
|
||||
|
||||
return CompletedTask.Instance;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Exceptions;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
@@ -49,7 +49,7 @@ namespace MQTTnet.Tests.Server
|
||||
|
||||
var client = await testEnvironment.ConnectClient();
|
||||
|
||||
var unsubscribeOptions = testEnvironment.Factory.CreateUnsubscribeOptionsBuilder().WithTopicFilter("X").WithUserProperty("A", "1").Build();
|
||||
var unsubscribeOptions = testEnvironment.ClientFactory.CreateUnsubscribeOptionsBuilder().WithTopicFilter("X").WithUserProperty("A", "1").Build();
|
||||
await client.UnsubscribeAsync(unsubscribeOptions);
|
||||
|
||||
CollectionAssert.AreEqual(unsubscribeOptions.UserProperties.ToList(), eventArgs.UserProperties);
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
using MQTTnet.Implementations;
|
||||
using MQTTnet.Internal;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Formatter;
|
||||
|
||||
namespace MQTTnet.Tests.Server
|
||||
@@ -20,14 +19,14 @@ namespace MQTTnet.Tests.Server
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var client = testEnvironment.CreateClient();
|
||||
var connectResult = await client.ConnectAsync(testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
var connectResult = await client.ConnectAsync(testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V311)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
|
||||
|
||||
Assert.IsTrue(connectResult.WildcardSubscriptionAvailable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public async Task Server_Reports_Wildcard_Subscription_Available_Tests_Supported_V5()
|
||||
{
|
||||
@@ -36,7 +35,7 @@ namespace MQTTnet.Tests.Server
|
||||
await testEnvironment.StartServer();
|
||||
|
||||
var client = testEnvironment.CreateClient();
|
||||
var connectResult = await client.ConnectAsync(testEnvironment.Factory.CreateClientOptionsBuilder()
|
||||
var connectResult = await client.ConnectAsync(testEnvironment.ClientFactory.CreateClientOptionsBuilder()
|
||||
.WithProtocolVersion(MqttProtocolVersion.V500)
|
||||
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Internal;
|
||||
using MQTTnet.Protocol;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using MQTTnet.Server;
|
||||
using MQTTnet.Server.Internal;
|
||||
|
||||
namespace MQTTnet.Tests
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user