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

Fix architecture retrival #3251

Merged
merged 3 commits into from
Jan 13, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion scripts/common.lib.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ function Install-DotNetCli
Write-Log "Install-DotNetCli: Get the latest dotnet cli toolset..."
$dotnetInstallPath = Join-Path $env:TP_TOOLS_DIR "dotnet"
New-Item -ItemType directory -Path $dotnetInstallPath -Force | Out-Null
& $dotnetInstallScript -Channel 6.0 -Quality Preview -InstallDir $dotnetInstallPath -Version $env:DOTNET_CLI_VERSION
& $dotnetInstallScript -Channel 6.0 -InstallDir $dotnetInstallPath -Version $env:DOTNET_CLI_VERSION

& $dotnetInstallScript -InstallDir "$dotnetInstallPath" -Runtime 'dotnet' -Version '2.1.30' -Channel '2.1' -Architecture x64 -NoPath
$env:DOTNET_ROOT= $dotnetInstallPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private bool TryGetExecutablePath(string executableBaseName, out string executab

public bool TryGetDotnetPathByArchitecture(PlatformArchitecture targetArchitecture, out string muxerPath)
{
if (this.environment.Architecture == targetArchitecture)
if (this.processHelper.GetCurrentProcessArchitecture() == targetArchitecture)
{
string currentProcessFileName = this.processHelper.GetCurrentProcessFileName();
if (Path.GetFileName(currentProcessFileName) != this.muxerName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,17 +184,6 @@ public int GetProcessId(object process)
return proc?.Id ?? -1;
}

/// <inheritdoc/>
public PlatformArchitecture GetCurrentProcessArchitecture()
{
if (IntPtr.Size == 8)
{
return PlatformArchitecture.X64;
}

return PlatformArchitecture.X86;
}

/// <inheritdoc/>
public string GetNativeDllDirectory()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ public IntPtr GetProcessHandle(int processId)
{
return Process.GetProcessById(processId).Handle;
}

/// <inheritdoc/>
public PlatformArchitecture GetCurrentProcessArchitecture()
{
if (IntPtr.Size == 8)
{
return PlatformArchitecture.X64;
}

return PlatformArchitecture.X86;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Microsoft.VisualStudio.TestPlatform.PlatformAbstractions
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;

public partial class ProcessHelper : IProcessHelper
Expand All @@ -26,6 +27,29 @@ public IntPtr GetProcessHandle(int processId)
// If the handle has been marked invalid with SetHandleAsInvalid, this method still returns the original handle value, which can be a stale value.
return Process.GetProcessById(processId).SafeHandle.DangerousGetHandle();
}

public PlatformArchitecture GetCurrentProcessArchitecture()
{
switch (RuntimeInformation.ProcessArchitecture)
{
case Architecture.X86:
return PlatformArchitecture.X86;
case Architecture.X64:
return PlatformArchitecture.X64;
case Architecture.Arm:
return PlatformArchitecture.ARM;
case Architecture.Arm64:
return PlatformArchitecture.ARM64;

// The symbolic value is only available with .NET 6
// preview 6 or later, so use the numerical value for now.
// case System.Runtime.InteropServices.Architecture.S390x:
case (Architecture)5:
return PlatformArchitecture.S390x;
default:
throw new NotSupportedException();
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,8 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo(
// We silently force x64 only if the target architecture is the default one and is not specified by user
// through --arch or runsettings or -- RunConfiguration.TargetPlatform=arch
bool forceToX64 = SilentlyForceToX64() && this.runsettingHelper.IsDefaultTargetArchitecture;
bool isSameArchitecture = IsSameArchitecture(this.architecture, this.platformEnvironment.Architecture);
EqtTrace.Verbose($"DotnetTestHostmanager: Current process architetcure '{this.processHelper.GetCurrentProcessArchitecture()}'");
bool isSameArchitecture = IsSameArchitecture(this.architecture, this.processHelper.GetCurrentProcessArchitecture());
var currentProcessPath = this.processHelper.GetCurrentProcessFileName();
bool isRunningWithDotnetMuxer = IsRunningWithDotnetMuxer(currentProcessPath);
if (useCustomDotnetHostpath)
Expand All @@ -424,10 +425,10 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo(
else
{
PlatformArchitecture targetArchitecture = TranslateToPlatformArchitecture(this.architecture);
EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Searching muxer for the architecture '{targetArchitecture}', OS '{this.platformEnvironment.OperatingSystem}' framework '{this.targetFramework}' SDK platform architecture '{this.platformEnvironment.Architecture}'");
EqtTrace.Verbose($"DotnetTestHostmanager: Searching muxer for the architecture '{targetArchitecture}', OS '{this.platformEnvironment.OperatingSystem}' framework '{this.targetFramework}' SDK platform architecture '{this.platformEnvironment.Architecture}'");
if (forceToX64)
{
EqtTrace.Verbose($"DotnetTestHostmanager.LaunchTestHostAsync: Forcing the search to x64 architecure, IsDefaultTargetArchitecture '{this.runsettingHelper.IsDefaultTargetArchitecture}' OS '{this.platformEnvironment.OperatingSystem}' framework '{this.targetFramework}'");
EqtTrace.Verbose($"DotnetTestHostmanager: Forcing the search to x64 architecure, IsDefaultTargetArchitecture '{this.runsettingHelper.IsDefaultTargetArchitecture}' OS '{this.platformEnvironment.OperatingSystem}' framework '{this.targetFramework}'");
}

PlatformArchitecture finalTargetArchitecture = forceToX64 ? PlatformArchitecture.X64 : targetArchitecture;
Expand All @@ -441,7 +442,7 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo(
startInfo.FileName = muxerPath;
}

EqtTrace.Verbose("DotnetTestHostmanager.LaunchTestHostAsync: Full path of testhost.dll is {0}", testHostPath);
EqtTrace.Verbose("DotnetTestHostmanager: Full path of testhost.dll is {0}", testHostPath);
args = "exec" + args;
args += " " + testHostPath.AddDoubleQuote();
}
Expand Down
28 changes: 26 additions & 2 deletions src/vstest.console/TestPlatformHelpers/TestRequestManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.TestPlatformHelpers
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;
using Microsoft.VisualStudio.TestPlatform.Utilities;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;

/// <summary>
/// Defines the test request manger which can fire off discovery and test run requests.
Expand Down Expand Up @@ -618,8 +619,9 @@ private bool UpdateRunSettingsIfRequired(
// it can be specified by user on the command line with --arch or through runsettings.
// If it's not specified by user will be filled by current processor architecture;
// should be the same as SDK.
defaultArchitecture = runConfiguration.TargetPlatform;
EqtTrace.Verbose($"Default architecture: {defaultArchitecture}");
defaultArchitecture = RunSettingsHelper.Instance.IsDefaultTargetArchitecture ?
TranslateToArchitecture(processHelper.GetCurrentProcessArchitecture()) :
runConfiguration.TargetPlatform;
#else
// We are running in vstest.console.exe that was built against .NET
// Framework. This console prefers 32-bit because it needs to run as 32-bit
Expand All @@ -630,6 +632,7 @@ private bool UpdateRunSettingsIfRequired(
// We want to find 64-bit SDK because it is more likely to be installed.
defaultArchitecture = Environment.Is64BitOperatingSystem ? Architecture.X64 : Architecture.X86;
#endif
EqtTrace.Verbose($"Default architecture: {defaultArchitecture} IsDefaultTargetArchitecture: {RunSettingsHelper.Instance.IsDefaultTargetArchitecture}");
}

settingsUpdated |= this.UpdatePlatform(
Expand All @@ -656,6 +659,27 @@ private bool UpdateRunSettingsIfRequired(
}

return settingsUpdated;

#if NETCOREAPP
Architecture TranslateToArchitecture(PlatformArchitecture targetArchitecture)
{
switch (targetArchitecture)
{
case PlatformArchitecture.X86:
return Architecture.X86;
case PlatformArchitecture.X64:
return Architecture.X64;
case PlatformArchitecture.ARM:
return Architecture.ARM;
case PlatformArchitecture.ARM64:
return Architecture.ARM64;
default:
break;
}

throw new TestPlatformException($"Invalid target architecture '{targetArchitecture}'");
}
#endif
}

private bool AddOrUpdateConsoleLogger(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public void GetDotnetPathByArchitecture_SameArchitecture()
environmentHelper.SetupGet(x => x.OperatingSystem).Returns(PlatformOperatingSystem.Windows);
environmentHelper.SetupGet(x => x.Architecture).Returns(PlatformArchitecture.X64);
processHelper.Setup(x => x.GetCurrentProcessFileName()).Returns(finalMuxerPath);
processHelper.Setup(x => x.GetCurrentProcessArchitecture()).Returns(PlatformArchitecture.X64);

// Act & Assert
Assert.IsTrue(dotnetHostHelper.TryGetDotnetPathByArchitecture(PlatformArchitecture.X64, out string muxerPath));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public DotnetTestHostManagerTests()
// Setup a dummy current process for tests
this.mockProcessHelper.Setup(ph => ph.GetCurrentProcessFileName()).Returns(DefaultDotnetPath);
this.mockProcessHelper.Setup(ph => ph.GetTestEngineDirectory()).Returns(DefaultDotnetPath);
this.mockProcessHelper.Setup(ph => ph.GetCurrentProcessArchitecture()).Returns(PlatformArchitecture.X64);
this.mockEnvironmentVariable.Setup(ev => ev.GetEnvironmentVariable(It.IsAny<string>())).Returns(Path.GetDirectoryName(DefaultDotnetPath));
this.mockFileHelper.Setup(ph => ph.Exists(this.defaultTestHostPath)).Returns(true);
this.mockFileHelper.Setup(ph => ph.Exists(DefaultDotnetPath)).Returns(true);
Expand Down