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

Add option to specify custom test host #2359

Merged
merged 1 commit into from
Mar 16, 2020
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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