diff --git a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs index f83ff7d0bc..d49af32336 100644 --- a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs +++ b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs @@ -479,7 +479,7 @@ private void StartMultiTestRunFinalization(MultiTestRunFinalizationPayload final { try { - testRequestManager.FinalizeMultiTestRun(finalizationPayload, new MultiTestRunFinalizationEventsHandler(this.communicationManager)); + testRequestManager.FinalizeMultiTestRun(finalizationPayload, new MultiTestRunFinalizationEventsHandler(this.communicationManager), this.protocolConfig); } catch (Exception ex) { diff --git a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs index 380484ab7f..eb18c4fa0b 100644 --- a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs +++ b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs @@ -49,7 +49,7 @@ public interface ITestRequestManager : IDisposable /// /// Multi test run finalization payload /// Multi test run finalization events handler - void FinalizeMultiTestRun(MultiTestRunFinalizationPayload multiTestRunFinalizationPayload, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationEventsHandler); + void FinalizeMultiTestRun(MultiTestRunFinalizationPayload multiTestRunFinalizationPayload, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationEventsHandler, ProtocolConfig protocolConfig); /// /// Cancel the current TestRun request diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/IMultiTestRunFinalizationManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/IMultiTestRunFinalizationManager.cs index 078bc1349f..d13ea35f71 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/IMultiTestRunFinalizationManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/IMultiTestRunFinalizationManager.cs @@ -20,7 +20,7 @@ internal interface IMultiTestRunFinalizationManager /// Collection of attachments /// EventHandler for handling multi test run finalization event /// Cancellation token - Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken); + Task FinalizeMultiTestRunAsync(IRequestData requestData, IEnumerable attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken); /// /// Finalizes multi test run @@ -28,6 +28,6 @@ internal interface IMultiTestRunFinalizationManager /// Collection of attachments /// Cancellation token /// Collection of attachments. - Task> FinalizeMultiTestRunAsync(ICollection attachments, CancellationToken cancellationToken); + Task> FinalizeMultiTestRunAsync(IRequestData requestData, IEnumerable attachments, CancellationToken cancellationToken); } } diff --git a/src/Microsoft.TestPlatform.Common/Telemetry/TelemetryDataConstants.cs b/src/Microsoft.TestPlatform.Common/Telemetry/TelemetryDataConstants.cs index b7a277e1e1..671350a63e 100644 --- a/src/Microsoft.TestPlatform.Common/Telemetry/TelemetryDataConstants.cs +++ b/src/Microsoft.TestPlatform.Common/Telemetry/TelemetryDataConstants.cs @@ -90,9 +90,19 @@ public static class TelemetryDataConstants public static string NumberOfAdapterUsedToDiscoverTests = "VS.TestDiscovery.AdaptersUsedCount"; + // *********************Finalization**************************** + public static string NumberOfAttachmentsSentForFinalization = "VS.TestFinalization.InitialAttachmentsCount"; + + public static string NumberOfAttachmentsAfterFinalization = "VS.TestFinalization.FinalAttachmentsCount"; + + public static string TimeTakenInSecForFinalization = "VS.TestFinalization.TotalTimeTakenInSec"; + public static string FinalizationState = "VS.TestFinalization.FinalizationState"; + // **************Events Name ********************************** public static string TestDiscoveryCompleteEvent = "vs/testplatform/testdiscoverysession"; public static string TestExecutionCompleteEvent = "vs/testplatform/testrunsession"; + + public static string TestFinalizationCompleteEvent = "vs/testplatform/testfinalizationsession"; } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelRunEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelRunEventsHandler.cs index bacf1da410..5a66d9528e 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelRunEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelRunEventsHandler.cs @@ -31,7 +31,7 @@ internal class ParallelRunEventsHandler : ITestRunEventsHandler2 private IDataSerializer dataSerializer; - private IRequestData requestData; + protected IRequestData requestData; public ParallelRunEventsHandler(IRequestData requestData, IProxyExecutionManager proxyExecutionManager, diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ParallelDataCollectionEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ParallelDataCollectionEventsHandler.cs index 0ac7a10312..f6c2ea0829 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ParallelDataCollectionEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ParallelDataCollectionEventsHandler.cs @@ -56,7 +56,7 @@ public override void HandleTestRunComplete( if (parallelRunComplete) { - runDataAggregator.RunContextAttachments = finalizationManager.FinalizeMultiTestRunAsync(runDataAggregator.RunContextAttachments, cancellationToken).Result ?? runDataAggregator.RunContextAttachments; + runDataAggregator.RunContextAttachments = finalizationManager.FinalizeMultiTestRunAsync(requestData, runDataAggregator.RunContextAttachments, cancellationToken).Result ?? runDataAggregator.RunContextAttachments; 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 f3a0188771..4bb4818ee9 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/MultiTestRunFinalization/MultiTestRunFinalizationManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/MultiTestRunFinalization/MultiTestRunFinalizationManager.cs @@ -4,9 +4,11 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing.Interfaces; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; @@ -20,6 +22,10 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.MultiTestRunFinali /// public class MultiTestRunFinalizationManager : IMultiTestRunFinalizationManager { + private static string FinalizationCompleted = "Completed"; + private static string FinalizationCanceled = "Canceled"; + private static string FinalizationFailed = "Failed"; + private readonly ITestPlatformEventSource testPlatformEventSource; private readonly IDataCollectorAttachments[] dataCollectorAttachmentsHandlers; @@ -33,65 +39,74 @@ public MultiTestRunFinalizationManager(ITestPlatformEventSource testPlatformEven } /// - public async Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken) + public async Task FinalizeMultiTestRunAsync(IRequestData requestData, IEnumerable attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken) { - await InternalFinalizeMultiTestRunAsync(new Collection(attachments.ToList()), eventHandler, cancellationToken).ConfigureAwait(false); + await InternalFinalizeMultiTestRunAsync(requestData, new Collection(attachments.ToList()), eventHandler, cancellationToken).ConfigureAwait(false); } - /// - public Task> FinalizeMultiTestRunAsync(ICollection attachments, CancellationToken cancellationToken) + public Task> FinalizeMultiTestRunAsync(IRequestData requestData, IEnumerable attachments, CancellationToken cancellationToken) { - return InternalFinalizeMultiTestRunAsync(new Collection(attachments.ToList()), null, cancellationToken); + return InternalFinalizeMultiTestRunAsync(requestData, new Collection(attachments.ToList()), null, cancellationToken); } - private async Task> InternalFinalizeMultiTestRunAsync(Collection attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken) + private async Task> InternalFinalizeMultiTestRunAsync(IRequestData requestData, Collection attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken) { + Stopwatch stopwatch = Stopwatch.StartNew(); + try { testPlatformEventSource.MultiTestRunFinalizationStart(attachments?.Count ?? 0); - + requestData.MetricsCollection.Add(TelemetryDataConstants.NumberOfAttachmentsSentForFinalization, attachments?.Count ?? 0); + cancellationToken.ThrowIfCancellationRequested(); - var taskCompletionSource = new TaskCompletionSource(); + var taskCompletionSource = new TaskCompletionSource>(); using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled())) { - Task task = Task.Run(() => + Task> task = Task.Run(() => { - HandleAttachments(attachments, cancellationToken); + return ProcessAttachments(new Collection(attachments.ToList()), new ProgressReporter(eventHandler, dataCollectorAttachmentsHandlers.Length), cancellationToken); }); var completedTask = await Task.WhenAny(task, taskCompletionSource.Task).ConfigureAwait(false); if (completedTask == task) { - await task; - eventHandler?.HandleMultiTestRunFinalizationComplete(attachments); - testPlatformEventSource.MultiTestRunFinalizationStop(attachments.Count); - return attachments; + return FinalizeOperation(requestData, await task, eventHandler, FinalizationCompleted); } else { eventHandler?.HandleLogMessage(ObjectModel.Logging.TestMessageLevel.Informational, "Finalization was cancelled."); - eventHandler?.HandleMultiTestRunFinalizationComplete(null); - testPlatformEventSource.MultiTestRunFinalizationStop(0); + return FinalizeOperation(requestData, attachments, eventHandler, FinalizationCanceled); } } - - return null; + } + catch (OperationCanceledException) + { + if (EqtTrace.IsWarningEnabled) + { + EqtTrace.Warning("MultiTestRunFinalizationManager: operation was cancelled."); + } + return FinalizeOperation(requestData, attachments, eventHandler, FinalizationCanceled); } catch (Exception e) { EqtTrace.Error("MultiTestRunFinalizationManager: Exception in FinalizeMultiTestRunAsync: " + e); eventHandler?.HandleLogMessage(ObjectModel.Logging.TestMessageLevel.Error, e.Message); - eventHandler?.HandleMultiTestRunFinalizationComplete(null); - testPlatformEventSource.MultiTestRunFinalizationStop(0); - return null; + return FinalizeOperation(requestData, attachments, eventHandler, FinalizationFailed); + } + finally + { + stopwatch.Stop(); + requestData.MetricsCollection.Metrics.Add(TelemetryDataConstants.TimeTakenInSecForFinalization, stopwatch.Elapsed.TotalSeconds); } } - private void HandleAttachments(ICollection attachments, CancellationToken cancellationToken) + private Collection ProcessAttachments(Collection attachments, ProgressReporter progressReporter, CancellationToken cancellationToken) { + if (attachments == null || !attachments.Any()) return attachments; + foreach (var dataCollectorAttachmentsHandler in dataCollectorAttachmentsHandlers) { Uri attachementUri = dataCollectorAttachmentsHandler.GetExtensionUri(); @@ -105,7 +120,7 @@ private void HandleAttachments(ICollection attachments, Cancellat attachments.Remove(attachment); } - ICollection processedAttachments = dataCollectorAttachmentsHandler.HandleDataCollectionAttachmentSets(new Collection(attachmentsToBeProcessed), cancellationToken); + ICollection processedAttachments = dataCollectorAttachmentsHandler.HandleDataCollectionAttachmentSets(new Collection(attachmentsToBeProcessed), progressReporter, cancellationToken); foreach (var attachment in processedAttachments) { attachments.Add(attachment); @@ -113,6 +128,42 @@ private void HandleAttachments(ICollection attachments, Cancellat } } } + + return attachments; + } + + private Collection FinalizeOperation(IRequestData requestData, Collection attachments, IMultiTestRunFinalizationEventsHandler eventHandler, string finalizationState) + { + eventHandler?.HandleMultiTestRunFinalizationComplete(attachments); + testPlatformEventSource.MultiTestRunFinalizationStop(attachments.Count); + requestData.MetricsCollection.Add(TelemetryDataConstants.NumberOfAttachmentsAfterFinalization, attachments.Count); + requestData.MetricsCollection.Add(TelemetryDataConstants.FinalizationState, attachments.Count); + + return attachments; + } + + private class ProgressReporter : IProgress + { + private readonly IMultiTestRunFinalizationEventsHandler eventsHandler; + private readonly int totalNumberOfHandlers; + private int currentHandlerIndex; + + public ProgressReporter(IMultiTestRunFinalizationEventsHandler eventsHandler, int totalNumberOfHandlers) + { + this.eventsHandler = eventsHandler; + this.currentHandlerIndex = 0; + this.totalNumberOfHandlers = totalNumberOfHandlers; + } + + public void IncremenetHandlerIndex() + { + currentHandlerIndex++; + } + + public void Report(int value) + { + //eventsHandler.report( current, total, value) + } } } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/MultiTestRunFinalizationPayload.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/MultiTestRunFinalizationPayload.cs index 13f7cfc229..844b86e8dc 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/MultiTestRunFinalizationPayload.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Payloads/MultiTestRunFinalizationPayload.cs @@ -15,6 +15,12 @@ public class MultiTestRunFinalizationPayload /// Collection of attachments. /// [DataMember] - public ICollection Attachments { get; set; } + public IEnumerable Attachments { get; set; } + + /// + /// Gets or sets whether Metrics should be collected or not. + /// + [DataMember] + public bool CollectMetrics { get; set; } } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/IDataCollectorAttachments.cs b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/IDataCollectorAttachments.cs index 84df144523..4c1d2bdabf 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/DataCollector/IDataCollectorAttachments.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/DataCollector/IDataCollectorAttachments.cs @@ -21,8 +21,11 @@ public interface IDataCollectorAttachments /// /// Gets the attachment set after Test Run Session /// + /// Attachments to be processed + /// Progress reporter. Accepts integers from 0 to 100 + /// Cancellation token /// Gets the attachment set after Test Run Session - ICollection HandleDataCollectionAttachmentSets(ICollection dataCollectionAttachments, CancellationToken cancellationToken); + ICollection HandleDataCollectionAttachmentSets(ICollection dataCollectionAttachments, IProgress progressReporter, CancellationToken cancellationToken); /// /// Gets the attachment Uri, which is handled by current Collector diff --git a/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs b/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs index 1ca310ceda..90ab94fd56 100644 --- a/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs +++ b/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs @@ -9,6 +9,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Utilities using System.IO; using System.Linq; using System.Reflection; + using System.Resources; using System.Threading; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection; @@ -33,15 +34,15 @@ public Uri GetExtensionUri() public ICollection HandleDataCollectionAttachmentSets(ICollection dataCollectionAttachments) { - return HandleDataCollectionAttachmentSets(dataCollectionAttachments, CancellationToken.None); + return HandleDataCollectionAttachmentSets(dataCollectionAttachments, null, CancellationToken.None); } - public ICollection HandleDataCollectionAttachmentSets(ICollection dataCollectionAttachments, CancellationToken cancellationToken) + public ICollection HandleDataCollectionAttachmentSets(ICollection dataCollectionAttachments, IProgress progressReporter, CancellationToken cancellationToken) { if (dataCollectionAttachments != null && dataCollectionAttachments.Any()) { var codeCoverageFiles = dataCollectionAttachments.Select(coverageAttachment => coverageAttachment.Attachments[0].Uri.LocalPath).ToArray(); - var outputFile = MergeCodeCoverageFiles(codeCoverageFiles, cancellationToken); + var outputFile = MergeCodeCoverageFiles(codeCoverageFiles, progressReporter, cancellationToken); var attachmentSet = new AttachmentSet(CodeCoverageDataCollectorUri, CoverageFriendlyName); if (!string.IsNullOrEmpty(outputFile)) @@ -57,7 +58,7 @@ public ICollection HandleDataCollectionAttachmentSets(ICollection return new Collection(); } - private string MergeCodeCoverageFiles(IList files, CancellationToken cancellationToken) + private string MergeCodeCoverageFiles(IList files, IProgress progressReporter, CancellationToken cancellationToken) { string fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + CoverageFileExtension); string outputfileName = files[0]; @@ -82,11 +83,14 @@ private string MergeCodeCoverageFiles(IList files, CancellationToken can cancellationToken.ThrowIfCancellationRequested(); File.Copy(fileName, outputfileName, true); + + progressReporter?.Report(100 * i / files.Count); } File.Delete(fileName); } + progressReporter?.Report(100); return outputfileName; } catch (OperationCanceledException) diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs index 45519affa7..35e50a9b10 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSender.cs @@ -14,7 +14,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces /// /// Defines contract to send test platform requests to test host /// - internal interface ITranslationLayerRequestSender : IDisposable + internal interface ITranslationLayerRequestSender : IDisposable, ITranslationLayerRequestSenderAsync { /// /// Initializes the communication for sending requests @@ -111,13 +111,5 @@ internal interface ITranslationLayerRequestSender : IDisposable /// Cancels the discovery of tests /// void CancelDiscovery(); - - /// - /// Provides back all attachments to TestPlatform for additional processing (for example merging) - /// - /// Collection of attachments - /// 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 0bf4ce0a82..19ef32c915 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/ITranslationLayerRequestSenderAsync.cs @@ -23,16 +23,6 @@ internal interface ITranslationLayerRequestSenderAsync : IDisposable /// Task InitializeCommunicationAsync(int clientConnectionTimeout); - /// - /// See - /// - void Close(); - - /// - /// See - /// - void InitializeExtensions(IEnumerable pathToAdditionalExtensions); - /// /// Asynchronous equivalent of ITranslationLayerRequestSender.DiscoverTests/>. /// @@ -58,32 +48,13 @@ internal interface ITranslationLayerRequestSenderAsync : IDisposable /// Task StartTestRunWithCustomHostAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler runEventsHandler, ITestHostLauncher customTestHostLauncher); - /// - /// See . - /// - void EndSession(); - - /// - /// See . - /// - void CancelTestRun(); - - /// - /// See . - /// - void AbortTestRun(); - - /// - /// See . - /// - void OnProcessExited(); - /// /// Provides back all attachments to TestPlatform for additional processing (for example merging) /// /// Collection of attachments + /// Enables metrics collection /// Events handler /// Cancellation token - Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler, CancellationToken cancellationToken); + Task FinalizeMultiTestRunAsync(IEnumerable attachments, bool collectMetrics, 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 d9b86dac3a..9cd3c6b5b9 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapper.cs @@ -4,8 +4,6 @@ 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; @@ -13,7 +11,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces /// /// Controller for various test operations on the test runner. /// - public interface IVsTestConsoleWrapper + public interface IVsTestConsoleWrapper : IVsTestConsoleWrapperAsync { /// /// Starts the test runner process and readies for requests. @@ -120,14 +118,6 @@ 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 attachments to TestPlatform for additional processing (for example merging) - /// - /// Collection of attachments - /// 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/IVsTestConsoleWrapperAsync.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs index 3e6cabe3b8..56e322d711 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Interfaces/IVsTestConsoleWrapperAsync.cs @@ -37,11 +37,6 @@ public interface IVsTestConsoleWrapperAsync /// Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler); - /// - /// See . - /// - void CancelDiscovery(); - /// /// Asynchronous equivalent of . /// @@ -86,23 +81,9 @@ public interface IVsTestConsoleWrapperAsync /// Provides back all attachments to TestPlatform for additional processing (for example merging) /// /// Collection of attachments + /// Enables metrics collection /// EventHandler to receive session complete event - /// Cancellation token - Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler, CancellationToken cancellationToken); - - /// - /// See . - /// - void CancelTestRun(); - - /// - /// See . - /// - void AbortTestRun(); - - /// - /// See . - /// - void EndSession(); + /// Cancellation token + Task FinalizeMultiTestRunAsync(IEnumerable attachments, bool collectMetrics, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler, CancellationToken cancellationToken); } } diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index 69589fe187..6d0e187be5 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -26,7 +26,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer /// /// VstestConsoleRequestSender for sending requests to Vstest.console.exe /// - internal class VsTestConsoleRequestSender : ITranslationLayerRequestSender, ITranslationLayerRequestSenderAsync + internal class VsTestConsoleRequestSender : ITranslationLayerRequestSender { private readonly ICommunicationManager communicationManager; @@ -384,9 +384,9 @@ public void EndSession() } /// - public Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) + public Task FinalizeMultiTestRunAsync(IEnumerable attachments, bool collectMetrics, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) { - return this.SendMessageAndListenAndReportFinalizationResultAsync(attachments, testSessionEventsHandler, cancellationToken); + return this.SendMessageAndListenAndReportFinalizationResultAsync(attachments, collectMetrics, testSessionEventsHandler, cancellationToken); } /// @@ -731,14 +731,16 @@ private async Task SendMessageAndListenAndReportTestResultsAsync(string messageT this.testPlatformEventSource.TranslationLayerExecutionStop(); } - private async Task SendMessageAndListenAndReportFinalizationResultAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken) + private async Task SendMessageAndListenAndReportFinalizationResultAsync(IEnumerable attachments, bool collectMetrics, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken) { try { var payload = new MultiTestRunFinalizationPayload { - Attachments = attachments + Attachments = attachments, + CollectMetrics = collectMetrics }; + this.communicationManager.SendMessage(MessageType.MultiTestRunFinalizationStart, payload); var isMultiTestRunFinalizationComplete = false; @@ -782,8 +784,10 @@ private async Task SendMessageAndListenAndReportFinalizationResultAsync(ICollect // know of the error, so that the TL can wait for the next instruction from the client itself. // Also, connection termination might not kill the process which could result in files being locked by testhost. } - - this.testPlatformEventSource.TranslationLayerMultiTestRunFinalizationStop(); + finally + { + this.testPlatformEventSource.TranslationLayerMultiTestRunFinalizationStop(); + } } private Message TryReceiveMessage() diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs index 550f72330a..e59cf1c0cc 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapper.cs @@ -274,17 +274,150 @@ public void EndSession() this.sessionStarted = false; } + #endregion + + #region IVsTestConsoleWrapper + + /// + public async Task StartSessionAsync() + { + EqtTrace.Info("VsTestConsoleWrapperAsync.StartSessionAsync: Starting VsTestConsoleWrapper session"); + + this.testPlatformEventSource.TranslationLayerInitializeStart(); + + var timeout = EnvironmentHelper.GetConnectionTimeout(); + // Start communication + var port = await this.requestSender.InitializeCommunicationAsync(timeout * 1000); + + if (port > 0) + { + // Fill the parameters + this.consoleParameters.ParentProcessId = Process.GetCurrentProcess().Id; + this.consoleParameters.PortNumber = port; + + // Start vstest.console.exe process + this.vstestConsoleProcessManager.StartProcess(this.consoleParameters); + } + else + { + // Close the sender as it failed to host server + this.requestSender.Close(); + throw new TransationLayerException("Error hosting communication channel and connecting to console"); + } + } + + /// + public async Task InitializeExtensionsAsync(IEnumerable pathToAdditionalExtensions) + { + await this.EnsureInitializedAsync(); + this.pathToAdditionalExtensions = pathToAdditionalExtensions.ToList(); + this.requestSender.InitializeExtensions(this.pathToAdditionalExtensions); + } + + /// + public async Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) + { + this.testPlatformEventSource.TranslationLayerDiscoveryStart(); + await this.EnsureInitializedAsync(); + + // Converts ITestDiscoveryEventsHandler to ITestDiscoveryEventsHandler2 + var discoveryCompleteEventsHandler2 = new DiscoveryEventsHandleConverter(discoveryEventsHandler); + await this.requestSender.DiscoverTestsAsync(sources, discoverySettings, options: null, discoveryEventsHandler: discoveryCompleteEventsHandler2); + } + + + /// + public async Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler) + { + this.testPlatformEventSource.TranslationLayerDiscoveryStart(); + await this.EnsureInitializedAsync(); + await this.requestSender.DiscoverTestsAsync(sources, discoverySettings, options, discoveryEventsHandler); + } + + /// + public async Task RunTestsAsync(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler) + { + await RunTestsAsync(sources, runSettings, null, testRunEventsHandler); + } + + /// + public async Task RunTestsAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler) + { + var sourceList = sources.ToList(); + this.testPlatformEventSource.TranslationLayerExecutionStart(0, sourceList.Count, 0, runSettings ?? string.Empty); + + await this.EnsureInitializedAsync(); + await this.requestSender.StartTestRunAsync(sourceList, runSettings, options, testRunEventsHandler); + } + /// - public Task FinalizeMultiTestRunAsync(ICollection attachments, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) + public async Task RunTestsAsync(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler) + { + var testCaseList = testCases.ToList(); + this.testPlatformEventSource.TranslationLayerExecutionStart(0, 0, testCaseList.Count, runSettings ?? string.Empty); + + await this.EnsureInitializedAsync(); + await this.requestSender.StartTestRunAsync(testCaseList, runSettings, options: null, runEventsHandler: testRunEventsHandler); + } + + /// + public async Task RunTestsAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler) + { + var testCaseList = testCases.ToList(); + this.testPlatformEventSource.TranslationLayerExecutionStart(0, 0, testCaseList.Count, runSettings ?? string.Empty); + + await this.EnsureInitializedAsync(); + await this.requestSender.StartTestRunAsync(testCaseList, runSettings, options, testRunEventsHandler); + } + + /// + public async Task RunTestsWithCustomTestHostAsync(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + { + await RunTestsWithCustomTestHostAsync(sources, runSettings, null, testRunEventsHandler, customTestHostLauncher); + } + + /// + public async Task RunTestsWithCustomTestHostAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + { + var sourceList = sources.ToList(); + this.testPlatformEventSource.TranslationLayerExecutionStart(1, sourceList.Count, 0, runSettings ?? string.Empty); + + await this.EnsureInitializedAsync(); + await this.requestSender.StartTestRunWithCustomHostAsync(sourceList, runSettings, options, testRunEventsHandler, customTestHostLauncher); + } + + /// + public async Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + { + var testCaseList = testCases.ToList(); + this.testPlatformEventSource.TranslationLayerExecutionStart(1, 0, testCaseList.Count, runSettings ?? string.Empty); + + await this.EnsureInitializedAsync(); + await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, runSettings, options: null, runEventsHandler: testRunEventsHandler, customTestHostLauncher: customTestHostLauncher); + } + + /// + public async Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) + { + var testCaseList = testCases.ToList(); + this.testPlatformEventSource.TranslationLayerExecutionStart(1, 0, testCaseList.Count, runSettings ?? string.Empty); + + await this.EnsureInitializedAsync(); + await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, runSettings, options, testRunEventsHandler, customTestHostLauncher); + } + + /// + public async Task FinalizeMultiTestRunAsync(IEnumerable attachments, bool collectMetrics, IMultiTestRunFinalizationEventsHandler testSessionEventsHandler, CancellationToken cancellationToken) { this.testPlatformEventSource.TranslationLayerMultiTestRunFinalizationStart(); - this.EnsureInitialized(); - return requestSender.FinalizeMultiTestRunAsync(attachments, testSessionEventsHandler, cancellationToken); + await this.EnsureInitializedAsync().ConfigureAwait(false); + await requestSender.FinalizeMultiTestRunAsync(attachments, collectMetrics, testSessionEventsHandler, cancellationToken).ConfigureAwait(false); } #endregion + private void EnsureInitialized() { if (!this.vstestConsoleProcessManager.IsProcessInitialized()) @@ -307,6 +440,28 @@ private void EnsureInitialized() } } + private async Task EnsureInitializedAsync() + { + if (!this.vstestConsoleProcessManager.IsProcessInitialized()) + { + EqtTrace.Info("VsTestConsoleWrapper.EnsureInitializedAsync: Process is not started."); + await this.StartSessionAsync(); + this.sessionStarted = this.WaitForConnection(); + + if (this.sessionStarted) + { + EqtTrace.Info("VsTestConsoleWrapper.EnsureInitializedAsync: Send a request to initialize extensions."); + this.requestSender.InitializeExtensions(this.pathToAdditionalExtensions); + } + } + + if (!this.sessionStarted && this.requestSender != null) + { + EqtTrace.Info("VsTestConsoleWrapper.EnsureInitializedAsync: Process Started."); + this.sessionStarted = this.WaitForConnection(); + } + } + private bool WaitForConnection() { EqtTrace.Info("VsTestConsoleWrapper.WaitForConnection: Waiting for connection to command line runner."); diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapperAsync.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapperAsync.cs deleted file mode 100644 index 0a0aaf829f..0000000000 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleWrapperAsync.cs +++ /dev/null @@ -1,269 +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 -{ - using System.Collections.Generic; - using System.Diagnostics; - 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; - using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing.Interfaces; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; - using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; - - /// - /// An implementation of to invoke test operations - /// via the vstest.console test runner. - /// - public class VsTestConsoleWrapperAsync : IVsTestConsoleWrapperAsync - { - #region Private Members - - private readonly IProcessManager vstestConsoleProcessManager; - - private readonly ITranslationLayerRequestSenderAsync requestSender; - - /// - /// Path to additional extensions to reinitialize vstest.console - /// - private IEnumerable pathToAdditionalExtensions; - - /// - /// Additional parameters for vstest.console.exe - /// - private readonly ConsoleParameters consoleParameters; - - private readonly ITestPlatformEventSource testPlatformEventSource; - - #endregion - - #region Constructor - - /// - /// Initializes a new instance of the class. - /// - /// - /// Path to the test runner vstest.console.exe. - /// - public VsTestConsoleWrapperAsync(string vstestConsolePath) : - this(vstestConsolePath, ConsoleParameters.Default) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// Path to the test runner vstest.console.exe. - /// The parameters to be passed onto the runner process - public VsTestConsoleWrapperAsync(string vstestConsolePath, ConsoleParameters consoleParameters) : - this(new VsTestConsoleRequestSender(), new VsTestConsoleProcessManager(vstestConsolePath), consoleParameters, TestPlatformEventSource.Instance) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// Sender for test messages. - /// Process manager. - /// The parameters to be passed onto the runner process - /// Performance event source - internal VsTestConsoleWrapperAsync(ITranslationLayerRequestSenderAsync requestSender, IProcessManager processManager, ConsoleParameters consoleParameters, ITestPlatformEventSource testPlatformEventSource) - { - this.requestSender = requestSender; - this.vstestConsoleProcessManager = processManager; - this.consoleParameters = consoleParameters; - this.testPlatformEventSource = testPlatformEventSource; - this.pathToAdditionalExtensions = new List(); - - this.vstestConsoleProcessManager.ProcessExited += (sender, args) => this.requestSender.OnProcessExited(); - } - - #endregion - - #region IVsTestConsoleWrapper - - /// - public async Task StartSessionAsync() - { - EqtTrace.Info("VsTestConsoleWrapperAsync.StartSessionAsync: Starting VsTestConsoleWrapper session"); - - this.testPlatformEventSource.TranslationLayerInitializeStart(); - - var timeout = EnvironmentHelper.GetConnectionTimeout(); - // Start communication - var port = await this.requestSender.InitializeCommunicationAsync(timeout * 1000); - - if (port > 0) - { - // Fill the parameters - this.consoleParameters.ParentProcessId = Process.GetCurrentProcess().Id; - this.consoleParameters.PortNumber = port; - - // Start vstest.console.exe process - this.vstestConsoleProcessManager.StartProcess(this.consoleParameters); - } - else - { - // Close the sender as it failed to host server - this.requestSender.Close(); - throw new TransationLayerException("Error hosting communication channel and connecting to console"); - } - } - - /// - public async Task InitializeExtensionsAsync(IEnumerable pathToAdditionalExtensions) - { - await this.EnsureInitializedAsync(); - this.pathToAdditionalExtensions = pathToAdditionalExtensions.ToList(); - this.requestSender.InitializeExtensions(this.pathToAdditionalExtensions); - } - - /// - public async Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) - { - this.testPlatformEventSource.TranslationLayerDiscoveryStart(); - await this.EnsureInitializedAsync(); - - // Converts ITestDiscoveryEventsHandler to ITestDiscoveryEventsHandler2 - var discoveryCompleteEventsHandler2 = new DiscoveryEventsHandleConverter(discoveryEventsHandler); - await this.requestSender.DiscoverTestsAsync(sources, discoverySettings, options: null, discoveryEventsHandler: discoveryCompleteEventsHandler2); - } - - - /// - public async Task DiscoverTestsAsync(IEnumerable sources, string discoverySettings, TestPlatformOptions options, ITestDiscoveryEventsHandler2 discoveryEventsHandler) - { - this.testPlatformEventSource.TranslationLayerDiscoveryStart(); - await this.EnsureInitializedAsync(); - await this.requestSender.DiscoverTestsAsync(sources, discoverySettings, options, discoveryEventsHandler); - } - - /// - public void CancelDiscovery() - { - // TODO: Cancel Discovery - // this.requestSender.CancelDiscovery(); - } - - /// - public async Task RunTestsAsync(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler) - { - await RunTestsAsync(sources, runSettings, null, testRunEventsHandler); - } - - /// - public async Task RunTestsAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler) - { - var sourceList = sources.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, sourceList.Count, 0, runSettings ?? string.Empty); - - await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunAsync(sourceList, runSettings, options, testRunEventsHandler); - } - - /// - public async Task RunTestsAsync(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler) - { - var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, 0, testCaseList.Count, runSettings ?? string.Empty); - - await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunAsync(testCaseList, runSettings, options: null, runEventsHandler: testRunEventsHandler); - } - - /// - public async Task RunTestsAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler) - { - var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(0, 0, testCaseList.Count, runSettings ?? string.Empty); - - await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunAsync(testCaseList, runSettings, options, testRunEventsHandler); - } - - /// - public async Task RunTestsWithCustomTestHostAsync(IEnumerable sources, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) - { - await RunTestsWithCustomTestHostAsync(sources, runSettings, null, testRunEventsHandler, customTestHostLauncher); - } - - /// - public async Task RunTestsWithCustomTestHostAsync(IEnumerable sources, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) - { - var sourceList = sources.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, sourceList.Count, 0, runSettings ?? string.Empty); - - await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunWithCustomHostAsync(sourceList, runSettings, options, testRunEventsHandler, customTestHostLauncher); - } - - /// - public async Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) - { - var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, 0, testCaseList.Count, runSettings ?? string.Empty); - - await this.EnsureInitializedAsync(); - await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, runSettings, options: null, runEventsHandler: testRunEventsHandler, customTestHostLauncher: customTestHostLauncher); - } - - /// - public async Task RunTestsWithCustomTestHostAsync(IEnumerable testCases, string runSettings, TestPlatformOptions options, ITestRunEventsHandler testRunEventsHandler, ITestHostLauncher customTestHostLauncher) - { - var testCaseList = testCases.ToList(); - this.testPlatformEventSource.TranslationLayerExecutionStart(1, 0, testCaseList.Count, runSettings ?? string.Empty); - - await this.EnsureInitializedAsync(); - 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().ConfigureAwait(false); - await requestSender.FinalizeMultiTestRunAsync(attachments, testSessionEventsHandler, cancellationToken).ConfigureAwait(false); - } - - /// - public void CancelTestRun() - { - this.requestSender.CancelTestRun(); - } - - /// - public void AbortTestRun() - { - this.requestSender.AbortTestRun(); - } - - /// - public void EndSession() - { - this.requestSender.EndSession(); - this.requestSender.Close(); - } - - #endregion - - private async Task EnsureInitializedAsync() - { - if (!this.vstestConsoleProcessManager.IsProcessInitialized()) - { - EqtTrace.Info("VsTestConsoleWrapper.EnsureInitializedAsync: Process is not started."); - await this.StartSessionAsync(); - - EqtTrace.Info("VsTestConsoleWrapper.EnsureInitializedAsync: Send a request to initialize extensions."); - this.requestSender.InitializeExtensions(this.pathToAdditionalExtensions); - } - } - - } -} diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index d38cc6cd0e..ac53184926 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -313,10 +313,13 @@ public void RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLaunc } /// - public void FinalizeMultiTestRun(MultiTestRunFinalizationPayload finalizationPayload, IMultiTestRunFinalizationEventsHandler finalizationEventsHandler) + public void FinalizeMultiTestRun(MultiTestRunFinalizationPayload finalizationPayload, IMultiTestRunFinalizationEventsHandler finalizationEventsHandler, ProtocolConfig protocolConfig) { EqtTrace.Info("TestRequestManager.FinalizeMultiTestRun: Multi test run finalization started."); + this.telemetryOptedIn = finalizationPayload.CollectMetrics; + var requestData = this.GetRequestData(protocolConfig); + // Make sure to run the run request inside a lock as the below section is not thread-safe // There can be only one discovery, execution or finalization request at a given point in time lock (this.syncObject) @@ -328,7 +331,7 @@ public void FinalizeMultiTestRun(MultiTestRunFinalizationPayload finalizationPay this.currentFinalizationCancellationTokenSource = new CancellationTokenSource(); - Task task = this.finalizationManager.FinalizeMultiTestRunAsync(finalizationPayload.Attachments, finalizationEventsHandler, this.currentFinalizationCancellationTokenSource.Token); + Task task = this.finalizationManager.FinalizeMultiTestRunAsync(requestData, finalizationPayload.Attachments, finalizationEventsHandler, this.currentFinalizationCancellationTokenSource.Token); task.Wait(); } finally @@ -341,6 +344,9 @@ public void FinalizeMultiTestRun(MultiTestRunFinalizationPayload finalizationPay EqtTrace.Info("TestRequestManager.FinalizeMultiTestRun: Multi test run finalization completed."); this.testPlatformEventSource.MultiTestRunFinalizationRequestStop(); + + // Post the finalization complete event + this.metricsPublisher.Result.PublishMetrics(TelemetryDataConstants.TestFinalizationCompleteEvent, requestData.MetricsCollection.Metrics); } } } diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/CodeCoverageTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/CodeCoverageTests.cs index aab70e6843..54cf57f5cb 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/CodeCoverageTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/CodeCoverageTests.cs @@ -102,7 +102,7 @@ public async Task TestRunWithCodeCoverageAndFinalization(RunnerInfo runnerInfo) Assert.AreEqual(2, this.runEventHandler.Attachments.Count); // act - await this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(runEventHandler.Attachments, multiTestRunFinalizationEventHandler, CancellationToken.None); + await this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(runEventHandler.Attachments, true, multiTestRunFinalizationEventHandler, CancellationToken.None); // Assert multiTestRunFinalizationEventHandler.EnsureSuccess(); @@ -128,7 +128,7 @@ public async Task TestRunWithCodeCoverageAndFinalizationModuleDuplicated(RunnerI Assert.AreEqual(3, this.runEventHandler.Attachments.Count); // act - await this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(runEventHandler.Attachments, multiTestRunFinalizationEventHandler, CancellationToken.None); + await this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(runEventHandler.Attachments, true, multiTestRunFinalizationEventHandler, CancellationToken.None); // Assert multiTestRunFinalizationEventHandler.EnsureSuccess(); @@ -154,7 +154,7 @@ public async Task TestRunWithCodeCoverageAndFinalizationCancelled(RunnerInfo run CancellationTokenSource cts = new CancellationTokenSource(); - Task finalization = this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(attachments, multiTestRunFinalizationEventHandler, cts.Token); + Task finalization = this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(attachments, true, multiTestRunFinalizationEventHandler, cts.Token); await Task.Delay(TimeSpan.FromSeconds(1)); // act @@ -186,7 +186,7 @@ public async Task EndSessionShouldEnsureVstestConsoleProcessDies(RunnerInfo runn Assert.AreEqual(6, this.runEventHandler.TestResults.Count); Assert.AreEqual(2, this.runEventHandler.Attachments.Count); - await this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(runEventHandler.Attachments, multiTestRunFinalizationEventHandler, CancellationToken.None); + await this.vstestConsoleWrapper.FinalizeMultiTestRunAsync(runEventHandler.Attachments, true, multiTestRunFinalizationEventHandler, CancellationToken.None); // act this.vstestConsoleWrapper?.EndSession(); diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs index 4c8c962e92..28818876d9 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs @@ -419,7 +419,8 @@ public void DesignModeClientConnectShouldSendTestMessageAndFinalizationCompleteO this.mockTestRequestManager.Setup( rm => rm.FinalizeMultiTestRun( It.IsAny(), - It.IsAny())) + It.IsAny(), + It.IsAny())) .Throws(new Exception()); this.designModeClient.ConnectToClientAndProcessRequests(PortNumber, this.mockTestRequestManager.Object); @@ -442,7 +443,8 @@ public void DesignModeClientConnectShouldSendTestMessageAndDiscoverCompleteOnTes this.mockTestRequestManager.Setup( rm => rm.FinalizeMultiTestRun( It.IsAny(), - It.IsAny())) + It.IsAny(), + It.IsAny())) .Throws(new TestPlatformException("Hello world")); this.designModeClient.ConnectToClientAndProcessRequests(PortNumber, this.mockTestRequestManager.Object); @@ -464,7 +466,8 @@ public void DesignModeClientConnectShouldCallRequestManagerForFinalizationStart( .Setup( rm => rm.FinalizeMultiTestRun( It.IsAny(), - It.IsAny())) + It.IsAny(), + It.IsAny())) .Callback(() => complateEvent.Set()); this.designModeClient.ConnectToClientAndProcessRequests(PortNumber, this.mockTestRequestManager.Object); @@ -472,7 +475,7 @@ public void DesignModeClientConnectShouldCallRequestManagerForFinalizationStart( Assert.IsTrue(this.complateEvent.WaitOne(Timeout), "Finalization not completed."); this.mockCommunicationManager.Verify(cm => cm.SendMessage(MessageType.TestMessage, It.IsAny()), Times.Never); this.mockCommunicationManager.Verify(cm => cm.SendMessage(MessageType.MultiTestRunFinalizationComplete, It.IsAny()), Times.Never); - this.mockTestRequestManager.Verify(rm => rm.FinalizeMultiTestRun(It.IsAny(), It.IsAny())); + this.mockTestRequestManager.Verify(rm => rm.FinalizeMultiTestRun(It.IsAny(), It.IsAny(), It.IsAny())); } [TestMethod] diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/DataCollection/ParallelDataCollectionEventsHandlerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/DataCollection/ParallelDataCollectionEventsHandlerTests.cs index 81bd9a7fe0..e341bb5c74 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/DataCollection/ParallelDataCollectionEventsHandlerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/DataCollection/ParallelDataCollectionEventsHandlerTests.cs @@ -61,14 +61,14 @@ public void HandleTestRunComplete_ShouldCallFinalizerWithAttachmentsAndUseResult new AttachmentSet(new Uri(uri1), "uri1_input1") }; - mockMultiTestRunFinalizationManager.Setup(f => f.FinalizeMultiTestRunAsync(It.IsAny>(), It.IsAny())).Returns(Task.FromResult(outputAttachments)); + mockMultiTestRunFinalizationManager.Setup(f => f.FinalizeMultiTestRunAsync(mockRequestData.Object, It.IsAny>(), It.IsAny())).Returns(Task.FromResult(outputAttachments)); // act parallelDataCollectionEventsHandler.HandleTestRunComplete(new TestRunCompleteEventArgs(null, false, false, null, null, TimeSpan.FromSeconds(1)), null, inputAttachments, null); // assert mockTestRunEventsHandler.Verify(h => h.HandleTestRunComplete(It.IsAny(), It.IsAny(), It.Is>(c => c.Count == 1 && c.Contains(outputAttachments[0])), It.IsAny>())); - mockMultiTestRunFinalizationManager.Verify(f => f.FinalizeMultiTestRunAsync(It.Is>(a => a.Count == 3), cancellationTokenSource.Token)); + mockMultiTestRunFinalizationManager.Verify(f => f.FinalizeMultiTestRunAsync(mockRequestData.Object, It.Is>(a => a.Count == 3), cancellationTokenSource.Token)); } [TestMethod] @@ -82,14 +82,14 @@ public void HandleTestRunComplete_ShouldCallFinalizerWithAttachmentsAndNotUserRe new AttachmentSet(new Uri(uri3), "uri3_input1") }; - mockMultiTestRunFinalizationManager.Setup(f => f.FinalizeMultiTestRunAsync(It.IsAny>(), It.IsAny())).Returns(Task.FromResult((Collection)null)); + mockMultiTestRunFinalizationManager.Setup(f => f.FinalizeMultiTestRunAsync(mockRequestData.Object, It.IsAny>(), It.IsAny())).Returns(Task.FromResult((Collection)null)); // act parallelDataCollectionEventsHandler.HandleTestRunComplete(new TestRunCompleteEventArgs(null, false, false, null, null, TimeSpan.FromSeconds(1)), null, inputAttachments, null); // assert mockTestRunEventsHandler.Verify(h => h.HandleTestRunComplete(It.IsAny(), It.IsAny(), It.Is>(c => c.Count == 3), It.IsAny>())); - mockMultiTestRunFinalizationManager.Verify(f => f.FinalizeMultiTestRunAsync(It.Is>(a => a.Count == 3), cancellationTokenSource.Token)); + mockMultiTestRunFinalizationManager.Verify(f => f.FinalizeMultiTestRunAsync(mockRequestData.Object, It.Is>(a => a.Count == 3), cancellationTokenSource.Token)); } } } diff --git a/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs b/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs index 915ad152b5..145c86993a 100644 --- a/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs +++ b/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs @@ -1,22 +1,23 @@ -using System.Collections.Generic; - -namespace Microsoft.TestPlatform.Utilities.UnitTests +namespace Microsoft.TestPlatform.Utilities.UnitTests { using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.Utilities; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using System; + using System.Collections.Generic; using System.Collections.ObjectModel; using System.Threading; [TestClass] public class CodeCoverageDataAttachmentsHandlerTests { - private CodeCoverageDataAttachmentsHandler coverageDataAttachmentsHandler; + private readonly Mock> mockProgressReporter; + private readonly CodeCoverageDataAttachmentsHandler coverageDataAttachmentsHandler; public CodeCoverageDataAttachmentsHandlerTests() { + mockProgressReporter = new Mock>(); coverageDataAttachmentsHandler = new CodeCoverageDataAttachmentsHandler(); } @@ -25,15 +26,17 @@ public void HandleDataCollectionAttachmentSetsShouldReturnEmptySetWhenNoAttachme { Collection attachment = new Collection(); ICollection resultAttachmentSets = - coverageDataAttachmentsHandler.HandleDataCollectionAttachmentSets(attachment, CancellationToken.None); + coverageDataAttachmentsHandler.HandleDataCollectionAttachmentSets(attachment, mockProgressReporter.Object, CancellationToken.None); Assert.IsNotNull(resultAttachmentSets); Assert.IsTrue(resultAttachmentSets.Count == 0); - resultAttachmentSets = coverageDataAttachmentsHandler.HandleDataCollectionAttachmentSets(null, CancellationToken.None); + resultAttachmentSets = coverageDataAttachmentsHandler.HandleDataCollectionAttachmentSets(null, mockProgressReporter.Object, CancellationToken.None); Assert.IsNotNull(resultAttachmentSets); Assert.IsTrue(resultAttachmentSets.Count == 0); + + mockProgressReporter.Verify(p => p.Report(It.IsAny()), Times.Never); } [TestMethod] @@ -49,9 +52,11 @@ public void HandleDataCollectionAttachmentSetsShouldThrowIfCancellationRequested attachmentSet }; - Assert.ThrowsException(() => coverageDataAttachmentsHandler.HandleDataCollectionAttachmentSets(attachment, cts.Token)); + Assert.ThrowsException(() => coverageDataAttachmentsHandler.HandleDataCollectionAttachmentSets(attachment, mockProgressReporter.Object, cts.Token)); Assert.AreEqual(1, attachment.Count); + + mockProgressReporter.Verify(p => p.Report(It.IsAny()), Times.Never); } [TestMethod] @@ -71,11 +76,13 @@ public void HandleDataCollectionAttachmentSetsShouldReturnExistingAttachmentsIfF attachmentSet2 }; - var result = coverageDataAttachmentsHandler.HandleDataCollectionAttachmentSets(attachment, cts.Token); + var result = coverageDataAttachmentsHandler.HandleDataCollectionAttachmentSets(attachment, mockProgressReporter.Object, cts.Token); Assert.AreEqual(2, result.Count); Assert.IsTrue(result.Contains(attachmentSet1)); Assert.IsTrue(result.Contains(attachmentSet2)); + + mockProgressReporter.Verify(p => p.Report(It.IsAny()), Times.Never); } } } diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs index d3d45ca6a7..c1f999f6d8 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs @@ -33,8 +33,6 @@ public class VsTestConsoleRequestSenderTests { private readonly ITranslationLayerRequestSender requestSender; - private readonly ITranslationLayerRequestSenderAsync requestSenderAsync; - private readonly Mock mockCommunicationManager; private readonly int WaitTimeout = 2000; @@ -49,10 +47,6 @@ public VsTestConsoleRequestSenderTests() this.mockCommunicationManager.Object, JsonDataSerializer.Instance, new Mock().Object); - this.requestSenderAsync = new VsTestConsoleRequestSender( - this.mockCommunicationManager.Object, - JsonDataSerializer.Instance, - new Mock().Object); } #region Communication Tests @@ -104,7 +98,7 @@ public async Task InitializeCommunicationAsyncShouldReturnInvalidPortNumberIfHos this.mockCommunicationManager.Setup(cm => cm.HostServer(new IPEndPoint(IPAddress.Loopback, 0))).Throws(new Exception("Fail")); this.mockCommunicationManager.Setup(cm => cm.AcceptClientAsync()).Returns(Task.FromResult(false)); - var portOutput = await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); + var portOutput = await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); Assert.IsTrue(portOutput < 0, "Negative port number must be returned if Hosting Server fails."); this.mockCommunicationManager.Verify(cm => cm.HostServer(new IPEndPoint(IPAddress.Loopback, 0)), Times.Once); @@ -143,7 +137,7 @@ public async Task InitializeCommunicationAsyncShouldFailConnectionIfMessageRecei this.mockCommunicationManager.Setup(cm => cm.AcceptClientAsync()).Returns(Task.FromResult(false)).Callback(() => { }); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).ThrowsAsync(new Exception("Fail")); - var portOutput = await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); + var portOutput = await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); // Connection must not succeed as handshake failed Assert.AreEqual(-1, portOutput, "Connection must fail if handshake failed."); @@ -189,7 +183,7 @@ public async Task InitializeCommunicationAsyncShouldFailConnectionIfSessionConne this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryMessage)); - var portOutput = await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); + var portOutput = await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); Assert.AreEqual(-1, portOutput, "Connection must fail if version check failed."); this.mockCommunicationManager.Verify(cm => cm.HostServer(new IPEndPoint(IPAddress.Loopback, 0)), Times.Once); @@ -239,7 +233,7 @@ public async Task InitializeCommunicationAsyncShouldFailConnectionIfSendMessageF this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(sessionConnected)); this.mockCommunicationManager.Setup(cm => cm.SendMessage(MessageType.VersionCheck, this.protocolVersion)).Throws(new Exception("Fail")); - var portOutput = await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); + var portOutput = await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); Assert.AreEqual(-1, portOutput, "Connection must fail if version check failed."); this.mockCommunicationManager.Verify(cm => cm.HostServer(new IPEndPoint(IPAddress.Loopback, 0)), Times.Once); @@ -310,7 +304,7 @@ public async Task InitializeCommunicationAsyncShouldFailConnectionIfProtocolIsNo this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(sessionConnected)); this.mockCommunicationManager.Setup(cm => cm.SendMessage(MessageType.VersionCheck)).Callback(changedMessage); - var portOutput = await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); + var portOutput = await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); Assert.AreEqual(-1, portOutput, "Connection must fail if version check failed."); this.mockCommunicationManager.Verify(cm => cm.HostServer(new IPEndPoint(IPAddress.Loopback, 0)), Times.Once); @@ -361,7 +355,7 @@ public async Task DiscoverTestsAsyncShouldCompleteWithZeroTests() }; this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete)); - await this.requestSenderAsync.DiscoverTestsAsync(new List() { "1.dll" }, null, null, mockHandler.Object); + await this.requestSender.DiscoverTestsAsync(new List() { "1.dll" }, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleDiscoveryComplete(It.IsAny(), null), Times.Once, "Discovery Complete must be called"); mockHandler.Verify(mh => mh.HandleDiscoveredTests(It.IsAny>()), Times.Never, "DiscoveredTests must not be called"); @@ -427,7 +421,7 @@ public async Task DiscoverTestsAsyncShouldCompleteWithSingleTest() mockHandler.Setup(mh => mh.HandleDiscoveredTests(It.IsAny>())).Callback( () => this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete))); - await this.requestSenderAsync.DiscoverTestsAsync(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.DiscoverTestsAsync(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); mockHandler.Verify(mh => mh.HandleDiscoveryComplete(It.IsAny(), null), Times.Once, "Discovery Complete must be called"); mockHandler.Verify(mh => mh.HandleDiscoveredTests(It.IsAny>()), Times.Once, "DiscoveredTests must be called"); @@ -498,7 +492,7 @@ public async Task DiscoverTestsAsyncShouldReportBackTestsWithTraitsInTestsFoundM this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult((discoveryComplete))); }); - await this.requestSenderAsync.DiscoverTestsAsync(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.DiscoverTestsAsync(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); Assert.IsNotNull(receivedTestCases); Assert.AreEqual(1, receivedTestCases.Count); @@ -570,7 +564,7 @@ public async Task DiscoverTestsAsyncShouldReportBackTestsWithTraitsInDiscoveryCo receivedTestCases = tests?.ToList(); }); - await this.requestSenderAsync.DiscoverTestsAsync(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.DiscoverTestsAsync(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); Assert.IsNotNull(receivedTestCases); Assert.AreEqual(1, receivedTestCases.Count); @@ -635,7 +629,7 @@ public async Task DiscoverTestsAsyncShouldCompleteWithTestMessage() mockHandler.Setup(mh => mh.HandleLogMessage(It.IsAny(), It.IsAny())).Callback( () => this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete))); - await this.requestSenderAsync.DiscoverTestsAsync(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.DiscoverTestsAsync(new List() { "1.dll" }, null, new TestPlatformOptions(), mockHandler.Object); mockHandler.Verify(mh => mh.HandleDiscoveryComplete(It.IsAny(), null), Times.Once, "Discovery Complete must be called"); mockHandler.Verify(mh => mh.HandleDiscoveredTests(It.IsAny>()), Times.Once, "DiscoveredTests must be called"); @@ -665,7 +659,7 @@ public async Task DiscoverTestsAsyncShouldAbortOnExceptionInSendMessage() var payload = new DiscoveryRequestPayload { Sources = sources, RunSettings = null }; this.mockCommunicationManager.Setup(cm => cm.SendMessage(MessageType.StartDiscovery, payload)).Throws(new IOException()); - await this.requestSenderAsync.DiscoverTestsAsync(sources, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.DiscoverTestsAsync(sources, null, new TestPlatformOptions(), mockHandler.Object); mockHandler.Verify(mh => mh.HandleDiscoveryComplete(It.IsAny(), null), Times.Once, "Discovery Complete must be called"); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once, "TestMessage event must be called"); @@ -710,16 +704,16 @@ public async Task DiscoverTestsAsyncShouldLogErrorWhenProcessExited() var testCase = new TestCase("hello", new Uri("world://how"), "1.dll"); var testCaseList = new List() { testCase }; var testsFound = CreateMessage(MessageType.TestCasesFound, testCaseList); - await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); + await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Callback( (CancellationToken c) => { - Task.Run(() => this.requestSenderAsync.OnProcessExited()).Wait(); + Task.Run(() => this.requestSender.OnProcessExited()).Wait(); Assert.IsTrue(c.IsCancellationRequested); }).Returns(Task.FromResult((Message)null)); - await this.requestSenderAsync.DiscoverTestsAsync(sources, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.DiscoverTestsAsync(sources, null, new TestPlatformOptions(), mockHandler.Object); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once); } @@ -778,7 +772,7 @@ public async Task StartTestRunAsyncShouldCompleteWithZeroTests() var runComplete = CreateMessage(MessageType.ExecutionComplete, payload); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); - await this.requestSenderAsync.StartTestRunAsync(new List() { "1.dll" }, null, null, mockHandler.Object); + await this.requestSender.StartTestRunAsync(new List() { "1.dll" }, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -888,7 +882,7 @@ public async Task StartTestRunAsyncShouldCompleteWithSingleTestAndMessage() this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - await this.requestSenderAsync.StartTestRunAsync(new List() { "1.dll" }, null, null, mockHandler.Object); + await this.requestSender.StartTestRunAsync(new List() { "1.dll" }, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1060,7 +1054,7 @@ public async Task StartTestRunAsyncWithCustomHostShouldComplete() this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runprocessInfoPayload)); - await this.requestSenderAsync.StartTestRunWithCustomHostAsync(new List() { "1.dll" }, null, null, mockHandler.Object, mockLauncher.Object); + await this.requestSender.StartTestRunWithCustomHostAsync(new List() { "1.dll" }, null, null, mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1161,7 +1155,7 @@ public async Task StartTestRunAsyncWithCustomHostShouldNotAbortAndSendErrorToVst this.mockCommunicationManager.Setup(cm => cm.SendMessage(It.IsAny(), It.IsAny(), this.protocolVersion)). Callback(() => this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete))); - await this.requestSenderAsync.StartTestRunWithCustomHostAsync(new List() { "1.dll" }, null, null, mockHandler.Object, mockLauncher.Object); + await this.requestSender.StartTestRunWithCustomHostAsync(new List() { "1.dll" }, null, null, mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1258,7 +1252,7 @@ public async Task StartTestRunAsyncWithSelectedTestsShouldCompleteWithZeroTests( var runComplete = CreateMessage(MessageType.ExecutionComplete, payload); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); - await this.requestSenderAsync.StartTestRunAsync(new List(), null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.StartTestRunAsync(new List(), null, new TestPlatformOptions(), mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1366,7 +1360,7 @@ public async Task StartTestRunAsyncWithSelectedTestsShouldCompleteWithSingleTest this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - await this.requestSenderAsync.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1474,7 +1468,7 @@ public async Task StartTestRunAsyncWithSelectedTestsHavingTraitsShouldReturnTest receivedChangeEventArgs = stats; }); - await this.requestSenderAsync.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); Assert.IsNotNull(receivedChangeEventArgs); Assert.IsTrue(receivedChangeEventArgs.NewTestResults.Count() > 0); @@ -1588,7 +1582,7 @@ public async Task StartTestRunAsyncWithSelectedTestsHavingTraitsShouldReturnTest this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runComplete)); }); - await this.requestSenderAsync.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); + await this.requestSender.StartTestRunAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object); Assert.IsNotNull(receivedChangeEventArgs); Assert.IsTrue(receivedChangeEventArgs.NewTestResults.Any()); @@ -1715,7 +1709,7 @@ public async Task StartTestRunWithCustomHostAsyncWithSelectedTestsShouldComplete this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(runprocessInfoPayload)); - await this.requestSenderAsync.StartTestRunWithCustomHostAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object, mockLauncher.Object); + await this.requestSender.StartTestRunWithCustomHostAsync(testCaseList, null, new TestPlatformOptions(), mockHandler.Object, mockLauncher.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), It.IsAny(), null, null), Times.Once, "Run Complete must be called"); @@ -1797,8 +1791,8 @@ public async Task StartTestRunWithCustomHostAsyncInParallelShouldCallCustomHostM } }); - await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); - await this.requestSenderAsync.StartTestRunWithCustomHostAsync(sources, null, null, mockHandler.Object, mockLauncher.Object); + await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); + await this.requestSender.StartTestRunWithCustomHostAsync(sources, null, null, mockHandler.Object, mockLauncher.Object); mockLauncher.Verify(ml => ml.LaunchTestHost(It.IsAny()), Times.Exactly(2)); } @@ -1830,7 +1824,7 @@ public async Task StartTestRunAsyncShouldAbortOnExceptionInSendMessage() this.mockCommunicationManager.Setup(cm => cm.SendMessage(MessageType.TestRunAllSourcesWithDefaultHost, payload, this.protocolVersion)).Throws(exception); - await this.requestSenderAsync.StartTestRunAsync(sources, null, null, mockHandler.Object); + await this.requestSender.StartTestRunAsync(sources, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleTestRunComplete(It.IsAny(), null, null, null), Times.Once, "Test Run Complete must be called"); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once, "TestMessage event must be called"); @@ -1883,16 +1877,16 @@ public async Task StartTestRunAsyncShouldLogErrorOnProcessExited() RunAttachments = null, TestRunCompleteArgs = dummyCompleteArgs }; - await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); + await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())) .Callback((CancellationToken c) => { - Task.Run(() => this.requestSenderAsync.OnProcessExited()).Wait(); + Task.Run(() => this.requestSender.OnProcessExited()).Wait(); Assert.IsTrue(c.IsCancellationRequested); }).Returns(Task.FromResult((Message)null)); - await this.requestSenderAsync.StartTestRunAsync(sources, null, null, mockHandler.Object); + await this.requestSender.StartTestRunAsync(sources, null, null, mockHandler.Object); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once); } @@ -1916,7 +1910,7 @@ public async Task FinalizeTestsShouldCompleteWithZeroAttachments() }; this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(finalizationComplete)); - await this.requestSenderAsync.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, mockHandler.Object, CancellationToken.None); + await this.requestSender.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, true, mockHandler.Object, CancellationToken.None); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationStart, It.IsAny())); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationCancel), Times.Never); @@ -1942,7 +1936,7 @@ public async Task FinalizeTestsShouldCompleteWithOneAttachment() }; this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(finalizationComplete)); - await this.requestSenderAsync.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, mockHandler.Object, CancellationToken.None); + await this.requestSender.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, true, mockHandler.Object, CancellationToken.None); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationStart, It.IsAny())); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationCancel), Times.Never); @@ -1974,7 +1968,7 @@ public async Task FinalizeTestsShouldCompleteWithOneAttachmentAndTestMessage() mockHandler.Setup(mh => mh.HandleLogMessage(It.IsAny(), It.IsAny())).Callback( () => this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(finalizationComplete))); - await this.requestSenderAsync.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, mockHandler.Object, CancellationToken.None); + await this.requestSender.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, false, mockHandler.Object, CancellationToken.None); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationStart, It.IsAny())); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationCancel), Times.Never); @@ -2011,7 +2005,7 @@ public async Task FinalizeTestsShouldSendCancelMessageIfCancellationTokenCancell this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(finalizationComplete)); }); - await this.requestSenderAsync.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, mockHandler.Object, cts.Token); + await this.requestSender.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, false, mockHandler.Object, cts.Token); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationStart, It.IsAny())); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationCancel)); @@ -2041,7 +2035,7 @@ public async Task FinalizeTestsShouldSendCancelMessageIfCancellationTokenCancell this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(finalizationComplete)); - await this.requestSenderAsync.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, mockHandler.Object, cts.Token); + await this.requestSender.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "a") }, true, mockHandler.Object, cts.Token); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationStart, It.IsAny())); mockCommunicationManager.Verify(c => c.SendMessage(MessageType.MultiTestRunFinalizationCancel)); @@ -2055,7 +2049,7 @@ public async Task FinalizeTestsShouldAbortOnExceptionInSendMessage() var mockHandler = new Mock(); this.mockCommunicationManager.Setup(cm => cm.SendMessage(MessageType.MultiTestRunFinalizationStart, It.IsAny())).Throws(new IOException()); - await this.requestSenderAsync.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "out") }, mockHandler.Object, CancellationToken.None); + await this.requestSender.FinalizeMultiTestRunAsync(new List { new AttachmentSet(new Uri("http://www.bing.com"), "out") }, false, mockHandler.Object, CancellationToken.None); mockHandler.Verify(mh => mh.HandleMultiTestRunFinalizationComplete(null), Times.Once, "Discovery Complete must be called"); mockHandler.Verify(mh => mh.HandleLogMessage(TestMessageLevel.Error, It.IsAny()), Times.Once, "TestMessage event must be called"); @@ -2147,7 +2141,7 @@ private async Task InitializeCommunicationAsync() this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(sessionConnected)); this.mockCommunicationManager.Setup(cm => cm.SendMessage(MessageType.VersionCheck, this.protocolVersion)).Callback(changedMessage); - var portOutput = await this.requestSenderAsync.InitializeCommunicationAsync(this.WaitTimeout); + var portOutput = await this.requestSender.InitializeCommunicationAsync(this.WaitTimeout); Assert.AreEqual(dummyPortInput, portOutput, "Connection must succeed."); } diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperAsyncTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperAsyncTests.cs index 634bb7e1a4..67b2010580 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperAsyncTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperAsyncTests.cs @@ -14,6 +14,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.UnitTests using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces; + using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -21,11 +22,13 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.UnitTests [TestClass] public class VsTestConsoleWrapperAsyncTests { - private IVsTestConsoleWrapperAsync consoleWrapper; + private IVsTestConsoleWrapper consoleWrapper; private Mock mockProcessManager; - private Mock mockRequestSender; + private Mock mockRequestSender; + + private Mock mockProcessHelper; private readonly List testSources = new List { "Hello", "World" }; @@ -42,13 +45,15 @@ public void TestInitialize() { this.consoleParameters = new ConsoleParameters(); - this.mockRequestSender = new Mock(); + this.mockRequestSender = new Mock(); this.mockProcessManager = new Mock(); - this.consoleWrapper = new VsTestConsoleWrapperAsync( + this.mockProcessHelper = new Mock(); + this.consoleWrapper = new VsTestConsoleWrapper( this.mockRequestSender.Object, this.mockProcessManager.Object, this.consoleParameters, - new Mock().Object); + new Mock().Object, + this.mockProcessHelper.Object); this.mockRequestSender.Setup(rs => rs.InitializeCommunicationAsync(It.IsAny())).Returns(Task.FromResult(100)); } @@ -312,10 +317,11 @@ public async Task FinalizeMultiTestRunAsyncShouldSucceed() await this.consoleWrapper.FinalizeMultiTestRunAsync( attachments, + true, new Mock().Object, cancellationToken); - this.mockRequestSender.Verify(rs => rs.FinalizeMultiTestRunAsync(attachments, It.IsAny(), cancellationToken)); + this.mockRequestSender.Verify(rs => rs.FinalizeMultiTestRunAsync(attachments, true, It.IsAny(), cancellationToken)); } [TestMethod] diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs index 8b6797b7f4..fd48f7b979 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs @@ -314,10 +314,11 @@ public async Task FinalizeMultiTestRunAsyncShouldSucceed() await this.consoleWrapper.FinalizeMultiTestRunAsync( attachments, + true, new Mock().Object, cancellationToken); - this.mockRequestSender.Verify(rs => rs.FinalizeMultiTestRunAsync(attachments, It.IsAny(), cancellationToken)); + this.mockRequestSender.Verify(rs => rs.FinalizeMultiTestRunAsync(attachments, true, It.IsAny(), cancellationToken)); } [TestMethod] diff --git a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs index 95e18855bb..fcb2619e0a 100644 --- a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs +++ b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs @@ -48,8 +48,6 @@ public class TestRequestManagerTests private InferHelper inferHelper; private ITestRequestManager testRequestManager; private Mock mockTestPlatformEventSource; - private Mock mockRequestData; - private Mock mockMetricsCollection; private ProtocolConfig protocolConfig; private Task mockMetricsPublisherTask; private Mock mockMetricsPublisher; @@ -89,9 +87,6 @@ public TestRequestManagerTests() this.mockMetricsPublisherTask, this.mockProcessHelper.Object, this.mockFinalizationManager.Object); - this.mockMetricsCollection = new Mock(); - this.mockRequestData = new Mock(); - this.mockRequestData.Setup(rd => rd.MetricsCollection).Returns(this.mockMetricsCollection.Object); this.mockTestPlatform.Setup(tp => tp.CreateDiscoveryRequest(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(this.mockDiscoveryRequest.Object); this.mockTestPlatform.Setup(tp => tp.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())) @@ -2183,21 +2178,43 @@ public void DiscoverTestsShouldOverrideOnlyAssemblyNameIfConsoleLoggerAlreadyPre } [TestMethod] - public void FinalizeMultiTestRunShouldSucceed() + public void FinalizeMultiTestRunShouldSucceedWithTelemetryEnabled() { var mockEventsHandler = new Mock(); mockFinalizationManager - .Setup(m => m.FinalizeMultiTestRunAsync(It.IsAny>(), It.IsAny(), It.IsAny())) + .Setup(m => m.FinalizeMultiTestRunAsync(It.IsAny(), It.IsAny>(), It.IsAny(), It.IsAny())) .Returns(Task.FromResult(true)); var payload = new MultiTestRunFinalizationPayload() { - Attachments = new List { new AttachmentSet(new Uri("http://www.bing.com"), "out") } + Attachments = new List { new AttachmentSet(new Uri("http://www.bing.com"), "out") }, + CollectMetrics = true + }; + + testRequestManager.FinalizeMultiTestRun(payload, mockEventsHandler.Object, this.protocolConfig); + + mockFinalizationManager.Verify(m => m.FinalizeMultiTestRunAsync(It.Is(r => r.IsTelemetryOptedIn), payload.Attachments, mockEventsHandler.Object, It.IsAny())); + mockTestPlatformEventSource.Verify(es => es.MultiTestRunFinalizationRequestStart()); + mockTestPlatformEventSource.Verify(es => es.MultiTestRunFinalizationRequestStop()); + } + + [TestMethod] + public void FinalizeMultiTestRunShouldSucceedWithTelemetryDisabled() + { + var mockEventsHandler = new Mock(); + mockFinalizationManager + .Setup(m => m.FinalizeMultiTestRunAsync(It.IsAny(), It.IsAny>(), It.IsAny(), It.IsAny())) + .Returns(Task.FromResult(true)); + + var payload = new MultiTestRunFinalizationPayload() + { + Attachments = new List { new AttachmentSet(new Uri("http://www.bing.com"), "out") }, + CollectMetrics = false }; - testRequestManager.FinalizeMultiTestRun(payload, mockEventsHandler.Object); + testRequestManager.FinalizeMultiTestRun(payload, mockEventsHandler.Object, this.protocolConfig); - mockFinalizationManager.Verify(m => m.FinalizeMultiTestRunAsync(payload.Attachments, mockEventsHandler.Object, It.IsAny())); + mockFinalizationManager.Verify(m => m.FinalizeMultiTestRunAsync(It.Is(r => !r.IsTelemetryOptedIn), payload.Attachments, mockEventsHandler.Object, It.IsAny())); mockTestPlatformEventSource.Verify(es => es.MultiTestRunFinalizationRequestStart()); mockTestPlatformEventSource.Verify(es => es.MultiTestRunFinalizationRequestStop()); } @@ -2207,7 +2224,7 @@ public async Task CancelMultiTestRunFinalizationShouldSucceedIfRequestInProgress { var mockEventsHandler = new Mock(); mockFinalizationManager - .Setup(m => m.FinalizeMultiTestRunAsync(It.IsAny>(), It.IsAny(), It.IsAny())) + .Setup(m => m.FinalizeMultiTestRunAsync(It.IsAny(), It.IsAny>(), It.IsAny(), It.IsAny())) .Returns((ICollection a, IMultiTestRunFinalizationEventsHandler h, CancellationToken token) => Task.Run(() => { int i = 0; @@ -2224,13 +2241,13 @@ public async Task CancelMultiTestRunFinalizationShouldSucceedIfRequestInProgress Attachments = new List { new AttachmentSet(new Uri("http://www.bing.com"), "out") } }; - Task task = Task.Run(() => testRequestManager.FinalizeMultiTestRun(payload, mockEventsHandler.Object)); + Task task = Task.Run(() => testRequestManager.FinalizeMultiTestRun(payload, mockEventsHandler.Object, this.protocolConfig)); await Task.Delay(50); testRequestManager.CancelMultiTestRunFinalization(); await task; - mockFinalizationManager.Verify(m => m.FinalizeMultiTestRunAsync(payload.Attachments, mockEventsHandler.Object, It.IsAny())); + mockFinalizationManager.Verify(m => m.FinalizeMultiTestRunAsync(It.IsAny(), payload.Attachments, mockEventsHandler.Object, It.IsAny())); mockTestPlatformEventSource.Verify(es => es.MultiTestRunFinalizationRequestStart()); mockTestPlatformEventSource.Verify(es => es.MultiTestRunFinalizationRequestStop()); }