Skip to content

Commit

Permalink
AnyCPU tests to choose default architecture based on process (#2206)
Browse files Browse the repository at this point in the history
* AnyCPU tests to choose default architecture based on process
  • Loading branch information
vagisha-nidhi committed Oct 18, 2019
1 parent ca987de commit 89d102d
Show file tree
Hide file tree
Showing 9 changed files with 313 additions and 83 deletions.
Expand Up @@ -67,6 +67,8 @@ public class DotnetTestHostManager : ITestRuntimeProvider

private Architecture architecture;

private bool isVersionCheckRequired = true;

/// <summary>
/// Initializes a new instance of the <see cref="DotnetTestHostManager"/> class.
/// </summary>
Expand Down Expand Up @@ -111,8 +113,20 @@ public DotnetTestHostManager()

/// <summary>
/// Gets a value indicating whether the test host supports protocol version check
/// By default this is set to true. For host package version 15.0.0, this will be set to false;
/// </summary>
internal virtual bool IsVersionCheckRequired => !this.hostPackageVersion.StartsWith("15.0.0");
internal virtual bool IsVersionCheckRequired
{
get
{
return this.isVersionCheckRequired;
}

private set
{
this.isVersionCheckRequired = value;
}
}

/// <summary>
/// Gets a value indicating whether the test host supports protocol version check
Expand Down Expand Up @@ -203,14 +217,46 @@ public async Task<bool> LaunchTestHostAsync(TestProcessStartInfo testHostStartIn
EqtTrace.Verbose("DotnetTestHostmanager: File {0}, doesnot exist", depsFilePath);
}

// If Testhost.exe is available use it
var exeName = this.architecture == Architecture.X86 ? "testhost.x86.exe" : "testhost.exe";
var fullExePath = Path.Combine(sourceDirectory, exeName);
if (this.platformEnvironment.OperatingSystem.Equals(PlatformOperatingSystem.Windows) && this.fileHelper.Exists(fullExePath))
var runtimeConfigDevPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.dev.json"));
string testHostPath = string.Empty;

// If testhost.exe is available use it
bool testHostExeFound = false;
if (this.platformEnvironment.OperatingSystem.Equals(PlatformOperatingSystem.Windows))
{
startInfo.FileName = fullExePath;
var exeName = this.architecture == Architecture.X86 ? "testhost.x86.exe" : "testhost.exe";
var fullExePath = Path.Combine(sourceDirectory, exeName);

// check for testhost.exe in sourceDirectory. If not found, check in nuget folder.
if (this.fileHelper.Exists(fullExePath))
{
EqtTrace.Verbose("DotnetTestHostManager: Testhost.exe/testhost.x86.exe found at path: " + fullExePath);
startInfo.FileName = fullExePath;
testHostExeFound = true;
}
else
{
// Check if testhost.dll is found in nuget folder.
testHostPath = this.GetTestHostPath(runtimeConfigDevPath, depsFilePath, sourceDirectory);
if (testHostPath.IndexOf("microsoft.testplatform.testhost", StringComparison.OrdinalIgnoreCase) >= 0)
{
// testhost.dll is present in path {testHostNugetRoot}\lib\netcoreapp2.1\testhost.dll
// testhost.(x86).exe is present in location {testHostNugetRoot}\build\netcoreapp2.1\{x86/x64}\{testhost.x86.exe/testhost.exe}
var folderName = this.architecture == Architecture.X86 ? "x86" : "x64";
var testHostNugetRoot = new DirectoryInfo(testHostPath).Parent.Parent.Parent;
var testHostExeNugetPath = Path.Combine(testHostNugetRoot.FullName, "build", "netcoreapp2.1", folderName, exeName);

if (this.fileHelper.Exists(testHostExeNugetPath))
{
EqtTrace.Verbose("DotnetTestHostManager: Testhost.exe/testhost.x86.exe found at path: " + testHostExeNugetPath);
startInfo.FileName = testHostExeNugetPath;
testHostExeFound = true;
}
}
}
}
else

if (!testHostExeFound)
{
var currentProcessPath = this.processHelper.GetCurrentProcessFileName();

Expand All @@ -227,9 +273,6 @@ public async Task<bool> LaunchTestHostAsync(TestProcessStartInfo testHostStartIn
startInfo.FileName = this.dotnetHostHelper.GetDotnetPath();
}

var runtimeConfigDevPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.dev.json"));
var testHostPath = this.GetTestHostPath(runtimeConfigDevPath, depsFilePath, sourceDirectory);

EqtTrace.Verbose("DotnetTestHostmanager: Full path of testhost.dll is {0}", testHostPath);
args = "exec" + args;
args += " " + testHostPath.AddDoubleQuote();
Expand Down Expand Up @@ -394,6 +437,7 @@ private string GetTestHostPath(string runtimeConfigDevPath, string depsFilePath,

testHostPath = Path.Combine(testhostPackage.Path, testHostPath);
this.hostPackageVersion = testhostPackage.Version;
this.IsVersionCheckRequired = !this.hostPackageVersion.StartsWith("15.0.0");
EqtTrace.Verbose("DotnetTestHostmanager: Relative path of testhost.dll with respect to package folder is {0}", testHostPath);
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/package/nuspec/Microsoft.TestPlatform.TestHost.NetCore.props
@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition=" '$(Platform)' == 'x86' AND '$(OS)' == 'Windows_NT'">
<ItemGroup Condition=" ('$(Platform)' == 'x86' OR '$(PlatformTarget)' == 'x86') AND '$(OS)' == 'Windows_NT'">
<Content Include="$(MSBuildThisFileDirectory)x86\testhost.x86.exe">
<Link>testhost.x86.exe</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)x86\testhost.x86.dll">
<Link>testhost.x86.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
<ItemGroup Condition=" '$(Platform)' != 'x86' AND '$(OS)' == 'Windows_NT'" >
<ItemGroup Condition=" ('$(Platform)'!= 'x86' AND '$(PlatformTarget)' != 'x86') AND '$(OS)' == 'Windows_NT'" >
<Content Include="$(MSBuildThisFileDirectory)x64\testhost.exe">
<Link>testhost.exe</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Visible>False</Visible>
</Content>
<Content Include="$(MSBuildThisFileDirectory)x64\testhost.dll">
<Link>testhost.dll</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<Visible>False</Visible>
</Content>
</ItemGroup>
Expand Down
20 changes: 15 additions & 5 deletions src/vstest.console/TestPlatformHelpers/TestRequestManager.cs
Expand Up @@ -29,6 +29,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.TestPlatformHelpers
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions;
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;
using Microsoft.VisualStudio.TestPlatform.Utilities;

/// <summary>
Expand All @@ -47,6 +48,7 @@ internal class TestRequestManager : ITestRequestManager
private readonly object syncObject = new object();
private readonly Task<IMetricsPublisher> metricsPublisher;
private bool isDisposed;
private IProcessHelper processHelper;

/// <summary>
/// Maintains the current active execution request
Expand All @@ -69,18 +71,20 @@ public TestRequestManager()
TestRunResultAggregator.Instance,
TestPlatformEventSource.Instance,
new InferHelper(AssemblyMetadataProvider.Instance),
MetricsPublisherFactory.GetMetricsPublisher(IsTelemetryOptedIn(), CommandLineOptions.Instance.IsDesignMode))
MetricsPublisherFactory.GetMetricsPublisher(IsTelemetryOptedIn(), CommandLineOptions.Instance.IsDesignMode),
new ProcessHelper())
{
}

internal TestRequestManager(CommandLineOptions commandLineOptions, ITestPlatform testPlatform, TestRunResultAggregator testRunResultAggregator, ITestPlatformEventSource testPlatformEventSource, InferHelper inferHelper, Task<IMetricsPublisher> metricsPublisher)
internal TestRequestManager(CommandLineOptions commandLineOptions, ITestPlatform testPlatform, TestRunResultAggregator testRunResultAggregator, ITestPlatformEventSource testPlatformEventSource, InferHelper inferHelper, Task<IMetricsPublisher> metricsPublisher, IProcessHelper processHelper)
{
this.testPlatform = testPlatform;
this.commandLineOptions = commandLineOptions;
this.testRunResultAggregator = testRunResultAggregator;
this.testPlatformEventSource = testPlatformEventSource;
this.inferHelper = inferHelper;
this.metricsPublisher = metricsPublisher;
this.processHelper = processHelper;
}

#endregion
Expand Down Expand Up @@ -381,9 +385,15 @@ private bool UpdateRunSettingsIfRequired(string runsettingsXml, List<string> sou
settingsUpdated |= this.UpdateFramework(document, navigator, sources, sourceFrameworks, registrar, out Framework chosenFramework);

// Choose default architecture based on the framework
// For .NET core, the default platform architecture should be x64.
var defaultArchitecture = chosenFramework.Name.IndexOf("netstandard", StringComparison.OrdinalIgnoreCase) >= 0
|| chosenFramework.Name.IndexOf("netcoreapp", StringComparison.OrdinalIgnoreCase) >= 0 ? Architecture.X64 : Architecture.X86;
// For .NET core, the default platform architecture should be based on the process.
// For a 64 bit process,
Architecture defaultArchitecture = Architecture.X86;
if (chosenFramework.Name.IndexOf("netstandard", StringComparison.OrdinalIgnoreCase) >= 0
|| chosenFramework.Name.IndexOf("netcoreapp", StringComparison.OrdinalIgnoreCase) >= 0)
{
var currentProcessName = this.processHelper.GetProcessName(this.processHelper.GetCurrentProcessId());
defaultArchitecture = (currentProcessName.StartsWith("dotnet", StringComparison.OrdinalIgnoreCase) && !Environment.Is64BitProcess) ? Architecture.X86: Architecture.X64;
}

settingsUpdated |= this.UpdatePlatform(document, navigator, sources, sourcePlatforms, defaultArchitecture, out Architecture chosenPlatform);
this.CheckSourcesForCompatibility(chosenFramework, chosenPlatform, sourcePlatforms, sourceFrameworks, registrar);
Expand Down

0 comments on commit 89d102d

Please sign in to comment.