Skip to content

Commit

Permalink
Review changes #1
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubch1 committed Jun 19, 2020
1 parent b25a64e commit fc7a1c0
Show file tree
Hide file tree
Showing 26 changed files with 403 additions and 471 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public interface ITestRequestManager : IDisposable
/// </summary>
/// <param name="multiTestRunFinalizationPayload">Multi test run finalization payload</param>
/// <param name="multiTestRunFinalizationEventsHandler">Multi test run finalization events handler</param>
void FinalizeMultiTestRun(MultiTestRunFinalizationPayload multiTestRunFinalizationPayload, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationEventsHandler);
void FinalizeMultiTestRun(MultiTestRunFinalizationPayload multiTestRunFinalizationPayload, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationEventsHandler, ProtocolConfig protocolConfig);

/// <summary>
/// Cancel the current TestRun request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ internal interface IMultiTestRunFinalizationManager
/// <param name="attachments">Collection of attachments</param>
/// <param name="eventHandler">EventHandler for handling multi test run finalization event</param>
/// <param name="cancellationToken">Cancellation token</param>
Task FinalizeMultiTestRunAsync(ICollection<AttachmentSet> attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken);
Task FinalizeMultiTestRunAsync(IRequestData requestData, IEnumerable<AttachmentSet> attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken);

/// <summary>
/// Finalizes multi test run
/// </summary>
/// <param name="attachments">Collection of attachments</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Collection of attachments.</returns>
Task<Collection<AttachmentSet>> FinalizeMultiTestRunAsync(ICollection<AttachmentSet> attachments, CancellationToken cancellationToken);
Task<Collection<AttachmentSet>> FinalizeMultiTestRunAsync(IRequestData requestData, IEnumerable<AttachmentSet> attachments, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal class ParallelRunEventsHandler : ITestRunEventsHandler2

private IDataSerializer dataSerializer;

private IRequestData requestData;
protected IRequestData requestData;

public ParallelRunEventsHandler(IRequestData requestData,
IProxyExecutionManager proxyExecutionManager,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -20,6 +22,10 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.MultiTestRunFinali
/// </summary>
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;

Expand All @@ -33,65 +39,74 @@ public MultiTestRunFinalizationManager(ITestPlatformEventSource testPlatformEven
}

/// <inheritdoc/>
public async Task FinalizeMultiTestRunAsync(ICollection<AttachmentSet> attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken)
public async Task FinalizeMultiTestRunAsync(IRequestData requestData, IEnumerable<AttachmentSet> attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken)
{
await InternalFinalizeMultiTestRunAsync(new Collection<AttachmentSet>(attachments.ToList()), eventHandler, cancellationToken).ConfigureAwait(false);
await InternalFinalizeMultiTestRunAsync(requestData, new Collection<AttachmentSet>(attachments.ToList()), eventHandler, cancellationToken).ConfigureAwait(false);
}

/// <inheritdoc/>
public Task<Collection<AttachmentSet>> FinalizeMultiTestRunAsync(ICollection<AttachmentSet> attachments, CancellationToken cancellationToken)
public Task<Collection<AttachmentSet>> FinalizeMultiTestRunAsync(IRequestData requestData, IEnumerable<AttachmentSet> attachments, CancellationToken cancellationToken)
{
return InternalFinalizeMultiTestRunAsync(new Collection<AttachmentSet>(attachments.ToList()), null, cancellationToken);
return InternalFinalizeMultiTestRunAsync(requestData, new Collection<AttachmentSet>(attachments.ToList()), null, cancellationToken);
}

private async Task<Collection<AttachmentSet>> InternalFinalizeMultiTestRunAsync(Collection<AttachmentSet> attachments, IMultiTestRunFinalizationEventsHandler eventHandler, CancellationToken cancellationToken)
private async Task<Collection<AttachmentSet>> InternalFinalizeMultiTestRunAsync(IRequestData requestData, Collection<AttachmentSet> 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<object>();
var taskCompletionSource = new TaskCompletionSource<Collection<AttachmentSet>>();
using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
{
Task task = Task.Run(() =>
Task<Collection<AttachmentSet>> task = Task.Run(() =>
{
HandleAttachments(attachments, cancellationToken);
return ProcessAttachments(new Collection<AttachmentSet>(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<AttachmentSet> attachments, CancellationToken cancellationToken)
private Collection<AttachmentSet> ProcessAttachments(Collection<AttachmentSet> attachments, ProgressReporter progressReporter, CancellationToken cancellationToken)
{
if (attachments == null || !attachments.Any()) return attachments;

foreach (var dataCollectorAttachmentsHandler in dataCollectorAttachmentsHandlers)
{
Uri attachementUri = dataCollectorAttachmentsHandler.GetExtensionUri();
Expand All @@ -105,14 +120,50 @@ private void HandleAttachments(ICollection<AttachmentSet> attachments, Cancellat
attachments.Remove(attachment);
}

ICollection<AttachmentSet> processedAttachments = dataCollectorAttachmentsHandler.HandleDataCollectionAttachmentSets(new Collection<AttachmentSet>(attachmentsToBeProcessed), cancellationToken);
ICollection<AttachmentSet> processedAttachments = dataCollectorAttachmentsHandler.HandleDataCollectionAttachmentSets(new Collection<AttachmentSet>(attachmentsToBeProcessed), progressReporter, cancellationToken);
foreach (var attachment in processedAttachments)
{
attachments.Add(attachment);
}
}
}
}

return attachments;
}

private Collection<AttachmentSet> FinalizeOperation(IRequestData requestData, Collection<AttachmentSet> 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<int>
{
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)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ public class MultiTestRunFinalizationPayload
/// Collection of attachments.
/// </summary>
[DataMember]
public ICollection<AttachmentSet> Attachments { get; set; }
public IEnumerable<AttachmentSet> Attachments { get; set; }

/// <summary>
/// Gets or sets whether Metrics should be collected or not.
/// </summary>
[DataMember]
public bool CollectMetrics { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ public interface IDataCollectorAttachments
/// <summary>
/// Gets the attachment set after Test Run Session
/// </summary>
/// <param name="dataCollectionAttachments">Attachments to be processed</param>
/// <param name="progressReporter">Progress reporter. Accepts integers from 0 to 100</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Gets the attachment set after Test Run Session</returns>
ICollection<AttachmentSet> HandleDataCollectionAttachmentSets(ICollection<AttachmentSet> dataCollectionAttachments, CancellationToken cancellationToken);
ICollection<AttachmentSet> HandleDataCollectionAttachmentSets(ICollection<AttachmentSet> dataCollectionAttachments, IProgress<int> progressReporter, CancellationToken cancellationToken);

/// <summary>
/// Gets the attachment Uri, which is handled by current Collector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -33,15 +34,15 @@ public Uri GetExtensionUri()

public ICollection<AttachmentSet> HandleDataCollectionAttachmentSets(ICollection<AttachmentSet> dataCollectionAttachments)
{
return HandleDataCollectionAttachmentSets(dataCollectionAttachments, CancellationToken.None);
return HandleDataCollectionAttachmentSets(dataCollectionAttachments, null, CancellationToken.None);
}

public ICollection<AttachmentSet> HandleDataCollectionAttachmentSets(ICollection<AttachmentSet> dataCollectionAttachments, CancellationToken cancellationToken)
public ICollection<AttachmentSet> HandleDataCollectionAttachmentSets(ICollection<AttachmentSet> dataCollectionAttachments, IProgress<int> 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))
Expand All @@ -57,7 +58,7 @@ public ICollection<AttachmentSet> HandleDataCollectionAttachmentSets(ICollection
return new Collection<AttachmentSet>();
}

private string MergeCodeCoverageFiles(IList<string> files, CancellationToken cancellationToken)
private string MergeCodeCoverageFiles(IList<string> files, IProgress<int> progressReporter, CancellationToken cancellationToken)
{
string fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + CoverageFileExtension);
string outputfileName = files[0];
Expand All @@ -82,11 +83,14 @@ private string MergeCodeCoverageFiles(IList<string> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces
/// <summary>
/// Defines contract to send test platform requests to test host
/// </summary>
internal interface ITranslationLayerRequestSender : IDisposable
internal interface ITranslationLayerRequestSender : IDisposable, ITranslationLayerRequestSenderAsync
{
/// <summary>
/// Initializes the communication for sending requests
Expand Down Expand Up @@ -111,13 +111,5 @@ internal interface ITranslationLayerRequestSender : IDisposable
/// Cancels the discovery of tests
/// </summary>
void CancelDiscovery();

/// <summary>
/// Provides back all attachments to TestPlatform for additional processing (for example merging)
/// </summary>
/// <param name="attachments">Collection of attachments</param>
/// <param name="multiTestRunFinalizationCompleteEventsHandler">Events handler</param>
/// <param name="cancellationToken">Cancellation token</param>
Task FinalizeMultiTestRunAsync(ICollection<AttachmentSet> attachments, IMultiTestRunFinalizationEventsHandler multiTestRunFinalizationCompleteEventsHandler, CancellationToken cancellationToken);
}
}
Loading

0 comments on commit fc7a1c0

Please sign in to comment.