diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/IMultiTestRunFinalizationManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/IMultiTestRunFinalizationManager.cs index 892c2336bb..7a82cd3ccd 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/IMultiTestRunFinalizationManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/IMultiTestRunFinalizationManager.cs @@ -11,7 +11,7 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine /// /// Orchestrates multi test run finalization operations. /// - public interface IMultiTestRunFinalizationManager + internal interface IMultiTestRunFinalizationManager { /// /// Finalizes multi test run diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyExecutionManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyExecutionManager.cs index 3e0e0da772..922541e63c 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyExecutionManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyExecutionManager.cs @@ -256,12 +256,15 @@ private ParallelRunEventsHandler GetEventsHandler(IProxyExecutionManager concurr { if (concurrentManager is ProxyExecutionManagerWithDataCollection) { + var concurrentManagerWithDataCollection = concurrentManager as ProxyExecutionManagerWithDataCollection; + return new ParallelDataCollectionEventsHandler( this.requestData, - concurrentManager, + concurrentManagerWithDataCollection, this.currentRunEventsHandler, this, - this.currentRunDataAggregator); + this.currentRunDataAggregator, + concurrentManagerWithDataCollection.CancellationToken); } return new ParallelRunEventsHandler( diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManagerWithDataCollection.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManagerWithDataCollection.cs index 6aa6684e2d..179a6df370 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManagerWithDataCollection.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyExecutionManagerWithDataCollection.cs @@ -5,7 +5,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client { using System; using System.Collections.Generic; - + using System.Threading; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection; using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection.Interfaces; @@ -70,6 +70,11 @@ internal IProxyDataCollectionManager ProxyDataCollectionManager get; private set; } + /// + /// Gets the cancellation token for execution. + /// + internal CancellationToken CancellationToken => CancellationTokenSource.Token; + /// /// Ensure that the Execution component of engine is ready for execution usually by loading extensions. /// Skip default adapters flag. diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/DataCollectorAttachmentsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/DataCollectorAttachmentsHandler.cs deleted file mode 100644 index d4da660a77..0000000000 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/DataCollectorAttachmentsHandler.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.VisualStudio.TestPlatform.ObjectModel; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Threading; - -namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection -{ - public class DataCollectorAttachmentsHandler - { - private readonly IDataCollectorAttachments[] dataCollectorAttachmentsHandlers; - - public DataCollectorAttachmentsHandler(params IDataCollectorAttachments[] dataCollectorAttachmentsHandlers) - { - this.dataCollectorAttachmentsHandlers = dataCollectorAttachmentsHandlers; - } - - public void HandleAttachements(ICollection attachments, CancellationToken cancellationToken) - { - foreach(var dataCollectorAttachmentsHandler in dataCollectorAttachmentsHandlers) - { - Uri attachementUri = dataCollectorAttachmentsHandler.GetExtensionUri(); - if (attachementUri != null) - { - var attachmentsToBeProcessed = attachments.Where(dataCollectionAttachment => attachementUri.Equals(dataCollectionAttachment.Uri)).ToArray(); - if(attachmentsToBeProcessed.Any()) - { - foreach (var attachment in attachmentsToBeProcessed) - { - attachments.Remove(attachment); - } - - ICollection processedAttachements = dataCollectorAttachmentsHandler.HandleDataCollectionAttachmentSets(new Collection(attachmentsToBeProcessed), cancellationToken); - foreach (var attachment in processedAttachements) - { - attachments.Add(attachment); - } - } - } - } - } - } -} diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ParallelDataCollectionEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ParallelDataCollectionEventsHandler.cs index 770554cac0..aa3e56de62 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ParallelDataCollectionEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ParallelDataCollectionEventsHandler.cs @@ -7,7 +7,9 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection using System.Threading; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; + using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing; using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel; + using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.MultiTestRunFinalization; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; @@ -16,17 +18,20 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection internal class ParallelDataCollectionEventsHandler : ParallelRunEventsHandler { private readonly ParallelRunDataAggregator runDataAggregator; - private readonly DataCollectorAttachmentsHandler attachmentsHandler; + private readonly IMultiTestRunFinalizationManager finalizationManager; + private readonly CancellationToken cancellationToken; public ParallelDataCollectionEventsHandler(IRequestData requestData, IProxyExecutionManager proxyExecutionManager, ITestRunEventsHandler actualRunEventsHandler, IParallelProxyExecutionManager parallelProxyExecutionManager, - ParallelRunDataAggregator runDataAggregator) : + ParallelRunDataAggregator runDataAggregator, + CancellationToken cancellationToken) : this(requestData, proxyExecutionManager, actualRunEventsHandler, parallelProxyExecutionManager, runDataAggregator, JsonDataSerializer.Instance) { // TODO : use TestPluginCache to iterate over all IDataCollectorAttachments - attachmentsHandler = new DataCollectorAttachmentsHandler(new CodeCoverageDataAttachmentsHandler()); + this.finalizationManager = new MultiTestRunFinalizationManager(TestPlatformEventSource.Instance, new CodeCoverageDataAttachmentsHandler()); + this.cancellationToken = cancellationToken; } internal ParallelDataCollectionEventsHandler(IRequestData requestData, @@ -53,7 +58,7 @@ public override void HandleTestRunComplete( if (parallelRunComplete) { - attachmentsHandler.HandleAttachements(runDataAggregator.RunContextAttachments, CancellationToken.None); + finalizationManager.FinalizeMultiTestRunAsync(runDataAggregator.RunContextAttachments, null, cancellationToken).Wait(); var completedArgs = new TestRunCompleteEventArgs(this.runDataAggregator.GetAggregatedRunStats(), this.runDataAggregator.IsCanceled, diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/MultiTestRunFinalization/MultiTestRunFinalizationManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/MultiTestRunFinalization/MultiTestRunFinalizationManager.cs index baf4626add..3099fc2ccb 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/MultiTestRunFinalization/MultiTestRunFinalizationManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/MultiTestRunFinalization/MultiTestRunFinalizationManager.cs @@ -3,12 +3,14 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing.Interfaces; -using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.MultiTestRunFinalization @@ -18,16 +20,16 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.MultiTestRunFinali /// public class MultiTestRunFinalizationManager : IMultiTestRunFinalizationManager { - private readonly DataCollectorAttachmentsHandler attachmentsHandler; private readonly ITestPlatformEventSource testPlatformEventSource; + private readonly IDataCollectorAttachments[] dataCollectorAttachmentsHandlers; /// /// Initializes a new instance of the class. /// - public MultiTestRunFinalizationManager(DataCollectorAttachmentsHandler attachmentsHandler, ITestPlatformEventSource testPlatformEventSource) + public MultiTestRunFinalizationManager(ITestPlatformEventSource testPlatformEventSource, params IDataCollectorAttachments[] dataCollectorAttachmentsHandlers) { - this.attachmentsHandler = attachmentsHandler ?? throw new ArgumentNullException(nameof(attachmentsHandler)); this.testPlatformEventSource = testPlatformEventSource ?? throw new ArgumentNullException(nameof(testPlatformEventSource)); + this.dataCollectorAttachmentsHandlers = dataCollectorAttachmentsHandlers ?? throw new ArgumentNullException(nameof(dataCollectorAttachmentsHandlers)); } /// @@ -52,19 +54,19 @@ public async Task FinalizeMultiTestRunAsync(ICollection attachmen Task task = Task.Run(() => { - attachmentsHandler.HandleAttachements(attachments, cancellationToken); + HandleAttachements(attachments, cancellationToken); }); var completedTask = await Task.WhenAny(task, taskCompletionSource.Task); if (completedTask == task) { - eventHandler.HandleMultiTestRunFinalizationComplete(attachments); + eventHandler?.HandleMultiTestRunFinalizationComplete(attachments); testPlatformEventSource.MultiTestRunFinalizationStop(attachments.Count); } else { - eventHandler.HandleMultiTestRunFinalizationComplete(null); + eventHandler?.HandleMultiTestRunFinalizationComplete(null); testPlatformEventSource.MultiTestRunFinalizationStop(0); } } @@ -72,11 +74,35 @@ public async Task FinalizeMultiTestRunAsync(ICollection attachmen { EqtTrace.Error("MultiTestRunFinalizationManager: Exception in FinalizeMultiTestRunAsync: " + e); - eventHandler.HandleLogMessage(ObjectModel.Logging.TestMessageLevel.Error, e.Message); - eventHandler.HandleMultiTestRunFinalizationComplete(null); + eventHandler?.HandleLogMessage(ObjectModel.Logging.TestMessageLevel.Error, e.Message); + eventHandler?.HandleMultiTestRunFinalizationComplete(null); testPlatformEventSource.MultiTestRunFinalizationStop(0); } + } + private void HandleAttachements(ICollection attachments, CancellationToken cancellationToken) + { + foreach (var dataCollectorAttachmentsHandler in dataCollectorAttachmentsHandlers) + { + Uri attachementUri = dataCollectorAttachmentsHandler.GetExtensionUri(); + if (attachementUri != null) + { + var attachmentsToBeProcessed = attachments.Where(dataCollectionAttachment => attachementUri.Equals(dataCollectionAttachment.Uri)).ToArray(); + if (attachmentsToBeProcessed.Any()) + { + foreach (var attachment in attachmentsToBeProcessed) + { + attachments.Remove(attachment); + } + + ICollection processedAttachements = dataCollectorAttachmentsHandler.HandleDataCollectionAttachmentSets(new Collection(attachmentsToBeProcessed), cancellationToken); + foreach (var attachment in processedAttachements) + { + attachments.Add(attachment); + } + } + } + } } } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/IDataCollectorAttachments.cs b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/IDataCollectorAttachments.cs index 6c1ed58acc..eff8238976 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/IDataCollectorAttachments.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/IDataCollectorAttachments.cs @@ -17,6 +17,7 @@ public interface IDataCollectorAttachments /// /// Gets the attachment set after Test Run Session ICollection HandleDataCollectionAttachmentSets(ICollection dataCollectionAttachments, CancellationToken cancellationToken); + // TODO: add new method /// /// Gets the attachment Uri, which is handled by current Collector diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs index 4200918f0c..224edbe0aa 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs @@ -5,7 +5,8 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces { using System; using System.Collections.Generic; - + using System.Threading; + using System.Threading.Tasks; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; @@ -115,12 +116,8 @@ internal interface ITranslationLayerRequestSender : IDisposable /// Provides back all attachements to TestPlatform for additional processing (for example merging) /// /// List of attachements - /// - void FinalizeMultiTestRun(ICollection attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler); - - /// - /// Cancels multi test run finalization - /// - void CancelMultiTestRunFinalization(); + /// Events handler + /// Cancellation token + Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler, CancellationToken cancellationToken); } } diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs index a49ce93fab..babfee4518 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs @@ -5,6 +5,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces { using System; using System.Collections.Generic; + using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.TestPlatform.ObjectModel; @@ -76,5 +77,13 @@ internal interface ITranslationLayerRequestSenderAsync : IDisposable /// See . /// void OnProcessExited(); + + /// + /// Provides back all attachements to TestPlatform for additional processing (for example merging) + /// + /// List of attachements + /// Events handler + /// Cancellation token + Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler, CancellationToken cancellationToken); } } diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs index b1469d3f8d..acc2ab836b 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs @@ -4,7 +4,8 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces { using System.Collections.Generic; - + using System.Threading; + using System.Threading.Tasks; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; @@ -119,6 +120,14 @@ public interface IVsTestConsoleWrapper /// Custom test host launcher for the run. void RunTestsWithCustomTestHost(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + /// + /// Provides back all attachements to TestPlatform for additional processing (for example merging) + /// + /// List of attachements + /// EventHandler to receive session complete event + /// Cancellation token + Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler, CancellationToken cancellationToken); + /// /// Cancel the last test run. /// diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper2.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper2.cs deleted file mode 100644 index 2eb0ccff72..0000000000 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper2.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces -{ - using System.Collections.Generic; - - using Microsoft.VisualStudio.TestPlatform.ObjectModel; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; - - /// - /// Controller for various test operations on the test runner. - /// - public interface IVsTestConsoleWrapper2 : IVsTestConsoleWrapper - { - /// - /// Provides back all attachements to TestPlatform for additional processing (for example merging) - /// - /// List of attachements - /// EventHandler to receive session complete event - void FinalizeMultiTestRun(ICollection attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler); - - /// - /// Cancel last multi test run finalization - /// - void CancelMultiTestRunFinalization(); - } -} diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs index a303a3504f..d3b705150b 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs @@ -4,6 +4,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces { using System.Collections.Generic; + using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.TestPlatform.ObjectModel; @@ -81,6 +82,14 @@ public interface IVsTestConsoleWrapperAsync /// Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher); + /// + /// Provides back all attachements to TestPlatform for additional processing (for example merging) + /// + /// List of attachements + /// EventHandler to receive session complete event + /// Cancellation token + Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler, CancellationToken cancellationToken); + /// /// See . /// diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index beb8efce4e..5516f33c0b 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -384,19 +384,9 @@ public void EndSession() } /// - public void FinalizeMultiTestRun(ICollection attachments, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler) + public Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) { - this.SendMessageAndListenAndReportAttachments(attachments, testSessionEventsHandler); - } - - /// - public void CancelMultiTestRunFinalization() - { - if (EqtTrace.IsInfoEnabled) - { - EqtTrace.Info("VsTestConsoleRequestSender.CancelMultiTestRunFinalization: Canceling multi test run finalization."); - } - this.communicationManager.SendMessage(MessageType.MultiTestRunFinalizationCancel); + return this.SendMessageAndListenAndReportFinalizationResultAsync(attachments, testSessionEventsHandler, cancellationToken); } /// @@ -741,7 +731,7 @@ private async Task SendMessageAndListenAndReportTestResultsAsync(string messageT this.testPlatformEventSource.TranslationLayerExecutionStop(); } - private void SendMessageAndListenAndReportAttachments(ICollection attachments, IMultiTestRunFinalizationEventsHandler eventHandler) + private async Task SendMessageAndListenAndReportFinalizationResultAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken) { try { @@ -752,12 +742,14 @@ private void SendMessageAndListenAndReportAttachments(ICollection this.communicationManager.SendMessage(MessageType.MultiTestRunFinalizationStart, payload); var isMultiTestRunFinalizationComplete = false; + cancellationToken.Register(() => this.communicationManager.SendMessage(MessageType.MultiTestRunFinalizationCancel)); + // Cycle through the messages that the vstest.console sends. // Currently each of the operations are not separate tasks since they should not each take much time. // This is just a notification. while (!isMultiTestRunFinalizationComplete) { - var message = this.TryReceiveMessage(); + var message = await this.TryReceiveMessageAsync(); if (string.Equals(MessageType.MultiTestRunFinalizationComplete, message.MessageType)) { diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs index d46256d3e6..d5145f5f65 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs @@ -7,7 +7,8 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer using System.Diagnostics; using System.Globalization; using System.Linq; - + using System.Threading; + using System.Threading.Tasks; using Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing; @@ -24,7 +25,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer /// An implementation of to invoke test operations /// via the vstest.console test runner. /// - public class VsTestConsoleWrapper : IVsTestConsoleWrapper2 + public class VsTestConsoleWrapper : IVsTestConsoleWrapper { #region Private Members @@ -273,17 +274,13 @@ public void EndSession() this.sessionStarted = false; } - #endregion - - #region IVsTestConsoleWrapper2 - /// - public void FinalizeMultiTestRun(ICollection attachments, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler) + public Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) { this.testPlatformEventSource.TranslationLayerMultiTestRunFinalizationStart(); this.EnsureInitialized(); - this.requestSender.FinalizeMultiTestRun(attachments, testSessionEventsHandler); + return requestSender.FinalizeMultiTestRunAsync(attachments, testSessionEventsHandler, cancellationToken); } /// diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapperAsync.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapperAsync.cs index ca0a357c75..fc0f9a40fe 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapperAsync.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapperAsync.cs @@ -6,6 +6,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer using System.Collections.Generic; using System.Diagnostics; using System.Linq; + using System.Threading; using System.Threading.Tasks; using Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; @@ -222,6 +223,15 @@ public async Task RunTestsWithCustomTestHostAsync(IEnumerable testCase await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, runSettings, options, testRunEventsHandler, customTestHostLauncher); } + /// + public async Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) + { + this.testPlatformEventSource.TranslationLayerMultiTestRunFinalizationStart(); + + await this.EnsureInitializedAsync(); + await requestSender.FinalizeMultiTestRunAsync(attachments, testSessionEventsHandler, cancellationToken); + } + /// public void CancelTestRun() { diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index 5f57eeb7ca..5ef58e6190 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -84,7 +84,7 @@ public TestRequestManager() new InferHelper(AssemblyMetadataProvider.Instance), MetricsPublisherFactory.GetMetricsPublisher(IsTelemetryOptedIn(), CommandLineOptions.Instance.IsDesignMode), new ProcessHelper(), - new MultiTestRunFinalizationManager(new CrossPlatEngine.DataCollection.DataCollectorAttachmentsHandler(new CodeCoverageDataAttachmentsHandler()), TestPlatformEventSource.Instance)) + new MultiTestRunFinalizationManager(TestPlatformEventSource.Instance, new CodeCoverageDataAttachmentsHandler())) { } diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/FinalizeMultiTestRunTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/FinalizeMultiTestRunTests.cs index 12fd9ae8a7..546d93efdc 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/FinalizeMultiTestRunTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/FinalizeMultiTestRunTests.cs @@ -6,7 +6,6 @@ namespace Microsoft.TestPlatform.AcceptanceTests.TranslationLayerTests using Microsoft.TestPlatform.TestUtilities; using Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; @@ -14,6 +13,8 @@ namespace Microsoft.TestPlatform.AcceptanceTests.TranslationLayerTests using System.Diagnostics; using System.IO; using System.Linq; + using System.Threading; + using System.Threading.Tasks; using VisualStudio.TestPlatform.ObjectModel.Logging; /// @@ -22,7 +23,7 @@ namespace Microsoft.TestPlatform.AcceptanceTests.TranslationLayerTests [TestClass] public class FinalizeMultiTestRunTests : AcceptanceTestBase { - private IVsTestConsoleWrapper2 vstestConsoleWrapper; + private IVsTestConsoleWrapper vstestConsoleWrapper; private RunEventHandler runEventHandler; private MultiTestRunFinalizationEventHandler multiTestRunFinalizationEventHandler; @@ -42,7 +43,7 @@ public void Cleanup() [TestMethod] [NetFullTargetFrameworkDataSource] [NetCoreTargetFrameworkDataSource] - public void FinalizeMultiTestRun(RunnerInfo runnerInfo) + public async Task FinalizeMultiTestRun(RunnerInfo runnerInfo) { AcceptanceTestBase.SetTestEnvironment(this.testEnvironment, runnerInfo); this.Setup(); @@ -53,7 +54,7 @@ public void FinalizeMultiTestRun(RunnerInfo runnerInfo) Assert.AreEqual(6, this.runEventHandler.TestResults.Count); Assert.AreEqual(2, this.runEventHandler.Attachments.Count); - this.vstestConsoleWrapper.FinalizeMultiTestRun(runEventHandler.Attachments, multiTestRunFinalizationEventHandler); + await this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(runEventHandler.Attachments, multiTestRunFinalizationEventHandler, CancellationToken.None); // Assert multiTestRunFinalizationEventHandler.EnsureSuccess(); @@ -63,7 +64,7 @@ public void FinalizeMultiTestRun(RunnerInfo runnerInfo) [TestMethod] [NetFullTargetFrameworkDataSource] [NetCoreTargetFrameworkDataSource] - public void EndSessionShouldEnsureVstestConsoleProcessDies(RunnerInfo runnerInfo) + public async Task EndSessionShouldEnsureVstestConsoleProcessDies(RunnerInfo runnerInfo) { var numOfProcesses = Process.GetProcessesByName("vstest.console").Length; @@ -76,7 +77,7 @@ public void EndSessionShouldEnsureVstestConsoleProcessDies(RunnerInfo runnerInfo Assert.AreEqual(6, this.runEventHandler.TestResults.Count); Assert.AreEqual(2, this.runEventHandler.Attachments.Count); - this.vstestConsoleWrapper.FinalizeMultiTestRun(runEventHandler.Attachments, multiTestRunFinalizationEventHandler); + await this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(runEventHandler.Attachments, multiTestRunFinalizationEventHandler, CancellationToken.None); this.vstestConsoleWrapper?.EndSession(); // Assert diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/RunTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/RunTests.cs index 87ed476082..9be9c83360 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/RunTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/RunTests.cs @@ -21,7 +21,7 @@ namespace Microsoft.TestPlatform.AcceptanceTests.TranslationLayerTests [TestClass] public class RunTests : AcceptanceTestBase { - private IVsTestConsoleWrapper2 vstestConsoleWrapper; + private IVsTestConsoleWrapper vstestConsoleWrapper; private RunEventHandler runEventHandler; private void Setup() diff --git a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs index 44356520c2..7d25744753 100644 --- a/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs +++ b/test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs @@ -451,7 +451,7 @@ protected virtual string SetVSTestConsoleDLLPathInArgs(string args) /// Returns the VsTestConsole Wrapper. /// /// - public IVsTestConsoleWrapper2 GetVsTestConsoleWrapper() + public IVsTestConsoleWrapper GetVsTestConsoleWrapper() { var logFileName = Path.GetFileName(Path.GetTempFileName()); var logFileDir = Path.Combine(Path.GetTempPath(), "VSTestConsoleWrapperLogs");