Update nugets (#2210)

* Upate nugets, fix breaking changes

* Fix CI build
This commit is contained in:
Christian
2025-10-17 21:29:46 +02:00
committed by GitHub
parent e7ccd897b0
commit 7ac7f256ef
57 changed files with 688 additions and 647 deletions
@@ -0,0 +1,3 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
[assembly: DoNotParallelize]
@@ -18,7 +18,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="BenchmarkDotNet" Version="0.15.4" />
</ItemGroup>
<ItemGroup>
@@ -24,6 +24,6 @@ public class RoundtripProcessingBenchmark : BaseBenchmark
[Benchmark]
public void Handle_100_000_Messages_In_Receiving_Client()
{
new Load_Tests().Handle_100_000_Messages_In_Receiving_Client().GetAwaiter().GetResult();
//new Load_Tests().Handle_100_000_Messages_In_Receiving_Client().GetAwaiter().GetResult();
}
}
@@ -28,12 +28,12 @@ public class ServerProcessingBenchmark : BaseBenchmark
[Benchmark]
public void Handle_100_000_Messages_In_Server_MqttClient()
{
new Load_Tests().Handle_100_000_Messages_In_Server().GetAwaiter().GetResult();
//new Load_Tests().Handle_100_000_Messages_In_Server().GetAwaiter().GetResult();
}
//[Benchmark]
[Benchmark]
public void Handle_100_000_Messages_In_Server_LowLevelMqttClient()
{
new Load_Tests().Handle_100_000_Messages_In_Low_Level_Client().GetAwaiter().GetResult();
//new Load_Tests().Handle_100_000_Messages_In_Low_Level_Client().GetAwaiter().GetResult();
}
}
@@ -48,7 +48,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
<PackageReference Include="System.ValueTuple" Version="4.6.1" />
</ItemGroup>
@@ -87,10 +87,6 @@ public sealed class MqttRetainedMessagesManager
}
}
if (saveIsRequired && hasHandlers)
{
messagesForSave = new List<MqttApplicationMessage>(_messages.Values);
}
_logger.Verbose("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
}
@@ -102,10 +98,13 @@ public sealed class MqttRetainedMessagesManager
if (saveIsRequired)
{
using (await _storageAccessLock.EnterAsync().ConfigureAwait(false))
if (_eventContainer.RetainedMessageChangedEvent.HasHandlers)
{
var eventArgs = new RetainedMessageChangedEventArgs(clientId, applicationMessage, messagesForSave);
await _eventContainer.RetainedMessageChangedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
using (await _storageAccessLock.EnterAsync().ConfigureAwait(false))
{
var eventArgs = new RetainedMessageChangedEventArgs(clientId, applicationMessage, messagesForSave);
await _eventContainer.RetainedMessageChangedEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
}
}
}
}
@@ -17,7 +17,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
<ItemGroup>
@@ -33,10 +33,10 @@ public class MqttConnectionContextTest
await pipe.Receive.Writer.WriteAsync(writer.AddMqttHeader(MqttControlPacketType.Connect, []));
await Assert.ThrowsExceptionAsync<MqttProtocolViolationException>(() => ctx.ReceivePacketAsync(CancellationToken.None));
await Assert.ThrowsExactlyAsync<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)).ConfigureAwait(false);
await Assert.ThrowsExactlyAsync<InvalidOperationException>(() => ctx.ReceivePacketAsync(CancellationToken.None)).ConfigureAwait(false);
}
// TODO: Fix test
@@ -102,7 +102,7 @@ public class MqttConnectionContextTest
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);
Assert.IsGreaterThan(20000, readResult.Buffer.Length);
}
[TestMethod]
@@ -116,7 +116,7 @@ public class MqttConnectionContextTest
await pipe.Receive.Writer.CompleteAsync();
await Assert.ThrowsExceptionAsync<MqttCommunicationException>(() => ctx.ReceivePacketAsync(CancellationToken.None)).ConfigureAwait(false);
await Assert.ThrowsExactlyAsync<MqttCommunicationException>(() => ctx.ReceivePacketAsync(CancellationToken.None)).ConfigureAwait(false);
}
class Startup
+3
View File
@@ -0,0 +1,3 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
[assembly: DoNotParallelize]
@@ -31,9 +31,9 @@ public sealed class LowLevelMqttClient_Tests : BaseTestClass
await lowLevelClient.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build(), CancellationToken.None);
var receivedPacket = await Authenticate(lowLevelClient).ConfigureAwait(false);
var receivedPacket = await Authenticate(lowLevelClient);
await lowLevelClient.DisconnectAsync(CancellationToken.None).ConfigureAwait(false);
await lowLevelClient.DisconnectAsync(CancellationToken.None);
Assert.IsNotNull(receivedPacket);
Assert.AreEqual(MqttConnectReturnCode.ConnectionAccepted, receivedPacket.ReturnCode);
@@ -53,23 +53,27 @@ public sealed class LowLevelMqttClient_Tests : BaseTestClass
}
[TestMethod]
[ExpectedException(typeof(MqttCommunicationException))]
public async Task Connect_To_Not_Existing_Broker()
public Task Connect_To_Not_Existing_Broker()
{
var client = new MqttClientFactory().CreateLowLevelMqttClient();
var options = new MqttClientOptionsBuilder().WithTcpServer("localhost").Build();
return Assert.ThrowsExactlyAsync<MqttCommunicationException>(async () =>
{
var client = new MqttClientFactory().CreateLowLevelMqttClient();
var options = new MqttClientOptionsBuilder().WithTcpServer("localhost").Build();
await client.ConnectAsync(options, CancellationToken.None).ConfigureAwait(false);
await client.ConnectAsync(options, CancellationToken.None);
});
}
[TestMethod]
[ExpectedException(typeof(MqttCommunicationException))]
public async Task Connect_To_Wrong_Host()
public Task Connect_To_Wrong_Host()
{
var client = new MqttClientFactory().CreateLowLevelMqttClient();
var options = new MqttClientOptionsBuilder().WithTcpServer("123.456.789.10").Build();
return Assert.ThrowsExactlyAsync<MqttCommunicationException>(async () =>
{
var client = new MqttClientFactory().CreateLowLevelMqttClient();
var options = new MqttClientOptionsBuilder().WithTcpServer("123.456.789.10").Build();
await client.ConnectAsync(options, CancellationToken.None).ConfigureAwait(false);
await client.ConnectAsync(options, CancellationToken.None);
});
}
[TestMethod]
@@ -83,7 +87,7 @@ public sealed class LowLevelMqttClient_Tests : BaseTestClass
var client = await testEnvironment.ConnectLowLevelClient(o => o.WithTimeout(TimeSpan.Zero));
await Authenticate(client).ConfigureAwait(false);
await Authenticate(client);
await server.StopAsync();
@@ -91,9 +95,9 @@ public sealed class LowLevelMqttClient_Tests : BaseTestClass
try
{
await client.SendAsync(MqttPingReqPacket.Instance, CancellationToken.None).ConfigureAwait(false);
await client.SendAsync(MqttPingReqPacket.Instance, CancellationToken.None);
await Task.Delay(2000);
await client.SendAsync(MqttPingReqPacket.Instance, CancellationToken.None).ConfigureAwait(false);
await client.SendAsync(MqttPingReqPacket.Instance, CancellationToken.None);
}
catch (MqttCommunicationException exception)
{
@@ -159,11 +163,11 @@ public sealed class LowLevelMqttClient_Tests : BaseTestClass
await lowLevelClient.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build(), CancellationToken.None);
await Authenticate(lowLevelClient).ConfigureAwait(false);
await Authenticate(lowLevelClient);
var receivedPacket = await Subscribe(lowLevelClient, "a").ConfigureAwait(false);
var receivedPacket = await Subscribe(lowLevelClient, "a");
await lowLevelClient.DisconnectAsync(CancellationToken.None).ConfigureAwait(false);
await lowLevelClient.DisconnectAsync(CancellationToken.None);
Assert.IsNotNull(receivedPacket);
Assert.AreEqual(MqttSubscribeReasonCode.GrantedQoS0, receivedPacket.ReasonCodes[0]);
@@ -179,10 +183,9 @@ public sealed class LowLevelMqttClient_Tests : BaseTestClass
Username = "user",
Password = Encoding.UTF8.GetBytes("pass")
},
CancellationToken.None)
.ConfigureAwait(false);
CancellationToken.None);
return await client.ReceiveAsync(CancellationToken.None).ConfigureAwait(false) as MqttConnAckPacket;
return await client.ReceiveAsync(CancellationToken.None) as MqttConnAckPacket;
}
async Task<MqttSubAckPacket> Subscribe(ILowLevelMqttClient client, string topic)
@@ -199,9 +202,8 @@ public sealed class LowLevelMqttClient_Tests : BaseTestClass
}
}
},
CancellationToken.None)
.ConfigureAwait(false);
CancellationToken.None);
return await client.ReceiveAsync(CancellationToken.None).ConfigureAwait(false) as MqttSubAckPacket;
return await client.ReceiveAsync(CancellationToken.None) as MqttSubAckPacket;
}
}
@@ -21,29 +21,35 @@ namespace MQTTnet.Tests.Clients.MqttClient;
public sealed class MqttClient_Connection_Tests : BaseTestClass
{
[TestMethod]
[ExpectedException(typeof(MqttCommunicationException))]
public async Task Connect_To_Invalid_Server_Port_Not_Opened()
public Task Connect_To_Invalid_Server_Port_Not_Opened()
{
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);
return Assert.ThrowsExactlyAsync<MqttCommunicationException>(async () =>
{
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);
});
}
[TestMethod]
[ExpectedException(typeof(OperationCanceledException))]
public async Task Connect_To_Invalid_Server_Wrong_IP()
public Task Connect_To_Invalid_Server_Wrong_IP()
{
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);
return Assert.ThrowsExactlyAsync<OperationCanceledException>(async () =>
{
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);
});
}
[TestMethod]
[ExpectedException(typeof(MqttCommunicationException))]
public async Task Connect_To_Invalid_Server_Wrong_Protocol()
public Task Connect_To_Invalid_Server_Wrong_Protocol()
{
var client = new MqttClientFactory().CreateMqttClient();
await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("http://127.0.0.1", 12345).WithTimeout(TimeSpan.FromSeconds(2)).Build()).ConfigureAwait(false);
return Assert.ThrowsExactlyAsync<MqttCommunicationException>(async () =>
{
var client = new MqttClientFactory().CreateMqttClient();
await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("http://127.0.0.1", 12345).WithTimeout(TimeSpan.FromSeconds(2)).Build());
});
}
[TestMethod]
@@ -150,7 +156,7 @@ public sealed class MqttClient_Connection_Tests : BaseTestClass
Assert.IsNotNull(eventArgs);
Assert.IsNotNull(eventArgs.UserProperties);
Assert.AreEqual(1, eventArgs.UserProperties.Count);
Assert.HasCount(1, eventArgs.UserProperties);
Assert.AreEqual("test_name", eventArgs.UserProperties[0].Name);
Assert.AreEqual("test_value", eventArgs.UserProperties[0].Value);
}
@@ -173,7 +179,7 @@ public sealed class MqttClient_Connection_Tests : BaseTestClass
var response = await eventArgs.ReceiveAsync(eventArgs.CancellationToken);
Assert.AreEqual(Encoding.UTF8.GetString(response.AuthenticationData), "reply context token");
Assert.AreEqual("reply context token", Encoding.UTF8.GetString(response.AuthenticationData));
// No further data is required, but we have to fulfil the exchange.
sendOptions = new SendMqttEnhancedAuthenticationDataOptions
@@ -181,7 +187,7 @@ public sealed class MqttClient_Connection_Tests : BaseTestClass
Data = []
};
await eventArgs.SendAsync(sendOptions, eventArgs.CancellationToken).ConfigureAwait(false);
await eventArgs.SendAsync(sendOptions, eventArgs.CancellationToken);
}
}
@@ -197,13 +203,13 @@ public sealed class MqttClient_Connection_Tests : BaseTestClass
{
var result = await args.ExchangeEnhancedAuthenticationAsync(new ExchangeEnhancedAuthenticationOptions(), args.CancellationToken);
Assert.AreEqual(Encoding.UTF8.GetString(result.AuthenticationData), "initial context token");
Assert.AreEqual("initial context token", Encoding.UTF8.GetString(result.AuthenticationData));
var authOptions = testEnvironment.ServerFactory.CreateExchangeExtendedAuthenticationOptionsBuilder().WithAuthenticationData("reply context token").Build();
result = await args.ExchangeEnhancedAuthenticationAsync(authOptions, args.CancellationToken);
Assert.AreEqual(Encoding.UTF8.GetString(result.AuthenticationData), "");
Assert.AreEqual(string.Empty, Encoding.UTF8.GetString(result.AuthenticationData));
args.ResponseAuthenticationData = "outcome of authentication"u8.ToArray();
}
@@ -271,8 +277,8 @@ public sealed class MqttClient_Connection_Tests : BaseTestClass
Assert.IsNotNull(response);
Assert.AreEqual(MqttClientConnectResultCode.QuotaExceeded, response.ResultCode);
Assert.AreEqual(response.UserProperties[0].Name, "Property");
Assert.AreEqual(response.UserProperties[0].Value, "Value");
Assert.AreEqual("Property", response.UserProperties[0].Name);
Assert.AreEqual("Value", response.UserProperties[0].Value);
}
[TestMethod]
@@ -83,17 +83,19 @@ public sealed class MqttClient_Tests : BaseTestClass
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task Connect_Multiple_Times_Should_Fail()
public Task Connect_Multiple_Times_Should_Fail()
{
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer();
return Assert.ThrowsExactlyAsync<InvalidOperationException>(async () =>
{
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer();
var clientOptions = testEnvironment.CreateDefaultClientOptions();
var client = testEnvironment.CreateClient();
var clientOptions = testEnvironment.CreateDefaultClientOptions();
var client = testEnvironment.CreateClient();
await client.ConnectAsync(clientOptions);
await client.ConnectAsync(clientOptions);
await client.ConnectAsync(clientOptions);
await client.ConnectAsync(clientOptions);
});
}
[TestMethod]
@@ -208,8 +210,8 @@ public sealed class MqttClient_Tests : BaseTestClass
Assert.IsTrue(clients[99].TryPingAsync().GetAwaiter().GetResult());
Assert.AreEqual(1, clientStatus.Count);
Assert.AreEqual(1, sessionStatus.Count);
Assert.HasCount(1, clientStatus);
Assert.HasCount(1, sessionStatus);
var receiveClient = clients[99];
object receivedPayload = null;
@@ -317,10 +319,10 @@ public sealed class MqttClient_Tests : BaseTestClass
var client = await testEnvironment.ConnectClient();
var result = await client.PublishStringAsync("a", "a");
Assert.AreEqual(null, result.PacketIdentifier);
Assert.IsNull(result.PacketIdentifier);
result = await client.PublishStringAsync("b", "b");
Assert.AreEqual(null, result.PacketIdentifier);
Assert.IsNull(result.PacketIdentifier);
result = await client.PublishStringAsync("a", "a", MqttQualityOfServiceLevel.AtLeastOnce);
Assert.AreEqual((ushort)1, result.PacketIdentifier);
@@ -470,7 +472,7 @@ public sealed class MqttClient_Tests : BaseTestClass
var client1 = await testEnvironment.ConnectClient();
client1.ApplicationMessageReceivedAsync += async _ =>
{
await client1.PublishStringAsync(client2Topic, expectedClient2Message, MqttQualityOfServiceLevel.AtLeastOnce).ConfigureAwait(false);
await client1.PublishStringAsync(client2Topic, expectedClient2Message, MqttQualityOfServiceLevel.AtLeastOnce);
};
await client1.SubscribeAsync(client1Topic, MqttQualityOfServiceLevel.AtLeastOnce);
@@ -494,7 +496,7 @@ public sealed class MqttClient_Tests : BaseTestClass
await Task.Delay(500);
Assert.AreEqual(2, client2TopicResults.Count);
Assert.HasCount(2, client2TopicResults);
Assert.AreEqual(expectedClient2Message, client2TopicResults[0]);
Assert.AreEqual(expectedClient2Message, client2TopicResults[1]);
}
@@ -526,7 +528,7 @@ public sealed class MqttClient_Tests : BaseTestClass
await Task.Delay(500);
Assert.AreEqual(1, receivedMessages.Count);
Assert.HasCount(1, receivedMessages);
Assert.IsFalse(receivedMessages[0].Retain); // Must be false even if set above!
}
@@ -572,7 +574,7 @@ public sealed class MqttClient_Tests : BaseTestClass
Interlocked.Increment(ref tries);
await Task.Delay(100);
await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build()).ConfigureAwait(false);
await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).Build());
};
try
@@ -830,7 +832,7 @@ public sealed class MqttClient_Tests : BaseTestClass
await Task.Delay(500);
Assert.AreEqual(1, receivedMessages.Count);
Assert.HasCount(1, receivedMessages);
Assert.AreEqual("DA|18RS00SC00XI0000RV00R100R200R300R400L100L200L300L400Y100Y200AC0102031800BELK0000BM0000|", receivedMessages.First().ConvertPayloadToString());
}
@@ -39,7 +39,7 @@ public sealed class PacketInspection_Tests : BaseTestClass
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Assert.AreEqual(2, packets.Count);
Assert.HasCount(2, packets);
Assert.AreEqual("Outbound:ECwABE1RVFQEAgAPACBJbnNwZWN0X0NsaWVudF9QYWNrZXRzX0NMSUVOVF9JRA==", packets[0]); // CONNECT
Assert.AreEqual("Inbound:IAIAAA==", packets[1]); // CONNACK
}
@@ -180,41 +180,45 @@ public sealed class MqttTopicTemplate_Tests
}
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException))]
public void RejectsEmptyTemplate()
{
_ = new MqttTopicTemplate("");
Assert.ThrowsExactly<MqttProtocolViolationException>(() => _ = new MqttTopicTemplate(""));
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void RejectsNullTemplate()
{
_ = new MqttTopicTemplate(null);
Assert.ThrowsExactly<ArgumentNullException>(() => _ = new MqttTopicTemplate(null));
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void RejectsReservedChars1()
{
var template = new MqttTopicTemplate("A/B/{foo}/D");
template.WithParameter("foo", "a#");
Assert.ThrowsExactly<ArgumentException>(() =>
{
var template = new MqttTopicTemplate("A/B/{foo}/D");
template.WithParameter("foo", "a#");
});
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void RejectsReservedChars2()
{
var template = new MqttTopicTemplate("A/B/{foo}/D");
template.WithParameter("foo", "a+b");
Assert.ThrowsExactly<ArgumentException>(() =>
{
var template = new MqttTopicTemplate("A/B/{foo}/D");
template.WithParameter("foo", "a+b");
});
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void RejectsReservedChars3()
{
var template = new MqttTopicTemplate("A/B/{foo}/D");
template.WithParameter("foo", "a/b");
Assert.ThrowsExactly<ArgumentException>(() =>
{
var template = new MqttTopicTemplate("A/B/{foo}/D");
template.WithParameter("foo", "a/b");
});
}
[TestMethod]
@@ -237,7 +241,7 @@ public sealed class MqttTopicTemplate_Tests
public void SendAndSubscribeSupport2()
{
var template = new MqttTopicTemplate("App/v1/{sender}/message");
Assert.ThrowsException<ArgumentException>(() => template.BuildMessage());
Assert.ThrowsExactly<ArgumentException>(() => template.BuildMessage());
}
[TestMethod]
+39 -33
View File
@@ -122,49 +122,55 @@ public sealed class Rpc_Tests : BaseTestClass
[TestMethod]
[ExpectedException(typeof(MqttCommunicationTimedOutException))]
public async Task Execute_Timeout()
public Task Execute_Timeout()
{
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer();
var requestSender = await testEnvironment.ConnectClient();
var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build());
await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
}
[TestMethod]
[ExpectedException(typeof(MqttCommunicationTimedOutException))]
public async Task Execute_Timeout_MQTT_V5_Mixed_Clients()
{
using var testEnvironment = new TestEnvironment(TestContext);
await testEnvironment.StartServer();
var responseSender = await testEnvironment.ConnectClient();
await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping");
responseSender.ApplicationMessageReceivedAsync += e =>
return Assert.ThrowsExactlyAsync<MqttCommunicationTimedOutException>(async () =>
{
Assert.IsNull(e.ApplicationMessage.ResponseTopic);
return CompletedTask.Instance;
};
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer();
var requestSender = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
var requestSender = await testEnvironment.ConnectClient();
using var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build());
await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build());
await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
});
}
[TestMethod]
[ExpectedException(typeof(MqttCommunicationTimedOutException))]
public async Task Execute_With_Custom_Topic_Names()
public Task Execute_Timeout_MQTT_V5_Mixed_Clients()
{
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer();
return Assert.ThrowsExactlyAsync<MqttCommunicationTimedOutException>(async () =>
{
using var testEnvironment = new TestEnvironment(TestContext);
await testEnvironment.StartServer();
var responseSender = await testEnvironment.ConnectClient();
await responseSender.SubscribeAsync("MQTTnet.RPC/+/ping");
var rpcClient = await testEnvironment.ConnectRpcClient(new MqttRpcClientOptionsBuilder().WithTopicGenerationStrategy(new TestTopicStrategy()).Build());
responseSender.ApplicationMessageReceivedAsync += e =>
{
Assert.IsNull(e.ApplicationMessage.ResponseTopic);
return CompletedTask.Instance;
};
await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
var requestSender = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V500));
using var rpcClient = new MqttRpcClient(requestSender, new MqttRpcClientOptionsBuilder().Build());
await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
});
}
[TestMethod]
public Task Execute_With_Custom_Topic_Names()
{
return Assert.ThrowsExactlyAsync<MqttCommunicationTimedOutException>(async () =>
{
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer();
var rpcClient = await testEnvironment.ConnectRpcClient(new MqttRpcClientOptionsBuilder().WithTopicGenerationStrategy(new TestTopicStrategy()).Build());
await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
});
}
[TestMethod]
@@ -16,31 +16,39 @@ namespace MQTTnet.Tests.Formatter;
public sealed class MqttBufferReader_Tests
{
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException), "Expected at least 4 bytes but there are only 3 bytes")]
public void Fire_Exception_If_Not_Enough_Data()
{
var buffer = new byte[] { 0, 1, 2 };
Assert.ThrowsExactly<MqttProtocolViolationException>(
() =>
{
var buffer = new byte[] { 0, 1, 2 };
var reader = new MqttBufferReader();
var reader = new MqttBufferReader();
reader.SetBuffer(buffer, 0, 3);
reader.SetBuffer(buffer, 0, 3);
// 1 byte is missing.
reader.ReadFourByteInteger();
// 1 byte is missing.
reader.ReadFourByteInteger();
},
"Expected at least 4 bytes but there are only 3 bytes");
}
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException), "Expected at least 4 bytes but there are only 3 bytes")]
public void Fire_Exception_If_Not_Enough_Data_With_Longer_Buffer()
{
var buffer = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
Assert.ThrowsExactly<MqttProtocolViolationException>(
() =>
{
var buffer = new byte[] { 0, 1, 2, 3, 4, 5, 6 };
var reader = new MqttBufferReader();
var reader = new MqttBufferReader();
reader.SetBuffer(buffer, 0, 3);
reader.SetBuffer(buffer, 0, 3);
// 1 byte is missing.
reader.ReadFourByteInteger();
// 1 byte is missing.
reader.ReadFourByteInteger();
},
"Expected at least 4 bytes but there are only 3 bytes");
}
[TestMethod]
@@ -68,10 +76,9 @@ public sealed class MqttBufferReader_Tests
Assert.IsTrue(reader.EndOfStream);
Assert.AreEqual(0, reader.BytesLeft);
Assert.AreEqual(5, remainingData.Length);
Assert.HasCount(5, remainingData);
}
[TestMethod]
public void Read_Various_Positions_and_Offsets()
{
@@ -284,13 +284,13 @@ public sealed class MqttPacketSerialization_V3_Binary_Tests
var adapter = new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535));
var ex = Assert.ThrowsException<MqttProtocolViolationException>(
var ex = Assert.ThrowsExactly<MqttProtocolViolationException>(
() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, [])));
Assert.AreEqual("CONNECT packet must have at least 7 bytes.", ex.Message);
ex = Assert.ThrowsException<MqttProtocolViolationException>(
ex = Assert.ThrowsExactly<MqttProtocolViolationException>(
() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[7])));
Assert.AreEqual("Protocol '' not supported.", ex.Message);
ex = Assert.ThrowsException<MqttProtocolViolationException>(
ex = Assert.ThrowsExactly<MqttProtocolViolationException>(
() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, [255, 255, 0, 0, 0, 0, 0])));
Assert.AreEqual("Expected at least 65537 bytes but there are only 7 bytes", ex.Message);
}
@@ -20,7 +20,7 @@ public sealed class MqttPacketSerialization_V3_Tests
public void Serialize_Full_MqttAuthPacket_V311()
{
var authPacket = new MqttAuthPacket();
Assert.ThrowsException<MqttProtocolViolationException>(() => MqttPacketSerializationHelper.EncodeAndDecodePacket(authPacket, MqttProtocolVersion.V311));
Assert.ThrowsExactly<MqttProtocolViolationException>(() => MqttPacketSerializationHelper.EncodeAndDecodePacket(authPacket, MqttProtocolVersion.V311));
}
[TestMethod]
@@ -53,24 +53,24 @@ public sealed class MqttPacketSerialization_V3_Tests
var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(connAckPacket, MqttProtocolVersion.V311);
CollectionAssert.AreEqual(null, deserialized.AuthenticationData); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.AuthenticationMethod); // Not supported in v3.1.1
Assert.IsNull(deserialized.AuthenticationMethod); // Not supported in v3.1.1
//Assert.AreEqual(connAckPacket.ReasonCode, deserialized.ReasonCode);
Assert.AreEqual(null, deserialized.ReasonString); // Not supported in v3.1.1
Assert.IsNull(deserialized.ReasonString); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.ReceiveMaximum); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.ResponseInformation); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.RetainAvailable); // Not supported in v3.1.1
Assert.IsNull(deserialized.ResponseInformation); // Not supported in v3.1.1
Assert.IsFalse(deserialized.RetainAvailable); // Not supported in v3.1.1
Assert.AreEqual(MqttConnectReturnCode.ConnectionRefusedNotAuthorized, deserialized.ReturnCode);
Assert.AreEqual(null, deserialized.ServerReference); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.AssignedClientIdentifier); // Not supported in v3.1.1
Assert.IsNull(deserialized.ServerReference); // Not supported in v3.1.1
Assert.IsNull(deserialized.AssignedClientIdentifier); // Not supported in v3.1.1
Assert.AreEqual(connAckPacket.IsSessionPresent, deserialized.IsSessionPresent);
Assert.AreEqual(0U, deserialized.MaximumPacketSize); // Not supported in v3.1.1
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, deserialized.MaximumQoS); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.ServerKeepAlive); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.SessionExpiryInterval); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.SharedSubscriptionAvailable); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.SubscriptionIdentifiersAvailable); // Not supported in v3.1.1
Assert.IsFalse(deserialized.SharedSubscriptionAvailable); // Not supported in v3.1.1
Assert.IsFalse(deserialized.SubscriptionIdentifiersAvailable); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.TopicAliasMaximum); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.WildcardSubscriptionAvailable);
Assert.IsFalse(deserialized.WildcardSubscriptionAvailable);
Assert.IsNull(deserialized.UserProperties); // Not supported in v3.1.1
}
@@ -104,24 +104,24 @@ public sealed class MqttPacketSerialization_V3_Tests
var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(connAckPacket, MqttProtocolVersion.V310);
CollectionAssert.AreEqual(null, deserialized.AuthenticationData); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.AuthenticationMethod); // Not supported in v3.1.1
Assert.IsNull(deserialized.AuthenticationMethod); // Not supported in v3.1.1
//Assert.AreEqual(connAckPacket.ReasonCode, deserialized.ReasonCode);
Assert.AreEqual(null, deserialized.ReasonString); // Not supported in v3.1.1
Assert.IsNull(deserialized.ReasonString); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.ReceiveMaximum); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.ResponseInformation); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.RetainAvailable); // Not supported in v3.1.1
Assert.IsNull(deserialized.ResponseInformation); // Not supported in v3.1.1
Assert.IsFalse(deserialized.RetainAvailable); // Not supported in v3.1.1
Assert.AreEqual(MqttConnectReturnCode.ConnectionRefusedNotAuthorized, deserialized.ReturnCode);
Assert.AreEqual(null, deserialized.ServerReference); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.AssignedClientIdentifier); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.IsSessionPresent); // Not supported in v3.1.0 <- !
Assert.IsNull(deserialized.ServerReference); // Not supported in v3.1.1
Assert.IsNull(deserialized.AssignedClientIdentifier); // Not supported in v3.1.1
Assert.IsFalse(deserialized.IsSessionPresent); // Not supported in v3.1.0 <- !
Assert.AreEqual(0U, deserialized.MaximumPacketSize); // Not supported in v3.1.1
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, deserialized.MaximumQoS); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.ServerKeepAlive); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.SessionExpiryInterval); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.SharedSubscriptionAvailable); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.SubscriptionIdentifiersAvailable); // Not supported in v3.1.1
Assert.IsFalse(deserialized.SharedSubscriptionAvailable); // Not supported in v3.1.1
Assert.IsFalse(deserialized.SubscriptionIdentifiersAvailable); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.TopicAliasMaximum); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.WildcardSubscriptionAvailable);
Assert.IsFalse(deserialized.WildcardSubscriptionAvailable);
Assert.IsNull(deserialized.UserProperties); // Not supported in v3.1.1
}
@@ -164,7 +164,7 @@ public sealed class MqttPacketSerialization_V3_Tests
CollectionAssert.AreEqual(connectPacket.Password, deserialized.Password);
Assert.AreEqual(connectPacket.ClientId, deserialized.ClientId);
CollectionAssert.AreEqual(null, deserialized.AuthenticationData); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.AuthenticationMethod); // Not supported in v3.1.1
Assert.IsNull(deserialized.AuthenticationMethod); // Not supported in v3.1.1
Assert.AreEqual(connectPacket.CleanSession, deserialized.CleanSession);
Assert.AreEqual(0L, deserialized.ReceiveMaximum); // Not supported in v3.1.1
Assert.AreEqual(connectPacket.WillFlag, deserialized.WillFlag);
@@ -203,8 +203,8 @@ public sealed class MqttPacketSerialization_V3_Tests
var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(disconnectPacket, MqttProtocolVersion.V311);
Assert.AreEqual(disconnectPacket.ReasonCode, deserialized.ReasonCode);
Assert.AreEqual(null, deserialized.ReasonString); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.ServerReference); // Not supported in v3.1.1
Assert.IsNull(deserialized.ReasonString); // Not supported in v3.1.1
Assert.IsNull(deserialized.ServerReference); // Not supported in v3.1.1
Assert.AreEqual(0U, deserialized.SessionExpiryInterval); // Not supported in v3.1.1
CollectionAssert.AreEqual(null, deserialized.UserProperties);
}
@@ -244,7 +244,7 @@ public sealed class MqttPacketSerialization_V3_Tests
Assert.AreEqual(pubAckPacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(MqttPubAckReasonCode.Success, deserialized.ReasonCode); // Not supported in v3.1.1
Assert.AreEqual(null, deserialized.ReasonString); // Not supported in v3.1.1
Assert.IsNull(deserialized.ReasonString); // Not supported in v3.1.1
CollectionAssert.AreEqual(null, deserialized.UserProperties);
}
@@ -297,8 +297,8 @@ public sealed class MqttPacketSerialization_V3_Tests
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.
Assert.AreEqual(null, deserialized.ContentType); // Not supported in v3.1.1.
Assert.IsNull(deserialized.ResponseTopic); // Not supported in v3.1.1.
Assert.IsNull(deserialized.ContentType); // Not supported in v3.1.1.
CollectionAssert.AreEqual(null, deserialized.CorrelationData); // Not supported in v3.1.1.
Assert.AreEqual(0U, deserialized.TopicAlias); // Not supported in v3.1.1.
CollectionAssert.AreEqual(null, deserialized.SubscriptionIdentifiers); // Not supported in v3.1.1
@@ -361,8 +361,8 @@ public sealed class MqttPacketSerialization_V3_Tests
var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(subAckPacket, MqttProtocolVersion.V311);
Assert.AreEqual(subAckPacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(null, deserialized.ReasonString); // Not supported in v3.1.1
Assert.AreEqual(subAckPacket.ReasonCodes.Count, deserialized.ReasonCodes.Count);
Assert.IsNull(deserialized.ReasonString); // Not supported in v3.1.1
Assert.HasCount(subAckPacket.ReasonCodes.Count, deserialized.ReasonCodes);
Assert.AreEqual(subAckPacket.ReasonCodes[0], deserialized.ReasonCodes[0]);
CollectionAssert.AreEqual(null, deserialized.UserProperties); // Not supported in v3.1.1
}
@@ -392,11 +392,11 @@ public sealed class MqttPacketSerialization_V3_Tests
Assert.AreEqual(subscribePacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(0U, deserialized.SubscriptionIdentifier); // Not supported in v3.1.1
Assert.AreEqual(1, deserialized.TopicFilters.Count);
Assert.HasCount(1, deserialized.TopicFilters);
Assert.AreEqual(subscribePacket.TopicFilters[0].Topic, deserialized.TopicFilters[0].Topic);
Assert.AreEqual(false, deserialized.TopicFilters[0].NoLocal); // Not supported in v3.1.1
Assert.IsFalse(deserialized.TopicFilters[0].NoLocal); // Not supported in v3.1.1
Assert.AreEqual(MqttRetainHandling.SendAtSubscribe, deserialized.TopicFilters[0].RetainHandling); // Not supported in v3.1.1
Assert.AreEqual(false, deserialized.TopicFilters[0].RetainAsPublished); // Not supported in v3.1.1
Assert.IsFalse(deserialized.TopicFilters[0].RetainAsPublished); // Not supported in v3.1.1
Assert.AreEqual(subscribePacket.TopicFilters[0].QualityOfServiceLevel, deserialized.TopicFilters[0].QualityOfServiceLevel);
CollectionAssert.AreEqual(null, deserialized.UserProperties); // Not supported in v3.1.1
}
@@ -415,7 +415,7 @@ public sealed class MqttPacketSerialization_V3_Tests
var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(unsubAckPacket, MqttProtocolVersion.V311);
Assert.AreEqual(unsubAckPacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(null, deserialized.ReasonString); // Not supported in v3.1.1
Assert.IsNull(deserialized.ReasonString); // Not supported in v3.1.1
CollectionAssert.AreEqual(null, deserialized.ReasonCodes); // Not supported in v3.1.1
CollectionAssert.AreEqual(null, deserialized.UserProperties); // Not supported in v3.1.1
}
@@ -433,7 +433,7 @@ public sealed class MqttPacketSerialization_V3_Tests
var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(unsubscribePacket, MqttProtocolVersion.V311);
Assert.AreEqual(unsubscribePacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(unsubscribePacket.TopicFilters.Count, deserialized.TopicFilters.Count);
Assert.HasCount(unsubscribePacket.TopicFilters.Count, deserialized.TopicFilters);
Assert.AreEqual(unsubscribePacket.TopicFilters[0], deserialized.TopicFilters[0]);
CollectionAssert.AreEqual(null, deserialized.UserProperties);
}
@@ -331,7 +331,7 @@ public sealed class MqttPacketSerialization_V5_Tests
Assert.AreEqual(subAckPacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(subAckPacket.ReasonString, deserialized.ReasonString);
Assert.AreEqual(subAckPacket.ReasonCodes.Count, deserialized.ReasonCodes.Count);
Assert.HasCount(subAckPacket.ReasonCodes.Count, deserialized.ReasonCodes);
Assert.AreEqual(subAckPacket.ReasonCodes[0], deserialized.ReasonCodes[0]);
CollectionAssert.AreEqual(subAckPacket.UserProperties, deserialized.UserProperties);
}
@@ -361,7 +361,7 @@ public sealed class MqttPacketSerialization_V5_Tests
Assert.AreEqual(subscribePacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(subscribePacket.SubscriptionIdentifier, deserialized.SubscriptionIdentifier);
Assert.AreEqual(1, deserialized.TopicFilters.Count);
Assert.HasCount(1, deserialized.TopicFilters);
Assert.AreEqual(subscribePacket.TopicFilters[0].Topic, deserialized.TopicFilters[0].Topic);
Assert.AreEqual(subscribePacket.TopicFilters[0].NoLocal, deserialized.TopicFilters[0].NoLocal);
Assert.AreEqual(subscribePacket.TopicFilters[0].RetainHandling, deserialized.TopicFilters[0].RetainHandling);
@@ -385,7 +385,7 @@ public sealed class MqttPacketSerialization_V5_Tests
Assert.AreEqual(unsubAckPacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(unsubAckPacket.ReasonString, deserialized.ReasonString);
Assert.AreEqual(unsubAckPacket.ReasonCodes.Count, deserialized.ReasonCodes.Count);
Assert.HasCount(unsubAckPacket.ReasonCodes.Count, deserialized.ReasonCodes);
Assert.AreEqual(unsubAckPacket.ReasonCodes[0], deserialized.ReasonCodes[0]);
CollectionAssert.AreEqual(unsubAckPacket.UserProperties, deserialized.UserProperties);
}
@@ -403,7 +403,7 @@ public sealed class MqttPacketSerialization_V5_Tests
var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(unsubscribePacket, MqttProtocolVersion.V500);
Assert.AreEqual(unsubscribePacket.PacketIdentifier, deserialized.PacketIdentifier);
Assert.AreEqual(unsubscribePacket.TopicFilters.Count, deserialized.TopicFilters.Count);
Assert.HasCount(unsubscribePacket.TopicFilters.Count, deserialized.TopicFilters);
Assert.AreEqual(unsubscribePacket.TopicFilters[0], deserialized.TopicFilters[0]);
CollectionAssert.AreEqual(unsubscribePacket.UserProperties, deserialized.UserProperties);
}
@@ -42,20 +42,22 @@ public sealed class MqttPacketWriter_Tests
reader.SetBuffer(buffer, 0, writer.Length);
Assert.AreEqual("AString", reader.ReadString());
Assert.IsTrue(reader.ReadByte() == 1);
Assert.IsTrue(reader.ReadByte() == 0);
Assert.IsTrue(reader.ReadByte() == 1);
Assert.AreEqual(1, reader.ReadByte());
Assert.AreEqual(0, reader.ReadByte());
Assert.AreEqual(1, reader.ReadByte());
Assert.AreEqual(1234U, reader.ReadVariableByteInteger());
Assert.AreEqual(9876U, reader.ReadVariableByteInteger());
}
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException))]
public void Throw_If_String_Too_Long()
{
var writer = new MqttBufferWriter(4096, 65535);
Assert.ThrowsExactly<MqttProtocolViolationException>(() =>
{
var writer = new MqttBufferWriter(4096, 65535);
writer.WriteString(string.Empty.PadLeft(65536));
writer.WriteString(string.Empty.PadLeft(65536));
});
}
[TestMethod]
@@ -82,7 +82,7 @@ public sealed class AsyncEvent_Tests
var testClass = new TestClass();
testClass.TestEventAsync += OnTestEventAsync;
Assert.AreEqual(true, testClass.HasTestHandlers);
Assert.IsTrue(testClass.HasTestHandlers);
}
[TestMethod]
@@ -90,7 +90,7 @@ public sealed class AsyncEvent_Tests
{
var testClass = new TestClass();
Assert.AreEqual(false, testClass.HasTestHandlers);
Assert.IsFalse(testClass.HasTestHandlers);
}
[TestMethod]
@@ -100,7 +100,7 @@ public sealed class AsyncEvent_Tests
testClass.TestEventAsync += OnTestEventAsync;
testClass.TestEventAsync -= OnTestEventAsync;
Assert.AreEqual(false, testClass.HasTestHandlers);
Assert.IsFalse(testClass.HasTestHandlers);
}
void OnTestEvent(EventArgs arg)
+122 -129
View File
@@ -21,80 +21,74 @@ public sealed class AsyncLock_Tests
var @lock = new AsyncLock();
// This call will not yet "release" the lock due to missing _using_.
var releaser = await @lock.EnterAsync().ConfigureAwait(false);
var releaser = await @lock.EnterAsync();
var counter = 0;
Debug.WriteLine("Prepared locked lock.");
_ = Task.Run(
async () =>
_ = Task.Run(async () =>
{
// SHOULD GET TIMEOUT!
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(1));
using (await @lock.EnterAsync(timeout.Token))
{
// SHOULD GET TIMEOUT!
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(1));
using (await @lock.EnterAsync(timeout.Token))
{
Debug.WriteLine("Task 1 incremented");
counter++;
}
});
Debug.WriteLine("Task 1 incremented");
counter++;
}
});
_ = Task.Run(
async () =>
_ = Task.Run(async () =>
{
// SHOULD GET TIMEOUT!
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(2));
using (await @lock.EnterAsync(timeout.Token))
{
// SHOULD GET TIMEOUT!
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(2));
using (await @lock.EnterAsync(timeout.Token))
{
Debug.WriteLine("Task 2 incremented");
counter++;
}
});
Debug.WriteLine("Task 2 incremented");
counter++;
}
});
_ = Task.Run(
async () =>
_ = Task.Run(async () =>
{
// SHOULD GET TIMEOUT!
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(3));
using (await @lock.EnterAsync(timeout.Token))
{
// SHOULD GET TIMEOUT!
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(3));
using (await @lock.EnterAsync(timeout.Token))
{
Debug.WriteLine("Task 3 incremented");
counter++;
}
});
Debug.WriteLine("Task 3 incremented");
counter++;
}
});
_ = Task.Run(
async () =>
_ = Task.Run(async () =>
{
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(4));
using (await @lock.EnterAsync(timeout.Token))
{
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(4));
using (await @lock.EnterAsync(timeout.Token))
{
Debug.WriteLine("Task 4 incremented");
counter++;
}
});
Debug.WriteLine("Task 4 incremented");
counter++;
}
});
_ = Task.Run(
async () =>
_ = Task.Run(async () =>
{
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
using (await @lock.EnterAsync(timeout.Token))
{
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
using (await @lock.EnterAsync(timeout.Token))
{
Debug.WriteLine("Task 5 incremented");
counter++;
}
});
Debug.WriteLine("Task 5 incremented");
counter++;
}
});
_ = Task.Run(
async () =>
_ = Task.Run(async () =>
{
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(6));
using (await @lock.EnterAsync(timeout.Token))
{
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(6));
using (await @lock.EnterAsync(timeout.Token))
{
Debug.WriteLine("Task 6 incremented");
counter++;
}
});
Debug.WriteLine("Task 6 incremented");
counter++;
}
});
Debug.WriteLine("Delay before release...");
await Task.Delay(TimeSpan.FromSeconds(3.1));
@@ -106,6 +100,49 @@ public sealed class AsyncLock_Tests
Assert.AreEqual(3, counter);
}
[TestMethod]
public void Lock_10_Parallel_Tasks_With_Dispose_Doesnt_Lockup()
{
const int ThreadsCount = 10;
var threads = new Task[ThreadsCount];
var @lock = new AsyncLock();
var globalI = 0;
for (var i = 0; i < ThreadsCount; i++)
{
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
threads[i] = Task.Run(async () =>
{
using (await @lock.EnterAsync())
{
var localI = globalI;
await Task.Delay(10); // Increase the chance for wrong data.
localI++;
globalI = localI;
}
})
.ContinueWith(x =>
{
if (globalI == 5)
{
@lock.Dispose();
@lock = new AsyncLock();
}
if (x.Exception != null)
{
Debug.WriteLine(x.Exception.GetBaseException().GetType().Name);
}
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
Task.WaitAll(threads);
// Expect only 6 because the others are failing due to disposal (if (globalI == 5)).
Assert.AreEqual(6, globalI);
}
[TestMethod]
public void Lock_Parallel_Tasks()
{
@@ -118,17 +155,16 @@ public sealed class AsyncLock_Tests
for (var i = 0; i < taskCount; i++)
{
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
tasks[i] = Task.Run(
async () =>
tasks[i] = Task.Run(async () =>
{
using (await @lock.EnterAsync())
{
using (await @lock.EnterAsync())
{
var localI = globalI;
await Task.Delay(5); // Increase the chance for wrong data.
localI++;
globalI = localI;
}
});
var localI = globalI;
await Task.Delay(5); // Increase the chance for wrong data.
localI++;
globalI = localI;
}
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
@@ -136,51 +172,6 @@ public sealed class AsyncLock_Tests
Assert.AreEqual(taskCount, globalI);
}
[TestMethod]
public void Lock_10_Parallel_Tasks_With_Dispose_Doesnt_Lockup()
{
const int ThreadsCount = 10;
var threads = new Task[ThreadsCount];
var @lock = new AsyncLock();
var globalI = 0;
for (var i = 0; i < ThreadsCount; i++)
{
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
threads[i] = Task.Run(
async () =>
{
using (await @lock.EnterAsync())
{
var localI = globalI;
await Task.Delay(10); // Increase the chance for wrong data.
localI++;
globalI = localI;
}
})
.ContinueWith(
x =>
{
if (globalI == 5)
{
@lock.Dispose();
@lock = new AsyncLock();
}
if (x.Exception != null)
{
Debug.WriteLine(x.Exception.GetBaseException().GetType().Name);
}
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
Task.WaitAll(threads);
// Expect only 6 because the others are failing due to disposal (if (globalI == 5)).
Assert.AreEqual(6, globalI);
}
[TestMethod]
public async Task Lock_Serial_Calls()
{
@@ -189,7 +180,7 @@ public sealed class AsyncLock_Tests
var @lock = new AsyncLock();
for (var i = 0; i < 100; i++)
{
using (await @lock.EnterAsync().ConfigureAwait(false))
using (await @lock.EnterAsync())
{
sum++;
}
@@ -199,16 +190,18 @@ public sealed class AsyncLock_Tests
}
[TestMethod]
[ExpectedException(typeof(TaskCanceledException))]
public async Task Test_Cancellation()
public Task Test_Cancellation()
{
var @lock = new AsyncLock();
return Assert.ThrowsExactlyAsync<TaskCanceledException>(async () =>
{
var @lock = new AsyncLock();
// This call will never "release" the lock due to missing _using_.
await @lock.EnterAsync().ConfigureAwait(false);
// This call will never "release" the lock due to missing _using_.
await @lock.EnterAsync();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await @lock.EnterAsync(cts.Token).ConfigureAwait(false);
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await @lock.EnterAsync(cts.Token);
});
}
[TestMethod]
@@ -216,13 +209,13 @@ public sealed class AsyncLock_Tests
{
var asyncLock = new AsyncLock();
var releaser = await asyncLock.EnterAsync().ConfigureAwait(false);
var releaser = await asyncLock.EnterAsync();
try
{
using (var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(3)))
{
await asyncLock.EnterAsync(timeout.Token).ConfigureAwait(false);
await asyncLock.EnterAsync(timeout.Token);
}
Assert.Fail("Exception should be thrown!");
@@ -233,7 +226,7 @@ public sealed class AsyncLock_Tests
releaser.Dispose();
using (await asyncLock.EnterAsync(CancellationToken.None).ConfigureAwait(false))
using (await asyncLock.EnterAsync(CancellationToken.None))
{
// When the method finished, the thread got access.
}
@@ -245,12 +238,12 @@ public sealed class AsyncLock_Tests
var @lock = new AsyncLock();
// This call will not yet "release" the lock due to missing _using_.
var releaser = await @lock.EnterAsync().ConfigureAwait(false);
var releaser = await @lock.EnterAsync();
try
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
await @lock.EnterAsync(cts.Token).ConfigureAwait(false);
await @lock.EnterAsync(cts.Token);
}
catch (OperationCanceledException)
{
@@ -260,15 +253,15 @@ public sealed class AsyncLock_Tests
releaser.Dispose();
// Regular usage after cancellation.
using (await @lock.EnterAsync().ConfigureAwait(false))
using (await @lock.EnterAsync())
{
}
using (await @lock.EnterAsync().ConfigureAwait(false))
using (await @lock.EnterAsync())
{
}
using (await @lock.EnterAsync().ConfigureAwait(false))
using (await @lock.EnterAsync())
{
}
}
@@ -53,7 +53,7 @@ public class AsyncQueue_Tests
success = (await queue.TryDequeueAsync(cancellationTokenSource.Token)).IsSuccess;
}
Assert.AreEqual(false, success);
Assert.IsFalse(success);
}
[TestMethod]
@@ -16,36 +16,40 @@ namespace MQTTnet.Tests.Internal;
public sealed class AsyncSignal_Tests
{
[TestMethod]
[ExpectedException(typeof(TaskCanceledException))]
public async Task Cancel_If_No_Signal()
public Task Cancel_If_No_Signal()
{
var asyncSignal = new AsyncSignal();
return Assert.ThrowsExactlyAsync<TaskCanceledException>(async () =>
{
var asyncSignal = new AsyncSignal();
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(2));
await asyncSignal.WaitAsync(timeout.Token);
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(2));
await asyncSignal.WaitAsync(timeout.Token);
Assert.Fail("There is no signal. So we must fail here!");
Assert.Fail("There is no signal. So we must fail here!");
});
}
[TestMethod]
[ExpectedException(typeof(ObjectDisposedException))]
public async Task Dispose_Properly()
public Task Dispose_Properly()
{
var asyncSignal = new AsyncSignal();
return Assert.ThrowsExactlyAsync<ObjectDisposedException>(async () =>
{
var asyncSignal = new AsyncSignal();
// The timeout will not be reached but another task will kill the async signal.
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(999));
_ = Task.Run(
async () =>
{
await Task.Delay(2000, CancellationToken.None);
asyncSignal.Dispose();
},
CancellationToken.None);
// The timeout will not be reached but another task will kill the async signal.
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(999));
_ = Task.Run(
async () =>
{
await Task.Delay(2000, CancellationToken.None);
asyncSignal.Dispose();
},
CancellationToken.None);
await asyncSignal.WaitAsync(timeout.Token);
await asyncSignal.WaitAsync(timeout.Token);
Assert.Fail("There is no signal. So we must fail here!");
Assert.Fail("There is no signal. So we must fail here!");
});
}
[TestMethod]
@@ -97,26 +101,28 @@ public sealed class AsyncSignal_Tests
stopwatch.Stop();
Assert.IsTrue(stopwatch.ElapsedMilliseconds > 900);
Assert.IsGreaterThan(900, stopwatch.ElapsedMilliseconds);
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public async Task Fail_For_Two_Waiters()
public Task Fail_For_Two_Waiters()
{
var asyncSignal = new AsyncSignal();
return Assert.ThrowsExactlyAsync<InvalidOperationException>(async () =>
{
var asyncSignal = new AsyncSignal();
// This thread will wait properly because it is the first waiter.
_ = Task.Run(
async () =>
{
await asyncSignal.WaitAsync().ConfigureAwait(false);
},
CancellationToken.None);
// This thread will wait properly because it is the first waiter.
_ = Task.Run(
async () =>
{
await asyncSignal.WaitAsync();
},
CancellationToken.None);
await Task.Delay(1000);
await Task.Delay(1000);
// Now the current thread must fail because there is already a waiter.
await asyncSignal.WaitAsync().ConfigureAwait(false);
// Now the current thread must fail because there is already a waiter.
await asyncSignal.WaitAsync();
});
}
}
@@ -76,7 +76,7 @@ public class BlockingQueue_Tests
await Task.Delay(100);
Assert.AreEqual(0, queue.Count);
Assert.AreEqual(null, item);
Assert.IsNull(item);
queue.Enqueue("x");
@@ -112,18 +112,21 @@ public class BlockingQueue_Tests
}
[TestMethod]
[ExpectedException(typeof(OperationCanceledException))]
public void Use_Disposed_Queue()
{
var queue = new BlockingQueue<int>();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(() =>
Assert.ThrowsExactly<OperationCanceledException>(() =>
{
Thread.Sleep(1000);
queue.Dispose();
});
var queue = new BlockingQueue<int>();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(() =>
{
Thread.Sleep(1000);
queue.Dispose();
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
queue.Dequeue(new CancellationTokenSource(TimeSpan.FromSeconds(2)).Token);
queue.Dequeue(new CancellationTokenSource(TimeSpan.FromSeconds(2)).Token);
});
}
}
@@ -32,19 +32,21 @@ public class CrossPlatformSocket_Tests
var responseText = Encoding.UTF8.GetString(buffer, 0, length);
Assert.IsTrue(responseText.Contains("HTTP/1.1"));
Assert.Contains("HTTP/1.1", responseText);
}
[TestMethod]
[ExpectedException(typeof(OperationCanceledException))]
public async Task Try_Connect_Invalid_Host()
public Task Try_Connect_Invalid_Host()
{
var crossPlatformSocket = new CrossPlatformSocket(ProtocolType.Tcp);
return Assert.ThrowsExactlyAsync<OperationCanceledException>(async () =>
{
var crossPlatformSocket = new CrossPlatformSocket(ProtocolType.Tcp);
var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(5));
cancellationToken.Token.Register(() => crossPlatformSocket.Dispose());
var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(5));
cancellationToken.Token.Register(() => crossPlatformSocket.Dispose());
await crossPlatformSocket.ConnectAsync(new DnsEndPoint("www.github.com", 54321), cancellationToken.Token).ConfigureAwait(false);
await crossPlatformSocket.ConnectAsync(new DnsEndPoint("www.github.com", 54321), cancellationToken.Token);
});
}
// [TestMethod]
@@ -30,14 +30,16 @@ public sealed class MqttPacketBusItem_Tests
}
[TestMethod]
[ExpectedException(typeof(TaskCanceledException))]
public async Task Wait_Packet_Bus_Item_After_Already_Canceled()
public Task Wait_Packet_Bus_Item_After_Already_Canceled()
{
var item = new MqttPacketBusItem(new MqttPublishPacket());
return Assert.ThrowsExactlyAsync<TaskCanceledException>(async () =>
{
var item = new MqttPacketBusItem(new MqttPublishPacket());
// Finish the item before the actual
item.Cancel();
// Finish the item before the actual
item.Cancel();
await item.WaitAsync().ConfigureAwait(false);
await item.WaitAsync();
});
}
}
@@ -96,13 +96,13 @@ public sealed class MqttPacketBus_Tests
Assert.AreEqual(3, bus.TotalItemsCount);
var exportedPackets = bus.ExportPackets(MqttPacketBusPartition.Control);
Assert.AreEqual(0, exportedPackets.Count);
Assert.HasCount(0, exportedPackets);
exportedPackets = bus.ExportPackets(MqttPacketBusPartition.Health);
Assert.AreEqual(0, exportedPackets.Count);
Assert.HasCount(0, exportedPackets);
exportedPackets = bus.ExportPackets(MqttPacketBusPartition.Data);
Assert.AreEqual(3, exportedPackets.Count);
Assert.HasCount(3, exportedPackets);
Assert.AreEqual(3, bus.TotalItemsCount);
}
@@ -137,12 +137,15 @@ public sealed class MqttPacketBus_Tests
}
[TestMethod]
[ExpectedException(typeof(TaskCanceledException))]
public async Task Wait_With_Empty_Bus()
public Task Wait_With_Empty_Bus()
{
var bus = new MqttPacketBus();
return Assert.ThrowsExactlyAsync<TaskCanceledException>(async () =>
{
var bus = new MqttPacketBus();
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(1));
await bus.DequeueItemAsync(timeout.Token);
});
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(1));
await bus.DequeueItemAsync(timeout.Token);
}
}
+2 -2
View File
@@ -18,8 +18,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0"/>
<PackageReference Include="MSTest" Version="3.6.4"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
<PackageReference Include="MSTest" Version="4.0.1" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />
+4 -4
View File
@@ -77,7 +77,7 @@ public sealed class Client_Tests : BaseTestClass
Assert.IsNotNull(receivedMessage);
Assert.AreEqual(2, receivedMessage.UserProperties.Count);
Assert.HasCount(2, receivedMessage.UserProperties);
}
[TestMethod]
@@ -288,7 +288,7 @@ public sealed class Client_Tests : BaseTestClass
await client.DisconnectAsync();
Assert.AreEqual(1, result.Items.Count);
Assert.HasCount(1, result.Items);
Assert.AreEqual(MqttClientSubscribeResultCode.GrantedQoS1, result.Items.First().ResultCode);
}
@@ -312,7 +312,7 @@ public sealed class Client_Tests : BaseTestClass
await client2.DisconnectAsync();
await client1.DisconnectAsync();
Assert.AreEqual(1, testMessageHandler.ReceivedEventArgs.Count);
Assert.HasCount(1, testMessageHandler.ReceivedEventArgs);
Assert.AreEqual("Subscribe_And_Publish_client1", testMessageHandler.ReceivedEventArgs[0].ClientId);
Assert.AreEqual("a", testMessageHandler.ReceivedEventArgs[0].ApplicationMessage.Topic);
Assert.AreEqual("b", testMessageHandler.ReceivedEventArgs[0].ApplicationMessage.ConvertPayloadToString());
@@ -330,7 +330,7 @@ public sealed class Client_Tests : BaseTestClass
var result = await client.UnsubscribeAsync("a");
await client.DisconnectAsync();
Assert.AreEqual(1, result.Items.Count);
Assert.HasCount(1, result.Items);
Assert.AreEqual(MqttClientUnsubscribeResultCode.Success, result.Items.First().ResultCode);
}
+3 -3
View File
@@ -113,7 +113,7 @@ public sealed class Server_Tests : BaseTestClass
// Session should not be present
Assert.IsTrue(!result.IsSessionPresent, "Session is present when it should not");
Assert.IsFalse(result.IsSessionPresent, "Session is present when it should not");
}
[TestMethod]
@@ -163,7 +163,7 @@ public sealed class Server_Tests : BaseTestClass
// Session should be present
Assert.IsTrue(!result3.IsSessionPresent, "Session is present when it should not");
Assert.IsFalse(result3.IsSessionPresent, "Session is present when it should not");
}
[TestMethod]
@@ -194,7 +194,7 @@ public sealed class Server_Tests : BaseTestClass
// Test client should be connected now
Assert.IsTrue(testClientId != null);
Assert.IsNotNull(testClientId);
// Have the server disconnect the client with AdministrativeAction reason
@@ -30,7 +30,7 @@ public sealed class MqttApplicationMessageBuilder_Tests
Assert.AreEqual("xyz", message.Topic);
Assert.IsFalse(message.Retain);
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, message.QualityOfServiceLevel);
Assert.AreEqual(Encoding.UTF8.GetString(message.Payload), "00:06:00");
Assert.AreEqual("00:06:00", Encoding.UTF8.GetString(message.Payload));
}
[TestMethod]
@@ -42,7 +42,7 @@ public sealed class MqttApplicationMessageBuilder_Tests
Assert.AreEqual("123", message.Topic);
Assert.IsFalse(message.Retain);
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, message.QualityOfServiceLevel);
Assert.AreEqual(Encoding.UTF8.GetString(message.Payload), "Hello");
Assert.AreEqual("Hello", Encoding.UTF8.GetString(message.Payload));
}
[TestMethod]
@@ -13,10 +13,10 @@ namespace MQTTnet.Tests;
public sealed class MqttApplicationMessageValidator_Tests
{
[TestMethod]
[ExpectedException(typeof(NotSupportedException))]
public void Succeed_When_Using_TopicAlias_And_MQTT_311()
{
MqttApplicationMessageValidator.ThrowIfNotSupported(new MqttApplicationMessageBuilder().WithTopicAlias(1).Build(), MqttProtocolVersion.V311);
Assert.ThrowsExactly<NotSupportedException>(() =>
MqttApplicationMessageValidator.ThrowIfNotSupported(new MqttApplicationMessageBuilder().WithTopicAlias(1).Build(), MqttProtocolVersion.V311));
}
[TestMethod]
@@ -34,11 +34,10 @@ public sealed class MqttApplicationMessageValidator_Tests
}
[TestMethod]
[ExpectedException(typeof(NotSupportedException))]
public void Succeed_When_Using_WillUserProperties_And_MQTT_311()
{
MqttApplicationMessageValidator.ThrowIfNotSupported(
Assert.ThrowsExactly<NotSupportedException>(() => MqttApplicationMessageValidator.ThrowIfNotSupported(
new MqttApplicationMessageBuilder().WithTopic("B").WithUserProperty("User", "Property").Build(),
MqttProtocolVersion.V311);
MqttProtocolVersion.V311));
}
}
@@ -19,10 +19,10 @@ public sealed class MqttClientOptionsValidator_Tests
}
[TestMethod]
[ExpectedException(typeof(NotSupportedException))]
public void Succeed_When_Using_WillUserProperties_And_MQTT_311()
{
new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V311).WithWillUserProperty("User", "Property").WithTcpServer("FAKE").Build();
Assert.ThrowsExactly<NotSupportedException>(() =>
new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V311).WithWillUserProperty("User", "Property").WithTcpServer("FAKE").Build());
}
[TestMethod]
@@ -32,17 +32,17 @@ public sealed class MqttClientOptionsValidator_Tests
}
[TestMethod]
[ExpectedException(typeof(NotSupportedException))]
public void Throw_When_Using_UserProperties_And_MQTT_311()
{
new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V311).WithUserProperty("User", "Property").WithTcpServer("FAKE").Build();
Assert.ThrowsExactly<NotSupportedException>(() =>
new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V311).WithUserProperty("User", "Property").WithTcpServer("FAKE").Build());
}
[TestMethod]
[ExpectedException(typeof(NotSupportedException))]
public void Throw_When_Using_WithRequestResponseInformation_And_MQTT_311()
{
new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V311).WithRequestResponseInformation().WithTcpServer("FAKE").Build();
Assert.ThrowsExactly<NotSupportedException>(() =>
new MqttClientOptionsBuilder().WithProtocolVersion(MqttProtocolVersion.V311).WithRequestResponseInformation().WithTcpServer("FAKE").Build());
}
[TestMethod]
@@ -43,16 +43,14 @@ public class MqttTopicValidatorSubscribe_Tests
}
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException))]
public void Invalid_Topic_Hash_In_Between()
{
MqttTopicValidator.ThrowIfInvalidSubscribe("/a/#/c");
Assert.ThrowsExactly<MqttProtocolViolationException>(() => MqttTopicValidator.ThrowIfInvalidSubscribe("/a/#/c"));
}
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException))]
public void Invalid_Topic_Empty()
{
MqttTopicValidator.ThrowIfInvalidSubscribe(string.Empty);
Assert.ThrowsExactly<MqttProtocolViolationException>(() => MqttTopicValidator.ThrowIfInvalidSubscribe(string.Empty));
}
}
@@ -13,24 +13,21 @@ namespace MQTTnet.Tests;
public sealed class MqttTopicValidator_Tests
{
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException))]
public void Invalid_Topic_Empty()
{
MqttTopicValidator.ThrowIfInvalid(string.Empty);
Assert.ThrowsExactly<MqttProtocolViolationException>(() => MqttTopicValidator.ThrowIfInvalid(string.Empty));
}
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException))]
public void Invalid_Topic_Hash()
{
MqttTopicValidator.ThrowIfInvalid("/a/#/c");
Assert.ThrowsExactly<MqttProtocolViolationException>(() => MqttTopicValidator.ThrowIfInvalid("/a/#/c"));
}
[TestMethod]
[ExpectedException(typeof(MqttProtocolViolationException))]
public void Invalid_Topic_Plus()
{
MqttTopicValidator.ThrowIfInvalid("/a/+/c");
Assert.ThrowsExactly<MqttProtocolViolationException>(() => MqttTopicValidator.ThrowIfInvalid("/a/+/c"));
}
[TestMethod]
@@ -27,9 +27,9 @@ public sealed class Cross_Version_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(1, receivedApplicationMessages.ReceivedEventArgs.Count);
Assert.AreEqual("My/Message", receivedApplicationMessages.ReceivedEventArgs.First().ApplicationMessage.Topic);
Assert.AreEqual("My_Payload", receivedApplicationMessages.ReceivedEventArgs.First().ApplicationMessage.ConvertPayloadToString());
Assert.HasCount(1, receivedApplicationMessages.ReceivedEventArgs);
Assert.AreEqual("My/Message", receivedApplicationMessages.ReceivedEventArgs[0].ApplicationMessage.Topic);
Assert.AreEqual("My_Payload", receivedApplicationMessages.ReceivedEventArgs[0].ApplicationMessage.ConvertPayloadToString());
}
[TestMethod]
@@ -55,8 +55,8 @@ public sealed class Cross_Version_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(1, receivedApplicationMessages.ReceivedEventArgs.Count);
Assert.AreEqual("My/Message", receivedApplicationMessages.ReceivedEventArgs.First().ApplicationMessage.Topic);
Assert.AreEqual("My_Payload", receivedApplicationMessages.ReceivedEventArgs.First().ApplicationMessage.ConvertPayloadToString());
Assert.HasCount(1, receivedApplicationMessages.ReceivedEventArgs);
Assert.AreEqual("My/Message", receivedApplicationMessages.ReceivedEventArgs[0].ApplicationMessage.Topic);
Assert.AreEqual("My_Payload", receivedApplicationMessages.ReceivedEventArgs[0].ApplicationMessage.ConvertPayloadToString());
}
}
+7 -7
View File
@@ -35,8 +35,8 @@ public sealed class Events_Tests : BaseTestClass
Assert.IsNotNull(eventArgs);
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Connected_Event)));
Assert.IsTrue(eventArgs.RemoteEndPoint.ToString().Contains("127.0.0.1"));
Assert.StartsWith(nameof(Fire_Client_Connected_Event), eventArgs.ClientId);
Assert.Contains("127.0.0.1", eventArgs.RemoteEndPoint.ToString()!);
Assert.AreEqual(MqttProtocolVersion.V311, eventArgs.ProtocolVersion);
Assert.AreEqual("TheUser", eventArgs.UserName);
Assert.AreEqual("ThePassword", eventArgs.Password);
@@ -62,8 +62,8 @@ public sealed class Events_Tests : BaseTestClass
Assert.IsNotNull(eventArgs);
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Disconnected_Event)));
Assert.IsTrue(eventArgs.RemoteEndPoint.ToString().Contains("127.0.0.1"));
Assert.StartsWith(nameof(Fire_Client_Disconnected_Event), eventArgs.ClientId);
Assert.Contains("127.0.0.1", eventArgs.RemoteEndPoint.ToString()!);
Assert.AreEqual(MqttClientDisconnectType.Clean, eventArgs.DisconnectType);
Assert.AreEqual("TheUser", eventArgs.UserName);
@@ -90,7 +90,7 @@ public sealed class Events_Tests : BaseTestClass
Assert.IsNotNull(eventArgs);
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Subscribed_Event)));
Assert.StartsWith(nameof(Fire_Client_Subscribed_Event), eventArgs.ClientId);
Assert.AreEqual("The/Topic", eventArgs.TopicFilter.Topic);
Assert.AreEqual(MqttQualityOfServiceLevel.AtLeastOnce, eventArgs.TopicFilter.QualityOfServiceLevel);
Assert.AreEqual("TheUser", eventArgs.UserName);
@@ -116,7 +116,7 @@ public sealed class Events_Tests : BaseTestClass
Assert.IsNotNull(eventArgs);
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Client_Unsubscribed_Event)));
Assert.StartsWith(nameof(Fire_Client_Unsubscribed_Event), eventArgs.ClientId);
Assert.AreEqual("The/Topic", eventArgs.TopicFilter);
Assert.AreEqual("TheUser", eventArgs.UserName);
}
@@ -141,7 +141,7 @@ public sealed class Events_Tests : BaseTestClass
Assert.IsNotNull(eventArgs);
Assert.IsTrue(eventArgs.ClientId.StartsWith(nameof(Fire_Application_Message_Received_Event)));
Assert.StartsWith(nameof(Fire_Application_Message_Received_Event), eventArgs.ClientId);
Assert.AreEqual("The_Topic", eventArgs.ApplicationMessage.Topic);
Assert.AreEqual("The_Payload", eventArgs.ApplicationMessage.ConvertPayloadToString());
Assert.AreEqual("TheUser", eventArgs.UserName);
+24 -24
View File
@@ -63,7 +63,7 @@ public sealed class General_Tests : BaseTestClass
await Task.Delay(500);
var clientStatus = await server.GetClientsAsync();
Assert.AreEqual(0, clientStatus.Count);
Assert.IsEmpty(clientStatus);
var client2 = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder().WithClientId("b").WithCleanSession(false).WithSessionExpiryInterval(60));
await client2.PublishStringAsync("x", "1");
@@ -76,8 +76,8 @@ public sealed class General_Tests : BaseTestClass
clientStatus = await server.GetClientsAsync();
var sessionStatus = await server.GetSessionsAsync();
Assert.AreEqual(0, clientStatus.Count);
Assert.AreEqual(2, sessionStatus.Count);
Assert.IsEmpty(clientStatus);
Assert.HasCount(2, sessionStatus);
Assert.AreEqual(3, sessionStatus.First(s => s.Id == client1.Options.ClientId).PendingApplicationMessagesCount);
}
@@ -244,7 +244,7 @@ public sealed class General_Tests : BaseTestClass
var retainedMessages = await server.GetRetainedMessagesAsync();
Assert.AreEqual(clientCount, retainedMessages.Count);
Assert.HasCount(clientCount, retainedMessages);
for (var i = 0; i < clientCount; i++)
{
@@ -346,7 +346,7 @@ public sealed class General_Tests : BaseTestClass
client.ConnectedAsync += async _ =>
{
await client.PublishStringAsync("Connected").ConfigureAwait(false);
await client.PublishStringAsync("Connected");
};
client.ApplicationMessageReceivedAsync += e =>
@@ -365,7 +365,7 @@ public sealed class General_Tests : BaseTestClass
await Task.Delay(500);
Assert.AreEqual(0, receivedMessages.Count);
Assert.IsEmpty(receivedMessages);
}
[TestMethod]
@@ -407,7 +407,7 @@ public sealed class General_Tests : BaseTestClass
})
{
SenderClientId = "server"
}).ConfigureAwait(false);
});
};
string receivedTopic = null;
@@ -434,19 +434,19 @@ public sealed class General_Tests : BaseTestClass
[TestMethod]
public async Task Publish_At_Least_Once_0x01()
{
await TestPublishAsync("A/B/C", MqttQualityOfServiceLevel.AtLeastOnce, "A/B/C", MqttQualityOfServiceLevel.AtLeastOnce, 1).ConfigureAwait(false);
await TestPublishAsync("A/B/C", MqttQualityOfServiceLevel.AtLeastOnce, "A/B/C", MqttQualityOfServiceLevel.AtLeastOnce, 1);
}
[TestMethod]
public async Task Publish_At_Most_Once_0x00()
{
await TestPublishAsync("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "A/B/C", MqttQualityOfServiceLevel.AtMostOnce, 1).ConfigureAwait(false);
await TestPublishAsync("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "A/B/C", MqttQualityOfServiceLevel.AtMostOnce, 1);
}
[TestMethod]
public async Task Publish_Exactly_Once_0x02()
{
await TestPublishAsync("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, "A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, 1).ConfigureAwait(false);
await TestPublishAsync("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, "A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, 1);
}
[TestMethod]
@@ -502,14 +502,14 @@ public sealed class General_Tests : BaseTestClass
return CompletedTask.Instance;
};
await c2.SubscribeAsync(new MqttTopicFilter { Topic = "a", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce }).ConfigureAwait(false);
await c3.SubscribeAsync(new MqttTopicFilter { Topic = "a", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce }).ConfigureAwait(false);
await c2.SubscribeAsync(new MqttTopicFilter { Topic = "a", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce });
await c3.SubscribeAsync(new MqttTopicFilter { Topic = "a", QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce });
var message = new MqttApplicationMessageBuilder().WithTopic("a").WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce).Build();
for (var i = 0; i < 500; i++)
{
await c1.PublishAsync(message).ConfigureAwait(false);
await c1.PublishAsync(message);
}
SpinWait.SpinUntil(() => receivedMessagesCount == 1000, TimeSpan.FromSeconds(20));
@@ -526,12 +526,12 @@ public sealed class General_Tests : BaseTestClass
var clientOptions = new MqttClientOptionsBuilder();
var c1 = await testEnvironment.ConnectClient(clientOptions);
await Task.Delay(500);
Assert.AreEqual(1, (await server.GetClientsAsync()).Count);
Assert.HasCount(1, await server.GetClientsAsync());
await c1.DisconnectAsync();
await Task.Delay(500);
Assert.AreEqual(0, (await server.GetClientsAsync()).Count);
Assert.IsEmpty(await server.GetClientsAsync());
}
[TestMethod]
@@ -600,14 +600,14 @@ public sealed class General_Tests : BaseTestClass
// nothing
Assert.AreEqual(false, c1.IsConnected);
Assert.IsFalse(c1.IsConnected);
await c1.TryDisconnectAsync();
Assert.AreEqual(false, c1.IsConnected);
Assert.IsFalse(c1.IsConnected);
await LongTestDelay();
// d
Assert.AreEqual(true, c2.IsConnected);
Assert.IsTrue(c2.IsConnected);
await c2.DisconnectAsync();
await LongTestDelay();
@@ -768,7 +768,7 @@ public sealed class General_Tests : BaseTestClass
server.ClientConnectedAsync += async e =>
{
// Every client will automatically subscribe to this topic.
await server.SubscribeAsync(e.ClientId, "topic1").ConfigureAwait(false);
await server.SubscribeAsync(e.ClientId, "topic1");
};
var client = await testEnvironment.ConnectClient();
@@ -788,11 +788,11 @@ public sealed class General_Tests : BaseTestClass
await client.PublishStringAsync("Hello");
await Task.Delay(100);
Assert.AreEqual(0, receivedMessages.Count);
Assert.IsEmpty(receivedMessages);
await client.PublishStringAsync("topic1");
await Task.Delay(100);
Assert.AreEqual(1, receivedMessages.Count);
Assert.HasCount(1, receivedMessages);
}
[TestMethod]
@@ -926,7 +926,7 @@ public sealed class General_Tests : BaseTestClass
// Test client should be connected now
Assert.IsTrue(testClientId != null);
Assert.IsNotNull(testClientId);
// Have the server disconnect the client with SessionTakenOver reason; no DISCONNECT should be sent to MQTT 3.1.1 clients
@@ -968,12 +968,12 @@ public sealed class General_Tests : BaseTestClass
await c2.PublishAsync(new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload([]).WithQualityOfServiceLevel(qualityOfServiceLevel).Build());
await Task.Delay(500);
await c2.DisconnectAsync().ConfigureAwait(false);
await c2.DisconnectAsync();
await Task.Delay(500);
await c1.UnsubscribeAsync(topicFilter);
await Task.Delay(500);
Assert.AreEqual(expectedReceivedMessagesCount, c1MessageHandler.ReceivedEventArgs.Count);
Assert.HasCount(expectedReceivedMessagesCount, c1MessageHandler.ReceivedEventArgs);
}
}
+11 -11
View File
@@ -40,12 +40,12 @@ public sealed class Injection_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(1, messageReceivedHandler1.ReceivedEventArgs.Count);
Assert.HasCount(1, messageReceivedHandler1.ReceivedEventArgs);
Assert.AreEqual(injectResult.PacketIdentifier, messageReceivedHandler1.ReceivedEventArgs[0].PacketIdentifier);
Assert.AreEqual("InjectedOne", messageReceivedHandler1.ReceivedEventArgs[0].ApplicationMessage.Topic);
// The second receiver should NOT receive the message.
Assert.AreEqual(0, messageReceivedHandler2.ReceivedEventArgs.Count);
Assert.IsEmpty(messageReceivedHandler2.ReceivedEventArgs);
}
[TestMethod]
@@ -228,12 +228,12 @@ public sealed class Injection_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(1, messageReceivedHandler1.ReceivedEventArgs.Count);
Assert.HasCount(1, messageReceivedHandler1.ReceivedEventArgs);
Assert.AreEqual(injectResult.PacketIdentifier, messageReceivedHandler1.ReceivedEventArgs[0].PacketIdentifier);
Assert.AreEqual("InjectedOne", messageReceivedHandler1.ReceivedEventArgs[0].ApplicationMessage.Topic);
// The second receiver should NOT receive the message.
Assert.AreEqual(0, messageReceivedHandler2.ReceivedEventArgs.Count);
Assert.IsEmpty(messageReceivedHandler2.ReceivedEventArgs);
}
[TestMethod]
@@ -312,9 +312,9 @@ public sealed class Injection_Tests : BaseTestClass
// Due to the DropNewMessage strategy the third message delivery will fail.
// As a result, no existing messages in the queue will be dropped (evicted).
Assert.AreEqual(firstMessageTask.Status, TaskStatus.WaitingForActivation);
Assert.AreEqual(secondMessageTask.Status, TaskStatus.WaitingForActivation);
Assert.AreEqual(thirdMessageTask.Status, TaskStatus.Faulted);
Assert.AreEqual(TaskStatus.WaitingForActivation, firstMessageTask.Status);
Assert.AreEqual(TaskStatus.WaitingForActivation, secondMessageTask.Status);
Assert.AreEqual(TaskStatus.Faulted, thirdMessageTask.Status);
Assert.IsTrue(thirdMessageTask.Exception?.InnerException is MqttPendingMessagesOverflowException);
Assert.IsFalse(firstMessageEvicted);
@@ -398,10 +398,10 @@ public sealed class Injection_Tests : BaseTestClass
// Due to the DropOldestQueuedMessage strategy, the second message delivery will fail
// to make room for the third one.
Assert.AreEqual(firstMessageTask.Status, TaskStatus.WaitingForActivation);
Assert.AreEqual(secondMessageTask.Status, TaskStatus.Faulted);
Assert.AreEqual(TaskStatus.WaitingForActivation, firstMessageTask.Status);
Assert.AreEqual(TaskStatus.Faulted, secondMessageTask.Status);
Assert.IsTrue(secondMessageTask.Exception?.InnerException is MqttPendingMessagesOverflowException);
Assert.AreEqual(thirdMessageTask.Status, TaskStatus.WaitingForActivation);
Assert.AreEqual(TaskStatus.WaitingForActivation, thirdMessageTask.Status);
Assert.IsFalse(firstMessageEvicted);
Assert.IsTrue(secondMessageEvicted);
@@ -427,7 +427,7 @@ public sealed class Injection_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(1, messageReceivedHandler.ReceivedEventArgs.Count);
Assert.HasCount(1, messageReceivedHandler.ReceivedEventArgs);
Assert.AreEqual("InjectedOne", messageReceivedHandler.ReceivedEventArgs[0].ApplicationMessage.Topic);
}
@@ -25,16 +25,16 @@ public sealed class KeepAlive_Tests : BaseTestClass
var client = await testEnvironment.ConnectLowLevelClient(o => o
.WithTimeout(TimeSpan.FromSeconds(1))
.WithTimeout(TimeSpan.Zero)
.WithProtocolVersion(MqttProtocolVersion.V500)).ConfigureAwait(false);
.WithProtocolVersion(MqttProtocolVersion.V500));
await client.SendAsync(new MqttConnectPacket
{
CleanSession = true,
ClientId = "Disconnect_Client_DueTo_KeepAlive",
KeepAlivePeriod = 1
}, CancellationToken.None).ConfigureAwait(false);
}, CancellationToken.None);
var responsePacket = await client.ReceiveAsync(CancellationToken.None).ConfigureAwait(false);
var responsePacket = await client.ReceiveAsync(CancellationToken.None);
Assert.IsTrue(responsePacket is MqttConnAckPacket);
for (var i = 0; i < 6; i++)
@@ -60,7 +60,7 @@ public sealed class KeepAlive_Tests : BaseTestClass
var disconnectPacket = responsePacket as MqttDisconnectPacket;
Assert.IsTrue(disconnectPacket != null);
Assert.AreEqual(disconnectPacket.ReasonCode, MqttDisconnectReasonCode.KeepAliveTimeout);
Assert.IsNotNull(disconnectPacket);
Assert.AreEqual(MqttDisconnectReasonCode.KeepAliveTimeout, disconnectPacket.ReasonCode);
}
}
+10 -7
View File
@@ -1,3 +1,5 @@
#if DEBUG
using System;
using System.Threading;
using System.Threading.Tasks;
@@ -9,9 +11,8 @@ using MQTTnet.Protocol;
namespace MQTTnet.Tests.Server;
// ReSharper disable InconsistentNaming
#if DEBUG
[TestClass]
#endif
public sealed class Load_Tests : BaseTestClass
{
[TestMethod]
@@ -48,7 +49,7 @@ public sealed class Load_Tests : BaseTestClass
var connAckPacket = packet as MqttConnAckPacket;
Assert.IsTrue(connAckPacket != null);
Assert.IsNotNull(connAckPacket);
Assert.AreEqual(MqttConnectReasonCode.Success, connAckPacket.ReasonCode);
var publishPacket = new MqttPublishPacket();
@@ -57,7 +58,7 @@ public sealed class Load_Tests : BaseTestClass
{
publishPacket.Topic = j.ToString();
await client.SendAsync(publishPacket, CancellationToken.None).ConfigureAwait(false);
await client.SendAsync(publishPacket, CancellationToken.None);
}
await client.DisconnectAsync(CancellationToken.None);
@@ -105,7 +106,7 @@ public sealed class Load_Tests : BaseTestClass
{
var message = applicationMessageBuilder.WithTopic("t/" + j).Build();
await client.PublishAsync(message).ConfigureAwait(false);
await client.PublishAsync(message);
}
await client.DisconnectAsync();
@@ -144,7 +145,7 @@ public sealed class Load_Tests : BaseTestClass
{
var message = applicationMessageBuilder.WithTopic(j.ToString()).Build();
await client.PublishAsync(message).ConfigureAwait(false);
await client.PublishAsync(message);
}
await client.DisconnectAsync();
@@ -156,4 +157,6 @@ public sealed class Load_Tests : BaseTestClass
Assert.IsTrue(result);
}
}
}
#endif
@@ -54,7 +54,7 @@ public sealed class MqttSubscriptionsManager_Tests : BaseTestClass
var result = CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, "");
Assert.IsTrue(result.IsSubscribed);
Assert.AreEqual(result.QualityOfServiceLevel, MqttQualityOfServiceLevel.AtMostOnce);
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, result.QualityOfServiceLevel);
}
[TestMethod]
@@ -83,7 +83,7 @@ public sealed class MqttSubscriptionsManager_Tests : BaseTestClass
var result = CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.AtMostOnce, "");
Assert.IsTrue(result.IsSubscribed);
Assert.AreEqual(result.QualityOfServiceLevel, MqttQualityOfServiceLevel.AtMostOnce);
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, result.QualityOfServiceLevel);
}
[TestMethod]
@@ -103,7 +103,7 @@ public sealed class MqttSubscriptionsManager_Tests : BaseTestClass
var result = CheckSubscriptions("A/B/C", MqttQualityOfServiceLevel.ExactlyOnce, "");
Assert.IsTrue(result.IsSubscribed);
Assert.AreEqual(result.QualityOfServiceLevel, MqttQualityOfServiceLevel.AtLeastOnce);
Assert.AreEqual(MqttQualityOfServiceLevel.AtLeastOnce, result.QualityOfServiceLevel);
}
[TestMethod]
@@ -188,14 +188,14 @@ public sealed class MqttSubscriptionsManager_Tests : BaseTestClass
]
};
await _subscriptionsManager.Subscribe(sp, CancellationToken.None).ConfigureAwait(false);
await _subscriptionsManager.Subscribe(sp, CancellationToken.None);
}
void CheckIsSubscribed(string topic)
{
var result = CheckSubscriptions(topic, MqttQualityOfServiceLevel.AtMostOnce, "");
Assert.IsTrue(result.IsSubscribed);
Assert.AreEqual(result.QualityOfServiceLevel, MqttQualityOfServiceLevel.AtMostOnce);
Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, result.QualityOfServiceLevel);
}
void CheckIsNotSubscribed(string topic)
+12 -10
View File
@@ -17,17 +17,19 @@ namespace MQTTnet.Tests.Server;
public sealed class Publishing_Tests : BaseTestClass
{
[TestMethod]
[ExpectedException(typeof(MqttClientDisconnectedException))]
public async Task Disconnect_While_Publishing()
public Task Disconnect_While_Publishing()
{
using var testEnvironment = CreateTestEnvironment();
var server = await testEnvironment.StartServer();
return Assert.ThrowsExactlyAsync<MqttClientDisconnectedException>(async () =>
{
using var testEnvironment = CreateTestEnvironment();
var server = await testEnvironment.StartServer();
// The client will be disconnected directly after subscribing!
server.InterceptingPublishAsync += ev => server.DisconnectClientAsync(ev.ClientId);
// The client will be disconnected directly after subscribing!
server.InterceptingPublishAsync += ev => server.DisconnectClientAsync(ev.ClientId);
var client = await testEnvironment.ConnectClient();
await client.PublishStringAsync("test", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
var client = await testEnvironment.ConnectClient();
await client.PublishStringAsync("test", qualityOfServiceLevel: MqttQualityOfServiceLevel.AtLeastOnce);
});
}
[TestMethod]
@@ -46,7 +48,7 @@ public sealed class Publishing_Tests : BaseTestClass
Assert.AreEqual(MqttClientPublishReasonCode.NoMatchingSubscribers, publishResult.ReasonCode);
Assert.AreEqual(true, publishResult.IsSuccess);
Assert.IsTrue(publishResult.IsSuccess);
}
[TestMethod]
@@ -65,7 +67,7 @@ public sealed class Publishing_Tests : BaseTestClass
Assert.AreEqual(MqttClientPublishReasonCode.Success, publishResult.ReasonCode);
Assert.AreEqual(true, publishResult.IsSuccess);
Assert.IsTrue(publishResult.IsSuccess);
}
[TestMethod]
+1 -1
View File
@@ -94,7 +94,7 @@ public sealed class QoS_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(1, eventArgs.Count);
Assert.HasCount(1, eventArgs);
var firstEvent = eventArgs[0];
@@ -86,8 +86,8 @@ public sealed class Security_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(3, publishedApplicationMessages.Count);
Assert.AreEqual(1, testEnvironment.Server.GetClientsAsync().GetAwaiter().GetResult().Count);
Assert.HasCount(3, publishedApplicationMessages);
Assert.HasCount(1, testEnvironment.Server.GetClientsAsync().GetAwaiter().GetResult());
}
[TestMethod]
@@ -123,7 +123,7 @@ public sealed class Security_Tests : BaseTestClass
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", testEnvironment.ServerPort).WithCredentials(username, password).Build();
var ex = await Assert.ThrowsExceptionAsync<MqttConnectingFailedException>(async () => await client.ConnectAsync(clientOptions).ConfigureAwait(false));
var ex = await Assert.ThrowsExactlyAsync<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);
}
+9 -9
View File
@@ -59,13 +59,13 @@ public sealed class Session_Tests : BaseTestClass
.Build();
var result = await client2.ConnectAsync(options).ConfigureAwait(false);
var result = await client2.ConnectAsync(options);
await client2.DisconnectAsync();
// Session should NOT be present for MQTT v311 and initial CleanSession == true
Assert.IsTrue(!result.IsSessionPresent, "Session present");
Assert.IsFalse(result.IsSessionPresent, "Session present");
}
[TestMethod]
@@ -85,7 +85,7 @@ public sealed class Session_Tests : BaseTestClass
var options = testEnvironment.CreateDefaultClientOptionsBuilder().WithClientId("Client1").WithCleanSession(false).WithSessionExpiryInterval(3).Build();
var connectResult = await c1.ConnectAsync(options);
Assert.AreEqual(false, connectResult.IsSessionPresent);
Assert.IsFalse(connectResult.IsSessionPresent);
}
[TestMethod]
@@ -131,9 +131,9 @@ public sealed class Session_Tests : BaseTestClass
await testEnvironment.ConnectClient();
var sessionStatus = await testEnvironment.Server.GetSessionsAsync();
var session = sessionStatus.First();
var session = sessionStatus[0];
Assert.AreEqual(true, session.Items["can_subscribe_x"]);
Assert.IsTrue((bool)session.Items["can_subscribe_x"]!);
}
[TestMethod]
@@ -158,7 +158,7 @@ public sealed class Session_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(1, connectedClients.Count);
Assert.HasCount(1, connectedClients);
var option2 = new MqttClientOptionsBuilder().WithClientId("2").WithKeepAlivePeriod(TimeSpan.FromSeconds(10));
var sendClient = await testEnvironment.ConnectClient(option2);
@@ -166,7 +166,7 @@ public sealed class Session_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(true, hasReceive);
Assert.IsTrue(hasReceive);
return;
void OnReceive()
@@ -348,7 +348,7 @@ public sealed class Session_Tests : BaseTestClass
{
try
{
var client = await testEnvironment.ConnectClient(options).ConfigureAwait(false);
var client = await testEnvironment.ConnectClient(options);
client.ApplicationMessageReceivedAsync += _ =>
{
@@ -357,7 +357,7 @@ public sealed class Session_Tests : BaseTestClass
};
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(30));
await client.SubscribeAsync("aaa", MqttQualityOfServiceLevel.AtMostOnce, timeout.Token).ConfigureAwait(false);
await client.SubscribeAsync("aaa", MqttQualityOfServiceLevel.AtMostOnce, timeout.Token);
return client;
}
+14 -14
View File
@@ -28,7 +28,7 @@ public sealed class Status_Tests : BaseTestClass
var clientStatus = await server.GetClientsAsync();
Assert.AreEqual(1, clientStatus.Count);
Assert.HasCount(1, clientStatus);
Assert.IsTrue(clientStatus.Any(s => s.Id == c1.Options.ClientId));
await clientStatus[0].DisconnectAsync();
@@ -39,7 +39,7 @@ public sealed class Status_Tests : BaseTestClass
clientStatus = await server.GetClientsAsync();
Assert.AreEqual(0, clientStatus.Count);
Assert.IsEmpty(clientStatus);
}
[TestMethod]
@@ -60,8 +60,8 @@ public sealed class Status_Tests : BaseTestClass
var clientStatus = await server.GetClientsAsync();
var sessionStatus = await server.GetSessionsAsync();
Assert.AreEqual(1, clientStatus.Count);
Assert.AreEqual(2, sessionStatus.Count);
Assert.HasCount(1, clientStatus);
Assert.HasCount(2, sessionStatus);
await c2.DisconnectAsync();
@@ -70,8 +70,8 @@ public sealed class Status_Tests : BaseTestClass
clientStatus = await server.GetClientsAsync();
sessionStatus = await server.GetSessionsAsync();
Assert.AreEqual(0, clientStatus.Count);
Assert.AreEqual(2, sessionStatus.Count);
Assert.IsEmpty(clientStatus);
Assert.HasCount(2, sessionStatus);
}
[TestMethod]
@@ -93,8 +93,8 @@ public sealed class Status_Tests : BaseTestClass
var clientStatus = await server.GetClientsAsync();
var sessionStatus = await server.GetSessionsAsync();
Assert.AreEqual(1, clientStatus.Count);
Assert.AreEqual(2, sessionStatus.Count);
Assert.HasCount(1, clientStatus);
Assert.HasCount(2, sessionStatus);
// The session expiry interval is mandatory for MQTT5.0.0 in order keep session!
await c2.DisconnectAsync(sessionExpiryInterval: 60);
@@ -104,8 +104,8 @@ public sealed class Status_Tests : BaseTestClass
clientStatus = await server.GetClientsAsync();
sessionStatus = await server.GetSessionsAsync();
Assert.AreEqual(0, clientStatus.Count);
Assert.AreEqual(2, sessionStatus.Count);
Assert.IsEmpty(clientStatus);
Assert.HasCount(2, sessionStatus);
}
[TestMethod]
@@ -122,8 +122,8 @@ public sealed class Status_Tests : BaseTestClass
var clientStatus = await server.GetClientsAsync();
var sessionStatus = await server.GetSessionsAsync();
Assert.AreEqual(2, clientStatus.Count);
Assert.AreEqual(2, sessionStatus.Count);
Assert.HasCount(2, clientStatus);
Assert.HasCount(2, sessionStatus);
Assert.IsTrue(clientStatus.Any(s => s.Id == c1.Options.ClientId));
Assert.IsTrue(clientStatus.Any(s => s.Id == c2.Options.ClientId));
@@ -136,8 +136,8 @@ public sealed class Status_Tests : BaseTestClass
clientStatus = await server.GetClientsAsync();
sessionStatus = await server.GetSessionsAsync();
Assert.AreEqual(0, clientStatus.Count);
Assert.AreEqual(0, sessionStatus.Count);
Assert.IsEmpty(clientStatus);
Assert.IsEmpty(sessionStatus);
}
[TestMethod]
+26 -24
View File
@@ -41,16 +41,16 @@ public sealed class Subscribe_Tests : BaseTestClass
public async Task Subscription_Roundtrip(string topic, string filter, bool shouldWork)
{
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer().ConfigureAwait(false);
await testEnvironment.StartServer();
var receiver = await testEnvironment.ConnectClient();
await receiver.SubscribeAsync(filter).ConfigureAwait(false);
await receiver.SubscribeAsync(filter);
var receivedMessages = receiver.TrackReceivedMessages();
var sender = await testEnvironment.ConnectClient();
await sender.PublishStringAsync(topic, "PAYLOAD").ConfigureAwait(false);
await sender.PublishStringAsync(topic, "PAYLOAD");
await LongTestDelay().ConfigureAwait(false);
await LongTestDelay();
if (shouldWork)
{
@@ -109,17 +109,19 @@ public sealed class Subscribe_Tests : BaseTestClass
}
[TestMethod]
[ExpectedException(typeof(MqttClientDisconnectedException))]
public async Task Disconnect_While_Subscribing()
public Task Disconnect_While_Subscribing()
{
using var testEnvironment = CreateTestEnvironment();
var server = await testEnvironment.StartServer();
return Assert.ThrowsExactlyAsync<MqttClientDisconnectedException>(async () =>
{
using var testEnvironment = CreateTestEnvironment();
var server = await testEnvironment.StartServer();
// The client will be disconnected directly after subscribing!
server.ClientSubscribedTopicAsync += ev => server.DisconnectClientAsync(ev.ClientId);
// The client will be disconnected directly after subscribing!
server.ClientSubscribedTopicAsync += ev => server.DisconnectClientAsync(ev.ClientId);
var client = await testEnvironment.ConnectClient();
await client.SubscribeAsync("#");
var client = await testEnvironment.ConnectClient();
await client.SubscribeAsync("#");
});
}
[TestMethod]
@@ -141,7 +143,7 @@ public sealed class Subscribe_Tests : BaseTestClass
await LongTestDelay();
Assert.AreEqual(1, receivedMessages.ReceivedEventArgs.Count);
Assert.HasCount(1, receivedMessages.ReceivedEventArgs);
}
[TestMethod]
@@ -200,7 +202,7 @@ public sealed class Subscribe_Tests : BaseTestClass
var response = await client.SubscribeAsync(subscribeOptions);
Assert.AreEqual(subscribeOptions.TopicFilters.Count, response.Items.Count);
Assert.HasCount(subscribeOptions.TopicFilters.Count, response.Items);
}
[TestMethod]
@@ -222,7 +224,7 @@ public sealed class Subscribe_Tests : BaseTestClass
{
var so = new MqttClientSubscribeOptionsBuilder().WithTopicFilter(i.ToString()).Build();
await c1.SubscribeAsync(so).ConfigureAwait(false);
await c1.SubscribeAsync(so);
await Task.Delay(10);
}
@@ -234,7 +236,7 @@ public sealed class Subscribe_Tests : BaseTestClass
{
messageBuilder.WithTopic(i.ToString());
await c2.PublishAsync(messageBuilder.Build()).ConfigureAwait(false);
await c2.PublishAsync(messageBuilder.Build());
await Task.Delay(10);
}
@@ -265,7 +267,7 @@ public sealed class Subscribe_Tests : BaseTestClass
optionsBuilder.WithTopicFilter(i.ToString());
}
await c1.SubscribeAsync(optionsBuilder.Build()).ConfigureAwait(false);
await c1.SubscribeAsync(optionsBuilder.Build());
var c2 = await testEnvironment.ConnectClient();
@@ -274,7 +276,7 @@ public sealed class Subscribe_Tests : BaseTestClass
{
messageBuilder.WithTopic(i.ToString());
await c2.PublishAsync(messageBuilder.Build()).ConfigureAwait(false);
await c2.PublishAsync(messageBuilder.Build());
}
SpinWait.SpinUntil(() => receivedMessagesCount == 500, TimeSpan.FromSeconds(20));
@@ -307,15 +309,15 @@ public sealed class Subscribe_Tests : BaseTestClass
await c2.PublishStringAsync("a");
await Task.Delay(100);
Assert.AreEqual(receivedMessagesCount, 1);
Assert.AreEqual(1, receivedMessagesCount);
await c2.PublishStringAsync("b");
await Task.Delay(100);
Assert.AreEqual(receivedMessagesCount, 2);
Assert.AreEqual(2, receivedMessagesCount);
await c2.PublishStringAsync("c");
await Task.Delay(100);
Assert.AreEqual(receivedMessagesCount, 3);
Assert.AreEqual(3, receivedMessagesCount);
}
[TestMethod]
@@ -339,15 +341,15 @@ public sealed class Subscribe_Tests : BaseTestClass
await c2.PublishStringAsync("a");
await Task.Delay(100);
Assert.AreEqual(receivedMessagesCount, 1);
Assert.AreEqual(1, receivedMessagesCount);
await c2.PublishStringAsync("b");
await Task.Delay(100);
Assert.AreEqual(receivedMessagesCount, 2);
Assert.AreEqual(2, receivedMessagesCount);
await c2.PublishStringAsync("c");
await Task.Delay(100);
Assert.AreEqual(receivedMessagesCount, 3);
Assert.AreEqual(3, receivedMessagesCount);
}
[TestMethod]
@@ -48,7 +48,7 @@ public sealed class Subscription_Identifier_Tests : BaseTestClass
applicationMessageHandler.AssertReceivedCountEquals(1);
Assert.IsTrue(applicationMessageHandler.ReceivedEventArgs[0].ApplicationMessage.SubscriptionIdentifiers.Contains(456));
Assert.Contains(456u, applicationMessageHandler.ReceivedEventArgs[0].ApplicationMessage.SubscriptionIdentifiers);
}
[TestMethod]
@@ -80,7 +80,7 @@ public sealed class Subscription_Identifier_Tests : BaseTestClass
applicationMessageHandler.AssertReceivedCountEquals(1);
Assert.IsTrue(applicationMessageHandler.ReceivedEventArgs[0].ApplicationMessage.SubscriptionIdentifiers.Contains(456));
Assert.IsTrue(applicationMessageHandler.ReceivedEventArgs[0].ApplicationMessage.SubscriptionIdentifiers.Contains(789));
Assert.Contains(456u, applicationMessageHandler.ReceivedEventArgs[0].ApplicationMessage.SubscriptionIdentifiers);
Assert.Contains(789u, applicationMessageHandler.ReceivedEventArgs[0].ApplicationMessage.SubscriptionIdentifiers);
}
}
@@ -28,12 +28,7 @@ public sealed class SubscriptionTopicHashTests
const int numPublishers = 5000;
const int numTopicsPerPublisher = 10;
TopicGenerator.Generate(
numPublishers,
numTopicsPerPublisher,
out var topicsByPublisher,
out _,
out _);
TopicGenerator.Generate(numPublishers, numTopicsPerPublisher, out var topicsByPublisher, out _, out _);
// There will be many 'similar' topics ending with, i.e. "sensor100", "sensor101", ...
// Hash bucket depths should remain low.
@@ -75,7 +70,7 @@ public sealed class SubscriptionTopicHashTests
Console.Write("Max bucket depth is " + maxBucketDepth);
// for the test case the bucket depth should be less than 100
Assert.IsTrue(maxBucketDepth < 100, "Unexpected high topic hash bucket depth");
Assert.IsLessThan(100, maxBucketDepth, "Unexpected high topic hash bucket depth");
}
@@ -162,11 +157,11 @@ public sealed class SubscriptionTopicHashTests
{
if (count < 7)
{
Assert.AreNotEqual(h, 0, "checksum mismatch");
Assert.AreNotEqual(0, h, "checksum mismatch");
}
else
{
Assert.AreEqual(h, 0, "checksum mismatch");
Assert.AreEqual(0, h, "checksum mismatch");
}
++count;
@@ -179,11 +174,11 @@ public sealed class SubscriptionTopicHashTests
{
if (count < 7)
{
Assert.AreEqual(h, 0xff, "mask mismatch");
Assert.AreEqual(0xff, h, "mask mismatch");
}
else
{
Assert.AreEqual(h, 0, "last mask mismatch");
Assert.AreEqual(0, h, "last mask mismatch");
}
++count;
@@ -223,7 +218,7 @@ public sealed class SubscriptionTopicHashTests
var count = 0;
foreach (var h in hashBytes)
{
Assert.AreNotEqual(h, 0, "checksum mismatch");
Assert.AreNotEqual(0, h, "checksum mismatch");
++count;
}
@@ -232,7 +227,7 @@ public sealed class SubscriptionTopicHashTests
count = 0;
foreach (var h in hashMaskBytes)
{
Assert.AreEqual(h, 0xff, "mask mismatch");
Assert.AreEqual(0xff, h, "mask mismatch");
++count;
}
}
@@ -282,12 +277,12 @@ public sealed class SubscriptionTopicHashTests
{
if (count < 7)
{
Assert.AreNotEqual(h, 0, "checksum mismatch");
Assert.AreNotEqual(0, h, "checksum mismatch");
}
else
{
// wildcard position
Assert.AreEqual(h, 0, "checksum mismatch");
Assert.AreEqual(0, h, "checksum mismatch");
}
++count;
@@ -300,11 +295,11 @@ public sealed class SubscriptionTopicHashTests
{
if (count < 7)
{
Assert.AreEqual(h, 0xff, "mask mismatch");
Assert.AreEqual(0xff, h, "mask mismatch");
}
else
{
Assert.AreEqual(h, 0, "last mask mismatch");
Assert.AreEqual(0, h, "last mask mismatch");
}
++count;
@@ -325,25 +320,25 @@ public sealed class SubscriptionTopicHashTests
Assert.IsTrue(topicHasWildcard, "Wildcard not detected");
var hashBytes = GetBytes(topicHash);
Assert.AreNotEqual(hashBytes[0], 0, "checksum 0 mismatch");
Assert.AreNotEqual(hashBytes[1], 0, "checksum 1 mismatch");
Assert.AreNotEqual(hashBytes[2], 0, "checksum 2 mismatch");
Assert.AreEqual(hashBytes[3], 0, "checksum 3 mismatch");
Assert.AreEqual(hashBytes[4], 0, "checksum 4 mismatch");
Assert.AreEqual(hashBytes[5], 0, "checksum 5 mismatch");
Assert.AreEqual(hashBytes[6], 0, "checksum 6 mismatch");
Assert.AreEqual(hashBytes[7], 0, "checksum 7 mismatch");
Assert.AreNotEqual(0, hashBytes[0], "checksum 0 mismatch");
Assert.AreNotEqual(0, hashBytes[1], "checksum 1 mismatch");
Assert.AreNotEqual(0, hashBytes[2], "checksum 2 mismatch");
Assert.AreEqual(0, hashBytes[3], "checksum 3 mismatch");
Assert.AreEqual(0, hashBytes[4], "checksum 4 mismatch");
Assert.AreEqual(0, hashBytes[5], "checksum 5 mismatch");
Assert.AreEqual(0, hashBytes[6], "checksum 6 mismatch");
Assert.AreEqual(0, hashBytes[7], "checksum 7 mismatch");
// The mask should have zeroes where the wildcard is and zero onward
var hashMaskBytes = GetBytes(topicHashMask);
Assert.AreEqual(hashMaskBytes[0], 0xff, "mask 0 mismatch");
Assert.AreEqual(hashMaskBytes[1], 0xff, "mask 1 mismatch");
Assert.AreEqual(hashMaskBytes[2], 0xff, "mask 2 mismatch");
Assert.AreEqual(hashMaskBytes[3], 0, "mask 3 mismatch");
Assert.AreEqual(hashMaskBytes[4], 0, "mask 4 mismatch");
Assert.AreEqual(hashMaskBytes[5], 0, "mask 5 mismatch");
Assert.AreEqual(hashMaskBytes[6], 0, "mask 6 mismatch");
Assert.AreEqual(hashMaskBytes[7], 0, "mask 7 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[0], "mask 0 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[1], "mask 1 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[2], "mask 2 mismatch");
Assert.AreEqual(0x0, hashMaskBytes[3], "mask 3 mismatch");
Assert.AreEqual(0x0, hashMaskBytes[4], "mask 4 mismatch");
Assert.AreEqual(0x0, hashMaskBytes[5], "mask 5 mismatch");
Assert.AreEqual(0x0, hashMaskBytes[6], "mask 6 mismatch");
Assert.AreEqual(0x0, hashMaskBytes[7], "mask 7 mismatch");
}
[TestMethod]
@@ -359,27 +354,26 @@ public sealed class SubscriptionTopicHashTests
Assert.IsFalse(topicHasWildcard, "Wildcard detected when not wildcard present");
var hashBytes = GetBytes(topicHash);
Assert.AreNotEqual(hashBytes[0], 0, "checksum 0 mismatch");
Assert.AreNotEqual(hashBytes[1], 0, "checksum 1 mismatch");
Assert.AreNotEqual(hashBytes[2], 0, "checksum 2 mismatch");
Assert.AreNotEqual(hashBytes[3], 0, "checksum 3 mismatch");
Assert.AreEqual(hashBytes[4], 0, "checksum 4 mismatch");
Assert.AreEqual(hashBytes[5], 0, "checksum 5 mismatch");
Assert.AreEqual(hashBytes[6], 0, "checksum 6 mismatch");
Assert.AreEqual(hashBytes[7], 0, "checksum 7 mismatch");
Assert.AreNotEqual(0, hashBytes[0], "checksum 0 mismatch");
Assert.AreNotEqual(0, hashBytes[1], "checksum 1 mismatch");
Assert.AreNotEqual(0, hashBytes[2], "checksum 2 mismatch");
Assert.AreNotEqual(0, hashBytes[3], "checksum 3 mismatch");
Assert.AreEqual(0, hashBytes[4], "checksum 4 mismatch");
Assert.AreEqual(0, hashBytes[5], "checksum 5 mismatch");
Assert.AreEqual(0, hashBytes[6], "checksum 6 mismatch");
Assert.AreEqual(0, hashBytes[7], "checksum 7 mismatch");
// The mask should have ff
var hashMaskBytes = GetBytes(topicHashMask);
Assert.AreEqual(hashMaskBytes[0], 0xff, "mask 0 mismatch");
Assert.AreEqual(hashMaskBytes[1], 0xff, "mask 1 mismatch");
Assert.AreEqual(hashMaskBytes[2], 0xff, "mask 2 mismatch");
Assert.AreEqual(hashMaskBytes[3], 0xff, "mask 3 mismatch");
Assert.AreEqual(hashMaskBytes[4], 0xff, "mask 4 mismatch");
Assert.AreEqual(hashMaskBytes[5], 0xff, "mask 5 mismatch");
Assert.AreEqual(hashMaskBytes[6], 0xff, "mask 6 mismatch");
Assert.AreEqual(hashMaskBytes[7], 0xff, "mask 7 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[0], "mask 0 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[1], "mask 1 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[2], "mask 2 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[3], "mask 3 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[4], "mask 4 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[5], "mask 5 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[6], "mask 6 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[7], "mask 7 mismatch");
}
[TestMethod]
@@ -453,25 +447,25 @@ public sealed class SubscriptionTopicHashTests
Assert.IsTrue(topicHasWildcard, "Wildcard not detected");
var hashBytes = GetBytes(topicHash);
Assert.AreNotEqual(hashBytes[0], 0, "checksum 0 mismatch");
Assert.AreNotEqual(hashBytes[1], 0, "checksum 1 mismatch");
Assert.AreEqual(hashBytes[2], 0, "checksum 2 mismatch");
Assert.AreNotEqual(hashBytes[3], 0, "checksum 3 mismatch");
Assert.AreEqual(hashBytes[4], 0, "checksum 4 mismatch");
Assert.AreEqual(hashBytes[5], 0, "checksum 5 mismatch");
Assert.AreEqual(hashBytes[6], 0, "checksum 6 mismatch");
Assert.AreEqual(hashBytes[7], 0, "checksum 7 mismatch");
Assert.AreNotEqual(0, hashBytes[0], "checksum 0 mismatch");
Assert.AreNotEqual(0, hashBytes[1], "checksum 1 mismatch");
Assert.AreEqual(0, hashBytes[2], "checksum 2 mismatch");
Assert.AreNotEqual(0, hashBytes[3], "checksum 3 mismatch");
Assert.AreEqual(0, hashBytes[4], "checksum 4 mismatch");
Assert.AreEqual(0, hashBytes[5], "checksum 5 mismatch");
Assert.AreEqual(0, hashBytes[6], "checksum 6 mismatch");
Assert.AreEqual(0, hashBytes[7], "checksum 7 mismatch");
// The mask should have zeroes where the wildcard and ff at the end
var hashMaskBytes = GetBytes(topicHashMask);
Assert.AreEqual(hashMaskBytes[0], 0xff, "mask 0 mismatch");
Assert.AreEqual(hashMaskBytes[1], 0xff, "mask 1 mismatch");
Assert.AreEqual(hashMaskBytes[2], 0, "mask 2 mismatch");
Assert.AreEqual(hashMaskBytes[3], 0xff, "mask 3 mismatch");
Assert.AreEqual(hashMaskBytes[4], 0xff, "mask 4 mismatch");
Assert.AreEqual(hashMaskBytes[5], 0xff, "mask 5 mismatch");
Assert.AreEqual(hashMaskBytes[6], 0xff, "mask 6 mismatch");
Assert.AreEqual(hashMaskBytes[7], 0xff, "mask 7 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[0], "mask 0 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[1], "mask 1 mismatch");
Assert.AreEqual(0x0, hashMaskBytes[2], "mask 2 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[3], "mask 3 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[4], "mask 4 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[5], "mask 5 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[6], "mask 6 mismatch");
Assert.AreEqual(0xff, hashMaskBytes[7], "mask 7 mismatch");
}
void CheckTopicHash(string topic, ulong expectedHash, ulong expectedHashMask)
@@ -541,12 +535,7 @@ public sealed class SubscriptionTopicHashTests
const int numPublishers = 1;
const int numTopicsPerPublisher = 10000;
TopicGenerator.Generate(
numPublishers,
numTopicsPerPublisher,
out var topicsByPublisher,
out var singleWildcardTopicsByPublisher,
out var multiWildcardTopicsByPublisher);
TopicGenerator.Generate(numPublishers, numTopicsPerPublisher, out var topicsByPublisher, out var singleWildcardTopicsByPublisher, out var multiWildcardTopicsByPublisher);
var topics = topicsByPublisher.FirstOrDefault().Value;
var singleWildcardTopics = singleWildcardTopicsByPublisher.FirstOrDefault().Value;
@@ -558,7 +547,13 @@ public sealed class SubscriptionTopicHashTests
var eventContainer = new MqttServerEventContainer();
var retainedMessagesManager = new MqttRetainedMessagesManager(eventContainer, logger);
var sessionManager = new MqttClientSessionsManager(serverOptions, retainedMessagesManager, eventContainer, logger);
_clientSession = new MqttSession(new MqttConnectPacket{ ClientId = clientId }, new Dictionary<object, object>(), serverOptions, eventContainer, retainedMessagesManager, sessionManager);
_clientSession = new MqttSession(
new MqttConnectPacket { ClientId = clientId },
new Dictionary<object, object>(),
serverOptions,
eventContainer,
retainedMessagesManager,
sessionManager);
List<string> topicsToSubscribe;
+2 -2
View File
@@ -165,7 +165,7 @@ public sealed class Tls_Tests : BaseTestClass
Assert.AreEqual(4, firstClientReceivedCount);
Assert.AreEqual(2, secondClientReceivedCount);
await server.StopAsync().ConfigureAwait(false);
await server.StopAsync();
}
static async Task<IMqttClient> ConnectClientAsync(TestEnvironment testEnvironment, Func<MqttClientCertificateValidationEventArgs, bool> certValidator)
@@ -180,7 +180,7 @@ public sealed class Tls_Tests : BaseTestClass
});
var clientOptions = clientOptionsBuilder.Build();
return await testEnvironment.ConnectClient(clientOptions).ConfigureAwait(false);
return await testEnvironment.ConnectClient(clientOptions);
}
sealed class CertificateProvider : ICertificateProvider
@@ -28,7 +28,7 @@ public sealed class Topic_Alias_Tests : BaseTestClass
.WithTcpServer("127.0.0.1", testEnvironment.ServerPort)
.Build());
Assert.AreEqual(connectResult.TopicAliasMaximum, ushort.MaxValue);
Assert.AreEqual(ushort.MaxValue, connectResult.TopicAliasMaximum);
}
[TestMethod]
@@ -69,7 +69,7 @@ public sealed class Topic_Alias_Tests : BaseTestClass
await Task.Delay(500);
Assert.AreEqual(3, receivedTopics.Count);
Assert.HasCount(3, receivedTopics);
CollectionAssert.AllItemsAreNotNull(receivedTopics);
Assert.IsTrue(receivedTopics.All(t => t.Equals("this_is_the_topic")));
}
@@ -17,18 +17,20 @@ namespace MQTTnet.Tests.Server;
public sealed class Unsubscribe_Tests : BaseTestClass
{
[TestMethod]
[ExpectedException(typeof(MqttClientDisconnectedException))]
public async Task Disconnect_While_Unsubscribing()
public Task Disconnect_While_Unsubscribing()
{
using var testEnvironment = CreateTestEnvironment();
var server = await testEnvironment.StartServer();
return Assert.ThrowsExactlyAsync<MqttClientDisconnectedException>(async () =>
{
using var testEnvironment = CreateTestEnvironment();
var server = await testEnvironment.StartServer();
// The client will be disconnected directly after subscribing!
server.ClientUnsubscribedTopicAsync += ev => server.DisconnectClientAsync(ev.ClientId);
// The client will be disconnected directly after subscribing!
server.ClientUnsubscribedTopicAsync += ev => server.DisconnectClientAsync(ev.ClientId);
var client = await testEnvironment.ConnectClient();
await client.SubscribeAsync("#");
await client.UnsubscribeAsync("#");
var client = await testEnvironment.ConnectClient();
await client.SubscribeAsync("#");
await client.UnsubscribeAsync("#");
});
}
[TestMethod]
@@ -52,6 +52,6 @@ public class Feature_Tests
Assert.IsNotNull(receivedMessage);
Assert.AreEqual("A", receivedMessage.Topic);
Assert.AreEqual(4, receivedMessage.UserProperties.Count);
Assert.HasCount(4, receivedMessage.UserProperties);
}
}
+13 -13
View File
@@ -13,7 +13,7 @@ public sealed class Will_Tests : BaseTestClass
public async Task Intercept_Will_Message()
{
using var testEnvironment = CreateTestEnvironment();
var server = await testEnvironment.StartServer().ConfigureAwait(false);
var server = await testEnvironment.StartServer();
MqttApplicationMessage willMessage = null;
server.InterceptingPublishAsync += eventArgs =>
@@ -22,12 +22,12 @@ public sealed class Will_Tests : BaseTestClass
return CompletedTask.Instance;
};
await testEnvironment.ConnectClient(new MqttClientOptionsBuilder()).ConfigureAwait(false);
await testEnvironment.ConnectClient(new MqttClientOptionsBuilder());
var clientOptions = new MqttClientOptionsBuilder().WithWillTopic("My/last/will").WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce);
var takeOverClient = await testEnvironment.ConnectClient(clientOptions).ConfigureAwait(false);
var takeOverClient = await testEnvironment.ConnectClient(clientOptions);
takeOverClient.Dispose(); // Dispose will not send a DISCONNECT pattern first so the will message must be sent.
await LongTestDelay().ConfigureAwait(false);
await LongTestDelay();
Assert.IsNotNull(willMessage);
}
@@ -38,19 +38,19 @@ public sealed class Will_Tests : BaseTestClass
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer();
var receiver = await testEnvironment.ConnectClient().ConfigureAwait(false);
var receiver = await testEnvironment.ConnectClient();
var receivedMessages = testEnvironment.CreateApplicationMessageHandler(receiver);
await receiver.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("#").Build());
var clientOptions = new MqttClientOptionsBuilder().WithWillTopic("My/last/will");
var sender = await testEnvironment.ConnectClient(clientOptions).ConfigureAwait(false);
await sender.DisconnectAsync().ConfigureAwait(false);
var sender = await testEnvironment.ConnectClient(clientOptions);
await sender.DisconnectAsync();
await LongTestDelay().ConfigureAwait(false);
await LongTestDelay();
Assert.AreEqual(0, receivedMessages.ReceivedEventArgs.Count);
Assert.IsEmpty(receivedMessages.ReceivedEventArgs);
}
[TestMethod]
@@ -59,16 +59,16 @@ public sealed class Will_Tests : BaseTestClass
using var testEnvironment = CreateTestEnvironment();
await testEnvironment.StartServer();
var receiver = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder()).ConfigureAwait(false);
var receiver = await testEnvironment.ConnectClient(new MqttClientOptionsBuilder());
var receivedMessages = testEnvironment.CreateApplicationMessageHandler(receiver);
await receiver.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic("#").Build());
var clientOptions = new MqttClientOptionsBuilder().WithWillTopic("My/last/will").WithWillQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce);
var takeOverClient = await testEnvironment.ConnectClient(clientOptions).ConfigureAwait(false);
var takeOverClient = await testEnvironment.ConnectClient(clientOptions);
takeOverClient.Dispose(); // Dispose will not send a DISCONNECT pattern first so the will message must be sent.
await LongTestDelay().ConfigureAwait(false);
await LongTestDelay();
Assert.AreEqual(1, receivedMessages.ReceivedEventArgs.Count);
Assert.HasCount(1, receivedMessages.ReceivedEventArgs);
}
}
@@ -157,7 +157,7 @@ public sealed class MqttTopicFilterComparer_Tests
if (expectedResult == MqttTopicFilterCompareResult.IsMatch)
{
// If it matches then the hash evaluation should also indicate a match
Assert.IsTrue((topicHash & filterTopicHashMask) == filterTopicHash, "Incorrect topic hash (is equal)");
Assert.AreEqual(topicHash & filterTopicHashMask, filterTopicHash, "Incorrect topic hash (is equal)");
}
}
}