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