Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logger support in run settings #1382

Merged
merged 15 commits into from
Jan 30, 2018
29 changes: 23 additions & 6 deletions src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public sealed class DiscoveryRequest : IDiscoveryRequest, ITestDiscoveryEventsHa
/// <param name="requestData">The Request Data instance providing services and data for discovery</param>
/// <param name="criteria">Discovery criterion.</param>
/// <param name="discoveryManager">Discovery manager instance.</param>
internal DiscoveryRequest(IRequestData requestData, DiscoveryCriteria criteria, IProxyDiscoveryManager discoveryManager)
: this(requestData, criteria, discoveryManager, JsonDataSerializer.Instance)
internal DiscoveryRequest(IRequestData requestData, DiscoveryCriteria criteria, IProxyDiscoveryManager discoveryManager, ITestLoggerManager loggerManager)
: this(requestData, criteria, discoveryManager, loggerManager, JsonDataSerializer.Instance)
{
}

Expand All @@ -47,11 +47,13 @@ internal DiscoveryRequest(
IRequestData requestData,
DiscoveryCriteria criteria,
IProxyDiscoveryManager discoveryManager,
ITestLoggerManager loggerManager,
IDataSerializer dataSerializer)
{
this.requestData = requestData;
this.DiscoveryCriteria = criteria;
this.DiscoveryManager = discoveryManager;
this.LoggerManager = loggerManager;
this.dataSerializer = dataSerializer;
}

Expand Down Expand Up @@ -84,7 +86,9 @@ public void DiscoverAsync()
this.requestData.MetricsCollection.Add(TelemetryDataConstants.NumberOfSourcesSentForDiscovery, this.DiscoveryCriteria.Sources.Count());

// Invoke OnDiscoveryStart event
this.OnDiscoveryStart.SafeInvoke(this, new DiscoveryStartEventArgs(this.DiscoveryCriteria), "DiscoveryRequest.DiscoveryStart");
var discoveryStartEvent = new DiscoveryStartEventArgs(this.DiscoveryCriteria);
this.OnDiscoveryStart.SafeInvoke(this, discoveryStartEvent, "DiscoveryRequest.DiscoveryStart");
this.LoggerManager.HandleDiscoveryStart(discoveryStartEvent);

this.DiscoveryManager.DiscoverTests(this.DiscoveryCriteria, this);
}
Expand Down Expand Up @@ -216,6 +220,11 @@ internal bool DiscoveryInProgress
/// </summary>
internal IProxyDiscoveryManager DiscoveryManager { get; private set; }

/// <summary>
/// Logger manager.
/// </summary>
internal ITestLoggerManager LoggerManager { get; private set; }

#region ITestDiscoveryEventsHandler2 Methods

/// <inheritdoc/>
Expand Down Expand Up @@ -260,10 +269,14 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete
// RS client is easier i.e. user does not have to listen on discovery complete event.)
if (lastChunk != null && lastChunk.Count() > 0)
{
this.OnDiscoveredTests.SafeInvoke(this, new DiscoveredTestsEventArgs(lastChunk), "DiscoveryRequest.DiscoveryComplete");
var discoveredTestsEvent = new DiscoveredTestsEventArgs(lastChunk);
this.OnDiscoveredTests.SafeInvoke(this, discoveredTestsEvent, "DiscoveryRequest.DiscoveryComplete");
this.LoggerManager.HandleDiscoveredTests(discoveredTestsEvent);
}

this.OnDiscoveryComplete.SafeInvoke(this, discoveryCompleteEventArgs, "DiscoveryRequest.DiscoveryComplete");
this.LoggerManager.HandleDiscoveryComplete(discoveryCompleteEventArgs);
this.LoggerManager.Dispose();
}
finally
{
Expand Down Expand Up @@ -329,7 +342,9 @@ public void HandleDiscoveredTests(IEnumerable<TestCase> discoveredTestCases)
return;
}

this.OnDiscoveredTests.SafeInvoke(this, new DiscoveredTestsEventArgs(discoveredTestCases), "DiscoveryRequest.OnDiscoveredTests");
var discoveredTestsEvent = new DiscoveredTestsEventArgs(discoveredTestCases);
this.OnDiscoveredTests.SafeInvoke(this, discoveredTestsEvent, "DiscoveryRequest.OnDiscoveredTests");
this.LoggerManager.HandleDiscoveredTests(discoveredTestsEvent);
}

if (EqtTrace.IsInfoEnabled)
Expand Down Expand Up @@ -362,7 +377,9 @@ public void HandleLogMessage(TestMessageLevel level, string message)
return;
}

this.OnDiscoveryMessage.SafeInvoke(this, new TestRunMessageEventArgs(level, message), "DiscoveryRequest.OnTestMessageRecieved");
var testRunMessageEvent = new TestRunMessageEventArgs(level, message);
this.OnDiscoveryMessage.SafeInvoke(this, testRunMessageEvent, "DiscoveryRequest.OnTestMessageRecieved");
this.LoggerManager.HandleDiscoveryMessage(testRunMessageEvent);
}

if (EqtTrace.IsInfoEnabled)
Expand Down
28 changes: 23 additions & 5 deletions src/Microsoft.TestPlatform.Client/Execution/TestRunRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,17 @@ public class TestRunRequest : ITestRunRequest, ITestRunEventsHandler
/// </summary>
private IRequestData requestData;

internal TestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteria, IProxyExecutionManager executionManager) :
this(requestData, testRunCriteria, executionManager, JsonDataSerializer.Instance)
internal TestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteria, IProxyExecutionManager executionManager, ITestLoggerManager loggerManager) :
this(requestData, testRunCriteria, executionManager, loggerManager, JsonDataSerializer.Instance)
{
}

internal TestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteria, IProxyExecutionManager executionManager, IDataSerializer dataSerializer)
internal TestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteria, IProxyExecutionManager executionManager, ITestLoggerManager loggerManager, IDataSerializer dataSerializer)
{
Debug.Assert(testRunCriteria != null, "Test run criteria cannot be null");
Debug.Assert(executionManager != null, "ExecutionManager cannot be null");
Debug.Assert(requestData != null, "request Data is null");
Debug.Assert(loggerManager != null, "LoggerManager cannot be null");

if (EqtTrace.IsVerboseEnabled)
{
Expand All @@ -88,6 +89,7 @@ internal TestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteri

this.testRunCriteria = testRunCriteria;
this.ExecutionManager = executionManager;
this.LoggerManager = loggerManager;
this.State = TestRunState.Pending;
this.dataSerializer = dataSerializer;
this.requestData = requestData;
Expand Down Expand Up @@ -158,7 +160,9 @@ public int ExecuteAsync()

// Start the stop watch for calculating the test run time taken overall
this.runRequestTimeTracker.Start();
this.OnRunStart.SafeInvoke(this, new TestRunStartEventArgs(this.testRunCriteria), "TestRun.TestRunStart");
var testRunStartEvent = new TestRunStartEventArgs(this.testRunCriteria);
this.OnRunStart.SafeInvoke(this, testRunStartEvent, "TestRun.TestRunStart");
this.LoggerManager.HandleTestRunStart(testRunStartEvent);
int processId = this.ExecutionManager.StartTestRun(this.testRunCriteria, this);

if (EqtTrace.IsInfoEnabled)
Expand Down Expand Up @@ -340,6 +344,14 @@ internal IProxyExecutionManager ExecutionManager
get; private set;
}

/// <summary>
/// Logger manager.
/// </summary>
internal ITestLoggerManager LoggerManager
{
get; private set;
}

#endregion

#region IDisposable implementation
Expand Down Expand Up @@ -402,6 +414,7 @@ public void HandleTestRunComplete(TestRunCompleteEventArgs runCompleteArgs, Test
{
// Raised the changed event also
this.OnRunStatsChange.SafeInvoke(this, lastChunkArgs, "TestRun.RunStatsChanged");
this.LoggerManager.HandleTestRunStatsChange(lastChunkArgs);
}

TestRunCompleteEventArgs runCompletedEvent =
Expand All @@ -418,6 +431,8 @@ public void HandleTestRunComplete(TestRunCompleteEventArgs runCompleteArgs, Test
// by either engines - as both calculate at different points
// If we use them, it would be an incorrect comparison between TAEF and Rocksteady
this.OnRunCompletion.SafeInvoke(this, runCompletedEvent, "TestRun.TestRunComplete");
this.LoggerManager.HandleTestRunComplete(runCompletedEvent);
this.LoggerManager.Dispose();
}
finally
{
Expand Down Expand Up @@ -491,6 +506,7 @@ public virtual void HandleTestRunStatsChange(TestRunChangedEventArgs testRunChan
// TODO: Invoke this event in a separate thread.
// For now, I am setting the ConcurrencyMode on the callback attribute to Multiple
this.OnRunStatsChange.SafeInvoke(this, testRunChangedArgs, "TestRun.RunStatsChanged");
this.LoggerManager.HandleTestRunStatsChange(testRunChangedArgs);
}

EqtTrace.Info("TestRunRequest:SendTestRunStatsChange: Completed.");
Expand All @@ -513,7 +529,9 @@ public void HandleLogMessage(TestMessageLevel level, string message)
return;
}

this.TestRunMessage.SafeInvoke(this, new TestRunMessageEventArgs(level, message), "TestRun.LogMessages");
var testRunMessageEvent = new TestRunMessageEventArgs(level, message);
this.TestRunMessage.SafeInvoke(this, testRunMessageEvent, "TestRun.LogMessages");
this.LoggerManager.HandleTestRunMessage(testRunMessageEvent);
}

EqtTrace.Info("TestRunRequest:SendTestRunMessage: Completed.");
Expand Down
22 changes: 12 additions & 10 deletions src/Microsoft.TestPlatform.Client/TestPlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,17 @@ public IDiscoveryRequest CreateDiscoveryRequest(IRequestData requestData, Discov
// Update cache with Extension Folder's files
this.AddExtensionAssemblies(discoveryCriteria.RunSettings);

// Update and initialize loggers only when DesignMode is false
// Update extension assemblies from source when design mode is false.
var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(discoveryCriteria.RunSettings);
if (runConfiguration.DesignMode == false)
{
this.AddExtensionAssembliesFromSource(discoveryCriteria.Sources);

// Initialize loggers
TestLoggerManager.Instance.InitializeLoggers(requestData);
}

// Initialize loggers
var loggerManager = this.TestEngine.GetLoggerManager(requestData);
loggerManager.Initialize(discoveryCriteria.RunSettings);

var testHostManager = this.testHostProviderManager.GetTestHostManagerByRunConfiguration(discoveryCriteria.RunSettings);
ThrowExceptionIfTestHostManagerIsNull(testHostManager, discoveryCriteria.RunSettings);

Expand All @@ -111,7 +112,7 @@ public IDiscoveryRequest CreateDiscoveryRequest(IRequestData requestData, Discov
var discoveryManager = this.TestEngine.GetDiscoveryManager(requestData, testHostManager, discoveryCriteria);
discoveryManager.Initialize();

return new DiscoveryRequest(requestData, discoveryCriteria, discoveryManager);
return new DiscoveryRequest(requestData, discoveryCriteria, discoveryManager, loggerManager);
}

/// <summary>
Expand All @@ -132,15 +133,16 @@ public ITestRunRequest CreateTestRunRequest(IRequestData requestData, TestRunCri

var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(testRunCriteria.TestRunSettings);

// Update and initialize loggers only when DesignMode is false
// Update extension assemblies from source when design mode is false.
if (runConfiguration.DesignMode == false)
{
this.AddExtensionAssembliesFromSource(testRunCriteria);

// Initialize loggers
TestLoggerManager.Instance.InitializeLoggers(requestData);
}

// Initialize loggers
var loggerManager = this.TestEngine.GetLoggerManager(requestData);
loggerManager.Initialize(testRunCriteria.TestRunSettings);

var testHostManager = this.testHostProviderManager.GetTestHostManagerByRunConfiguration(testRunCriteria.TestRunSettings);
ThrowExceptionIfTestHostManagerIsNull(testHostManager, testRunCriteria.TestRunSettings);

Expand All @@ -154,7 +156,7 @@ public ITestRunRequest CreateTestRunRequest(IRequestData requestData, TestRunCri
var executionManager = this.TestEngine.GetExecutionManager(requestData, testHostManager, testRunCriteria);
executionManager.Initialize();

return new TestRunRequest(requestData, testRunCriteria, executionManager);
return new TestRunRequest(requestData, testRunCriteria, executionManager, loggerManager);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ public LazyExtension<TExtension, TMetadata> TryGetTestExtension(Uri extensionUri
{
ValidateArg.NotNull<Uri>(extensionUri, "extensionUri");

LazyExtension<TExtension, TMetadata> testExtension;
this.TestExtensionByUri.TryGetValue(extensionUri, out testExtension);
this.TestExtensionByUri.TryGetValue(extensionUri, out var testExtension);

return testExtension;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// 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.VisualStudio.TestPlatform.Common.Logging
namespace Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework
{
using System.Collections.Generic;

using Microsoft.VisualStudio.TestPlatform.Common;
using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework;
using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework.Utilities;
using Microsoft.VisualStudio.TestPlatform.Common.Interfaces;
Expand Down Expand Up @@ -62,4 +62,43 @@ public static TestLoggerExtensionManager Create(IMessageLogger messageLogger)
return new TestLoggerExtensionManager(unfilteredTestExtensions, filteredTestExtensions, messageLogger);
}
}

/// <summary>
/// Hold data about the Test logger.
/// </summary>
public class TestLoggerMetadata : ITestLoggerCapabilities
{
/// <summary>
/// Constructor for TestLoggerMetadata
/// </summary>
/// <param name="extension">
/// Uri identifying the logger.
/// </param>
/// <param name="friendlyName">
/// The friendly Name.
/// </param>
public TestLoggerMetadata(string extension, string friendlyName)
{
this.ExtensionUri = extension;
this.FriendlyName = friendlyName;
}

/// <summary>
/// Gets Uri identifying the logger.
/// </summary>
public string ExtensionUri
{
get;
private set;
}

/// <summary>
/// Gets Friendly Name identifying the logger.
/// </summary>
public string FriendlyName
{
get;
private set;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,12 @@ public interface ITestEngine
/// </summary>
/// <returns>ITestExtensionManager object that helps with extensibility</returns>
ITestExtensionManager GetExtensionManager();

/// <summary>
/// Fetches the logger manager for this engine. This manager will provide logger extensibility features that this engine supports.
/// </summary>
/// <param name="requestData">The request data for providing common execution services and data</param>
/// <returns>ITestLoggerManager object that helps with logger extensibility.</returns>
ITestLoggerManager GetLoggerManager(IRequestData requestData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// 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.VisualStudio.TestPlatform.ObjectModel.Engine
{
using System;

using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging;

/// <summary>
/// Orchestrates logger operations for this engine.
/// </summary>
public interface ITestLoggerManager : IDisposable
{
/// <summary>
/// Initialize loggers.
/// </summary>
void Initialize(string runSettings);

/// <summary>
/// Handles test run message.
/// </summary>
/// <param name="e"></param>
void HandleTestRunMessage(TestRunMessageEventArgs e);

/// <summary>
/// Handles test run start.
/// </summary>
/// <param name="e"></param>
void HandleTestRunStart(TestRunStartEventArgs e);

/// <summary>
/// Handles test run stats change.
/// </summary>
/// <param name="e"></param>
void HandleTestRunStatsChange(TestRunChangedEventArgs e);

/// <summary>
/// Handles test run complete.
/// </summary>
/// <param name="e"></param>
void HandleTestRunComplete(TestRunCompleteEventArgs e);

/// <summary>
/// Handles discovery message.
/// </summary>
/// <param name="e"></param>
void HandleDiscoveryMessage(TestRunMessageEventArgs e);

/// <summary>
/// Handles discovery start.
/// </summary>
/// <param name="e"></param>
void HandleDiscoveryStart(DiscoveryStartEventArgs e);

/// <summary>
/// Handles discovered tests.
/// </summary>
/// <param name="e"></param>
void HandleDiscoveredTests(DiscoveredTestsEventArgs e);

/// <summary>
/// Handles discovery complete.
/// </summary>
/// <param name="e"></param>
void HandleDiscoveryComplete(DiscoveryCompleteEventArgs e);
}
}
Loading