From df0634b1bfd4fbd8302eb143599aa8bf84f7039b Mon Sep 17 00:00:00 2001 From: Tim Taylor Date: Wed, 13 Mar 2024 12:24:08 -0700 Subject: [PATCH] Fix bug where module client send batch fails if output name already set (#3441) #3434 The method ```Add``` on a dictionary throws if the key is already present. This change will overwrite any previously set output name without throwing. --- iothub/device/src/InternalClient.cs | 2 +- iothub/device/tests/ModuleClientTests.cs | 35 +++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/iothub/device/src/InternalClient.cs b/iothub/device/src/InternalClient.cs index 59472dd3fd..73e8aaac90 100644 --- a/iothub/device/src/InternalClient.cs +++ b/iothub/device/src/InternalClient.cs @@ -1570,7 +1570,7 @@ public Task SendEventBatchAsync(string outputName, IEnumerable messages throw new ArgumentNullException(nameof(messages)); } - messagesList.ForEach(m => m.SystemProperties.Add(MessageSystemPropertyNames.OutputName, outputName)); + messagesList.ForEach(m => m.SystemProperties[MessageSystemPropertyNames.OutputName] = outputName); return InnerHandler.SendEventAsync(messagesList, cancellationToken); } diff --git a/iothub/device/tests/ModuleClientTests.cs b/iothub/device/tests/ModuleClientTests.cs index cdffa26901..f9dbf754e5 100644 --- a/iothub/device/tests/ModuleClientTests.cs +++ b/iothub/device/tests/ModuleClientTests.cs @@ -1,6 +1,11 @@ -using System; +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; using NSubstitute; @@ -352,5 +357,33 @@ public void ModuleClient_InvokeMethodAsyncWithoutBodyShouldNotThrow() // act _ = new MethodInvokeRequest(request.Name, request.DataAsJson, request.ResponseTimeout, request.ConnectionTimeout); } + + [TestMethod] + public async Task SendEventBatchToOutputSetOutputNameIfNotSet() + { + // arrange + var moduleClient = ModuleClient.CreateFromConnectionString(FakeConnectionString, TransportType.Mqtt_Tcp_Only); + + var innerHandler = Substitute.For(); + innerHandler.SendEventAsync(Arg.Any(), Arg.Any()).Returns(Task.FromResult(0)); + moduleClient.InnerHandler = innerHandler; + + // act + var messageWithoutOutputName = new Message(); + var messageWithOutputName = new Message(); + + messageWithOutputName.SystemProperties.Remove(MessageSystemPropertyNames.OutputName); + string initialOutputName = "someInitialOutputName"; + messageWithOutputName.SystemProperties.Add(MessageSystemPropertyNames.OutputName, initialOutputName); + + string newOutputName = "someNewOutputName"; + await moduleClient.SendEventBatchAsync(newOutputName, new List { messageWithoutOutputName, messageWithOutputName }).ConfigureAwait(false); + + // assert + messageWithoutOutputName.SystemProperties.Keys.Should().Contain(MessageSystemPropertyNames.OutputName); + messageWithoutOutputName.SystemProperties[MessageSystemPropertyNames.OutputName].Should().Equals(newOutputName); + messageWithOutputName.SystemProperties.Keys.Should().Contain(MessageSystemPropertyNames.OutputName); + messageWithOutputName.SystemProperties[MessageSystemPropertyNames.OutputName].Should().Equals(newOutputName); + } } }