mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-25 07:41:32 +08:00
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:
@@ -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;
|
||||
// //}
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user