Skip to content

Commit 89d102d

Browse files
AnyCPU tests to choose default architecture based on process (#2206)
* AnyCPU tests to choose default architecture based on process
1 parent ca987de commit 89d102d

File tree

9 files changed

+313
-83
lines changed

9 files changed

+313
-83
lines changed

src/Microsoft.TestPlatform.TestHostProvider/Hosting/DotnetTestHostManager.cs

+54-10
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ public class DotnetTestHostManager : ITestRuntimeProvider
6767

6868
private Architecture architecture;
6969

70+
private bool isVersionCheckRequired = true;
71+
7072
/// <summary>
7173
/// Initializes a new instance of the <see cref="DotnetTestHostManager"/> class.
7274
/// </summary>
@@ -111,8 +113,20 @@ internal DotnetTestHostManager(
111113

112114
/// <summary>
113115
/// Gets a value indicating whether the test host supports protocol version check
116+
/// By default this is set to true. For host package version 15.0.0, this will be set to false;
114117
/// </summary>
115-
internal virtual bool IsVersionCheckRequired => !this.hostPackageVersion.StartsWith("15.0.0");
118+
internal virtual bool IsVersionCheckRequired
119+
{
120+
get
121+
{
122+
return this.isVersionCheckRequired;
123+
}
124+
125+
private set
126+
{
127+
this.isVersionCheckRequired = value;
128+
}
129+
}
116130

117131
/// <summary>
118132
/// Gets a value indicating whether the test host supports protocol version check
@@ -203,14 +217,46 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo(
203217
EqtTrace.Verbose("DotnetTestHostmanager: File {0}, doesnot exist", depsFilePath);
204218
}
205219

206-
// If Testhost.exe is available use it
207-
var exeName = this.architecture == Architecture.X86 ? "testhost.x86.exe" : "testhost.exe";
208-
var fullExePath = Path.Combine(sourceDirectory, exeName);
209-
if (this.platformEnvironment.OperatingSystem.Equals(PlatformOperatingSystem.Windows) && this.fileHelper.Exists(fullExePath))
220+
var runtimeConfigDevPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.dev.json"));
221+
string testHostPath = string.Empty;
222+
223+
// If testhost.exe is available use it
224+
bool testHostExeFound = false;
225+
if (this.platformEnvironment.OperatingSystem.Equals(PlatformOperatingSystem.Windows))
210226
{
211-
startInfo.FileName = fullExePath;
227+
var exeName = this.architecture == Architecture.X86 ? "testhost.x86.exe" : "testhost.exe";
228+
var fullExePath = Path.Combine(sourceDirectory, exeName);
229+
230+
// check for testhost.exe in sourceDirectory. If not found, check in nuget folder.
231+
if (this.fileHelper.Exists(fullExePath))
232+
{
233+
EqtTrace.Verbose("DotnetTestHostManager: Testhost.exe/testhost.x86.exe found at path: " + fullExePath);
234+
startInfo.FileName = fullExePath;
235+
testHostExeFound = true;
236+
}
237+
else
238+
{
239+
// Check if testhost.dll is found in nuget folder.
240+
testHostPath = this.GetTestHostPath(runtimeConfigDevPath, depsFilePath, sourceDirectory);
241+
if (testHostPath.IndexOf("microsoft.testplatform.testhost", StringComparison.OrdinalIgnoreCase) >= 0)
242+
{
243+
// testhost.dll is present in path {testHostNugetRoot}\lib\netcoreapp2.1\testhost.dll
244+
// testhost.(x86).exe is present in location {testHostNugetRoot}\build\netcoreapp2.1\{x86/x64}\{testhost.x86.exe/testhost.exe}
245+
var folderName = this.architecture == Architecture.X86 ? "x86" : "x64";
246+
var testHostNugetRoot = new DirectoryInfo(testHostPath).Parent.Parent.Parent;
247+
var testHostExeNugetPath = Path.Combine(testHostNugetRoot.FullName, "build", "netcoreapp2.1", folderName, exeName);
248+
249+
if (this.fileHelper.Exists(testHostExeNugetPath))
250+
{
251+
EqtTrace.Verbose("DotnetTestHostManager: Testhost.exe/testhost.x86.exe found at path: " + testHostExeNugetPath);
252+
startInfo.FileName = testHostExeNugetPath;
253+
testHostExeFound = true;
254+
}
255+
}
256+
}
212257
}
213-
else
258+
259+
if (!testHostExeFound)
214260
{
215261
var currentProcessPath = this.processHelper.GetCurrentProcessFileName();
216262

@@ -227,9 +273,6 @@ public virtual TestProcessStartInfo GetTestHostProcessStartInfo(
227273
startInfo.FileName = this.dotnetHostHelper.GetDotnetPath();
228274
}
229275

230-
var runtimeConfigDevPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.dev.json"));
231-
var testHostPath = this.GetTestHostPath(runtimeConfigDevPath, depsFilePath, sourceDirectory);
232-
233276
EqtTrace.Verbose("DotnetTestHostmanager: Full path of testhost.dll is {0}", testHostPath);
234277
args = "exec" + args;
235278
args += " " + testHostPath.AddDoubleQuote();
@@ -394,6 +437,7 @@ private string GetTestHostPath(string runtimeConfigDevPath, string depsFilePath,
394437

395438
testHostPath = Path.Combine(testhostPackage.Path, testHostPath);
396439
this.hostPackageVersion = testhostPackage.Version;
440+
this.IsVersionCheckRequired = !this.hostPackageVersion.StartsWith("15.0.0");
397441
EqtTrace.Verbose("DotnetTestHostmanager: Relative path of testhost.dll with respect to package folder is {0}", testHostPath);
398442
}
399443
}

src/package/nuspec/Microsoft.TestPlatform.TestHost.NetCore.props

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3-
<ItemGroup Condition=" '$(Platform)' == 'x86' AND '$(OS)' == 'Windows_NT'">
3+
<ItemGroup Condition=" ('$(Platform)' == 'x86' OR '$(PlatformTarget)' == 'x86') AND '$(OS)' == 'Windows_NT'">
44
<Content Include="$(MSBuildThisFileDirectory)x86\testhost.x86.exe">
55
<Link>testhost.x86.exe</Link>
6-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
6+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
77
<Visible>False</Visible>
88
</Content>
99
<Content Include="$(MSBuildThisFileDirectory)x86\testhost.x86.dll">
1010
<Link>testhost.x86.dll</Link>
11-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
11+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
1212
<Visible>False</Visible>
1313
</Content>
1414
</ItemGroup>
15-
<ItemGroup Condition=" '$(Platform)' != 'x86' AND '$(OS)' == 'Windows_NT'" >
15+
<ItemGroup Condition=" ('$(Platform)'!= 'x86' AND '$(PlatformTarget)' != 'x86') AND '$(OS)' == 'Windows_NT'" >
1616
<Content Include="$(MSBuildThisFileDirectory)x64\testhost.exe">
1717
<Link>testhost.exe</Link>
18-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
18+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
1919
<Visible>False</Visible>
2020
</Content>
2121
<Content Include="$(MSBuildThisFileDirectory)x64\testhost.dll">
2222
<Link>testhost.dll</Link>
23-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
23+
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
2424
<Visible>False</Visible>
2525
</Content>
2626
</ItemGroup>

src/vstest.console/TestPlatformHelpers/TestRequestManager.cs

+15-5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommandLine.TestPlatformHelpers
2929
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Interfaces;
3030
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities;
3131
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions;
32+
using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces;
3233
using Microsoft.VisualStudio.TestPlatform.Utilities;
3334

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

5153
/// <summary>
5254
/// Maintains the current active execution request
@@ -69,18 +71,20 @@ public TestRequestManager()
6971
TestRunResultAggregator.Instance,
7072
TestPlatformEventSource.Instance,
7173
new InferHelper(AssemblyMetadataProvider.Instance),
72-
MetricsPublisherFactory.GetMetricsPublisher(IsTelemetryOptedIn(), CommandLineOptions.Instance.IsDesignMode))
74+
MetricsPublisherFactory.GetMetricsPublisher(IsTelemetryOptedIn(), CommandLineOptions.Instance.IsDesignMode),
75+
new ProcessHelper())
7376
{
7477
}
7578

76-
internal TestRequestManager(CommandLineOptions commandLineOptions, ITestPlatform testPlatform, TestRunResultAggregator testRunResultAggregator, ITestPlatformEventSource testPlatformEventSource, InferHelper inferHelper, Task<IMetricsPublisher> metricsPublisher)
79+
internal TestRequestManager(CommandLineOptions commandLineOptions, ITestPlatform testPlatform, TestRunResultAggregator testRunResultAggregator, ITestPlatformEventSource testPlatformEventSource, InferHelper inferHelper, Task<IMetricsPublisher> metricsPublisher, IProcessHelper processHelper)
7780
{
7881
this.testPlatform = testPlatform;
7982
this.commandLineOptions = commandLineOptions;
8083
this.testRunResultAggregator = testRunResultAggregator;
8184
this.testPlatformEventSource = testPlatformEventSource;
8285
this.inferHelper = inferHelper;
8386
this.metricsPublisher = metricsPublisher;
87+
this.processHelper = processHelper;
8488
}
8589

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

383387
// Choose default architecture based on the framework
384-
// For .NET core, the default platform architecture should be x64.
385-
var defaultArchitecture = chosenFramework.Name.IndexOf("netstandard", StringComparison.OrdinalIgnoreCase) >= 0
386-
|| chosenFramework.Name.IndexOf("netcoreapp", StringComparison.OrdinalIgnoreCase) >= 0 ? Architecture.X64 : Architecture.X86;
388+
// For .NET core, the default platform architecture should be based on the process.
389+
// For a 64 bit process,
390+
Architecture defaultArchitecture = Architecture.X86;
391+
if (chosenFramework.Name.IndexOf("netstandard", StringComparison.OrdinalIgnoreCase) >= 0
392+
|| chosenFramework.Name.IndexOf("netcoreapp", StringComparison.OrdinalIgnoreCase) >= 0)
393+
{
394+
var currentProcessName = this.processHelper.GetProcessName(this.processHelper.GetCurrentProcessId());
395+
defaultArchitecture = (currentProcessName.StartsWith("dotnet", StringComparison.OrdinalIgnoreCase) && !Environment.Is64BitProcess) ? Architecture.X86: Architecture.X64;
396+
}
387397

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

0 commit comments

Comments
 (0)