Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine
{
using System.Collections.Generic;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;

/// <summary>
Expand Down Expand Up @@ -33,7 +34,8 @@ public interface ITestCaseEventsHandler
/// Send session start event.
/// The purpose of this is to perform any initialization before the test case level events are sent.
/// </summary>
void SendSessionStart();
/// <param name="properties"> The session start properties. </param>
void SendSessionStart(IDictionary<string, object> properties);

/// <summary>
/// Sends session end event.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

using System.Xml;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection.Interfaces;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollector.InProcDataCollector;
Expand All @@ -25,6 +25,8 @@ internal class InProcDataCollectionExtensionManager

private IDataCollectionSink inProcDataCollectionSink;

private string defaultCodeBase;

/// <summary>
/// Loaded in-proc datacollectors collection
/// </summary>
Expand All @@ -39,10 +41,14 @@ internal class InProcDataCollectionExtensionManager
/// <param name="testEventsPublisher">
/// The data collection test case event manager.
/// </param>
public InProcDataCollectionExtensionManager(string runSettings, ITestEventsPublisher testEventsPublisher)
/// <param name="defaultCodeBase">
/// The default codebase to be used by inproc data collector
/// </param>
public InProcDataCollectionExtensionManager(string runSettings, ITestEventsPublisher testEventsPublisher, string defaultCodeBase)
{
this.InProcDataCollectors = new Dictionary<string, IInProcDataCollector>();
this.inProcDataCollectionSink = new InProcDataCollectionSink();
this.defaultCodeBase = defaultCodeBase;

// Initialize InProcDataCollectors
this.InitializeInProcDataCollectors(runSettings);
Expand Down Expand Up @@ -74,13 +80,13 @@ public InProcDataCollectionExtensionManager(string runSettings, ITestEventsPubli
/// <returns>
/// The <see cref="IInProcDataCollector"/>.
/// </returns>
protected virtual IInProcDataCollector CreateDataCollector(DataCollectorSettings dataCollectorSettings, TypeInfo interfaceTypeInfo)
protected virtual IInProcDataCollector CreateDataCollector(string assemblyQualifiedName, string codebase, XmlElement configuration, TypeInfo interfaceTypeInfo)
{
var inProcDataCollector = new InProcDataCollector(
dataCollectorSettings.CodeBase,
dataCollectorSettings.AssemblyQualifiedName,
codebase,
assemblyQualifiedName,
interfaceTypeInfo,
dataCollectorSettings.Configuration.OuterXml);
configuration?.OuterXml);

inProcDataCollector.LoadDataCollector(this.inProcDataCollectionSink);

Expand All @@ -98,7 +104,7 @@ protected virtual IInProcDataCollector CreateDataCollector(DataCollectorSettings
/// </param>
private void TriggerTestSessionStart(object sender, SessionStartEventArgs e)
{
TestSessionStartArgs testSessionStartArgs = new TestSessionStartArgs();
TestSessionStartArgs testSessionStartArgs = new TestSessionStartArgs(this.GetSessionStartProperties(e));
this.TriggerInProcDataCollectionMethods(Constants.TestSessionStartMethodName, testSessionStartArgs);
}

Expand Down Expand Up @@ -172,7 +178,7 @@ private void TriggerUpdateTestResult(object sender, TestResultEventArgs e)
private void InitializeInProcDataCollectors(string runSettings)
{
try
{
{
// Check if runsettings contains in-proc datacollector element
var inProcDataCollectionRunSettings = XmlRunSettingsUtilities.GetInProcDataCollectionRunSettings(runSettings);
var inProcDataCollectionSettingsPresentInRunSettings = inProcDataCollectionRunSettings?.IsCollectionEnabled ?? false;
Expand All @@ -189,7 +195,10 @@ private void InitializeInProcDataCollectors(string runSettings)
var interfaceTypeInfo = typeof(InProcDataCollection).GetTypeInfo();
foreach (var inProcDc in this.inProcDataCollectorSettingsCollection)
{
var inProcDataCollector = this.CreateDataCollector(inProcDc, interfaceTypeInfo);
var codeBase = this.GetCodebase(inProcDc.CodeBase);
var assemblyQualifiedName = inProcDc.AssemblyQualifiedName;
var configuration = inProcDc.Configuration;
var inProcDataCollector = this.CreateDataCollector(assemblyQualifiedName, codeBase, configuration, interfaceTypeInfo);
this.InProcDataCollectors[inProcDataCollector.AssemblyQualifiedName] = inProcDataCollector;
}
}
Expand All @@ -204,6 +213,24 @@ private void InitializeInProcDataCollectors(string runSettings)
}
}

/// <summary>
/// Gets codebase for inproc datacollector
/// Uses default codebase if given path is not absolute path of inproc datacollector
/// </summary>
/// <param name="codeBase">The run Settings.</param>
/// <returns> Codebase </returns>
private string GetCodebase(string codeBase)
{
return Path.IsPathRooted(codeBase) ? codeBase : Path.Combine(this.defaultCodeBase, codeBase);
}

private IDictionary<string, object> GetSessionStartProperties(SessionStartEventArgs sessionStartEventArgs)
{
var properties = new Dictionary<string, object>();
properties.Add(Constants.TestSourcesPropertyName, sessionStartEventArgs.GetPropertyValue<IEnumerable<string>>(Constants.TestSourcesPropertyName));
return properties;
}

private void TriggerInProcDataCollectionMethods(string methodName, InProcDataCollectionArgs methodArg)
{
try
Expand Down Expand Up @@ -263,5 +290,10 @@ internal static class Constants
/// The test case end method name.
/// </summary>
public const string TestCaseEndMethodName = "TestCaseEnd";

/// <summary>
/// Test sources property name
/// </summary>
public const string TestSourcesPropertyName = "TestSources";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.EventHandlers
{
using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection.Interfaces;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.DataCollection;
Expand Down Expand Up @@ -51,9 +52,9 @@ public void SendTestResult(TestResult result)
}

/// <inheritdoc />
public void SendSessionStart()
public void SendSessionStart(IDictionary<string, object> properties)
{
this.SessionStart.SafeInvoke(this, new SessionStartEventArgs(), "TestCaseEventsHandler.RaiseSessionStart");
this.SessionStart.SafeInvoke(this, new SessionStartEventArgs(properties), "TestCaseEventsHandler.RaiseSessionStart");
}

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ public void RunTests()
try
{
// Call Session-Start event on in-proc datacollectors
this.testCaseEventsHandler?.SendSessionStart();
this.SendSessionStart();

elapsedTime = this.RunTestsInternal();

Expand All @@ -230,7 +230,7 @@ public void RunTests()
finally
{
// Trigger Session End on in-proc datacollectors
this.testCaseEventsHandler?.SendSessionEnd();
this.SendSessionEnd();

try
{
Expand Down Expand Up @@ -288,6 +288,10 @@ internal void Cancel()

protected abstract void InvokeExecutor(LazyExtension<ITestExecutor, ITestExecutorCapabilities> executor, Tuple<Uri, string> executorUriExtensionTuple, RunContext runContext, IFrameworkHandle frameworkHandle);

protected abstract void SendSessionStart();

protected abstract void SendSessionEnd();

#endregion

private void CancelTestRunInternal(ITestExecutor executor)
Expand All @@ -309,17 +313,6 @@ private void SetContext()
{
this.testRunCache = new TestRunCache(this.testExecutionContext.FrequencyOfRunStatsChangeEvent, this.testExecutionContext.RunStatsChangeEventTimeout, this.OnCacheHit);

// Initialize data collectors if declared in run settings.
if (DataCollectionTestCaseEventSender.Instance != null && XmlRunSettingsUtilities.IsDataCollectionEnabled(this.runSettings))
{
var outOfProcDataCollectionManager = new ProxyOutOfProcDataCollectionManager(DataCollectionTestCaseEventSender.Instance, this.testEventsPublisher);
}

if (XmlRunSettingsUtilities.IsInProcDataCollectionEnabled(this.runSettings))
{
var inProcDataCollectionExtensionManager = new InProcDataCollectionExtensionManager(this.runSettings, this.testEventsPublisher);
}

this.runContext = new RunContext();
this.runContext.RunSettings = RunSettingsUtilities.CreateAndInitializeRunSettings(this.runSettings);
this.runContext.KeepAlive = this.testExecutionContext.KeepAlive;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution

using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework;
using Microsoft.VisualStudio.TestPlatform.Common.SettingsProvider;
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing.Interfaces;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection.Interfaces;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Utilities;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.ClientProtocol;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;

/// <summary>
/// Orchestrates test execution related functionality for the engine communicating with the test host process.
Expand Down Expand Up @@ -85,6 +90,8 @@ public void StartTestRun(
{
try
{
this.InitializeDataCollectors(runSettings, testCaseEventsHandler as ITestEventsPublisher, TestSourcesUtility.GetDefaultCodebasePath(adapterSourceMap));

this.activeTestRun = new RunTestsWithSources(this.requestData, adapterSourceMap, package, runSettings, testExecutionContext, testCaseEventsHandler, runEventsHandler);

this.activeTestRun.RunTests();
Expand Down Expand Up @@ -119,6 +126,8 @@ public void StartTestRun(
{
try
{
this.InitializeDataCollectors(runSettings, testCaseEventsHandler as ITestEventsPublisher, TestSourcesUtility.GetDefaultCodebasePath(tests));

this.activeTestRun = new RunTestsWithTests(this.requestData, tests, package, runSettings, testExecutionContext, testCaseEventsHandler, runEventsHandler);

this.activeTestRun.RunTests();
Expand Down Expand Up @@ -196,6 +205,24 @@ private void LoadExtensions()
}
}

/// <summary>
/// Initializes outproc and inproc data collectors.
/// </summary>
private void InitializeDataCollectors(string runSettings, ITestEventsPublisher testEventsPublisher, string defaultCodeBase)
{
// Initialize outproc data collectors if declared in run settings.
if (DataCollectionTestCaseEventSender.Instance != null && XmlRunSettingsUtilities.IsDataCollectionEnabled(runSettings))
{
var outOfProcDataCollectionManager = new ProxyOutOfProcDataCollectionManager(DataCollectionTestCaseEventSender.Instance, testEventsPublisher);
}

// Initialize inproc data collectors if declared in run settings.
if (XmlRunSettingsUtilities.IsInProcDataCollectionEnabled(runSettings))
{
var inProcDataCollectionExtensionManager = new InProcDataCollectionExtensionManager(runSettings, testEventsPublisher, defaultCodeBase);
}
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Adapter;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.ClientProtocol;
Expand All @@ -30,6 +31,8 @@ internal class RunTestsWithSources : BaseRunTests

private Dictionary<Tuple<Uri,string>, IEnumerable<string>> executorUriVsSourceList;

private ITestCaseEventsHandler testCaseEventsHandler;

public RunTestsWithSources(IRequestData requestData, Dictionary<string, IEnumerable<string>> adapterSourceMap, string package, string runSettings, TestExecutionContext testExecutionContext, ITestCaseEventsHandler testCaseEventsHandler, ITestRunEventsHandler testRunEventsHandler)
: this(requestData, adapterSourceMap, package, runSettings, testExecutionContext, testCaseEventsHandler, testRunEventsHandler, null)
{
Expand All @@ -52,6 +55,7 @@ internal RunTestsWithSources(IRequestData requestData, Dictionary<string, IEnume
{
this.adapterSourceMap = adapterSourceMap;
this.executorUriVsSourceList = executorUriVsSourceList;
this.testCaseEventsHandler = testCaseEventsHandler;
}

protected override void BeforeRaisingTestRunComplete(bool exceptionsHitDuringRunTests)
Expand Down Expand Up @@ -203,5 +207,30 @@ private static string TestCaseFilterToShow(string testCaseFilter)

return testCaseFilterToShow;
}

/// <summary>
/// Sends Session-End event on in-proc datacollectors
/// </summary>
protected override void SendSessionEnd()
{
this.testCaseEventsHandler?.SendSessionEnd();
}

/// <summary>
/// Sends Session-Start event on in-proc datacollectors
/// </summary>
protected override void SendSessionStart()
{
// Send session start with test sources in property bag for session start event args.
if (this.testCaseEventsHandler == null)
{
return;
}

var properties = new Dictionary<string, object>();
properties.Add("TestSources", TestSourcesUtility.GetSources(this.adapterSourceMap));

this.testCaseEventsHandler.SendSessionStart(properties);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Execution
using Microsoft.VisualStudio.TestPlatform.Common.Interfaces;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Adapter;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Utilities;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.ClientProtocol;
Expand All @@ -24,6 +25,8 @@ internal class RunTestsWithTests : BaseRunTests

private Dictionary<Tuple<Uri, string>, List<TestCase>> executorUriVsTestList;

private ITestCaseEventsHandler testCaseEventsHandler;

public RunTestsWithTests(IRequestData requestData, IEnumerable<TestCase> testCases, string package, string runSettings, TestExecutionContext testExecutionContext, ITestCaseEventsHandler testCaseEventsHandler, ITestRunEventsHandler testRunEventsHandler)
: this(requestData, testCases, package, runSettings, testExecutionContext, testCaseEventsHandler, testRunEventsHandler, null)
{
Expand All @@ -45,6 +48,7 @@ internal RunTestsWithTests(IRequestData requestData, IEnumerable<TestCase> testC
{
this.testCases = testCases;
this.executorUriVsTestList = executorUriVsTestList;
this.testCaseEventsHandler = testCaseEventsHandler;
}

protected override void BeforeRaisingTestRunComplete(bool exceptionsHitDuringRunTests)
Expand All @@ -67,6 +71,31 @@ protected override void InvokeExecutor(LazyExtension<ITestExecutor, ITestExecuto
executor?.Value.RunTests(this.executorUriVsTestList[executorUri], runContext, frameworkHandle);
}

/// <summary>
/// Sends Session-End event on in-proc datacollectors
/// </summary>
protected override void SendSessionEnd()
{
this.testCaseEventsHandler?.SendSessionEnd();
}

/// <summary>
/// Sends Session-Start event on in-proc datacollectors
/// </summary>
protected override void SendSessionStart()
{
// Send session start with test sources in property bag for session start event args.
if (this.testCaseEventsHandler == null)
{
return;
}

var properties = new Dictionary<string, object>();
properties.Add("TestSources", TestSourcesUtility.GetSources(this.testCases));

this.testCaseEventsHandler.SendSessionStart(properties);
}

/// <summary>
/// Returns the executor Vs TestCase list
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.DataCollection;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Utilities;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine;
Expand Down Expand Up @@ -313,7 +314,7 @@ private IRequestData GetRequestData(bool isTelemetryOptedIn)
/// <returns>test sources</returns>
private IEnumerable<string> GetSourcesFromTestRunCriteria(TestRunCriteria testRunCriteria)
{
return testRunCriteria.HasSpecificTests ? testRunCriteria.Tests.Select(tc => tc.Source).Distinct() : testRunCriteria.Sources;
return testRunCriteria.HasSpecificTests ? TestSourcesUtility.GetSources(testRunCriteria.Tests) : testRunCriteria.Sources;
}
}
}
Loading