diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/EqtTrace.cs b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/EqtTrace.cs
index 0ebfa16aa3..c946f142d5 100644
--- a/src/Microsoft.TestPlatform.CoreUtilities/Tracing/EqtTrace.cs
+++ b/src/Microsoft.TestPlatform.CoreUtilities/Tracing/EqtTrace.cs
@@ -146,7 +146,19 @@ public static bool IsWarningEnabled
///
public static bool InitializeVerboseTrace(string customLogFile)
{
- if (!traceImpl.InitializeVerboseTrace(customLogFile))
+ return InitializeTrace(customLogFile, PlatformTraceLevel.Verbose);
+ }
+
+ ///
+ /// Initializes the tracing with custom log file and trace level.
+ /// Overrides if any trace is set before.
+ ///
+ /// Custom log file for trace messages.
+ /// Trace level.
+ /// Trace initialized flag.
+ public static bool InitializeTrace(string customLogFile, PlatformTraceLevel traceLevel)
+ {
+ if (!traceImpl.InitializeTrace(customLogFile, traceLevel))
{
ErrorOnInitialization = PlatformEqtTrace.ErrorOnInitialization;
return false;
diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs
index 0a2a83b2f5..681db2a770 100644
--- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs
+++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyOperationManager.cs
@@ -116,7 +116,7 @@ public virtual bool SetupChannel(IEnumerable sources)
}
var processId = this.processHelper.GetCurrentProcessId();
- var connectionInfo = new TestRunnerConnectionInfo { Port = portNumber, ConnectionInfo = testHostConnectionInfo, RunnerProcessId = processId, LogFile = this.GetTimestampedLogFile(EqtTrace.LogFile) };
+ var connectionInfo = new TestRunnerConnectionInfo { Port = portNumber, ConnectionInfo = testHostConnectionInfo, RunnerProcessId = processId, LogFile = this.GetTimestampedLogFile(EqtTrace.LogFile), TraceLevel = (int)EqtTrace.TraceLevel };
// Subscribe to TestHost Event
this.testHostManager.HostLaunched += this.TestHostManagerHostLaunched;
diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ProxyDataCollectionManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ProxyDataCollectionManager.cs
index c8f5cdf63c..72a5f9f7d5 100644
--- a/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ProxyDataCollectionManager.cs
+++ b/src/Microsoft.TestPlatform.CrossPlatEngine/DataCollection/ProxyDataCollectionManager.cs
@@ -38,6 +38,7 @@ internal class ProxyDataCollectionManager : IProxyDataCollectionManager
private const string PortOption = "--port";
private const string DiagOption = "--diag";
private const string ParentProcessIdOption = "--parentprocessid";
+ private const string TraceLevelOption = "--tracelevel";
public const string DebugEnvironmentVaribleName = "VSTEST_DATACOLLECTOR_DEBUG";
private IDataCollectionRequestSender dataCollectionRequestSender;
@@ -299,6 +300,9 @@ private IList GetCommandLineArguments(int portNumber)
{
commandlineArguments.Add(DiagOption);
commandlineArguments.Add(this.GetTimestampedLogFile(EqtTrace.LogFile));
+
+ commandlineArguments.Add(TraceLevelOption);
+ commandlineArguments.Add(((int)EqtTrace.TraceLevel).ToString());
}
return commandlineArguments;
diff --git a/src/Microsoft.TestPlatform.ObjectModel/ConnectionInfo/TestRunnerConnectionInfo.cs b/src/Microsoft.TestPlatform.ObjectModel/ConnectionInfo/TestRunnerConnectionInfo.cs
index 77d6925ae4..52364a369e 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/ConnectionInfo/TestRunnerConnectionInfo.cs
+++ b/src/Microsoft.TestPlatform.ObjectModel/ConnectionInfo/TestRunnerConnectionInfo.cs
@@ -98,6 +98,15 @@ public string LogFile
set;
}
+ ///
+ /// Gets or sets the trace level of logs.
+ ///
+ public int TraceLevel
+ {
+ get;
+ set;
+ }
+
///
/// Gets or sets the runner process id.
///
diff --git a/src/Microsoft.TestPlatform.ObjectModel/ConnectionInfo/TestRunnerConnectionInfoExtensions.cs b/src/Microsoft.TestPlatform.ObjectModel/ConnectionInfo/TestRunnerConnectionInfoExtensions.cs
index fbf6042b84..87ef7f5789 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/ConnectionInfo/TestRunnerConnectionInfoExtensions.cs
+++ b/src/Microsoft.TestPlatform.ObjectModel/ConnectionInfo/TestRunnerConnectionInfoExtensions.cs
@@ -19,6 +19,7 @@ public static string ToCommandLineOptions(this TestRunnerConnectionInfo connecti
if (!string.IsNullOrEmpty(connectionInfo.LogFile))
{
options += " --diag " + connectionInfo.LogFile;
+ options += " --tracelevel " + connectionInfo.TraceLevel;
}
return options;
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/Tracing/IPlatformEqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/Tracing/IPlatformEqtTrace.cs
index 4e9aadcf4b..1f47eb20a0 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/Tracing/IPlatformEqtTrace.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/Tracing/IPlatformEqtTrace.cs
@@ -37,6 +37,15 @@ bool DoNotInitialize
///
bool InitializeVerboseTrace(string customLogFile);
+ ///
+ /// Initializes the tracing with custom log file and trace level.
+ /// Overrides if any trace is set before.
+ ///
+ /// Customr log file for trace messages.
+ /// Trace level.
+ /// Trace initialized flag.
+ bool InitializeTrace(string customLogFile, PlatformTraceLevel traceLevel);
+
///
/// Gets a value indicating if tracing is enabled for a trace level.
///
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/PlatformEqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/PlatformEqtTrace.cs
index 69e8050429..d9c66fbf6b 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/PlatformEqtTrace.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/common/Tracing/PlatformEqtTrace.cs
@@ -161,12 +161,18 @@ private static TraceSource Source
///
public bool InitializeVerboseTrace(string customLogFile)
+ {
+ return this.InitializeTrace(customLogFile, PlatformTraceLevel.Verbose);
+ }
+
+ ///
+ public bool InitializeTrace(string customLogFile, PlatformTraceLevel platformTraceLevel)
{
isInitialized = false;
LogFile = customLogFile;
- TraceLevel = TraceLevel.Verbose;
- Source.Switch.Level = SourceLevels.All;
+ TraceLevel = this.MapPlatformTraceToTrace(platformTraceLevel);
+ Source.Switch.Level = TraceSourceLevelsMap[TraceLevel];
// Ensure trace is initlized
return EnsureTraceIsInitialized();
@@ -351,7 +357,7 @@ private static bool EnsureTraceIsInitialized()
}
catch (Exception e)
{
- UnInitializeVerboseTrace();
+ UnInitializeTrace();
ErrorOnInitialization = e.ToString();
return false;
}
@@ -419,7 +425,7 @@ private static int GetProcessId()
}
}
- private static void UnInitializeVerboseTrace()
+ private static void UnInitializeTrace()
{
isInitialized = false;
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard1.0/Tracing/PlatformEqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard1.0/Tracing/PlatformEqtTrace.cs
index 4f65b03031..97b1387497 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard1.0/Tracing/PlatformEqtTrace.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard1.0/Tracing/PlatformEqtTrace.cs
@@ -39,6 +39,11 @@ public bool InitializeVerboseTrace(string customLogFile)
throw new NotImplementedException();
}
+ public bool InitializeTrace(string customLogFile, PlatformTraceLevel traceLevel)
+ {
+ throw new NotImplementedException();
+ }
+
public bool ShouldTrace(PlatformTraceLevel traceLevel)
{
throw new NotImplementedException();
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/Tracing/PlatformEqtTrace.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/Tracing/PlatformEqtTrace.cs
index e87a00d4b5..20cdac9b00 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/Tracing/PlatformEqtTrace.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/Tracing/PlatformEqtTrace.cs
@@ -69,6 +69,12 @@ public void WriteLine(PlatformTraceLevel level, string message)
///
public bool InitializeVerboseTrace(string customLogFile)
+ {
+ return this.InitializeTrace(customLogFile, PlatformTraceLevel.Verbose);
+ }
+
+ ///
+ public bool InitializeTrace(string customLogFile, PlatformTraceLevel traceLevel)
{
string logFileName = string.Empty;
try
@@ -81,7 +87,7 @@ public bool InitializeVerboseTrace(string customLogFile)
}
LogFile = Path.Combine(Path.GetTempPath(), logFileName + ".TpTrace.log");
- TraceLevel = PlatformTraceLevel.Verbose;
+ TraceLevel = traceLevel;
return this.TraceInitialized();
}
@@ -154,7 +160,7 @@ private bool TraceInitialized()
}
catch (Exception ex)
{
- this.UnInitializeVerboseTrace();
+ this.UnInitializeTrace();
ErrorOnInitialization = ex.Message;
return false;
}
@@ -163,7 +169,7 @@ private bool TraceInitialized()
}
}
- private void UnInitializeVerboseTrace()
+ private void UnInitializeTrace()
{
isInitialized = false;
LogFile = null;
diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/ConsoleParameters.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/ConsoleParameters.cs
index d45fcdc44e..3fc17b4bda 100644
--- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/ConsoleParameters.cs
+++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/ConsoleParameters.cs
@@ -3,12 +3,14 @@
namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer
{
+ using System;
+ using System.Diagnostics;
+ using System.IO;
+
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Extensions;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;
- using System;
- using System.IO;
///
/// Class which defines additional specifiable parameters for vstest.console.exe
@@ -35,6 +37,11 @@ public ConsoleParameters(IFileHelper fileHelper)
this.fileHelper = fileHelper;
}
+ ///
+ /// Trace level for logs.
+ ///
+ public TraceLevel TraceLevel { get; set; } = TraceLevel.Verbose;
+
///
/// Full path for the log file
///
diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Microsoft.TestPlatform.VsTestConsole.TranslationLayer.csproj b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Microsoft.TestPlatform.VsTestConsole.TranslationLayer.csproj
index 5195d5883b..1139b62a48 100644
--- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Microsoft.TestPlatform.VsTestConsole.TranslationLayer.csproj
+++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/Microsoft.TestPlatform.VsTestConsole.TranslationLayer.csproj
@@ -22,7 +22,7 @@
-
+
4.1.1
@@ -37,6 +37,9 @@
4.1.0
+
+
+ 4.0.0
diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleProcessManager.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleProcessManager.cs
index a12ba19292..dca45aac6e 100644
--- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleProcessManager.cs
+++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleProcessManager.cs
@@ -32,7 +32,7 @@ internal class VsTestConsoleProcessManager : IProcessManager
/// Diagnostics argument for Vstest CLI
/// Enables Diagnostic logging for Vstest CLI and TestHost - Optional
///
- private const string DIAG_ARGUMENT = "/diag:{0}";
+ private const string DIAG_ARGUMENT = "/diag:{0};tracelevel={1}";
private string vstestConsolePath;
private object syncObject = new object();
@@ -134,8 +134,8 @@ private string[] BuildArguments(ConsoleParameters parameters)
if(!string.IsNullOrEmpty(parameters.LogFilePath))
{
- // Extra args: --diag|/diag:
- args.Add(string.Format(CultureInfo.InvariantCulture, DIAG_ARGUMENT, parameters.LogFilePath));
+ // Extra args: --diag|/diag:;tracelevel=
+ args.Add(string.Format(CultureInfo.InvariantCulture, DIAG_ARGUMENT, parameters.LogFilePath, parameters.TraceLevel));
}
return args.ToArray();
diff --git a/src/datacollector/DataCollectorMain.cs b/src/datacollector/DataCollectorMain.cs
index e57f914da6..7e61df298b 100644
--- a/src/datacollector/DataCollectorMain.cs
+++ b/src/datacollector/DataCollectorMain.cs
@@ -35,6 +35,11 @@ public class DataCollectorMain
///
private const string LogFileArgument = "--diag";
+ ///
+ /// Trace level for logs.
+ ///
+ private const string TraceLevelArgument = "--tracelevel";
+
private IProcessHelper processHelper;
private IEnvironment environment;
@@ -65,7 +70,20 @@ public void Run(string[] args)
string logFile;
if (argsDictionary.TryGetValue(LogFileArgument, out logFile))
{
- EqtTrace.InitializeVerboseTrace(logFile);
+ var traceLevelInt = CommandLineArgumentsHelper.GetIntArgFromDict(argsDictionary, TraceLevelArgument);
+ var isTraceLevelArgValid = Enum.IsDefined(typeof(PlatformTraceLevel), traceLevelInt);
+
+ // In case traceLevelInt is not defined in PlatfromTraceLevel, default it to verbose.
+ var traceLevel = isTraceLevelArgValid ? (PlatformTraceLevel)traceLevelInt : PlatformTraceLevel.Verbose;
+
+ // Initialize trace.
+ EqtTrace.InitializeTrace(logFile, traceLevel);
+
+ // Log warning in case tracelevel passed in arg is invalid
+ if (!isTraceLevelArgValid)
+ {
+ EqtTrace.Warning("DataCollectorMain.Run: Invalid trace level: {0}, defaulting to verbose tracelevel.", traceLevelInt);
+ }
}
else
{
@@ -100,7 +118,7 @@ public void Run(string[] args)
// Can only do this after InitializeCommunication because datacollector cannot "Send Log" unless communications are initialized
if (!string.IsNullOrEmpty(EqtTrace.LogFile))
{
- ((DataCollectionRequestHandler)this.requestHandler).SendDataCollectionMessage(new DataCollectionMessageEventArgs(TestMessageLevel.Informational, string.Format("Logging DataCollector Diagnostics in file: {0}", EqtTrace.LogFile)));
+ (this.requestHandler as DataCollectionRequestHandler)?.SendDataCollectionMessage(new DataCollectionMessageEventArgs(TestMessageLevel.Informational, string.Format("Logging DataCollector Diagnostics in file: {0}", EqtTrace.LogFile)));
}
// Start processing async in a different task
diff --git a/src/testhost.x86/DefaultEngineInvoker.cs b/src/testhost.x86/DefaultEngineInvoker.cs
index 12acfc0d44..24f8c5be5d 100644
--- a/src/testhost.x86/DefaultEngineInvoker.cs
+++ b/src/testhost.x86/DefaultEngineInvoker.cs
@@ -44,6 +44,8 @@ internal class DefaultEngineInvoker :
private const string LogFileArgument = "--diag";
+ private const string TraceLevelArgument = "--tracelevel";
+
private const string DataCollectionPortArgument = "--datacollectionport";
private const string TelemetryOptedIn = "--telemetryoptedin";
@@ -228,7 +230,14 @@ private static void InitializeEqtTrace(IDictionary argsDictionar
// Setup logging if enabled
if (argsDictionary.TryGetValue(LogFileArgument, out string logFile))
{
- EqtTrace.InitializeVerboseTrace(logFile);
+ var traceLevelInt = CommandLineArgumentsHelper.GetIntArgFromDict(argsDictionary, TraceLevelArgument);
+
+ // In case traceLevelInt is not defined in PlatfromTraceLevel, default it to verbose.
+ var traceLevel = Enum.IsDefined(typeof(PlatformTraceLevel), traceLevelInt) ?
+ (PlatformTraceLevel)traceLevelInt :
+ PlatformTraceLevel.Verbose;
+
+ EqtTrace.InitializeTrace(logFile, traceLevel);
}
else
{
diff --git a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs
index 4ac5180800..e98557c82c 100644
--- a/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs
+++ b/src/vstest.console/Processors/EnableBlameArgumentProcessor.cs
@@ -6,6 +6,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors
using System;
using System.Collections.Generic;
using System.Globalization;
+ using System.Linq;
using System.Xml;
using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities;
@@ -135,83 +136,86 @@ internal EnableBlameArgumentExecutor(IRunSettingsProvider runSettingsManager, IE
/// Argument that was provided with the command.
public void Initialize(string argument)
{
- bool isDumpEnabled = false;
+ var enableDump = false;
+ var exceptionMessage = string.Format(CultureInfo.CurrentUICulture, CommandLineResources.InvalidBlameArgument, argument);
+ Dictionary collectDumpParameters = null;
- var parseSucceeded = LoggerUtilities.TryParseLoggerArgument(argument, out string loggerIdentifier, out Dictionary parameters);
-
- if (!string.IsNullOrWhiteSpace(argument) && !parseSucceeded)
+ if (!string.IsNullOrWhiteSpace(argument))
{
- throw new CommandLineException(string.Format(CultureInfo.CurrentUICulture, CommandLineResources.BlameInvalidFormat, argument));
- }
+ // Get blame argument list.
+ var blameArgumentList = ArgumentProcessorUtilities.GetArgumentList(argument, ArgumentProcessorUtilities.SemiColonArgumentSeparator, exceptionMessage);
- if (loggerIdentifier != null && loggerIdentifier.Equals(Constants.BlameCollectDumpKey, StringComparison.OrdinalIgnoreCase))
- {
- if (this.environment.OperatingSystem == PlatformOperatingSystem.Windows &&
- this.environment.Architecture != PlatformArchitecture.ARM64 &&
- this.environment.Architecture != PlatformArchitecture.ARM)
- {
- isDumpEnabled = true;
- }
- else
- {
- Output.Warning(false, CommandLineResources.BlameCollectDumpNotSupportedForPlatform);
- }
- }
- else
- {
- Output.Warning(false, string.Format(CultureInfo.CurrentUICulture, CommandLineResources.BlameIncorrectOption, loggerIdentifier));
+ // Get collect dump key.
+ var collectDumpKey = blameArgumentList[0];
+ bool isCollectDumpKeyValid = ValidateCollectDumpKey(collectDumpKey);
+
+ // Check if dump should be enabled or not.
+ enableDump = isCollectDumpKeyValid && IsDumpCollectionSupported();
+
+ // Get collect dump parameters.
+ var collectDumpParameterArgs = blameArgumentList.Skip(1);
+ collectDumpParameters = ArgumentProcessorUtilities.GetArgumentParameters(collectDumpParameterArgs, ArgumentProcessorUtilities.EqualNameValueSeparator, exceptionMessage);
}
+ // Initialize blame.
+ InitializeBlame(enableDump, collectDumpParameters);
+ }
+
+ ///
+ /// Executes the argument processor.
+ ///
+ /// The .
+ public ArgumentProcessorResult Execute()
+ {
+ // Nothing to do since we updated the logger and data collector list in initialize
+ return ArgumentProcessorResult.Success;
+ }
+
+ ///
+ /// Initialize blame.
+ ///
+ /// Enable dump.
+ /// Blame parameters.
+ private void InitializeBlame(bool enableDump, Dictionary collectDumpParameters)
+ {
// Add Blame Logger
- EnableLoggerArgumentExecutor.AddLoggerToRunSettings(BlameFriendlyName, this.runSettingsManager);
+ LoggerUtilities.AddLoggerToRunSettings(BlameFriendlyName, null, this.runSettingsManager);
// Add Blame Data Collector
CollectArgumentExecutor.AddDataCollectorToRunSettings(BlameFriendlyName, this.runSettingsManager);
- // Get results directory from RunSettingsManager
- var runSettings = this.runSettingsManager.ActiveRunSettings;
- string resultsDirectory = null;
- if (runSettings != null)
- {
- try
- {
- RunConfiguration runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runSettings.SettingsXml);
- resultsDirectory = RunSettingsUtilities.GetTestResultsDirectory(runConfiguration);
- }
- catch (SettingsException se)
- {
- if (EqtTrace.IsErrorEnabled)
- {
- EqtTrace.Error("EnableBlameArgumentProcessor: Unable to get the test results directory: Error {0}", se);
- }
- }
- }
- // Add configuration element
- var settings = runSettings?.SettingsXml;
- if (settings == null)
+ // Add default run settings if required.
+ if (this.runSettingsManager.ActiveRunSettings?.SettingsXml == null)
{
- runSettingsManager.AddDefaultRunSettings();
- settings = runSettings?.SettingsXml;
+ this.runSettingsManager.AddDefaultRunSettings(); ;
}
+ var settings = this.runSettingsManager.ActiveRunSettings?.SettingsXml;
+ // Get results directory from RunSettingsManager
+ var resultsDirectory = GetResultsDirectory(settings);
+
+ // Get data collection run settings. Create if not present.
var dataCollectionRunSettings = XmlRunSettingsUtilities.GetDataCollectionRunSettings(settings);
if (dataCollectionRunSettings == null)
{
dataCollectionRunSettings = new DataCollectionRunSettings();
}
+ // Create blame configuration element.
var XmlDocument = new XmlDocument();
var outernode = XmlDocument.CreateElement("Configuration");
var node = XmlDocument.CreateElement("ResultsDirectory");
outernode.AppendChild(node);
node.InnerText = resultsDirectory;
- if (isDumpEnabled)
+ // Add collect dump node in configuration element.
+ if (enableDump)
{
- AddCollectDumpNode(parameters, XmlDocument, outernode);
+ AddCollectDumpNode(collectDumpParameters, XmlDocument, outernode);
}
+ // Add blame configuration element to blame collector.
foreach (var item in dataCollectionRunSettings.DataCollectorSettingsList)
{
if (item.FriendlyName.Equals(BlameFriendlyName))
@@ -220,9 +224,78 @@ public void Initialize(string argument)
}
}
+ // Update run settings.
runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.DataCollectionRunSettingsName, dataCollectionRunSettings.ToXml().InnerXml);
}
+ ///
+ /// Get results directory.
+ ///
+ /// Settings xml.
+ /// Results directory.
+ private string GetResultsDirectory(string settings)
+ {
+ string resultsDirectory = null;
+ if (settings != null)
+ {
+ try
+ {
+ RunConfiguration runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(settings);
+ resultsDirectory = RunSettingsUtilities.GetTestResultsDirectory(runConfiguration);
+ }
+ catch (SettingsException se)
+ {
+ if (EqtTrace.IsErrorEnabled)
+ {
+ EqtTrace.Error("EnableBlameArgumentProcessor: Unable to get the test results directory: Error {0}", se);
+ }
+ }
+ }
+
+ return resultsDirectory;
+ }
+
+ ///
+ /// Checks if dump collection is supported.
+ ///
+ /// Dump collection supported flag.
+ private bool IsDumpCollectionSupported()
+ {
+ var dumpCollectionSupported = this.environment.OperatingSystem == PlatformOperatingSystem.Windows &&
+ this.environment.Architecture != PlatformArchitecture.ARM64 &&
+ this.environment.Architecture != PlatformArchitecture.ARM;
+
+ if (!dumpCollectionSupported)
+ {
+ Output.Warning(false, CommandLineResources.BlameCollectDumpNotSupportedForPlatform);
+ }
+
+ return dumpCollectionSupported;
+ }
+
+ ///
+ /// Check if collect dump key is valid.
+ ///
+ /// Collect dump key.
+ /// Flag for collect dump key valid or not.
+ private bool ValidateCollectDumpKey(string collectDumpKey)
+ {
+ var isCollectDumpKeyValid = collectDumpKey != null && collectDumpKey.Equals(Constants.BlameCollectDumpKey, StringComparison.OrdinalIgnoreCase);
+
+ if (!isCollectDumpKeyValid)
+ {
+ Output.Warning(false, string.Format(CultureInfo.CurrentUICulture, CommandLineResources.BlameIncorrectOption, collectDumpKey));
+ }
+
+ return isCollectDumpKeyValid;
+ }
+
+ ///
+ /// Adds collect dump node in outer node.
+ ///
+ /// Parameters.
+ /// Xml document.
+ /// Outer node.
private void AddCollectDumpNode(Dictionary parameters, XmlDocument XmlDocument, XmlElement outernode)
{
var dumpNode = XmlDocument.CreateElement(Constants.BlameCollectDumpKey);
@@ -238,16 +311,6 @@ private void AddCollectDumpNode(Dictionary parameters, XmlDocume
outernode.AppendChild(dumpNode);
}
- ///
- /// Executes the argument processor.
- ///
- /// The .
- public ArgumentProcessorResult Execute()
- {
- // Nothing to do since we updated the logger and data collector list in initialize
- return ArgumentProcessorResult.Success;
- }
-
#endregion
}
}
diff --git a/src/vstest.console/Processors/EnableDiagArgumentProcessor.cs b/src/vstest.console/Processors/EnableDiagArgumentProcessor.cs
index bd5a6c95b3..2656c0105c 100644
--- a/src/vstest.console/Processors/EnableDiagArgumentProcessor.cs
+++ b/src/vstest.console/Processors/EnableDiagArgumentProcessor.cs
@@ -4,14 +4,17 @@
namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors
{
using System;
+ using System.Collections.Generic;
+ using System.Globalization;
using System.IO;
-
+ using System.Linq;
+ using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+ using Microsoft.VisualStudio.TestPlatform.Utilities;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;
using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources;
- using Microsoft.VisualStudio.TestPlatform.Utilities;
internal class EnableDiagArgumentProcessor : IArgumentProcessor
{
@@ -102,6 +105,11 @@ internal class EnableDiagArgumentExecutor : IArgumentExecutor
{
private readonly IFileHelper fileHelper;
+ ///
+ /// Parameter for trace level
+ ///
+ public const string TraceLevelParam = "tracelevel";
+
#region Constructor
///
@@ -123,44 +131,122 @@ public EnableDiagArgumentExecutor(IFileHelper fileHelper)
/// Argument that was provided with the command.
public void Initialize(string argument)
{
+ string exceptionMessage = string.Format(CultureInfo.CurrentUICulture, CommandLineResources.InvalidDiagArgument, argument);
+
+ // Throw error if argument is null or empty.
if (string.IsNullOrWhiteSpace(argument))
{
- throw new CommandLineException(CommandLineResources.EnableDiagUsage);
+ throw new CommandLineException(exceptionMessage);
+ }
+
+ // Get diag argument list.
+ var diagArgumentList = ArgumentProcessorUtilities.GetArgumentList(argument, ArgumentProcessorUtilities.SemiColonArgumentSeparator, exceptionMessage);
+
+ // Get diag file path.
+ // Note: Even though semi colon is valid file path, we are not respecting the file name having semi-colon [As we are separating arguments based on semi colon].
+ var diagFilePathArg = diagArgumentList[0];
+ var diagFilePath = GetDiagFilePath(diagFilePathArg);
+
+ // Get diag parameters.
+ var diagParameterArgs = diagArgumentList.Skip(1);
+ var diagParameters = ArgumentProcessorUtilities.GetArgumentParameters(diagParameterArgs, ArgumentProcessorUtilities.EqualNameValueSeparator, exceptionMessage);
+
+ // Initialize diag logging.
+ InitializeDiagLogging(diagFilePath, diagParameters);
+ }
+
+ ///
+ /// Executes the argument processor.
+ ///
+ /// The .
+ public ArgumentProcessorResult Execute()
+ {
+ // Nothing to do since we updated the parameter during initialize parameter
+ return ArgumentProcessorResult.Success;
+ }
+
+ ///
+ /// Initialize diag logging.
+ ///
+ /// Diag file path.
+ /// Diag parameters
+ private void InitializeDiagLogging(string diagFilePath, Dictionary diagParameters)
+ {
+ // Get trace level from diag parameters.
+ var traceLevel = GetDiagTraceLevel(diagParameters);
+
+ // Initialize trace.
+ // Trace initialized is false in case of any exception at time of initialization like Catch exception(UnauthorizedAccessException, PathTooLongException...)
+ var traceInitialized = EqtTrace.InitializeTrace(diagFilePath, traceLevel);
+
+ // Show console warning in case trace is not initialized.
+ if (!traceInitialized && !string.IsNullOrEmpty(EqtTrace.ErrorOnInitialization))
+ {
+ ConsoleOutput.Instance.Warning(false, EqtTrace.ErrorOnInitialization);
}
+ }
- if (string.IsNullOrWhiteSpace(Path.GetExtension(argument)))
+ ///
+ /// Gets diag trace level.
+ ///
+ /// Diag parameters.
+ /// Diag trace level.
+ private PlatformTraceLevel GetDiagTraceLevel(Dictionary diagParameters)
+ {
+ // If diag parameters is null, set value of trace level as verbose.
+ if (diagParameters == null)
{
- // Throwing error if the argument is just path and not a file
- throw new CommandLineException(CommandLineResources.EnableDiagUsage);
+ return PlatformTraceLevel.Verbose;
}
- // Create the base directory for logging if doesn't exist. Directory could be empty if just a
- // filename is provided. E.g. log.txt
- var logDirectory = Path.GetDirectoryName(argument);
- if (!string.IsNullOrEmpty(logDirectory) && !this.fileHelper.DirectoryExists(logDirectory))
+ // Get trace level from diag parameters.
+ var traceLevelExists = diagParameters.TryGetValue(TraceLevelParam, out string traceLevelStr);
+ if (traceLevelExists && Enum.TryParse(traceLevelStr, true, out PlatformTraceLevel traceLevel))
{
- this.fileHelper.CreateDirectory(logDirectory);
+ return traceLevel;
}
- // Find full path and send this to testhost so that vstest and testhost create logs at same location.
- argument = Path.GetFullPath(argument);
+ // Default value of diag trace level is verbose.
+ return PlatformTraceLevel.Verbose;
+ }
+
+ ///
+ /// Gets diag file path.
+ ///
+ /// Diag file path argument.
+ /// Diag file path.
+ private string GetDiagFilePath(string diagFilePathArgument)
+ {
+ // Remove double quotes if present.
+ diagFilePathArgument = diagFilePathArgument.Replace("\"", "");
- // Catch exception(UnauthorizedAccessException, PathTooLongException...) if there is any at time of initialization.
- if (!EqtTrace.InitializeVerboseTrace(argument))
+ // Throw error in case diag file path is not a valid file path
+ var fileExtension = Path.GetExtension(diagFilePathArgument);
+ if (string.IsNullOrWhiteSpace(fileExtension))
{
- if (!string.IsNullOrEmpty(EqtTrace.ErrorOnInitialization))
- ConsoleOutput.Instance.Warning(false, EqtTrace.ErrorOnInitialization);
+ throw new CommandLineException(string.Format(CultureInfo.CurrentCulture, CommandLineResources.InvalidDiagFilePath, diagFilePathArgument));
}
+
+ // Create base directory for diag file path (if doesn't exist)
+ CreateDirectoryIfNotExists(diagFilePathArgument);
+
+ // return full diag file path. (This is done so that vstest and testhost create logs at same location.)
+ return Path.GetFullPath(diagFilePathArgument);
}
///
- /// Executes the argument processor.
+ /// Create directory if not exists.
///
- /// The .
- public ArgumentProcessorResult Execute()
+ /// File path.
+ private void CreateDirectoryIfNotExists(string filePath)
{
- // Nothing to do since we updated the parameter during initialize parameter
- return ArgumentProcessorResult.Success;
+ // Create the base directory of file path if doesn't exist.
+ // Directory could be empty if just a filename is provided. E.g. log.txt
+ var directory = Path.GetDirectoryName(filePath);
+ if (!string.IsNullOrEmpty(directory) && !this.fileHelper.DirectoryExists(directory))
+ {
+ this.fileHelper.CreateDirectory(directory);
+ }
}
#endregion
diff --git a/src/vstest.console/Processors/EnableLoggerArgumentProcessor.cs b/src/vstest.console/Processors/EnableLoggerArgumentProcessor.cs
index 117b098c15..2b56f96a1e 100644
--- a/src/vstest.console/Processors/EnableLoggerArgumentProcessor.cs
+++ b/src/vstest.console/Processors/EnableLoggerArgumentProcessor.cs
@@ -7,6 +7,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Globalization;
+ using System.Linq;
using System.Xml;
using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities;
@@ -143,100 +144,30 @@ public EnableLoggerArgumentExecutor(IRunSettingsProvider runSettingsManager)
/// Argument that was provided with the command.
public void Initialize(string argument)
{
- AddLoggerToRunSettings(argument, runSettingsManager);
- }
-
- ///
- /// Add logger to runsettings.
- ///
- ///
- ///
- public static void AddLoggerToRunSettings(string loggerArgument, IRunSettingsProvider runSettingsManager)
- {
- if (string.IsNullOrWhiteSpace(loggerArgument))
- {
- HandleInvalidArgument(loggerArgument);
- }
+ string exceptionMessage = string.Format(CultureInfo.CurrentUICulture, CommandLineResources.LoggerUriInvalid, argument);
- var settings = runSettingsManager.ActiveRunSettings?.SettingsXml;
- if (settings == null)
+ // Throw error in case logger argument null or empty.
+ if (string.IsNullOrWhiteSpace(argument))
{
- runSettingsManager.AddDefaultRunSettings();
- settings = runSettingsManager.ActiveRunSettings?.SettingsXml;
+ throw new CommandLineException(exceptionMessage);
}
- var loggerRunSettings = XmlRunSettingsUtilities.GetLoggerRunSettings(settings) ?? new LoggerRunSettings();
- string loggerIdentifier = null;
- Dictionary parameters = null;
- var parseSucceeded = LoggerUtilities.TryParseLoggerArgument(loggerArgument, out loggerIdentifier, out parameters);
+ // Get logger argument list.
+ var loggerArgumentList = ArgumentProcessorUtilities.GetArgumentList(argument, ArgumentProcessorUtilities.SemiColonArgumentSeparator, exceptionMessage);
- if (parseSucceeded)
+ // Get logger identifier.
+ var loggerIdentifier = loggerArgumentList[0];
+ if (loggerIdentifier.Contains("="))
{
- var logger = default(LoggerSettings);
-
- try
- {
- // Logger as uri in command line.
- var loggerUri = new Uri(loggerIdentifier);
- logger = new LoggerSettings
- {
- Uri = loggerUri,
- IsEnabled = true
- };
- }
- catch (UriFormatException)
- {
- // Logger as friendlyName in command line.
- logger = new LoggerSettings
- {
- FriendlyName = loggerIdentifier,
- IsEnabled = true
- };
- }
-
- // Converting logger console params to Configuration element
- if (parameters != null && parameters.Count > 0)
- {
- var XmlDocument = new XmlDocument();
- var outerNode = XmlDocument.CreateElement("Configuration");
- foreach (KeyValuePair entry in parameters)
- {
- var node = XmlDocument.CreateElement(entry.Key);
- node.InnerText = entry.Value;
- outerNode.AppendChild(node);
- }
-
- logger.Configuration = outerNode;
- }
-
- // Remove existing logger.
- var existingLoggerIndex = loggerRunSettings.GetExistingLoggerIndex(logger);
- if (existingLoggerIndex >= 0)
- {
- loggerRunSettings.LoggerSettingsList.RemoveAt(existingLoggerIndex);
- }
-
- loggerRunSettings.LoggerSettingsList.Add(logger);
- }
- else
- {
- HandleInvalidArgument(loggerArgument);
+ throw new CommandLineException(exceptionMessage);
}
- runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.LoggerRunSettingsName, loggerRunSettings.ToXml().InnerXml);
- }
+ // Get logger parameters
+ var loggerParameterArgs = loggerArgumentList.Skip(1);
+ var loggerParameters = ArgumentProcessorUtilities.GetArgumentParameters(loggerParameterArgs, ArgumentProcessorUtilities.EqualNameValueSeparator, exceptionMessage);
- ///
- /// Throws an exception indicating that the argument is invalid.
- ///
- /// Argument which is invalid.
- private static void HandleInvalidArgument(string argument)
- {
- throw new CommandLineException(
- string.Format(
- CultureInfo.CurrentUICulture,
- CommandLineResources.LoggerUriInvalid,
- argument));
+ // Add logger to run settings.
+ LoggerUtilities.AddLoggerToRunSettings(loggerIdentifier, loggerParameters, runSettingsManager);
}
///
diff --git a/src/vstest.console/Processors/Utilities/ArgumentProcessorUtilities.cs b/src/vstest.console/Processors/Utilities/ArgumentProcessorUtilities.cs
new file mode 100644
index 0000000000..83b7c0328b
--- /dev/null
+++ b/src/vstest.console/Processors/Utilities/ArgumentProcessorUtilities.cs
@@ -0,0 +1,65 @@
+// 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.CommandLine.Processors.Utilities
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources;
+
+ internal class ArgumentProcessorUtilities
+ {
+ public static readonly char[] SemiColonArgumentSeparator = { ';' };
+ public static readonly char[] EqualNameValueSeparator = { '=' };
+
+ ///
+ /// Get argument list from raw argument usign argument separator.
+ ///
+ /// Raw argument.
+ /// Argument separator.
+ /// Exception Message.
+ /// Argument list.
+ public static string[] GetArgumentList(string rawArgument, char[] argumentSeparator, string exceptionMessage)
+ {
+ var argumentList = rawArgument?.Split(argumentSeparator, StringSplitOptions.RemoveEmptyEntries);
+
+ // Throw error in case of invalid argument.
+ if (argumentList == null || argumentList.Length <= 0)
+ {
+ throw new CommandLineException(exceptionMessage);
+ }
+
+ return argumentList;
+ }
+
+ ///
+ /// Get argument parameters.
+ ///
+ /// Parameter args.
+ /// Name value separator.
+ /// Exception message.
+ /// Parameters dictionary.
+ public static Dictionary GetArgumentParameters(IEnumerable parameterArgs, char[] nameValueSeparator, string exceptionMessage)
+ {
+ var parameters = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ // Get parameters from parameterNameValuePairs.
+ // Throw error in case of invalid name value pairs.
+ foreach (string parameterArg in parameterArgs)
+ {
+ var nameValuePair = parameterArg?.Split(nameValueSeparator, StringSplitOptions.RemoveEmptyEntries);
+
+ if (nameValuePair.Length != 2)
+ {
+ throw new CommandLineException(exceptionMessage);
+ }
+
+ parameters[nameValuePair[0]] = nameValuePair[1];
+ }
+
+ return parameters;
+ }
+ }
+}
diff --git a/src/vstest.console/Processors/Utilities/LoggerUtilities.cs b/src/vstest.console/Processors/Utilities/LoggerUtilities.cs
index 5ab4a4e8bc..fd778c32d2 100644
--- a/src/vstest.console/Processors/Utilities/LoggerUtilities.cs
+++ b/src/vstest.console/Processors/Utilities/LoggerUtilities.cs
@@ -5,59 +5,79 @@
namespace Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities
{
using System;
+ using System.Xml;
using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using ObjectModel;
- using ObjectModel.Logging;
+ using Microsoft.VisualStudio.TestPlatform.Common.Interfaces;
+ using Microsoft.VisualStudio.TestPlatform.Common.Utilities;
+ using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+ using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;
internal class LoggerUtilities
{
///
- /// Parses the parameters passed as name values pairs along with the logger argument.
+ /// Add logger to run settings.
///
- /// Logger argument
- /// Receives logger Uri or friendly name.
- /// Receives parse name value pairs.
- /// True is successful, false otherwise.
- public static bool TryParseLoggerArgument(string argument, out string loggerIdentifier, out Dictionary parameters)
+ /// Logger Identifier.
+ /// Logger parameters.
+ /// Run settings manager.
+ public static void AddLoggerToRunSettings(string loggerIdentifier, Dictionary loggerParameters, IRunSettingsProvider runSettingsManager)
{
- loggerIdentifier = null;
- parameters = null;
-
- var parseSucceeded = true;
- char[] ArgumentSeperator = new char[] { ';' };
- char[] NameValueSeperator = new char[] { '=' };
+ // Creating default run settings if required.
+ var settings = runSettingsManager.ActiveRunSettings?.SettingsXml;
+ if (settings == null)
+ {
+ runSettingsManager.AddDefaultRunSettings();
+ settings = runSettingsManager.ActiveRunSettings?.SettingsXml;
+ }
- var argumentParts = argument.Split(ArgumentSeperator, StringSplitOptions.RemoveEmptyEntries);
+ var logger = default(LoggerSettings);
+ var loggerRunSettings = XmlRunSettingsUtilities.GetLoggerRunSettings(settings) ?? new LoggerRunSettings();
- if (argumentParts.Length > 0 && !argumentParts[0].Contains("="))
+ try
+ {
+ // Logger as uri in command line.
+ var loggerUri = new Uri(loggerIdentifier);
+ logger = new LoggerSettings
+ {
+ Uri = loggerUri,
+ IsEnabled = true
+ };
+ }
+ catch (UriFormatException)
{
- loggerIdentifier = argumentParts[0];
+ // Logger as friendlyName in command line.
+ logger = new LoggerSettings
+ {
+ FriendlyName = loggerIdentifier,
+ IsEnabled = true
+ };
+ }
- if (argumentParts.Length > 1)
+ // Converting logger console params to Configuration element
+ if (loggerParameters != null && loggerParameters.Count > 0)
+ {
+ var XmlDocument = new XmlDocument();
+ var outerNode = XmlDocument.CreateElement("Configuration");
+ foreach (KeyValuePair entry in loggerParameters)
{
- parameters = new Dictionary(StringComparer.OrdinalIgnoreCase);
- for (int index = 1; index < argumentParts.Length; ++index)
- {
- string[] nameValuePair = argumentParts[index].Split(NameValueSeperator, StringSplitOptions.RemoveEmptyEntries);
- if (nameValuePair.Length == 2)
- {
- parameters[nameValuePair[0]] = nameValuePair[1];
- }
- else
- {
- parseSucceeded = false;
- break;
- }
- }
+ var node = XmlDocument.CreateElement(entry.Key);
+ node.InnerText = entry.Value;
+ outerNode.AppendChild(node);
}
+
+ logger.Configuration = outerNode;
}
- else
+
+ // Remove existing logger.
+ var existingLoggerIndex = loggerRunSettings.GetExistingLoggerIndex(logger);
+ if (existingLoggerIndex >= 0)
{
- parseSucceeded = false;
+ loggerRunSettings.LoggerSettingsList.RemoveAt(existingLoggerIndex);
}
- return parseSucceeded;
+ loggerRunSettings.LoggerSettingsList.Add(logger);
+
+ runSettingsManager.UpdateRunSettingsNodeInnerXml(Constants.LoggerRunSettingsName, loggerRunSettings.ToXml().InnerXml);
}
}
}
diff --git a/src/vstest.console/Resources/Resources.Designer.cs b/src/vstest.console/Resources/Resources.Designer.cs
index 72469be8e8..110b2fc908 100644
--- a/src/vstest.console/Resources/Resources.Designer.cs
+++ b/src/vstest.console/Resources/Resources.Designer.cs
@@ -246,17 +246,6 @@ public static string BlameIncorrectOption
}
}
- ///
- /// The blame option specified '{0}' is not a valid format. Please correct it and retry..
- ///
- public static string BlameInvalidFormat
- {
- get
- {
- return ResourceManager.GetString("BlameInvalidFormat", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to --BuildBasePath|/BuildBasePath:<BuildBasePath>
/// The directory containing the temporary outputs..
@@ -497,8 +486,12 @@ public static string EnableCodeCoverageArgumentProcessorHelp
///
/// Looks up a localized string similar to --Diag|/Diag:<Path to log file>
- /// Enable verbose logs for test platform.
- /// Logs are written to the provided file..
+ /// Enable logs for test platform.
+ /// Logs are written to the provided file.
+ ///
+ /// Change the trace level for logs as shown below
+ /// Example: /Diag:<Path to log file>;tracelevel=<Defaults to "verbose">
+ /// Allowed values for tracelevel: off, error, warning, info and verbose.
///
public static string EnableDiagUsage
{
@@ -767,6 +760,17 @@ public static string InvalidBatchSize
}
}
+ ///
+ /// Looks up a localized string similar to Blame argument '{0}' is not valid..
+ ///
+ internal static string InvalidBlameArgument
+ {
+ get
+ {
+ return ResourceManager.GetString("InvalidBlameArgument", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The given configuration is invalid..
///
@@ -778,6 +782,28 @@ public static string InvalidConfiguration
}
}
+ ///
+ /// Looks up a localized string similar to Diag argument '{0}' is not valid..
+ ///
+ internal static string InvalidDiagArgument
+ {
+ get
+ {
+ return ResourceManager.GetString("InvalidDiagArgument", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Diag file path '{0}' is not valid..
+ ///
+ internal static string InvalidDiagFilePath
+ {
+ get
+ {
+ return ResourceManager.GetString("InvalidDiagFilePath", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Argument {0} is not expected in the 'EnableCodeCoverage' command. Specify the command without the argument (Example: vstest.console.exe myTests.dll /EnableCodeCoverage) and try again..
///
@@ -811,6 +837,17 @@ public static string InvalidInIsolationCommand
}
}
+ ///
+ /// Looks up a localized string similar to Logger argument '{0}' is not valid..
+ ///
+ internal static string InvalidLoggerArgument
+ {
+ get
+ {
+ return ResourceManager.GetString("InvalidLoggerArgument", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Argument {0} is not expected in the 'Parallel' command. Specify the command without the argument (Example: vstest.console.exe myTests.dll /Parallel) and try again..
///
diff --git a/src/vstest.console/Resources/Resources.resx b/src/vstest.console/Resources/Resources.resx
index 4d1bd137df..056cbc3aed 100644
--- a/src/vstest.console/Resources/Resources.resx
+++ b/src/vstest.console/Resources/Resources.resx
@@ -230,8 +230,12 @@
--Diag|/Diag:<Path to log file>
- Enable verbose logs for test platform.
- Logs are written to the provided file.
+ Enable logs for test platform.
+ Logs are written to the provided file.
+
+ Change the trace level for logs as shown below
+ Example: /Diag:<Path to log file>;tracelevel=<Defaults to "verbose">
+ Allowed values for tracelevel: off, error, warning, info and verbose.
--logger|/logger:<Logger Uri/FriendlyName>
@@ -699,7 +703,16 @@
The blame parameter specified with blame, {0} is invalid. Ignoring this parameter.
-
- The blame option specified '{0}' is not a valid format. Please correct it and retry.
+
+ Diag file path '{0}' is not valid.
+
+
+ Blame argument '{0}' is not valid.
+
+
+ Diag argument '{0}' is not valid.
+
+
+ Logger argument '{0}' is not valid.
\ No newline at end of file
diff --git a/src/vstest.console/Resources/xlf/Resources.cs.xlf b/src/vstest.console/Resources/xlf/Resources.cs.xlf
index 32bdf20b24..e2ad288d94 100644
--- a/src/vstest.console/Resources/xlf/Resources.cs.xlf
+++ b/src/vstest.console/Resources/xlf/Resources.cs.xlf
@@ -1387,12 +1387,16 @@
--Diag|/Diag:<Path to log file>
- Enable verbose logs for test platform.
- Logs are written to the provided file.
- --Diag|/Diag:<Cesta k souboru protokolu>
+ Enable logs for test platform.
+ Logs are written to the provided file.
+
+ Change the trace level for logs as shown below
+ Example: /Diag:<Path to log file>;tracelevel=<Defaults to "verbose">
+ Allowed values for tracelevel: off, error, warning, info and verbose.
+ --Diag|/Diag:<Cesta k souboru protokolu>
Povolí podrobné protokoly pro testovací platformu.
Protokoly se zapisují do zadaného souboru.
-
+
-Diag | / Diag: < cesta k souboru protokolu >
Povolení podrobného protokolování pro testovací platformu.
@@ -1589,16 +1593,31 @@
Možnost CollectDump pro Blame není pro tuto platformu podporovaná.
-
- The blame option specified '{0}' is not a valid format. Please correct it and retry.
- The blame option specified '{0}' is not valid. This will be ignored.
-
-
The blame parameter specified with blame, {0} is invalid. Ignoring this parameter.
The option specified with blame, {0} is invalid. This will be ignored.
+
+ Diag file path '{0}' is not valid.
+ Diag file path '{0}' is not valid.
+
+
+
+ Blame argument '{0}' is not valid.
+ Blame argument '{0}' in invalid.
+
+
+
+ Diag argument '{0}' is not valid.
+ Diag argument '{0}' is invalid.
+
+
+
+ Logger argument '{0}' is not valid.
+ Logger argument '{0}' is invalid.
+
+