-
Notifications
You must be signed in to change notification settings - Fork 331
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 extensibility #557
Logger extensibility #557
Changes from 8 commits
3014f9b
5d8aac7
89288db
ffa89e1
409dc44
34d23db
01d1eb6
8b56fd4
d9d8aa6
7be3bd9
935afb6
689cdc7
b71b303
afe0a00
e40a450
73129bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// 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.Client | ||
{ | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel; | ||
using System; | ||
|
||
public class InvalidLoggerException : TestPlatformException | ||
{ | ||
#region Constructors | ||
|
||
/// <summary> | ||
/// Initializes with the message. | ||
/// </summary> | ||
/// <param name="message">Message for the exception.</param> | ||
public InvalidLoggerException(string message) | ||
: base(message) | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Initializes with message and inner exception. | ||
/// </summary> | ||
/// <param name="message">Message for the exception.</param> | ||
/// <param name="innerException">The inner exception.</param> | ||
public InvalidLoggerException(string message, Exception innerException) | ||
: base(message, innerException) | ||
{ | ||
} | ||
|
||
#endregion | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// 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.Client | ||
{ | ||
using System.Collections.Generic; | ||
public class LoggerList | ||
{ | ||
private static LoggerList loggerList; | ||
private List<LoggerInfo> loggers = new List<LoggerInfo>(); | ||
|
||
protected LoggerList() | ||
{ | ||
} | ||
|
||
public static LoggerList Instance | ||
{ | ||
get | ||
{ | ||
if (loggerList == null) | ||
{ | ||
loggerList = new LoggerList(); | ||
} | ||
return loggerList; | ||
} | ||
|
||
protected set | ||
{ | ||
loggerList = value; | ||
} | ||
} | ||
|
||
public IEnumerable<LoggerInfo> Loggers | ||
{ | ||
get | ||
{ | ||
return this.loggers; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Update the list of logger with their identifier and parameter. | ||
/// </summary> | ||
/// <param name="arument">Argument pass by user</param> | ||
/// <param name="loggerIdentifier">Identifier of the logger</param> | ||
/// <param name="parameters">parameter for logger</param> | ||
public void AddLogger(string arument, string loggerIdentifier, Dictionary<string, string> parameters) | ||
{ | ||
this.loggers.Add(new LoggerInfo(arument, loggerIdentifier, parameters)); | ||
} | ||
} | ||
|
||
public class LoggerInfo | ||
{ | ||
public string arument; | ||
public string loggerIdentifier; | ||
public Dictionary<string, string> parameters = new Dictionary<string, string>(); | ||
|
||
public LoggerInfo(string arument, string loggerIdentifier, Dictionary<string, string> parameters) | ||
{ | ||
this.arument = arument; | ||
this.loggerIdentifier = loggerIdentifier; | ||
this.parameters = parameters; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,27 +6,35 @@ namespace Microsoft.VisualStudio.TestPlatform.Client | |
using System; | ||
using System.IO; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Globalization; | ||
|
||
using Microsoft.VisualStudio.TestPlatform.Client.Discovery; | ||
using Microsoft.VisualStudio.TestPlatform.Client.Execution; | ||
using ClientResources = Microsoft.VisualStudio.TestPlatform.Client.Resources.Resources; | ||
using Microsoft.VisualStudio.TestPlatform.Common; | ||
using Microsoft.VisualStudio.TestPlatform.Common.Logging; | ||
using Microsoft.VisualStudio.TestPlatform.Common.Utilities; | ||
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine; | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel; | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; | ||
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; | ||
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; | ||
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; | ||
|
||
/// <summary> | ||
/// Implementation for TestPlatform | ||
/// </summary> | ||
public class TestPlatform : ITestPlatform | ||
{ | ||
protected IFileHelper fileHelper; | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="TestPlatform"/> class. | ||
/// </summary> | ||
public TestPlatform() : this(new TestEngine()) | ||
{ | ||
fileHelper = new FileHelper(); | ||
} | ||
|
||
/// <summary> | ||
|
@@ -62,7 +70,7 @@ public IDiscoveryRequest CreateDiscoveryRequest(DiscoveryCriteria discoveryCrite | |
|
||
var runconfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(discoveryCriteria.RunSettings); | ||
var testHostManager = this.TestEngine.GetDefaultTestHostManager(runconfiguration); | ||
|
||
var discoveryManager = this.TestEngine.GetDiscoveryManager(testHostManager, discoveryCriteria); | ||
discoveryManager.Initialize(); | ||
|
||
|
@@ -85,6 +93,13 @@ public ITestRunRequest CreateTestRunRequest(TestRunCriteria testRunCriteria) | |
UpdateTestAdapterPaths(testRunCriteria.TestRunSettings); | ||
|
||
var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(testRunCriteria.TestRunSettings); | ||
|
||
// Update and initialize loggers only when DesignMode is false | ||
if (runConfiguration.DesignMode == false) | ||
{ | ||
UpdateAndInitializeLoggers(testRunCriteria); | ||
} | ||
|
||
var testHostManager = this.TestEngine.GetDefaultTestHostManager(runConfiguration); | ||
|
||
if (testRunCriteria.TestHostLauncher != null) | ||
|
@@ -148,14 +163,101 @@ private void UpdateTestAdapterPaths(string runSettings) | |
continue; | ||
} | ||
List<string> adapterFiles = new List<string>( | ||
Directory.EnumerateFiles(adapterPath,TestPlatformConstants.TestAdapterPattern , SearchOption.AllDirectories) | ||
this.fileHelper.EnumerateFiles(adapterPath, TestPlatformConstants.TestAdapterResxPattern, SearchOption.AllDirectories) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: typo RegexPattern instead of ResxPattern There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in next commit |
||
); | ||
if (adapterFiles.Count > 0) | ||
{ | ||
this.UpdateExtensions(adapterFiles, false); | ||
this.UpdateExtensions(adapterFiles, true); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Update the test adapter paths provided through run settings to be used by the test service | ||
/// </summary> | ||
private void UpdateAndInitializeLoggers(TestRunCriteria testRunCriteria) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in next commit |
||
{ | ||
this.UpdateTestLoggerPath(testRunCriteria); | ||
|
||
// Initialize Loggers | ||
TestLoggerManager loggerManager = TestLoggerManager.Instance; | ||
|
||
foreach (var logger in LoggerList.Instance.Loggers) | ||
{ | ||
string loggerIdentifier = logger.loggerIdentifier; | ||
Dictionary<string, string> parameters = logger.parameters; | ||
|
||
// First assume the logger is specified by URI. If that fails try with friendly name. | ||
try | ||
{ | ||
this.AddLoggerByUri(loggerManager, loggerIdentifier, parameters); | ||
} | ||
catch (InvalidLoggerException) | ||
{ | ||
string loggerUri; | ||
if (loggerManager.TryGetUriFromFriendlyName(loggerIdentifier, out loggerUri)) | ||
{ | ||
this.AddLoggerByUri(loggerManager, loggerUri, parameters); | ||
} | ||
else | ||
{ | ||
throw new InvalidLoggerException( | ||
String.Format( | ||
CultureInfo.CurrentUICulture, | ||
ClientResources.LoggerNotFound, | ||
logger.arument)); | ||
} | ||
} | ||
} | ||
} | ||
|
||
private void AddLoggerByUri(TestLoggerManager loggerManager, string argument, Dictionary<string, string> parameters) | ||
{ | ||
// Get the uri and if it is not valid, throw. | ||
Uri loggerUri = null; | ||
try | ||
{ | ||
loggerUri = new Uri(argument); | ||
} | ||
catch (UriFormatException) | ||
{ | ||
throw new InvalidLoggerException( | ||
string.Format( | ||
CultureInfo.CurrentUICulture, | ||
ClientResources.LoggerUriInvalid, | ||
argument)); | ||
} | ||
|
||
// Add the logger and if it is a non-existent logger, throw. | ||
try | ||
{ | ||
loggerManager.AddLogger(loggerUri, parameters); | ||
} | ||
catch (InvalidOperationException e) | ||
{ | ||
throw new InvalidLoggerException(e.Message, e); | ||
} | ||
} | ||
|
||
private void UpdateTestLoggerPath(TestRunCriteria testRunCriteria) | ||
{ | ||
List<string> loggersToUpdate = new List<string>(); | ||
|
||
var sources = testRunCriteria.Sources; | ||
foreach (var source in sources) | ||
{ | ||
var sourceDirectory = Path.GetDirectoryName(source); | ||
if (!string.IsNullOrEmpty(sourceDirectory) && this.fileHelper.DirectoryExists(sourceDirectory)) | ||
{ | ||
loggersToUpdate.AddRange(this.fileHelper.EnumerateFiles(sourceDirectory, TestPlatformConstants.TestLoggerResxPattern, SearchOption.TopDirectoryOnly).ToList()); | ||
} | ||
} | ||
|
||
if (loggersToUpdate.Count > 0) | ||
{ | ||
this.UpdateExtensions(loggersToUpdate, true); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it better is inject IFileHelper via ctor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, its a valid point. Fixed in next commit.