diff --git a/Source/MQTTnet/Client/MqttClient.cs b/Source/MQTTnet/Client/MqttClient.cs index 86264e40..4891b1f0 100644 --- a/Source/MQTTnet/Client/MqttClient.cs +++ b/Source/MQTTnet/Client/MqttClient.cs @@ -25,8 +25,8 @@ namespace MQTTnet.Client private IMqttClientOptions _options; private CancellationTokenSource _cancellationTokenSource; - private Task _packetReceiverTask; - private Task _keepAliveMessageSenderTask; + internal Task _packetReceiverTask; + internal Task _keepAliveMessageSenderTask; private IMqttChannelAdapter _adapter; private bool _cleanDisconnectInitiated; private TaskCompletionSource _disconnectReason; diff --git a/Source/MQTTnet/Properties/AssemblyInfo.cs b/Source/MQTTnet/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..8259cc15 --- /dev/null +++ b/Source/MQTTnet/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly:InternalsVisibleTo("MQTTnet.Core.Tests")] diff --git a/Tests/MQTTnet.Core.Tests/MqttClientTests.cs b/Tests/MQTTnet.Core.Tests/MqttClientTests.cs index 455cf7dc..2f1c5e99 100644 --- a/Tests/MQTTnet.Core.Tests/MqttClientTests.cs +++ b/Tests/MQTTnet.Core.Tests/MqttClientTests.cs @@ -1,9 +1,13 @@ using System; using System.Net.Sockets; +using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; +using MQTTnet.Adapter; using MQTTnet.Client; +using MQTTnet.Diagnostics; using MQTTnet.Exceptions; +using MQTTnet.Packets; namespace MQTTnet.Core.Tests { @@ -35,5 +39,37 @@ namespace MQTTnet.Core.Tests Assert.IsInstanceOfType(ex, typeof(MqttCommunicationException)); Assert.IsInstanceOfType(ex.InnerException, typeof(SocketException)); } + + [TestMethod] + public async Task ClientCleanupOnAuthentificationFails() + { + var channel = new TestMqttCommunicationAdapter(); + var channel2 = new TestMqttCommunicationAdapter(); + channel.Partner = channel2; + channel2.Partner = channel; + + Task.Run(async () => { + var connect = await channel2.ReceivePacketAsync(TimeSpan.Zero, CancellationToken.None); + await channel2.SendPacketAsync(new MqttConnAckPacket() { ConnectReturnCode = Protocol.MqttConnectReturnCode.ConnectionRefusedNotAuthorized }, CancellationToken.None); + }); + + + + var fake = new TestMqttCommunicationAdapterFactory(channel); + + var client = new MqttClient(fake, new MqttNetLogger()); + + try + { + await client.ConnectAsync(new MqttClientOptionsBuilder().WithTcpServer("any-server").Build()); + } + catch (Exception ex) + { + Assert.IsInstanceOfType(ex, typeof(MqttConnectingFailedException)); + } + + Assert.IsTrue(client._packetReceiverTask == null || client._packetReceiverTask.IsCompleted, "receive loop not completed"); + Assert.IsTrue(client._keepAliveMessageSenderTask == null || client._keepAliveMessageSenderTask.IsCompleted, "keepalive loop not completed"); + } } }