Skip to content

Commit

Permalink
Add option to specify custom test host (#2359)
Browse files Browse the repository at this point in the history
  • Loading branch information
nohwnd committed Mar 16, 2020
1 parent 3726dae commit 1f92342
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,11 @@ public bool ResultsDirectorySet
/// </summary>
public bool CollectSourceInformationSet { get; private set; } = false;

/// <summary>
/// Path to dotnet executable to be used to invoke testhost.dll. Specifying this will skip looking up testhost.exe and will force usage of the testhost.dll.
/// </summary>
public string DotnetHostPath { get; private set; }

#endregion

/// <inheritdoc/>
Expand Down Expand Up @@ -571,6 +576,13 @@ public override XmlElement ToXml()
root.AppendChild(targetDevice);
}

if (!string.IsNullOrEmpty(this.DotnetHostPath))
{
XmlElement dotnetHostPath = doc.CreateElement(nameof(DotnetHostPath));
dotnetHostPath.InnerXml = this.DotnetHostPath;
root.AppendChild(dotnetHostPath);
}

return root;
}

Expand Down Expand Up @@ -867,6 +879,11 @@ public static RunConfiguration FromXml(XmlReader reader)
runConfiguration.TargetDevice = reader.ReadElementContentAsString();
break;

case "DotNetHostPath":
XmlRunSettingsUtilities.ThrowOnHasAttributes(reader);
runConfiguration.DotnetHostPath = reader.ReadElementContentAsString();
break;

default:
// Ignore a runsettings element that we don't understand. It could occur in the case
// the test runner is of a newer version, but the test host is of an earlier version.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public class DotnetTestHostManager : ITestRuntimeProvider

private bool isVersionCheckRequired = true;

private string dotnetHostPath;

/// <summary>
/// Initializes a new instance of the <see cref="DotnetTestHostManager"/> class.
/// </summary>
Expand Down Expand Up @@ -156,6 +158,7 @@ public void Initialize(IMessageLogger logger, string runsettingsXml)

var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettingsXml);
this.architecture = runConfiguration.TargetPlatform;
this.dotnetHostPath = runConfiguration.DotnetHostPath;
}

/// <inheritdoc/>
Expand Down Expand Up @@ -218,10 +221,16 @@ public async Task<bool> LaunchTestHostAsync(TestProcessStartInfo testHostStartIn

var runtimeConfigDevPath = Path.Combine(sourceDirectory, string.Concat(sourceFile, ".runtimeconfig.dev.json"));
string testHostPath = string.Empty;
bool useCustomDotnetHostpath = !string.IsNullOrEmpty(this.dotnetHostPath);

// If testhost.exe is available use it
if (useCustomDotnetHostpath)
{
EqtTrace.Verbose("DotnetTestHostmanager: User specified custom path to dotnet host: '{0}'.", this.dotnetHostPath);
}

// If testhost.exe is available use it, unless user specified path to dotnet.exe, then we will use the testhost.dll
bool testHostExeFound = false;
if (this.platformEnvironment.OperatingSystem.Equals(PlatformOperatingSystem.Windows))
if (!useCustomDotnetHostpath && this.platformEnvironment.OperatingSystem.Equals(PlatformOperatingSystem.Windows))
{
var exeName = this.architecture == Architecture.X86 ? "testhost.x86.exe" : "testhost.exe";
var fullExePath = Path.Combine(sourceDirectory, exeName);
Expand Down Expand Up @@ -257,17 +266,21 @@ public async Task<bool> LaunchTestHostAsync(TestProcessStartInfo testHostStartIn

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

if (string.IsNullOrEmpty(testHostPath))
{
testHostPath = this.GetTestHostPath(runtimeConfigDevPath, depsFilePath, sourceDirectory);
}

var currentProcessPath = this.processHelper.GetCurrentProcessFileName();
if (useCustomDotnetHostpath)
{
startInfo.FileName = this.dotnetHostPath;
}

// This host manager can create process start info for dotnet core targets only.
// If already running with the dotnet executable, use it; otherwise pick up the dotnet available on path.
// Wrap the paths with quotes in case dotnet executable is installed on a path with whitespace.
if (currentProcessPath.EndsWith("dotnet", StringComparison.OrdinalIgnoreCase)
else if (currentProcessPath.EndsWith("dotnet", StringComparison.OrdinalIgnoreCase)
|| currentProcessPath.EndsWith("dotnet.exe", StringComparison.OrdinalIgnoreCase))
{
startInfo.FileName = currentProcessPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,18 @@ public void GetTestHostProcessStartInfoShouldUseTestHostExeIfPresentOnWindows()
StringAssert.Contains(startInfo.FileName, testhostExePath);
}

[TestMethod]
public void GetTestHostProcessStartInfoShouldUseDotnetHostPathFromRunsettings()
{
var dotnetHostPath = @"C:\dotnet.exe";
this.mockFileHelper.Setup(ph => ph.Exists("testhost.dll")).Returns(true);
this.mockEnvironment.Setup(ev => ev.OperatingSystem).Returns(PlatformOperatingSystem.Windows);
this.dotnetHostManager.Initialize(this.mockMessageLogger.Object, $"<RunSettings><RunConfiguration><DotNetHostPath>{dotnetHostPath}</DotNetHostPath></RunConfiguration></RunSettings>");
var startInfo = this.GetDefaultStartInfo();

StringAssert.Contains(startInfo.FileName, dotnetHostPath);
}

[TestMethod]
public void GetTestHostProcessStartInfoShouldUseTestHostExeFromNugetIfNotFoundInSourceLocation()
{
Expand Down

0 comments on commit 1f92342

Please sign in to comment.