Skip to content

Commit

Permalink
Added a command-line argument to vstest.console.exe for setting envir…
Browse files Browse the repository at this point in the history
…onment variables (#2528)

* --Environment argument implementation for vstest.console.exe

* Rebuilt resources.

* Tests added.

* Refactored tests and added copyright header.

* PR suggestions fixed.
  • Loading branch information
Haplois authored Aug 20, 2020
1 parent 193ed30 commit b661b07
Show file tree
Hide file tree
Showing 22 changed files with 688 additions and 3 deletions.
145 changes: 145 additions & 0 deletions src/vstest.console/Processors/EnvironmentArgumentProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// 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
{
using System;
using System.Diagnostics.Contracts;
using Microsoft.VisualStudio.TestPlatform.Common;
using Microsoft.VisualStudio.TestPlatform.Common.Interfaces;
using Microsoft.VisualStudio.TestPlatform.Common.Utilities;
using Microsoft.VisualStudio.TestPlatform.Utilities;
using CommandLineResources = Microsoft.VisualStudio.TestPlatform.CommandLine.Resources.Resources;

/// <summary>
/// Argument Executor for the "-e|--Environment|/e|/Environment" command line argument.
/// </summary>
internal class EnvironmentArgumentProcessor : IArgumentProcessor
{
#region Constants
/// <summary>
/// The short name of the command line argument that the EnvironmentArgumentProcessor handles.
/// </summary>
public const string ShortCommandName = "/e";

/// <summary>
/// The name of the command line argument that the EnvironmentArgumentProcessor handles.
/// </summary>
public const string CommandName = "/Environment";
#endregion

private Lazy<IArgumentProcessorCapabilities> metadata;

private Lazy<IArgumentExecutor> executor;

public Lazy<IArgumentExecutor> Executor
{
get
{
if (this.executor == null)
{
this.executor = new Lazy<IArgumentExecutor>(
() => new ArgumentExecutor(CommandLineOptions.Instance, RunSettingsManager.Instance, ConsoleOutput.Instance)
);
}

return this.executor;
}
set
{
this.executor = value;
}
}

public Lazy<IArgumentProcessorCapabilities> Metadata
{
get
{
if (this.metadata == null)
{
this.metadata = new Lazy<IArgumentProcessorCapabilities>(() => new ArgumentProcessorCapabilities());
}

return this.metadata;
}
}

internal class ArgumentProcessorCapabilities : BaseArgumentProcessorCapabilities
{
public override string CommandName => EnvironmentArgumentProcessor.CommandName;
public override string ShortCommandName => EnvironmentArgumentProcessor.ShortCommandName;
public override bool AllowMultiple => true;
public override bool IsAction => false;
public override string HelpContentResourceName => CommandLineResources.EnvironmentArgumentHelp;
public override ArgumentProcessorPriority Priority => ArgumentProcessorPriority.Normal;
public override HelpContentPriority HelpPriority => HelpContentPriority.EnvironmentArgumentProcessorHelpPriority;
}

internal class ArgumentExecutor : IArgumentExecutor
{
#region Fields
/// <summary>
/// Used when warning about overriden environment variables.
/// </summary>
private IOutput output;

/// <summary>
/// Used when setting Environemnt variables.
/// </summary>
private IRunSettingsProvider runSettingsProvider;

/// <summary>
/// Used when checking and forcing InIsolation mode.
/// </summary>
private CommandLineOptions commandLineOptions;
#endregion

public ArgumentExecutor(CommandLineOptions commandLineOptions, IRunSettingsProvider runSettingsProvider, IOutput output)
{
this.commandLineOptions = commandLineOptions;
this.output = output;
this.runSettingsProvider = runSettingsProvider;
}

/// <summary>
/// Set the environment variables in RunSettings.xml
/// </summary>
/// <param name="argument">
/// Environment variable to set.
/// </param>
public void Initialize(string argument)
{
Contract.Assert(!string.IsNullOrWhiteSpace(argument));
Contract.Assert(this.output != null);
Contract.Assert(this.commandLineOptions != null);
Contract.Assert(!string.IsNullOrWhiteSpace(this.runSettingsProvider.ActiveRunSettings.SettingsXml));
Contract.EndContractBlock();

var key = argument;
var value = string.Empty;

if(key.Contains("="))
{
value = key.Substring(key.IndexOf("=") + 1);
key = key.Substring(0, key.IndexOf("="));
}

var node = this.runSettingsProvider.QueryRunSettingsNode($"RunConfiguration.EnvironmentVariables.{key}");
if(node != null)
{
output.Warning(true, CommandLineResources.EnvironmentVariableXIsOverriden, key);
}

this.runSettingsProvider.UpdateRunSettingsNode($"RunConfiguration.EnvironmentVariables.{key}", value);

if(!this.commandLineOptions.InIsolation) {
this.commandLineOptions.InIsolation = true;
this.runSettingsProvider.UpdateRunSettingsNode(InIsolationArgumentExecutor.RunSettingsPath, "true");
}
}

// Nothing to do here, the work was done in initialization.
public ArgumentProcessorResult Execute() => ArgumentProcessorResult.Success;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ public IEnumerable<IArgumentProcessor> GetArgumentProcessorsToAlwaysExecute()
new ListLoggersArgumentProcessor(),
new ListSettingsProvidersArgumentProcessor(),
new ListFullyQualifiedTestsArgumentProcessor(),
new ListTestsTargetPathArgumentProcessor()
new ListTestsTargetPathArgumentProcessor(),
new EnvironmentArgumentProcessor()
};

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ internal enum HelpContentPriority
/// </summary>
PlatformArgumentProcessorHelpPriority,


/// <summary>
/// EnvironmentArgumentProcessor Help
/// </summary>
EnvironmentArgumentProcessorHelpPriority,

/// <summary>
/// RunSettingsArgumentProcessor Help
/// </summary>
Expand Down
27 changes: 26 additions & 1 deletion src/vstest.console/Resources/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions src/vstest.console/Resources/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -750,4 +750,17 @@
<data name="BlameCollectDumpTestTimeoutNotSupportedForPlatform" xml:space="preserve">
<value>Collecting hang dumps by option CollectDump with TestTimeout for Blame is not supported for this platform.</value>
</data>
<data name="EnvironmentArgumentHelp" xml:space="preserve">
<value>-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if it does not exist, overrides if it does. This will imply /InIsolation switch and force the tests to be run in an isolated process.

This argument can be specified multiple times to provide multiple variables.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semicolons"</value>
</data>
<data name="EnvironmentVariableXIsOverriden" xml:space="preserve">
<value>Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</value>
</data>
</root>
22 changes: 22 additions & 0 deletions src/vstest.console/Resources/xlf/Resources.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,28 @@
<target state="new">- {0} {1}</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentArgumentHelp">
<source>-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if it does not exist, overrides if it does. This will imply /InIsolation switch and force the tests to be run in an isolated process.

This argument can be specified multiple times to provide multiple variables.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semicolons"</source>
<target state="new">-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if one with the requested name does not exist.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semi-columns"</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentVariableXIsOverriden">
<source>Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</source>
<target state="new">Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>
22 changes: 22 additions & 0 deletions src/vstest.console/Resources/xlf/Resources.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,28 @@
<target state="new">- {0} {1}</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentArgumentHelp">
<source>-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if it does not exist, overrides if it does. This will imply /InIsolation switch and force the tests to be run in an isolated process.

This argument can be specified multiple times to provide multiple variables.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semicolons"</source>
<target state="new">-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if one with the requested name does not exist.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semi-columns"</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentVariableXIsOverriden">
<source>Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</source>
<target state="new">Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>
22 changes: 22 additions & 0 deletions src/vstest.console/Resources/xlf/Resources.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1686,6 +1686,28 @@
<target state="new">- {0} {1}</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentArgumentHelp">
<source>-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if it does not exist, overrides if it does. This will imply /InIsolation switch and force the tests to be run in an isolated process.

This argument can be specified multiple times to provide multiple variables.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semicolons"</source>
<target state="new">-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if one with the requested name does not exist.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semi-columns"</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentVariableXIsOverriden">
<source>Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</source>
<target state="new">Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>
22 changes: 22 additions & 0 deletions src/vstest.console/Resources/xlf/Resources.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,28 @@
<target state="new">- {0} {1}</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentArgumentHelp">
<source>-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if it does not exist, overrides if it does. This will imply /InIsolation switch and force the tests to be run in an isolated process.

This argument can be specified multiple times to provide multiple variables.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semicolons"</source>
<target state="new">-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if one with the requested name does not exist.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semi-columns"</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentVariableXIsOverriden">
<source>Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</source>
<target state="new">Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>
22 changes: 22 additions & 0 deletions src/vstest.console/Resources/xlf/Resources.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,28 @@
<target state="new">- {0} {1}</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentArgumentHelp">
<source>-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if it does not exist, overrides if it does. This will imply /InIsolation switch and force the tests to be run in an isolated process.

This argument can be specified multiple times to provide multiple variables.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semicolons"</source>
<target state="new">-e|--Environment|/e|/Environment:&lt;NAME&gt;=&lt;VALUE&gt;
Sets the value of an environment variable. Creates the variable if one with the requested name does not exist.

Example: -e:VARIABLE1=VALUE1
-e:ANOTHER_VARIABLE="VALUE WITH SPACES"
-e:ANOTHER_VARIABLE="VALUE;seperated with;semi-columns"</target>
<note></note>
</trans-unit>
<trans-unit id="EnvironmentVariableXIsOverriden">
<source>Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</source>
<target state="new">Environment variable '{0}' was already defined, but it's overridden by -Environment argument.</target>
<note></note>
</trans-unit>
</body>
</file>
</xliff>
Loading

0 comments on commit b661b07

Please sign in to comment.