diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index 1add332506..669654952c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -711,6 +711,8 @@ private static async Task BuildTestFrameworkAsync(TestFrameworkB { if (consumerService is ITestSessionLifetimeHandler handler) { + // Validate that a handler with the same UID is not already registered + testSessionLifetimeHandlers.ValidateUniqueExtension(handler); testSessionLifetimeHandlers.Add(handler); } @@ -722,6 +724,8 @@ private static async Task BuildTestFrameworkAsync(TestFrameworkB // We register the lifetime handler if we're connected to the dotnet test pipe if (pushOnlyProtocolDataConsumer is not null) { + // Validate that a handler with the same UID is not already registered + testSessionLifetimeHandlers.ValidateUniqueExtension(pushOnlyProtocolDataConsumer); testSessionLifetimeHandlers.Add(pushOnlyProtocolDataConsumer); } @@ -735,6 +739,8 @@ private static async Task BuildTestFrameworkAsync(TestFrameworkB // We register the data consumer handler if we're connected to the dotnet test pipe if (pushOnlyProtocolDataConsumer is not null) { + // Validate that a consumer with the same UID is not already registered + dataConsumersBuilder.ValidateUniqueExtension(pushOnlyProtocolDataConsumer); dataConsumersBuilder.Add(pushOnlyProtocolDataConsumer); } @@ -746,6 +752,8 @@ private static async Task BuildTestFrameworkAsync(TestFrameworkB if (await abortForMaxFailedTestsExtension.IsEnabledAsync().ConfigureAwait(false)) { + // Validate that a consumer with the same UID is not already registered + dataConsumersBuilder.ValidateUniqueExtension(abortForMaxFailedTestsExtension); dataConsumersBuilder.Add(abortForMaxFailedTestsExtension); } @@ -795,6 +803,9 @@ private static async Task RegisterAsServiceOrConsumerOrBothAsync(object service, return; } + // Validate that a consumer with the same UID is not already registered + dataConsumersBuilder.ValidateUniqueExtension(dataConsumer); + dataConsumersBuilder.Add(dataConsumer); } diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs index f22c21b359..859b3661bf 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs @@ -78,6 +78,30 @@ public async Task TestSessionLifetimeHandle_DuplicatedIdWithCompositeFactory_Sho Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(TestSessionLifetimeHandler).ToString())); } + [TestMethod] + public void DataConsumer_AddingDuplicateToExistingList_ShouldFail() + { + // Simulate the scenario in BuildTestFrameworkAsync where consumers are added to a list + List existingConsumers = [new Consumer("duplicatedId")]; + IDataConsumer newConsumer = new Consumer("duplicatedId"); + + // This should throw when trying to add a duplicate + InvalidOperationException invalidOperationException = Assert.ThrowsExactly(() => existingConsumers.ValidateUniqueExtension(newConsumer)); + Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(Consumer).ToString())); + } + + [TestMethod] + public void TestSessionLifetimeHandler_AddingDuplicateToExistingList_ShouldFail() + { + // Simulate the scenario in BuildTestFrameworkAsync where handlers are added to a list + List existingHandlers = [new TestSessionLifetimeHandler("duplicatedId")]; + ITestSessionLifetimeHandler newHandler = new TestSessionLifetimeHandler("duplicatedId"); + + // This should throw when trying to add a duplicate + InvalidOperationException invalidOperationException = Assert.ThrowsExactly(() => existingHandlers.ValidateUniqueExtension(newHandler)); + Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(TestSessionLifetimeHandler).ToString())); + } + [DataRow(true)] [DataRow(false)] [TestMethod]