Skip to content

Commit

Permalink
Console Logger related fixes. (microsoft#416)
Browse files Browse the repository at this point in the history
* Consolelogger related fixes.
- Adding the IsDesignMode boolean in CommandlineOptions
- Make sure Console Logger does not get initialized in design mode.
- Code changes for adding verbosity parameter for console logger.
  • Loading branch information
singhsarab authored Feb 2, 2017
1 parent 79b3982 commit 8f5c4f6
Show file tree
Hide file tree
Showing 18 changed files with 401 additions and 118 deletions.
80 changes: 51 additions & 29 deletions src/Microsoft.TestPlatform.Common/Logging/TestLoggerManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ internal class TestLoggerManager : ITestDiscoveryEventsRegistrar, ITestRunEvents
/// <summary>
/// Default constructor.
/// </summary>
protected TestLoggerManager()
protected TestLoggerManager(TestSessionMessageLogger sessionLogger, InternalTestLoggerEvents loggerEvents)
{
this.messageLogger = TestSessionMessageLogger.Instance;
this.messageLogger = sessionLogger;
this.testLoggerExtensionManager = TestLoggerExtensionManager.Create(messageLogger);
this.loggerEvents = new InternalTestLoggerEvents((TestSessionMessageLogger)messageLogger);
this.loggerEvents = loggerEvents;
}

/// <summary>
Expand All @@ -85,7 +85,8 @@ public static TestLoggerManager Instance
{
if (testLoggerManager == null)
{
testLoggerManager = new TestLoggerManager();
testLoggerManager = new TestLoggerManager(TestSessionMessageLogger.Instance,
new InternalTestLoggerEvents(TestSessionMessageLogger.Instance));
}
}
}
Expand Down Expand Up @@ -129,6 +130,25 @@ protected HashSet<string> InitializedLoggers

#region Public Methods

/// <summary>
/// Add and initialize the logger with the given parameters
/// </summary>
/// <param name="logger">The logger that needs to be initialized</param>
/// <param name="extensionUri">URI of the logger</param>
/// <param name="parameters">Logger parameters</param>
public void AddLogger(ITestLogger logger, string extensionUri, Dictionary<string, string> parameters)
{
this.CheckDisposed();

// If the logger has already been initialized just return.
if (this.initializedLoggers.Contains(extensionUri, StringComparer.OrdinalIgnoreCase))
{
return;
}
this.initializedLoggers.Add(extensionUri);
InitializeLogger(logger, extensionUri, parameters);
}

/// <summary>
/// Adds the logger with the specified URI and parameters.
/// For ex. TfsPublisher takes parameters such as Platform, Flavor etc.
Expand All @@ -153,37 +173,40 @@ public void AddLogger(Uri uri, Dictionary<string, string> parameters)
var extensionManager = this.testLoggerExtensionManager;
var logger = extensionManager.TryGetTestExtension(uri.AbsoluteUri);

if (logger != null)
if (logger == null)
{
try
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentUICulture,
CommonResources.LoggerNotFound,
uri.OriginalString));
}

InitializeLogger(logger.Value, logger.Metadata.ExtensionUri, parameters);
}

private void InitializeLogger(ITestLogger logger, string extensionUri, Dictionary<string, string> parameters)
{
try
{
if (logger is ITestLoggerWithParameters)
{
if (logger.Value is ITestLoggerWithParameters)
{
((ITestLoggerWithParameters)logger.Value).Initialize(this.loggerEvents, this.UpdateLoggerParamters(parameters));
}
else
{
((ITestLogger)logger.Value).Initialize(this.loggerEvents, this.GetResultsDirectory(RunSettingsManager.Instance.ActiveRunSettings));
}
((ITestLoggerWithParameters)logger).Initialize(this.loggerEvents, this.UpdateLoggerParameters(parameters));
}
catch (Exception e)
else
{
this.messageLogger.SendMessage(
TestMessageLevel.Error,
string.Format(
CultureInfo.CurrentUICulture,
CommonResources.LoggerInitializationError,
logger.Metadata.ExtensionUri,
e));
((ITestLogger)logger).Initialize(this.loggerEvents, this.GetResultsDirectory(RunSettingsManager.Instance.ActiveRunSettings));
}
}
else
catch (Exception e)
{
throw new InvalidOperationException(
String.Format(
this.messageLogger.SendMessage(
TestMessageLevel.Error,
string.Format(
CultureInfo.CurrentUICulture,
CommonResources.LoggerNotFound,
uri.OriginalString));
CommonResources.LoggerInitializationError,
extensionUri,
e));
}
}

Expand Down Expand Up @@ -376,7 +399,7 @@ internal string GetResultsDirectory(RunSettings runSettings)
/// <summary>
/// Populates user supplied and default logger parameters.
/// </summary>
private Dictionary<string, string> UpdateLoggerParamters(Dictionary<string, string> parameters)
private Dictionary<string, string> UpdateLoggerParameters(Dictionary<string, string> parameters)
{
var loggerParams = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (parameters != null)
Expand Down Expand Up @@ -426,7 +449,6 @@ private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e)
this.loggerEvents.CompleteTestRun(e.TestRunStatistics, e.IsCanceled, e.IsAborted, e.Error, e.AttachmentSets, e.ElapsedTimeInRunningTests);
}


/// <summary>
/// Called when data collection message is received.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/vstest.console/CommandLine/CommandLineOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ public IEnumerable<string> Sources
/// </summary>
public string TestAdapterPath { get; set; }

/// <summary>
/// True if console runner is running in design mode.
/// </summary>
public bool IsDesignMode { get; set; }

/// <summary>
/// Process Id of the process which launched vstest runner
/// </summary>
Expand Down
54 changes: 50 additions & 4 deletions src/vstest.console/Internal/ConsoleLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Internal
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
Expand All @@ -22,7 +23,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Internal
/// </summary>
[FriendlyName(ConsoleLogger.FriendlyName)]
[ExtensionUri(ConsoleLogger.ExtensionUri)]
internal class ConsoleLogger : ITestLogger
internal class ConsoleLogger : ITestLoggerWithParameters
{
#region Constants
private const string TestMessageFormattingPrefix = " ";
Expand All @@ -37,10 +38,26 @@ internal class ConsoleLogger : ITestLogger
/// </summary>
public const string FriendlyName = "Console";

/// <summary>
/// Parameter for Verbosity
/// </summary>
public const string VerbosityParam = "verbosity";

#endregion

internal enum Verbosity
{
Minimal,
Normal
}

#region Fields

/// <summary>
/// Level of verbosity
/// </summary>
private Verbosity verbosityLevel = Verbosity.Normal;

private TestOutcome testOutcome = TestOutcome.None;
private int testsTotal = 0;
private int testsPassed = 0;
Expand Down Expand Up @@ -79,9 +96,15 @@ protected static IOutput Output
get;
private set;
}
#endregion

/// <summary>
/// Get the verbosity level for the console logger
/// </summary>
public Verbosity VerbosityLevel => verbosityLevel;

#region ITestLogger
#endregion

#region ITestLoggerWithParameters

/// <summary>
/// Initializes the Test Logger.
Expand All @@ -106,6 +129,26 @@ public void Initialize(TestLoggerEvents events, string testRunDirectory)
events.TestRunComplete += this.TestRunCompleteHandler;
}

public void Initialize(TestLoggerEvents events, Dictionary<string, string> parameters)
{
if (parameters == null)
{
throw new ArgumentNullException(nameof(parameters));
}

if (parameters.Count == 0)
{
throw new ArgumentException("No default parameters added", nameof(parameters));
}

var verbosityExists = parameters.TryGetValue(ConsoleLogger.VerbosityParam, out string verbosity);
if (verbosityExists && Enum.TryParse(verbosity, true, out Verbosity verbosityLevel))
{
this.verbosityLevel = verbosityLevel;
}

this.Initialize(events, String.Empty);
}
#endregion

#region Private Methods
Expand Down Expand Up @@ -282,7 +325,10 @@ private void TestResultHandler(object sender, TestResultEventArgs e)
else if (e.Result.Outcome == TestOutcome.Passed)
{
string output = string.Format(CultureInfo.CurrentCulture, CommandLineResources.PassedTestIndicator, name);
Output.WriteLine(output, OutputLevel.Information);
if (!this.verbosityLevel.Equals(Verbosity.Minimal))
{
Output.WriteLine(output, OutputLevel.Information);
}
this.testsPassed++;
}
}
Expand Down
34 changes: 21 additions & 13 deletions src/vstest.console/Processors/EnableLoggerArgumentProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors
using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities;

using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources;
using Microsoft.VisualStudio.TestPlatform.CommandLine.Internal;

/// <summary>
/// An argument processor that allows the user to enable a specific logger
Expand Down Expand Up @@ -154,25 +155,32 @@ public void Initialize(string argument)

if (parseSucceeded)
{
// First assume the logger is specified by URI. If that fails try with friendly name.
try
if (loggerIdentifier.Equals(ConsoleLogger.FriendlyName, StringComparison.OrdinalIgnoreCase))
{
this.AddLoggerByUri(loggerIdentifier, parameters);
this.loggerManager.AddLogger(new ConsoleLogger(), ConsoleLogger.ExtensionUri, parameters);
}
catch (CommandLineException)
else
{
string loggerUri;
if (this.loggerManager.TryGetUriFromFriendlyName(loggerIdentifier, out loggerUri))
// First assume the logger is specified by URI. If that fails try with friendly name.
try
{
this.AddLoggerByUri(loggerUri, parameters);
this.AddLoggerByUri(loggerIdentifier, parameters);
}
else
catch (CommandLineException)
{
throw new CommandLineException(
String.Format(
CultureInfo.CurrentUICulture,
CommandLineResources.LoggerNotFound,
argument));
string loggerUri;
if (this.loggerManager.TryGetUriFromFriendlyName(loggerIdentifier, out loggerUri))
{
this.AddLoggerByUri(loggerUri, parameters);
}
else
{
throw new CommandLineException(
String.Format(
CultureInfo.CurrentUICulture,
CommandLineResources.LoggerNotFound,
argument));
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ internal class ParentProcessIdArgumentProcessorCapabilities : BaseArgumentProces

public override bool IsAction => false;

public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.ParentProcessId;
public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.DesignMode;

public override string HelpContentResourceName => CommandLineResources.ParentProcessIdArgumentHelp;

Expand Down
10 changes: 5 additions & 5 deletions src/vstest.console/Processors/PortArgumentProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ internal class PortArgumentProcessorCapabilities : BaseArgumentProcessorCapabili

public override bool IsAction => false;

public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.Normal;
public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.DesignMode;

public override string HelpContentResourceName => CommandLineResources.PortArgumentHelp;

Expand Down Expand Up @@ -152,20 +152,20 @@ internal PortArgumentExecutor(CommandLineOptions options, ITestRequestManager te
/// <param name="argument">Argument that was provided with the command.</param>
public void Initialize(string argument)
{
int portNumber;
if (string.IsNullOrWhiteSpace(argument) || !int.TryParse(argument, out portNumber))
if (string.IsNullOrWhiteSpace(argument) || !int.TryParse(argument, out int portNumber))
{
throw new CommandLineException(CommandLineResources.InvalidPortArgument);
}

this.commandLineOptions.Port = portNumber;
this.commandLineOptions.IsDesignMode = true;
this.designModeClient = this.designModeInitializer?.Invoke(this.commandLineOptions.ParentProcessId);
}

/// <summary>
/// The port is already set, return success.
/// Initialize the design mode client.
/// </summary>
/// <returns> The <see cref="ArgumentProcessorResult"/> Success </returns>
/// <returns> The <see cref="ArgumentProcessorResult.Success"/> if initialization is successful. </returns>
public ArgumentProcessorResult Execute()
{
try
Expand Down
9 changes: 8 additions & 1 deletion src/vstest.console/Processors/RunTestsArgumentProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ public ArgumentProcessorResult Execute()
Contract.Assert(this.commandLineOptions != null);
Contract.Assert(!string.IsNullOrWhiteSpace(this.runSettingsManager?.ActiveRunSettings?.SettingsXml));

if (this.commandLineOptions.IsDesignMode)
{
// Do not attempt execution in case of design mode. Expect execution to happen
// via the design mode client.
return ArgumentProcessorResult.Success;
}

// Ensure a test source file was provided
var anySource = this.commandLineOptions.Sources.FirstOrDefault();
if (anySource == null)
Expand Down Expand Up @@ -184,7 +191,7 @@ private bool RunTests(IEnumerable<string> sources)
// for command line keep alive is always false.
// for Windows Store apps it should be false, as Windows Store apps executor should terminate after finishing the test execution.
var keepAlive = false;

var runRequestPayload = new TestRunRequestPayload() { Sources = this.commandLineOptions.Sources.ToList(), RunSettings = runSettings, KeepAlive = keepAlive };
var result = this.testRequestManager.RunTests(runRequestPayload, null, this.testRunEventsRegistrar);

Expand Down
Loading

0 comments on commit 8f5c4f6

Please sign in to comment.