Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverts change that breaks DOTNET_ROOT #3844

Merged
merged 1 commit into from
Jul 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ public class DotnetTestHostManager : ITestRuntimeProvider2
private const string TestAdapterRegexPattern = @"TestAdapter.dll";
private const string PROCESSOR_ARCHITECTURE = nameof(PROCESSOR_ARCHITECTURE);

private static readonly Version Version6_0 = new(6, 0);

private readonly IDotnetHostHelper _dotnetHostHelper;
private readonly IEnvironment _platformEnvironment;
private readonly IProcessHelper _processHelper;
Expand Down Expand Up @@ -471,7 +469,24 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo(
// i.e. I've got only private install and no global installation, in this case apphost needs to use env var to locate runtime.
if (testHostExeFound)
{
ForwardDotnetRootEnvironmentVariable(startInfo);
string prefix = "VSTEST_WINAPPHOST_";
string dotnetRootEnvName = $"{prefix}DOTNET_ROOT(x86)";
var dotnetRoot = _environmentVariableHelper.GetEnvironmentVariable(dotnetRootEnvName);
if (dotnetRoot is null)
{
dotnetRootEnvName = $"{prefix}DOTNET_ROOT";
dotnetRoot = _environmentVariableHelper.GetEnvironmentVariable(dotnetRootEnvName);
}

if (dotnetRoot != null)
{
EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Found '{dotnetRootEnvName}' in env variables, value '{dotnetRoot}', forwarding to '{dotnetRootEnvName.Replace(prefix, string.Empty)}'");
startInfo.EnvironmentVariables.Add(dotnetRootEnvName.Replace(prefix, string.Empty), dotnetRoot);
}
else
{
EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Prefix '{prefix}*' not found in env variables");
}
}

startInfo.WorkingDirectory = sourceDirectory;
Expand Down Expand Up @@ -568,54 +583,6 @@ bool IsNativeModule(string modulePath)
}
}

internal /* for testing purposes */ void ForwardDotnetRootEnvironmentVariable(TestProcessStartInfo startInfo)
{
TPDebug.Assert(_targetFramework is not null, "Initialize must have been called before this method.");
const string prefix = "VSTEST_WINAPPHOST_";
const string dotnetRoot = "DOTNET_ROOT";
string vstestDotnetRootEnvName = $"{prefix}{dotnetRoot}(x86)";

// Check if VSTEST_WINAPPHOST_DOTNET_ROOT(x86) is set, if not then looks for VSTEST_WINAPPHOST_DOTNET_ROOT.
// If none of these variables is set we exit as we have nothing to forward.
var vstestDotnetRootEnvValue = _environmentVariableHelper.GetEnvironmentVariable(vstestDotnetRootEnvName);
if (vstestDotnetRootEnvValue is null)
{
vstestDotnetRootEnvName = $"{prefix}{dotnetRoot}";
vstestDotnetRootEnvValue = _environmentVariableHelper.GetEnvironmentVariable(vstestDotnetRootEnvName);

// None of the forwarding environment variables are set so exit.
if (vstestDotnetRootEnvValue is null)
{
EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Prefix '{prefix}*' not found in env variables");
return;
}
}

// For .NET 6.0 onward, the DOTNET_ROOT* environment variable to set was changed.
// This implementation is based on the logic defined in SDK:
// https://github.com/dotnet/sdk/blob/c3f8d746f4d5cd87f462d711a3caa7a4f6621826/src/Cli/dotnet/commands/dotnet-run/RunCommand.cs#L264-L279
string dotnetRootEnvName;
if (Version.Parse(_targetFramework.Version) >= Version6_0)
{
dotnetRootEnvName = $"{dotnetRoot}_{_processHelper.GetCurrentProcessArchitecture().ToString().ToUpperInvariant()}";

// SDK side of TP is not checking for the .NET6.0+ environment variables so we want to make sure we
// are not overriding user definition.
if (_environmentVariableHelper.GetEnvironmentVariable(dotnetRootEnvName) is string dotnetRootEnvValue)
{
EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Found '{vstestDotnetRootEnvName}' in env variables but also found '{dotnetRootEnvName}' with value '{dotnetRootEnvValue}'. Skipping forwarding.");
return;
}
}
else
{
dotnetRootEnvName = vstestDotnetRootEnvName.Replace(prefix, string.Empty);
}

EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Found '{vstestDotnetRootEnvName}' in env variables, value '{vstestDotnetRootEnvValue}', forwarding to '{dotnetRootEnvName}' (target framework is {_targetFramework.Name}, Version={_targetFramework.Version}).");
startInfo.EnvironmentVariables!.Add(dotnetRootEnvName, vstestDotnetRootEnvValue);
}

/// <inheritdoc/>
public IEnumerable<string> GetTestPlatformExtensions(IEnumerable<string> sources, IEnumerable<string> extensions)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1025,143 +1025,6 @@ public async Task CleanTestHostAsyncShouldNotThrowIfTestHostIsNotStarted()
Assert.IsTrue(isVerified);
}

[TestMethod]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT(x86)", "DOTNET_ROOT(x86)")]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT", "DOTNET_ROOT")]
public void ForwardDotnetRootEnvironmentVariableWhenTargetFrameworkIsLessThanNet6SetsCorrectEnvVariable(string envVarName, string expectedForwaredName)
{
// Arrange
const string envVarValue = "c:\\SomePath";
_mockEnvironmentVariable.Reset();
_mockEnvironmentVariable.Setup(x => x.GetEnvironmentVariable(envVarName)).Returns(envVarValue);
string runSettingsXml = """
<RunSettings>
<RunConfiguration>
<TargetFrameworkVersion>net5.0</TargetFrameworkVersion>
</RunConfiguration>
</RunSettings>
""";
_dotnetHostManager.Initialize(_mockMessageLogger.Object, runSettingsXml);

var startInfo = new TestProcessStartInfo { EnvironmentVariables = new Dictionary<string, string?>() };
// Sanity check
Assert.AreEqual(0, startInfo.EnvironmentVariables.Count);

// Act
_dotnetHostManager.ForwardDotnetRootEnvironmentVariable(startInfo);

// Assert
Assert.AreEqual(1, startInfo.EnvironmentVariables.Count);
Assert.IsTrue(startInfo.EnvironmentVariables.TryGetValue(expectedForwaredName, out var actualEnvVarValue));
Assert.AreEqual(envVarValue, actualEnvVarValue);
}

[TestMethod]
[DataRow("DOTNET_ROOT(x86)", "net5.0")]
[DataRow("DOTNET_ROOT(x86)", "net6.0")]
[DataRow("DOTNET_ROOT", "net5.0")]
[DataRow("DOTNET_ROOT", "net6.0")]
[DataRow("DOTNET_ROOT_X86", "net5.0")]
[DataRow("DOTNET_ROOT_X86", "net6.0")]
[DataRow("DOTNET_ROOT_X64", "net5.0")]
[DataRow("DOTNET_ROOT_X64", "net6.0")]
[DataRow("DOTNET_ROOT_ARM64", "net5.0")]
[DataRow("DOTNET_ROOT_ARM64", "net6.0")]
public void ForwardDotnetRootEnvironmentVariableWhenIncorrectEnvVarDoesNothing(string envVarName, string framework)
{
// Arrange
const string envVarValue = "c:\\SomePath";
_mockEnvironmentVariable.Reset();
_mockEnvironmentVariable.Setup(x => x.GetEnvironmentVariable(envVarName)).Returns(envVarValue);
string runSettingsXml = $"""
<RunSettings>
<RunConfiguration>
<TargetFrameworkVersion>{framework}</TargetFrameworkVersion>
</RunConfiguration>
</RunSettings>
""";
_dotnetHostManager.Initialize(_mockMessageLogger.Object, runSettingsXml);

var startInfo = new TestProcessStartInfo { EnvironmentVariables = new Dictionary<string, string?>() };

// Act
_dotnetHostManager.ForwardDotnetRootEnvironmentVariable(startInfo);

// Assert
Assert.AreEqual(0, startInfo.EnvironmentVariables.Count);
}

[TestMethod]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT(x86)", PlatformArchitecture.X86)]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT(x86)", PlatformArchitecture.X64)]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT", PlatformArchitecture.X86)]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT", PlatformArchitecture.X64)]
public void ForwardDotnetRootEnvironmentVariableWhenTargetFrameworkIsGreaterOrEqualsToNet6SetsCorrectEnvVariable(string envVarName, PlatformArchitecture platformArchitecture)
{
// Arrange
const string envVarValue = "c:\\SomePath";
_mockEnvironmentVariable.Reset();
_mockEnvironmentVariable.Setup(x => x.GetEnvironmentVariable(envVarName)).Returns(envVarValue);
_mockProcessHelper.Setup(x => x.GetCurrentProcessArchitecture()).Returns(platformArchitecture);
string runSettingsXml = """
<RunSettings>
<RunConfiguration>
<TargetFrameworkVersion>net6.0</TargetFrameworkVersion>
</RunConfiguration>
</RunSettings>
""";
_dotnetHostManager.Initialize(_mockMessageLogger.Object, runSettingsXml);

var startInfo = new TestProcessStartInfo { EnvironmentVariables = new Dictionary<string, string?>() };
// Sanity check
Assert.AreEqual(0, startInfo.EnvironmentVariables.Count);

// Act
_dotnetHostManager.ForwardDotnetRootEnvironmentVariable(startInfo);

// Assert
Assert.AreEqual(1, startInfo.EnvironmentVariables.Count);
Assert.IsTrue(startInfo.EnvironmentVariables.TryGetValue($"DOTNET_ROOT_{platformArchitecture.ToString().ToUpperInvariant()}", out var actualEnvVarValue));
Assert.AreEqual(envVarValue, actualEnvVarValue);
}

[TestMethod]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT(x86)", PlatformArchitecture.X86)]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT(x86)", PlatformArchitecture.X64)]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT(x86)", PlatformArchitecture.ARM64)]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT", PlatformArchitecture.X86)]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT", PlatformArchitecture.X64)]
[DataRow("VSTEST_WINAPPHOST_DOTNET_ROOT", PlatformArchitecture.ARM64)]
public void ForwardDotnetRootEnvironmentVariableWhenTargetFrameworkIsGreaterOrEqualsToNet6DoesNotOverrideEnvVar(string envVarName, PlatformArchitecture platformArchitecture)
{
// Arrange
const string expectedEnvVarValue = "c:\\SomePath";
const string nonForwardedEnvVarValue = "C:\\SomeOtherPath";
var expectedForwardedEnvVarName = $"DOTNET_ROOT_{platformArchitecture.ToString().ToUpperInvariant()}";
_mockEnvironmentVariable.Reset();
_mockEnvironmentVariable.Setup(x => x.GetEnvironmentVariable(envVarName)).Returns(expectedEnvVarValue);
_mockEnvironmentVariable.Setup(x => x.GetEnvironmentVariable(expectedForwardedEnvVarName)).Returns(nonForwardedEnvVarValue);
_mockProcessHelper.Setup(x => x.GetCurrentProcessArchitecture()).Returns(platformArchitecture);
string runSettingsXml = """
<RunSettings>
<RunConfiguration>
<TargetFrameworkVersion>net6.0</TargetFrameworkVersion>
</RunConfiguration>
</RunSettings>
""";
_dotnetHostManager.Initialize(_mockMessageLogger.Object, runSettingsXml);

var startInfo = new TestProcessStartInfo { EnvironmentVariables = new Dictionary<string, string?>() };
// Sanity check
Assert.AreEqual(0, startInfo.EnvironmentVariables.Count);

// Act
_dotnetHostManager.ForwardDotnetRootEnvironmentVariable(startInfo);

// Assert
Assert.AreEqual(0, startInfo.EnvironmentVariables.Count);
}

private void DotnetHostManagerExitCodeTesterHostExited(object? sender, HostProviderEventArgs e)
{
_errorMessage = e.Data.TrimEnd(Environment.NewLine.ToCharArray());
Expand Down
10 changes: 5 additions & 5 deletions test/Microsoft.TestPlatform.TestUtilities/IntegrationTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public void InvokeVsTest(string? arguments, Dictionary<string, string?>? environ
/// Invokes our local copy of dotnet that is patched with artifacts from the build with specified arguments.
/// </summary>
/// <param name="arguments">Arguments provided to <c>vstest.console</c>.exe</param>
public void InvokeDotnetTest(string arguments, Dictionary<string, string?>? environmentVariables = null, bool useDotnetFromTools = false, string? workingDirectory = null)
public void InvokeDotnetTest(string arguments, Dictionary<string, string?>? environmentVariables = null)
{
var debugEnvironmentVariables = AddDebugEnvironmentVariables(environmentVariables);

Expand All @@ -208,7 +208,7 @@ public void InvokeDotnetTest(string arguments, Dictionary<string, string?>? envi
// https://github.com/dotnet/sdk/blob/main/src/Cli/dotnet/commands/dotnet-test/VSTestForwardingApp.cs#L30-L39
debugEnvironmentVariables["VSTEST_CONSOLE_PATH"] = vstestConsolePath;

ExecutePatchedDotnet("test", arguments, out _standardTestOutput, out _standardTestError, out _runnerExitCode, debugEnvironmentVariables, useDotnetFromTools, workingDirectory);
ExecutePatchedDotnet("test", arguments, out _standardTestOutput, out _standardTestError, out _runnerExitCode, debugEnvironmentVariables);
FormatStandardOutCome();
}

Expand Down Expand Up @@ -762,7 +762,7 @@ protected void ExecuteVsTestConsole(string? args, out string stdOut, out string
/// <param name="stdError"></param>
/// <param name="exitCode"></param>
private void ExecutePatchedDotnet(string command, string args, out string stdOut, out string stdError, out int exitCode,
Dictionary<string, string?>? environmentVariables = null, bool useDotnetFromTools = false, string? workingDirectory = null)
Dictionary<string, string?>? environmentVariables = null)
{
if (environmentVariables is null)
{
Expand All @@ -772,8 +772,8 @@ private void ExecutePatchedDotnet(string command, string args, out string stdOut
environmentVariables["DOTNET_MULTILEVEL_LOOKUP"] = "0";

var executablePath = IsWindows ? @"dotnet\dotnet.exe" : @"dotnet-linux/dotnet";
var patchedDotnetPath = Path.Combine(useDotnetFromTools ? _testEnvironment.ToolsDirectory : _testEnvironment.TestArtifactsDirectory, executablePath);
ExecuteApplication(patchedDotnetPath, string.Join(" ", command, args), out stdOut, out stdError, out exitCode, environmentVariables, workingDirectory);
var patchedDotnetPath = Path.Combine(_testEnvironment.TestArtifactsDirectory, executablePath);
ExecuteApplication(patchedDotnetPath, string.Join(" ", command, args), out stdOut, out stdError, out exitCode, environmentVariables);
}

protected static void ExecuteApplication(string path, string? args, out string stdOut, out string stdError, out int exitCode,
Expand Down

This file was deleted.

68 changes: 0 additions & 68 deletions test/TestAssets/ProjectLaunch32BitsProcess/Test32Bit.cs

This file was deleted.

Loading