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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.de.xlf b/src/vstest.console/Resources/xlf/Resources.de.xlf index a5422091cc..c9e4788bb3 100644 --- a/src/vstest.console/Resources/xlf/Resources.de.xlf +++ b/src/vstest.console/Resources/xlf/Resources.de.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:<Pfad zur Protokolldatei> + 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:<Pfad zur Protokolldatei> Aktiviert ausführliche Protokolle für die Testplattform. Protokolle werden in die angegebene Datei geschrieben. - + -Diag | / Diag: < Pfad zur Protokolldatei > Aktivieren Sie ausführliche Protokolle Testplattform. @@ -1589,16 +1593,31 @@ Die CollectDump-Option für Blame wird für diese Plattform nicht unterstützt. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.es.xlf b/src/vstest.console/Resources/xlf/Resources.es.xlf index 1c54f9f1df..ae9a42fe2e 100644 --- a/src/vstest.console/Resources/xlf/Resources.es.xlf +++ b/src/vstest.console/Resources/xlf/Resources.es.xlf @@ -1392,12 +1392,16 @@ --Diag|/Diag:<Path to log file> - Enable verbose logs for test platform. - Logs are written to the provided file. - --Diag|/Diag:<RutaDelArchivoDeRegistro> + 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:<RutaDelArchivoDeRegistro> Habilita registros detallados para la plataforma de pruebas. Los registros se escriben en el archivo proporcionado. - + --Diag | / Diag: < ruta de acceso al archivo de registro > Habilitar registros detallados de la plataforma de pruebas. @@ -1594,16 +1598,31 @@ No se admite la opción CollectDump para Blame en esta plataforma. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.fr.xlf b/src/vstest.console/Resources/xlf/Resources.fr.xlf index 3fd78458eb..bbfbfe9a51 100644 --- a/src/vstest.console/Resources/xlf/Resources.fr.xlf +++ b/src/vstest.console/Resources/xlf/Resources.fr.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:<chemin du fichier journal> + 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:<chemin du fichier journal> Permet d'activer les journaux détaillés pour la plateforme de test. Les journaux sont écrits dans le fichier fourni. - + --Diag | / Diag : < chemin d’accès au fichier journal > Activer les fichiers journaux détaillés pour la plate-forme de test. @@ -1589,16 +1593,31 @@ L'option CollectDump pour Blame n'est pas prise en charge pour cette plateforme. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.it.xlf b/src/vstest.console/Resources/xlf/Resources.it.xlf index e9a327c784..8bd8b05cc4 100644 --- a/src/vstest.console/Resources/xlf/Resources.it.xlf +++ b/src/vstest.console/Resources/xlf/Resources.it.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:<Percorso dei file di log> + 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:<Percorso dei file di log> Abilita i log dettagliati per la piattaforma di test. I log vengono scritti nel file specificato. - + -Diag | / Diag: < percorso file registro > Attiva log dettagliato per la piattaforma di test. @@ -1589,16 +1593,31 @@ L'opzione CollectDump per Blame non è supportata per questa piattaforma. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ja.xlf b/src/vstest.console/Resources/xlf/Resources.ja.xlf index 02df7b95f9..202cb5a5db 100644 --- a/src/vstest.console/Resources/xlf/Resources.ja.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ja.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:<ログ ファイルのパス> + 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:<ログ ファイルのパス> テスト プラットフォームの詳細ログを有効にします。 ログは指定されたファイルに書き込まれます。 - + --Diag | または Diag: < ログ ファイルへのパス > テスト プラットフォームの詳細なログを有効にします。 @@ -1589,16 +1593,31 @@ このプラットフォームでは、Blame の CollectDump オプションはサポートされていません。 - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ko.xlf b/src/vstest.console/Resources/xlf/Resources.ko.xlf index f857f80db3..0635cb99d6 100644 --- a/src/vstest.console/Resources/xlf/Resources.ko.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ko.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:<로그 파일 경로> + 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:<로그 파일 경로> 테스트 플랫폼에 대해 자세한 정보 표시 로그를 사용하도록 설정합니다. 로그가 제공된 파일에 기록됩니다. - + -진단 | / 진단: < 로그 파일 경로 > 테스트 플랫폼에 대 한 자세한 정보 표시 로그를 활성화 합니다. @@ -1589,16 +1593,31 @@ Blame에 대한 CollectDump 옵션이 이 플랫폼에서 지원되지 않습니다. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.pl.xlf b/src/vstest.console/Resources/xlf/Resources.pl.xlf index 293e5991fd..c7ed345188 100644 --- a/src/vstest.console/Resources/xlf/Resources.pl.xlf +++ b/src/vstest.console/Resources/xlf/Resources.pl.xlf @@ -1386,12 +1386,16 @@ --Diag|/Diag:<Path to log file> - Enable verbose logs for test platform. - Logs are written to the provided file. - --Diag|/Diag:<ścieżka do pliku dziennika> + 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:<ścieżka do pliku dziennika> Włącza pełne dzienniki dla platformy testowej. Dzienniki są zapisywane do podanego pliku. - + --Diag | / Diag: < ścieżka do pliku dziennika > Włączyć pełne dzienniki dla platformy testowej. @@ -1587,16 +1591,31 @@ Opcja CollectDump dla narzędzia Blame nie jest obsługiwana na tej platformie. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf b/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf index fcbead77bb..88861206fd 100644 --- a/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf +++ b/src/vstest.console/Resources/xlf/Resources.pt-BR.xlf @@ -1386,12 +1386,16 @@ --Diag|/Diag:<Path to log file> - Enable verbose logs for test platform. - Logs are written to the provided file. - --Diag|/Diag:<Path to log 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. + --Diag|/Diag:<Path to log file> Habilitar logs detalhados para a plataforma de teste. Os logs são gravados no arquivo fornecido. - + -Diag | / Diag: < caminho para arquivo de log > Habilite logs verbosos para plataforma de teste. @@ -1587,16 +1591,31 @@ A opção CollectDump para Blame não é compatível com esta plataforma. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.ru.xlf b/src/vstest.console/Resources/xlf/Resources.ru.xlf index fa1cbe992c..05a7e43fd0 100644 --- a/src/vstest.console/Resources/xlf/Resources.ru.xlf +++ b/src/vstest.console/Resources/xlf/Resources.ru.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:<путь к файлу журнала> + 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:<путь к файлу журнала> Включение подробных журналов для платформы тестирования. Журналы записываются в указанный файл. - + --Diag | / Diag: < путь к файлу журнала > Включение подробных журналов для тестовой платформы. @@ -1589,16 +1593,31 @@ Параметр CollectDump для Blame не поддерживается на этой платформе. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.tr.xlf b/src/vstest.console/Resources/xlf/Resources.tr.xlf index 2c2bfa0cbb..e879af328d 100644 --- a/src/vstest.console/Resources/xlf/Resources.tr.xlf +++ b/src/vstest.console/Resources/xlf/Resources.tr.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:<Günlük dosyasının yolu> + 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:<Günlük dosyasının yolu> Test platformuna yönelik ayrıntılı günlükleri etkinleştirir. Günlükler belirtilen dosyaya yazılır. - + --Diag | / Diag: < günlük dosyası yolu > Test platformu için ayrıntılı günlüklerini etkinleştirir. @@ -1589,16 +1593,31 @@ Blame için CollectDump seçeneği bu platformda desteklenmez. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.xlf b/src/vstest.console/Resources/xlf/Resources.xlf index f831e0553e..9fa5b7c1c9 100644 --- a/src/vstest.console/Resources/xlf/Resources.xlf +++ b/src/vstest.console/Resources/xlf/Resources.xlf @@ -591,8 +591,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. @@ -785,16 +789,31 @@ CollectDump option for Blame is not supported for this platform. - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf b/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf index 923efbcf74..1dd12f337b 100644 --- a/src/vstest.console/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/vstest.console/Resources/xlf/Resources.zh-Hans.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:<Path to log 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. + --Diag|/Diag:<Path to log file> 为测试平台启用详细日志。 日志写入到所提供的文件。 - + -诊断 | / 诊断︰ < 日志文件路径 > 启用详细日志中的测试平台。 @@ -1589,16 +1593,31 @@ 此平台不支持用于追责的 CollectDump 选项。 - - 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. + + \ No newline at end of file diff --git a/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf b/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf index 8f5cc110b0..4158898d47 100644 --- a/src/vstest.console/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/vstest.console/Resources/xlf/Resources.zh-Hant.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:<記錄檔的路徑> + 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:<記錄檔的路徑> 啟用測試平台的詳細資訊記錄檔。 記錄會寫入提供的檔案中。 - + -诊断 | / 诊断︰ < 日志文件路径 > 启用详细日志中的测试平台。 @@ -1589,16 +1593,31 @@ 對此平台不支援 Blame 的 CollectDump 選項。 - - 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. + + \ No newline at end of file diff --git a/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Tracing/EqtTraceTests.cs b/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Tracing/EqtTraceTests.cs index 20a067f72c..1f867808ba 100644 --- a/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Tracing/EqtTraceTests.cs +++ b/test/Microsoft.TestPlatform.CoreUtilities.UnitTests/Tracing/EqtTraceTests.cs @@ -33,7 +33,7 @@ public static void Init(TestContext testContext) Console.WriteLine(ex.Message); } - EqtTrace.InitializeVerboseTrace(logFile); + EqtTrace.InitializeTrace(logFile, PlatformTraceLevel.Off); } [TestMethod] @@ -134,6 +134,22 @@ public void TraceShouldWriteInfo() Assert.IsTrue(ReadLogFile().Contains("Dummy Info Message"), "Expected Info message"); } + [TestMethod] + public void TraceShouldNotWriteVerboseIfTraceLevelIsInfo() + { +#if NET451 + EqtTrace.TraceLevel = TraceLevel.Info; +#else + EqtTrace.TraceLevel = PlatformTraceLevel.Info; +#endif + EqtTrace.Info("Dummy Info Message"); + EqtTrace.Verbose("Unexpected Dummy Verbose Message"); + + var logFileContent = ReadLogFile(); + Assert.IsFalse(logFileContent.Contains("Unexpected Dummy Verbose Message"), "Verbose message not expected"); + Assert.IsTrue(logFileContent.Contains("Dummy Info Message"), "Expected Info message"); + } + [TestMethod] public void TraceShouldNotWriteIfDoNotInitializationIsSetToTrue() { diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyOperationManagerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyOperationManagerTests.cs index a2211c3c9a..96bafc2b74 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyOperationManagerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/ProxyOperationManagerTests.cs @@ -85,7 +85,7 @@ public void SetupChannelShouldLaunchTestHost() public void SetupChannelShouldCreateTimestampedLogFileForHost() { this.mockRequestSender.Setup(rs => rs.InitializeCommunication()).Returns(123); - EqtTrace.InitializeVerboseTrace("log.txt"); + EqtTrace.InitializeTrace("log.txt", PlatformTraceLevel.Verbose); this.testOperationManager.SetupChannel(Enumerable.Empty()); @@ -119,6 +119,26 @@ public void SetupChannelShouldAddRunnerProcessIdForTestHost() It.Is(t => t.RunnerProcessId.Equals(Process.GetCurrentProcess().Id)))); } + [TestMethod] + public void SetupChannelShouldAddCorrectTraceLevelForTestHost() + { +#if NET451 + EqtTrace.TraceLevel = TraceLevel.Info; +#else + EqtTrace.TraceLevel = PlatformTraceLevel.Info; +#endif + + this.mockRequestSender.Setup(rs => rs.InitializeCommunication()).Returns(123); + this.testOperationManager.SetupChannel(Enumerable.Empty()); + + this.mockTestHostManager.Verify( + th => + th.GetTestHostProcessStartInfo( + It.IsAny>(), + null, + It.Is(t => t.TraceLevel == (int)PlatformTraceLevel.Info))); + } + [TestMethod] public void SetupChannelShouldSetupServerForCommunication() { diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/DataCollection/ProxyDataCollectionManagerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/DataCollection/ProxyDataCollectionManagerTests.cs index 2388b21be7..274ec42080 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/DataCollection/ProxyDataCollectionManagerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/DataCollection/ProxyDataCollectionManagerTests.cs @@ -118,22 +118,23 @@ public void InitializeShouldPassDiagArgumentsIfDiagIsEnabled() try { - EqtTrace.InitializeVerboseTrace("mylog.txt"); + EqtTrace.InitializeTrace("mylog.txt", PlatformTraceLevel.Info); this.mockDataCollectionRequestSender.Setup(x => x.WaitForRequestHandlerConnection(It.IsAny())).Returns(true); this.proxyDataCollectionManager.Initialize(); + var expectedTraceLevel = (int)PlatformTraceLevel.Info; this.mockDataCollectionLauncher.Verify( x => x.LaunchDataCollector( It.IsAny>(), - It.Is>(list => list.Contains("--diag"))), + It.Is>(list => list.Contains("--diag") && list.Contains("--tracelevel") && list.Contains(expectedTraceLevel.ToString()))), Times.Once); } finally { // Restoring to initial state for EqtTrace - EqtTrace.InitializeVerboseTrace(traceFileName); + EqtTrace.InitializeTrace(traceFileName, PlatformTraceLevel.Verbose); #if NET451 EqtTrace.TraceLevel = traceLevel; #else diff --git a/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Hosting/TestRunnerConnectionInfoExtensionsTests.cs b/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Hosting/TestRunnerConnectionInfoExtensionsTests.cs index 333b995bec..a2fa14f682 100644 --- a/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Hosting/TestRunnerConnectionInfoExtensionsTests.cs +++ b/test/Microsoft.TestPlatform.ObjectModel.UnitTests/Hosting/TestRunnerConnectionInfoExtensionsTests.cs @@ -52,7 +52,7 @@ public void ToCommandLineOptionsShouldIncludeParentProcessId() } [TestMethod] - public void ToCommandLineOptionsShouldIncludeDiagnosticsOptionIfEnabled() + public void ToCommandLineOptionsShouldNotIncludeDiagnosticsOptionIfNotEnabled() { var connectionInfo = default(TestRunnerConnectionInfo); @@ -62,13 +62,13 @@ public void ToCommandLineOptionsShouldIncludeDiagnosticsOptionIfEnabled() } [TestMethod] - public void ToCommandLineOptionsShouldNotIncludeDiagnosticsOptionIfNotEnabled() + public void ToCommandLineOptionsShouldIncludeDiagnosticsOptionIfEnabled() { - var connectionInfo = new TestRunnerConnectionInfo { LogFile = "log.txt" }; + var connectionInfo = new TestRunnerConnectionInfo { LogFile = "log.txt", TraceLevel = 3 }; var options = connectionInfo.ToCommandLineOptions(); - StringAssert.EndsWith(options, "--diag log.txt"); + StringAssert.EndsWith(options, "--diag log.txt --tracelevel 3"); } } #pragma warning restore SA1600 diff --git a/test/TranslationLayer.UnitTests/ConsoleParametersTests.cs b/test/TranslationLayer.UnitTests/ConsoleParametersTests.cs index 2772859644..a299d5c925 100644 --- a/test/TranslationLayer.UnitTests/ConsoleParametersTests.cs +++ b/test/TranslationLayer.UnitTests/ConsoleParametersTests.cs @@ -3,10 +3,12 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.UnitTests { + using System.Diagnostics; + using Microsoft.TestPlatform.VsTestConsole.TranslationLayer; + using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers; using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces; using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; [TestClass] @@ -26,5 +28,12 @@ public void LogFilePathShouldEnsureDoubleQuote() Assert.IsTrue(result.StartsWith("\"")); } + + [TestMethod] + public void TraceLevelShouldHaveVerboseAsDefaultValue() + { + var consoleParameters = new ConsoleParameters(new FileHelper()); + Assert.AreEqual(consoleParameters.TraceLevel, TraceLevel.Verbose); + } } } diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs index 5777957c99..1c7f158755 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleWrapperTests.cs @@ -5,7 +5,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer.UnitTests { using System; using System.Collections.Generic; - + using System.Diagnostics; using Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing.Interfaces; using Microsoft.VisualStudio.TestPlatform.ObjectModel; @@ -63,6 +63,7 @@ public void StartSessionShouldStartVsTestConsoleWithCorrectArguments() Assert.AreEqual(expectedParentProcessId, this.consoleParameters.ParentProcessId, "Parent process Id must be set"); Assert.AreEqual(inputPort, this.consoleParameters.PortNumber, "Port number must be set"); + Assert.AreEqual(TraceLevel.Verbose, this.consoleParameters.TraceLevel, "Default value of trace level should be verbose."); this.mockProcessManager.Verify(pm => pm.StartProcess(this.consoleParameters), Times.Once); } diff --git a/test/datacollector.UnitTests/DataCollectorMainTests.cs b/test/datacollector.UnitTests/DataCollectorMainTests.cs index 9a122778c5..9a6a0f5661 100644 --- a/test/datacollector.UnitTests/DataCollectorMainTests.cs +++ b/test/datacollector.UnitTests/DataCollectorMainTests.cs @@ -4,23 +4,22 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.DataCollector.UnitTests { using System; - using System.Globalization; + using System.Diagnostics; + using CommunicationUtilities.DataCollection.Interfaces; using CoreUtilities.Helpers; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; using PlatformAbstractions.Interfaces; using TestPlatform.DataCollector; - using CommunicationUtilitiesResources = Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Resources.Resources; - using CoreUtilitiesConstants = Microsoft.VisualStudio.TestPlatform.CoreUtilities.Constants; - [TestClass] public class DataCollectorMainTests { - private readonly string[] args = {"--port", "1025", "--parentprocessid", "100" }; + private readonly string[] args = {"--port", "1025", "--parentprocessid", "100", "--diag", "abc.txt", "--tracelevel", "3" }; + private readonly string[] argsWithEmptyDiagArg = { "--port", "1025", "--parentprocessid", "100", "--diag", "", "--tracelevel", "3" }; + private readonly string[] argsWithInvalidTraceLevel = { "--port", "1025", "--parentprocessid", "100", "--diag", "abc.txt", "--tracelevel", "5" }; private static readonly string TimoutErrorMessage = "datacollector process failed to connect to vstest.console process after 90 seconds. This may occur due to machine slowness, please set environment variable VSTEST_CONNECTION_TIMEOUT to increase timeout."; @@ -60,6 +59,54 @@ public void RunShouldTimeoutBasedDefaulValueIfEnvVariableNotSet() this.mockDataCollectionRequestHandler.Verify(rh => rh.WaitForRequestSenderConnection(EnvironmentHelper.DefaultConnectionTimeout * 1000)); } + [TestMethod] + public void RunShouldInitializeTraceWithTraceLevelOffIfDiagArgIsEmpty() + { + // Setting EqtTrace.TraceLevel to a value other than info. +#if NET451 + EqtTrace.TraceLevel = TraceLevel.Verbose; +#else + EqtTrace.TraceLevel = PlatformTraceLevel.Verbose; +#endif + // Action + this.dataCollectorMain.Run(argsWithEmptyDiagArg); // Passing tracelevel as info and diag file path is empty. + + // Verify + Assert.AreEqual(TraceLevel.Off, (TraceLevel)EqtTrace.TraceLevel); + } + + [TestMethod] + public void RunShouldInitializeTraceWithVerboseTraceLevelIfInvalidTraceLevelPassed() + { + // Setting EqtTrace.TraceLevel to a value other than info. +#if NET451 + EqtTrace.TraceLevel = TraceLevel.Info; +#else + EqtTrace.TraceLevel = PlatformTraceLevel.Info; +#endif + // Action + this.dataCollectorMain.Run(argsWithInvalidTraceLevel); + + // Verify + Assert.AreEqual(TraceLevel.Verbose, (TraceLevel)EqtTrace.TraceLevel); + } + + [TestMethod] + public void RunShouldInitializeTraceWithCorrectVerboseTraceLevel() + { + // Setting EqtTrace.TraceLevel to a value other than info. +#if NET451 + EqtTrace.TraceLevel = TraceLevel.Verbose; +#else + EqtTrace.TraceLevel = PlatformTraceLevel.Verbose; +#endif + // Action + this.dataCollectorMain.Run(args); // Trace level is set as info in args. + + // Verify + Assert.AreEqual(TraceLevel.Info, (TraceLevel)EqtTrace.TraceLevel); + } + [TestMethod] public void RunShouldThrowIfTimeoutOccured() { diff --git a/test/testhost.UnitTests/DefaultEngineInvokerTests.cs b/test/testhost.UnitTests/DefaultEngineInvokerTests.cs index 3f392d06b1..16ed30475f 100644 --- a/test/testhost.UnitTests/DefaultEngineInvokerTests.cs +++ b/test/testhost.UnitTests/DefaultEngineInvokerTests.cs @@ -5,6 +5,7 @@ namespace testhost.UnitTests { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Globalization; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers; @@ -28,7 +29,8 @@ public class DefaultEngineInvokerTests { "--endpoint", "127.0.0.1:021291" }, { "--role", "client"}, { "--parentprocessid", ParentProcessId.ToString() }, - { "--diag", @"C:\Users\samadala\src\vstest\log_3.host.18-04-17_20-25-45_48171_1.txt"}, + { "--diag", "temp.txt"}, + { "--tracelevel", "3"}, { "--telemetryoptedin", "false"}, { "--datacollectionport", "21290"} }; @@ -93,5 +95,44 @@ public void InvokeShouldSetParentProcessExistCallback() this.mockProcssHelper.Verify(h => h.SetExitCallback(ParentProcessId, It.IsAny>())); } + + [TestMethod] + public void InvokeShouldInitializeTraceWithCorrectTraceLevel() + { + // Setting EqtTrace.TraceLevel to a value other than info. +#if NET451 + EqtTrace.TraceLevel = TraceLevel.Verbose; +#else + EqtTrace.TraceLevel = PlatformTraceLevel.Verbose; +#endif + + this.engineInvoker.Invoke(argsDictionary); + + // Verify + Assert.AreEqual(TraceLevel.Info, (TraceLevel)EqtTrace.TraceLevel); + } + + [TestMethod] + public void InvokeShouldInitializeTraceWithVerboseTraceLevelIfInvalidTraceLevelPassed() + { + // Setting EqtTrace.TraceLevel to a value other than info. +#if NET451 + EqtTrace.TraceLevel = TraceLevel.Warning; +#else + EqtTrace.TraceLevel = PlatformTraceLevel.Warning; +#endif + + try + { + argsDictionary["--tracelevel"] = "5"; // int value which is not defined in TraceLevel. + this.engineInvoker.Invoke(argsDictionary); + } + finally{ + argsDictionary["--tracelevel"] = "3"; // Setting to default value of 3. + } + + // Verify + Assert.AreEqual(TraceLevel.Verbose, (TraceLevel)EqtTrace.TraceLevel); + } } } diff --git a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs index 66c12096cf..99904578d8 100644 --- a/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableBlameArgumentProcessorTests.cs @@ -159,7 +159,7 @@ public void InitializeShouldThrowIfInvalidParameterFormatIsSpecifiedForCollectDu .Returns(PlatformArchitecture.X64); this.executor.Initialize(invalidString); - this.mockOutput.Verify(x => x.WriteLine(string.Format(CultureInfo.CurrentUICulture, CommandLineResources.BlameInvalidFormat, invalidString), OutputLevel.Warning)); + this.mockOutput.Verify(x => x.WriteLine(string.Format(CultureInfo.CurrentUICulture, CommandLineResources.InvalidBlameArgument, invalidString), OutputLevel.Warning)); Assert.IsNotNull(this.settingsProvider.ActiveRunSettings); Assert.AreEqual("\r\n\r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n C:\\dir\\TestResults\r\n \r\n \r\n \r\n \r\n \r\n \r\n", this.settingsProvider.ActiveRunSettings.SettingsXml); diff --git a/test/vstest.console.UnitTests/Processors/EnableDiagArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableDiagArgumentProcessorTests.cs index d7a0748498..73c06e7d95 100644 --- a/test/vstest.console.UnitTests/Processors/EnableDiagArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableDiagArgumentProcessorTests.cs @@ -3,7 +3,9 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.UnitTests.Processors { + using System; using System.Diagnostics; + using System.Globalization; using System.IO; using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors; @@ -48,7 +50,7 @@ public EnableDiagArgumentProcessorTests() public void Cleanup() { // Restoring to initial state for EqtTrace - EqtTrace.InitializeVerboseTrace(traceFileName); + EqtTrace.InitializeTrace(traceFileName, PlatformTraceLevel.Verbose); #if NET451 EqtTrace.TraceLevel = traceLevel; #else @@ -71,10 +73,13 @@ public void EnableDiagArgumentProcessorMetadataShouldProvideAppropriateCapabilit } [TestMethod] - public void EnableDiagArgumentProcessorExecutorThrowsIfFileNameIsNullOrEmpty() + [DataRow(null)] + [DataRow(" ")] + [DataRow("")] + public void EnableDiagArgumentProcessorExecutorThrowsIfDiagArgumentIsNullOrEmpty(string argument) { - Assert.ThrowsException(() => this.diagProcessor.Executor.Value.Initialize(null)); - Assert.ThrowsException(() => this.diagProcessor.Executor.Value.Initialize(string.Empty)); + string exceptionMessage = string.Format(CultureInfo.CurrentUICulture, CommandLineResources.InvalidDiagArgument, argument); + EnableDiagArgumentProcessorExecutorShouldThrowIfInvalidArgument(argument, exceptionMessage); } [TestMethod] @@ -86,9 +91,62 @@ public void EnableDiagArgumentProcessorExecutorDoesNotThrowsIfFileDotOpenThrow() } [TestMethod] - public void EnableDiagArgumentProcessorExecutorShouldThrowIfAPathIsProvided() + [DataRow("abs;dfsdc.txt;verbosity=normal", "abs")] // ; in file path is not supported + [DataRow("\"abst;dfsdc.txt\";verbosity=normal", "abst")] // Even though in escaped double quotes, semi colon is not supported in file path + [DataRow("foo", "foo")] + public void EnableDiagArgumentProcessorExecutorShouldThrowIfDirectoryPathIsProvided(string argument, string filePath) { - Assert.ThrowsException(() => this.diagProcessor.Executor.Value.Initialize("foo")); + var exceptionMessage = string.Format(CultureInfo.CurrentCulture, CommandLineResources.InvalidDiagFilePath, filePath); + + EnableDiagArgumentProcessorExecutorShouldThrowIfInvalidArgument(argument, exceptionMessage); + } + + [TestMethod] + [DataRow("abc.txt;verbosity=normal=verbose")] // Multiple '=' in parameter + [DataRow("abc.txt;verbosity;key1=value1")] // No '=' in parameter + public void EnableDiagArgumentProcessorExecutorShouldThrowIfInvalidArgument(string argument) + { + string exceptionMessage = string.Format(CultureInfo.CurrentCulture, CommandLineResources.InvalidDiagArgument, argument); + EnableDiagArgumentProcessorExecutorShouldThrowIfInvalidArgument(argument, exceptionMessage); + } + + [TestMethod] + [DataRow("abc.txt")] + [DataRow("abc.txt;verbosity=normal")] + [DataRow("abc.txt;tracelevel=info;newkey=newvalue")] + [DataRow("\"abc.txt\";verbosity=normal;newkey=newvalue")] //escaped double quotes are allowed for file path. + [DataRow(";;abc.txt;;;;verbosity=normal;;;;")] + public void EnableDiagArgumentProcessorExecutorShouldNotThrowIfValidArgument(string argument) + { + try + { + this.diagProcessor.Executor.Value.Initialize(argument); + } + catch (Exception ex) + { + Assert.Fail("Expected no exception, but got: " + ex.Message); + } + } + + [TestMethod] + [DataRow("abc.txt;tracelevel=info;newkey=newvalue")] + [DataRow("abc.txt;tracelevel=info;")] + [DataRow("abc.txt;tracelevel=INfO")] + [DataRow("abc.txt;traCELevel=info")] + [DataRow("abc.txt;traCELevel=INfO")] + public void EnableDiagArgumentProcessorExecutorShouldInitializeTraceWithCorrectTraceLevel(string argument) + { + // Setting any trace level other than info. +#if NET451 + EqtTrace.TraceLevel = TraceLevel.Verbose; +#else + EqtTrace.TraceLevel = PlatformTraceLevel.Verbose; +#endif + + this.diagProcessor.Executor.Value.Initialize(argument); + + Assert.AreEqual(TraceLevel.Info, (TraceLevel)EqtTrace.TraceLevel); + Assert.IsTrue(EqtTrace.LogFile.Contains("abc.txt")); } [TestMethod] @@ -131,5 +189,18 @@ public TestableEnableDiagArgumentProcessor(IFileHelper fileHelper) { } } + + private void EnableDiagArgumentProcessorExecutorShouldThrowIfInvalidArgument(string argument, string exceptionMessage) + { + try + { + this.diagProcessor.Executor.Value.Initialize(argument); + } + catch (Exception e) + { + Assert.IsTrue(e.GetType().Equals(typeof(CommandLineException))); + Assert.IsTrue(e.Message.Contains(exceptionMessage)); + } + } } } \ No newline at end of file diff --git a/test/vstest.console.UnitTests/Processors/EnableLoggersArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/EnableLoggersArgumentProcessorTests.cs index 7d3b980856..ef0d759097 100644 --- a/test/vstest.console.UnitTests/Processors/EnableLoggersArgumentProcessorTests.cs +++ b/test/vstest.console.UnitTests/Processors/EnableLoggersArgumentProcessorTests.cs @@ -3,15 +3,14 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.UnitTests.Processors { + using System; + using System.Globalization; + using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors; - using Microsoft.VisualStudio.TestPlatform.Common.Logging; + using Microsoft.VisualStudio.TestPlatform.Common; using Microsoft.VisualStudio.TestTools.UnitTesting; - using vstest.console.UnitTests.TestDoubles; - using System.Linq; - using Microsoft.VisualStudio.TestPlatform.Common; - using Moq; - using System; + using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources; [TestClass] public class EnableLoggersArgumentProcessorTests @@ -57,23 +56,22 @@ public void CapabilitiesShouldAppropriateProperties() } [TestMethod] - public void ExecutorInitializeWithNullOrEmptyArgumentsShouldThrowException() + [DataRow(" ")] + [DataRow(null)] + [DataRow("TestLoggerExtension;==;;;Collection=http://localhost:8080/tfs/DefaultCollection;TeamProject=MyProject;BuildName=DailyBuild_20121130.1")] + public void ExectorInitializeShouldThrowExceptionIfInvalidArgumentIsPassed(string argument) { var executor = new EnableLoggerArgumentExecutor(RunSettingsManager.Instance); - Assert.ThrowsException(() => + try { - executor.Initialize(null); - }); - } - - [TestMethod] - public void ExectorInitializeShouldThrowExceptionIfInvalidArgumentIsPassed() - { - var executor = new EnableLoggerArgumentExecutor(RunSettingsManager.Instance); - Assert.ThrowsException(() => + executor.Initialize(argument); + } + catch (Exception e) { - executor.Initialize("TestLoggerExtension;==;;;Collection=http://localhost:8080/tfs/DefaultCollection;TeamProject=MyProject;BuildName=DailyBuild_20121130.1"); - }); + string exceptionMessage = string.Format(CultureInfo.CurrentUICulture, CommandLineResources.LoggerUriInvalid, argument); + Assert.IsTrue(e.GetType().Equals(typeof(CommandLineException))); + Assert.IsTrue(e.Message.Contains(exceptionMessage)); + } } [TestMethod] diff --git a/test/vstest.console.UnitTests/Processors/Utilities/ArgumentProcessorUtilitiesTests.cs b/test/vstest.console.UnitTests/Processors/Utilities/ArgumentProcessorUtilitiesTests.cs new file mode 100644 index 0000000000..c966df482d --- /dev/null +++ b/test/vstest.console.UnitTests/Processors/Utilities/ArgumentProcessorUtilitiesTests.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.UnitTests.Processors.Utilities +{ + using Microsoft.VisualStudio.TestPlatform.CommandLine.Processors.Utilities; + using System; + using System.Collections.Generic; + using System.Linq; + using TestTools.UnitTesting; + + [TestClass] + public class ArgumentProcessorUtilitiesTests + { + [TestMethod] + [DataRow("")] + [DataRow(" ")] + [DataRow(";;;;")] + public void GetArgumentListShouldThrowErrorOnInvalidArgument(string argument) + { + try + { + ArgumentProcessorUtilities.GetArgumentList(argument, ArgumentProcessorUtilities.SemiColonArgumentSeparator, "test exception."); + } + catch (Exception e) + { + Assert.IsTrue(e.GetType().Equals(typeof(CommandLineException))); + Assert.IsTrue(e.Message.Contains("test exception.")); + } + } + + [TestMethod] + [DataRow("abc.txt;tracelevel=info;newkey=newvalue")] + [DataRow(";;;abc.txt;;;tracelevel=info;;;newkey=newvalue;;;;")] + public void GetArgumentListShouldReturnCorrectArgumentList(string argument) + { + var argumentList = ArgumentProcessorUtilities.GetArgumentList(argument, ArgumentProcessorUtilities.SemiColonArgumentSeparator, "test exception."); + argumentList.SequenceEqual(new string[] { "abc.txt", "tracelevel=info", "newkey=newvalue" }); + } + + [TestMethod] + [DataRow(new string[] { "key1=value1", "invalidPair", "key2=value2"})] + public void GetArgumentParametersShouldThrowErrorOnInvalidParameters(string[] parameterArgs) + { + try + { + ArgumentProcessorUtilities.GetArgumentParameters(parameterArgs, ArgumentProcessorUtilities.EqualNameValueSeparator, "test exception."); + } + catch (Exception e) + { + Assert.IsTrue(e.GetType().Equals(typeof(CommandLineException))); + Assert.IsTrue(e.Message.Contains("test exception.")); + } + } + + [TestMethod] + public void GetArgumentParametersShouldReturnCorrectParameterDictionary() + { + var parameterDict = ArgumentProcessorUtilities.GetArgumentParameters(new string[] { "key1=value1", "key2=value2", "key3=value3" }, ArgumentProcessorUtilities.EqualNameValueSeparator, "test exception."); + + var expectedDict = new Dictionary { { "key1", "value1"}, { "key2", "value2"}, { "key3", "value3"} }; + CollectionAssert.AreEqual(parameterDict.OrderBy(kv => kv.Key).ToList(), expectedDict.OrderBy(kv => kv.Key).ToList()); + } + } +} \ No newline at end of file