Merge branch 'master' of https://github.com/chkr1011/MQTTnet into feature/pending-appmsg-acknowledge

# Conflicts:
#	Source/MQTTnet/Client/MqttClient.cs
#	Source/MQTTnet/MqttApplicationMessageReceivedEventArgs.cs
This commit is contained in:
tamas.kurucsai
2021-02-20 12:55:28 +01:00
114 changed files with 1823 additions and 2110 deletions
@@ -1,23 +1,24 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Formatter;
using MQTTnet.Internal;
//using System.IO;
//using System.Threading;
//using System.Threading.Tasks;
//using Microsoft.VisualStudio.TestTools.UnitTesting;
//using MQTTnet.Formatter;
//using MQTTnet.Internal;
namespace MQTTnet.Tests
{
[TestClass]
public class MqttPacketReader_Tests
{
[TestMethod]
public async Task MqttPacketReader_EmptyStream()
{
var fixedHeader = new byte[2];
var reader = new MqttPacketReader(new TestMqttChannel(new MemoryStream()));
var readResult = await reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None);
//namespace MQTTnet.Tests
//{
// [TestClass]
// public class MqttPacketReader_Tests
// {
// [TestMethod]
// public async Task MqttPacketReader_EmptyStream()
// {
// var fixedHeader = new byte[2];
// var reader = new MqttPacketReader(new TestMqttChannel(new MemoryStream()));
// var readResult = await reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None);
Assert.IsTrue(readResult.ConnectionClosed);
}
}
}
// Assert.IsTrue(readResult.ConnectionClosed);
// }
// }
//}
// TODO: Fix
@@ -6,6 +6,7 @@ using System.Text;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Exceptions;
using MQTTnet.Formatter;
using MQTTnet.Formatter.V3;
@@ -22,7 +23,7 @@ namespace MQTTnet.Tests
[TestMethod]
public void DetectVersionFromMqttConnectPacket()
{
var p = new MqttConnectPacket
var packet = new MqttConnectPacket
{
ClientId = "XYZ",
Password = Encoding.UTF8.GetBytes("PASS"),
@@ -30,17 +31,26 @@ namespace MQTTnet.Tests
KeepAlivePeriod = 123,
CleanSession = true
};
var adapter = new MqttPacketFormatterAdapter(WriterFactory());
Assert.AreEqual(MqttProtocolVersion.V310, DeserializeAndDetectVersion(adapter, Serialize(p, MqttProtocolVersion.V310)));
Assert.AreEqual(MqttProtocolVersion.V311, DeserializeAndDetectVersion(adapter, Serialize(p, MqttProtocolVersion.V311)));
Assert.AreEqual(MqttProtocolVersion.V500, DeserializeAndDetectVersion(adapter, Serialize(p, MqttProtocolVersion.V500)));
Assert.AreEqual(
MqttProtocolVersion.V310,
DeserializeAndDetectVersion(new MqttPacketFormatterAdapter(new MqttPacketWriter()), Serialize(packet, MqttProtocolVersion.V310)));
Assert.AreEqual(
MqttProtocolVersion.V311,
DeserializeAndDetectVersion(new MqttPacketFormatterAdapter(new MqttPacketWriter()), Serialize(packet, MqttProtocolVersion.V311)));
Assert.AreEqual(
MqttProtocolVersion.V500,
DeserializeAndDetectVersion(new MqttPacketFormatterAdapter(new MqttPacketWriter()), Serialize(packet, MqttProtocolVersion.V500)));
var adapter = new MqttPacketFormatterAdapter(new MqttPacketWriter());
var ex = Assert.ThrowsException<MqttProtocolViolationException>(() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[0])));
Assert.AreEqual("CONNECT packet must have at least 7 bytes.", ex.Message);
ex = Assert.ThrowsException<MqttProtocolViolationException>(() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[7])));
Assert.AreEqual("Protocol '' not supported.", ex.Message);
ex = Assert.ThrowsException<MqttProtocolViolationException>(() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[] { 255, 255, 0,0,0,0,0 })));
ex = Assert.ThrowsException<MqttProtocolViolationException>(() => DeserializeAndDetectVersion(adapter, WriterFactory().AddMqttHeader(MqttControlPacketType.Connect, new byte[] { 255, 255, 0, 0, 0, 0, 0 })));
Assert.AreEqual("Expected at least 65537 bytes but there are only 7 bytes", ex.Message);
}
@@ -205,24 +215,28 @@ namespace MQTTnet.Tests
Payload = payload
};
var buffer = serializer.Encode(publishPacket);
var testChannel = new TestMqttChannel(new MemoryStream(buffer.Array, buffer.Offset, buffer.Count));
var header = new MqttPacketReader(testChannel).ReadFixedHeaderAsync(
new byte[2],
CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
var publishPacketCopy = Roundtrip(publishPacket);
var eof = buffer.Offset + buffer.Count;
//var buffer = serializer.Encode(publishPacket);
//var testChannel = new TestMqttChannel(new MemoryStream(buffer.Array, buffer.Offset, buffer.Count));
var receivedPacket = new ReceivedMqttPacket(
header.Flags,
new MqttPacketBodyReader(buffer.Array, eof - header.RemainingLength, buffer.Count + buffer.Offset),
0);
var packet = (MqttPublishPacket)serializer.Decode(receivedPacket);
//var header = new MqttPacketReader(testChannel).ReadFixedHeaderAsync(
// new byte[2],
// CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
Assert.AreEqual(publishPacket.Topic, packet.Topic);
Assert.IsTrue(publishPacket.Payload.SequenceEqual(packet.Payload));
//var eof = buffer.Offset + buffer.Count;
//var receivedPacket = new ReceivedMqttPacket(
// header.Flags,
// new MqttPacketBodyReader(buffer.Array, eof - header.RemainingLength, buffer.Count + buffer.Offset),
// 0);
//var packet = (MqttPublishPacket)serializer.Decode(receivedPacket);
Assert.AreEqual(publishPacket.Topic, publishPacketCopy.Topic);
Assert.IsTrue(publishPacket.Payload.SequenceEqual(publishPacketCopy.Payload));
}
[TestMethod]
@@ -262,7 +276,7 @@ namespace MQTTnet.Tests
[TestMethod]
public void SerializeV500_MqttPublishPacket()
{
var prop = new MqttPublishPacketProperties {UserProperties = new List<MqttUserProperty>()};
var prop = new MqttPublishPacketProperties { UserProperties = new List<MqttUserProperty>() };
prop.ResponseTopic = "/Response";
@@ -581,15 +595,14 @@ namespace MQTTnet.Tests
DeserializeAndCompare(p, "sAIAew==");
}
private void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
void SerializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
{
Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Serialize(packet, protocolVersion)));
}
private byte[] Serialize(MqttBasePacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
byte[] Serialize(MqttBasePacket packet, MqttProtocolVersion protocolVersion)
{
var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, WriterFactory());
return Join(serializer.Encode(packet));
return MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, WriterFactory()).Encode(packet).ToArray();
}
protected virtual IMqttPacketWriter WriterFactory()
@@ -602,83 +615,92 @@ namespace MQTTnet.Tests
return new MqttPacketBodyReader(data, 0, data.Length);
}
private void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
{
var writer = WriterFactory();
var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
var buffer1 = serializer.Encode(packet);
using (var headerStream = new MemoryStream(Join(buffer1)))
using (var headerStream = new MemoryStream(buffer1.ToArray()))
{
var channel = new TestMqttChannel(headerStream);
var fixedHeader = new byte[2];
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
var adapter = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, writer), null, new MqttNetLogger());
var receivedPacket = adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
{
var reader = ReaderFactory(bodyStream.ToArray());
var deserializedPacket = serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
var buffer2 = serializer.Encode(deserializedPacket);
var buffer2 = serializer.Encode(receivedPacket);
Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
}
Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(buffer2.ToArray()));
//adapter.ReceivePacketAsync(CancellationToken.None);
//var fixedHeader = new byte[2];
//var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
//using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
//{
// var reader = ReaderFactory(bodyStream.ToArray());
// var deserializedPacket = serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
// var buffer2 = serializer.Encode(deserializedPacket);
// Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
//}
}
}
private T Roundtrip<T>(T packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
where T : MqttBasePacket
TPacket Roundtrip<TPacket>(TPacket packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
where TPacket : MqttBasePacket
{
var writer = WriterFactory();
var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);
var buffer = serializer.Encode(packet);
var buffer1 = serializer.Encode(packet);
var channel = new TestMqttChannel(buffer.ToArray());
var adapter = new MqttChannelAdapter(channel, new MqttPacketFormatterAdapter(protocolVersion, writer), null, new MqttNetLogger());
return (TPacket)adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
using (var headerStream = new MemoryStream(Join(buffer1)))
{
var channel = new TestMqttChannel(headerStream);
var fixedHeader = new byte[2];
//using (var headerStream = new MemoryStream(buffer1.ToArray()))
//{
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, (int)header.RemainingLength))
{
var reader = ReaderFactory(bodyStream.ToArray());
return (T)serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
}
}
// //var fixedHeader = new byte[2];
// //var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
// //using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, (int)header.RemainingLength))
// //{
// // var reader = ReaderFactory(bodyStream.ToArray());
// // return (T)serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
// //}
//}
}
private MqttProtocolVersion DeserializeAndDetectVersion(MqttPacketFormatterAdapter adapter, byte[] buffer)
MqttProtocolVersion DeserializeAndDetectVersion(MqttPacketFormatterAdapter packetFormatterAdapter, byte[] buffer)
{
using (var headerStream = new MemoryStream(buffer))
{
var channel = new TestMqttChannel(headerStream);
var fixedHeader = new byte[2];
var channel = new TestMqttChannel(buffer);
var adapter = new MqttChannelAdapter(channel, packetFormatterAdapter, null, new MqttNetLogger());
var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
adapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
return packetFormatterAdapter.ProtocolVersion;
using (var bodyStream = new MemoryStream(buffer, (int)headerStream.Position, (int)header.RemainingLength))
{
var reader = ReaderFactory(bodyStream.ToArray());
var packet = new ReceivedMqttPacket(header.Flags, reader, 0);
adapter.DetectProtocolVersion(packet);
return adapter.ProtocolVersion;
}
}
}
//using (var headerStream = new MemoryStream(buffer))
//{
private static byte[] Join(params ArraySegment<byte>[] chunks)
{
var buffer = new MemoryStream();
foreach (var chunk in chunks)
{
buffer.Write(chunk.Array, chunk.Offset, chunk.Count);
}
return buffer.ToArray();
// //var fixedHeader = new byte[2];
// //var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;
// //using (var bodyStream = new MemoryStream(buffer, (int)headerStream.Position, (int)header.RemainingLength))
// //{
// // var reader = ReaderFactory(bodyStream.ToArray());
// // var packet = new ReceivedMqttPacket(header.Flags, reader, 0);
// // packetFormatterAdapter.DetectProtocolVersion(packet);
// // return adapter.ProtocolVersion;
// //}
//}
}
}
}
+53 -3
View File
@@ -1,4 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MQTTnet.Adapter;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
@@ -6,6 +6,7 @@ using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MQTTnet.Client.Receiving;
using MQTTnet.Client.Subscribing;
using MQTTnet.Exceptions;
using MQTTnet.Protocol;
using MQTTnet.Server;
using MQTTnet.Tests.Mockups;
@@ -25,6 +26,55 @@ namespace MQTTnet.Tests
{
public TestContext TestContext { get; set; }
[TestMethod]
[DataRow("", null)]
[DataRow("", "")]
[DataRow(null, null)]
public async Task Use_Admissible_Credentials(string username, string password)
{
using (var testEnvironment = new TestEnvironment())
{
await testEnvironment.StartServerAsync();
var client = testEnvironment.CreateClient();
var clientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("localhost", testEnvironment.ServerPort)
.WithCredentials(username, password)
.Build();
var connectResult = await client.ConnectAsync(clientOptions);
Assert.IsFalse(connectResult.IsSessionPresent);
Assert.IsTrue(client.IsConnected);
}
}
[TestMethod]
public async Task Use_Username_Null_Password_Empty()
{
string username = null;
string password = string.Empty;
using (var testEnvironment = new TestEnvironment())
{
testEnvironment.IgnoreClientLogErrors = true;
await testEnvironment.StartServerAsync();
var client = testEnvironment.CreateClient();
var clientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("localhost", testEnvironment.ServerPort)
.WithCredentials(username, password)
.Build();
var ex = await Assert.ThrowsExceptionAsync<MqttConnectingFailedException>(async () => await client.ConnectAsync(clientOptions));
Assert.IsInstanceOfType(ex.InnerException, typeof(MqttProtocolViolationException));
Assert.AreEqual("Error while authenticating. If the User Name Flag is set to 0, the Password Flag MUST be set to 0 [MQTT-3.1.2-22].", ex.Message, false);
}
}
[TestMethod]
public async Task Use_Empty_Client_ID()
{
@@ -416,7 +466,7 @@ namespace MQTTnet.Tests
public async Task Publish_Multiple_Clients()
{
var receivedMessagesCount = 0;
using (var testEnvironment = new TestEnvironment(TestContext))
{
await testEnvironment.StartServerAsync();
@@ -446,7 +496,7 @@ namespace MQTTnet.Tests
}
SpinWait.SpinUntil(() => receivedMessagesCount == 1000, TimeSpan.FromSeconds(20));
Assert.AreEqual(1000, receivedMessagesCount);
}
}
@@ -6,6 +6,20 @@ namespace MQTTnet.Tests
[TestClass]
public class TopicFilterComparer_Tests
{
[TestMethod]
public void TopicFilterComparer_Plus_Match_With_Separator_Only()
{
//A Topic Name or Topic Filter consisting only of the ‘/’ character is valid
CompareAndAssert("A", "+", true);
}
[TestMethod]
public void TopicFilterComparer_Hash_Match_With_Separator_Only()
{
//A Topic Name or Topic Filter consisting only of the ‘/’ character is valid
CompareAndAssert("/", "#", true);
}
[TestMethod]
public void TopicFilterComparer_DirectMatch()
{
@@ -54,6 +68,12 @@ namespace MQTTnet.Tests
CompareAndAssert("A/B/C/D", "A/C/#", false);
}
[TestMethod]
public void TopicFilterComparer_EndMultipleLevelsWildcardMatchEmptyLevel()
{
CompareAndAssert("A/", "A/#", true);
}
[TestMethod]
public void TopicFilterComparer_AllLevelsWildcardMatch()
{