Skip to content

Commit

Permalink
Add env var to control host priority (#3740)
Browse files Browse the repository at this point in the history
  • Loading branch information
Evangelink authored Jun 13, 2022
1 parent f6b89cf commit d2fc0fc
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,15 @@ namespace Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers;

internal class EnvironmentVariableHelper : IEnvironmentVariableHelper
{
/// <inheritdoc />
public string GetEnvironmentVariable(string variable)
=> Environment.GetEnvironmentVariable(variable);

/// <inheritdoc />
public TEnum GetEnvironmentVariableAsEnum<TEnum>(string variable, TEnum defaultValue = default) where TEnum : struct, Enum
=> Environment.GetEnvironmentVariable(variable) is string value && !string.IsNullOrEmpty(value)
? Enum.TryParse<TEnum>(value, out var enumValue) ? enumValue : defaultValue
: defaultValue;
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,25 @@

#nullable disable

using System;

namespace Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;

internal interface IEnvironmentVariableHelper
{
/// <summary>
/// Retrieves the value of an environment variable from the current process.
/// </summary>
/// <param name="variable">The name of the environment variable.</param>
/// <returns>The value of the environment variable specified by variable, or null if the environment variable is not found.</returns>
string GetEnvironmentVariable(string variable);

/// <summary>
/// Retrieves the value of an environment variable from the current process and converts it to the given type.
/// </summary>
/// <typeparam name="TEnum">The type used for conversion.</typeparam>
/// <param name="variable">The name of the environment variable.</param>
/// <param name="defaultValue">The default value to return if the environment variable is not found.</param>
/// <returns></returns>
TEnum GetEnvironmentVariableAsEnum<TEnum>(string variable, TEnum defaultValue = default) where TEnum : struct, Enum;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Microsoft.TestPlatform.TestHostProvider.Hosting;
using Microsoft.TestPlatform.TestHostProvider.Resources;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Extensions;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Helpers;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Helpers.Interfaces;
using Microsoft.VisualStudio.TestPlatform.DesktopTestHostRuntimeProvider;
Expand Down Expand Up @@ -57,6 +58,7 @@ public class DefaultTestHostManager : ITestRuntimeProvider2
private readonly IFileHelper _fileHelper;
private readonly IEnvironment _environment;
private readonly IDotnetHostHelper _dotnetHostHelper;
private readonly IEnvironmentVariableHelper _environmentVariableHelper;

private ITestHostLauncher _customTestHostLauncher;
private Process _testHostProcess;
Expand All @@ -68,7 +70,12 @@ public class DefaultTestHostManager : ITestRuntimeProvider2
/// Initializes a new instance of the <see cref="DefaultTestHostManager"/> class.
/// </summary>
public DefaultTestHostManager()
: this(new ProcessHelper(), new FileHelper(), new PlatformEnvironment(), new DotnetHostHelper())
: this(
new ProcessHelper(),
new FileHelper(),
new DotnetHostHelper(),
new PlatformEnvironment(),
new EnvironmentVariableHelper())
{
}

Expand All @@ -79,12 +86,18 @@ public DefaultTestHostManager()
/// <param name="fileHelper">File helper instance.</param>
/// <param name="environment">Instance of platform environment.</param>
/// <param name="dotnetHostHelper">Instance of dotnet host helper.</param>
internal DefaultTestHostManager(IProcessHelper processHelper, IFileHelper fileHelper, IEnvironment environment, IDotnetHostHelper dotnetHostHelper)
internal DefaultTestHostManager(
IProcessHelper processHelper,
IFileHelper fileHelper,
IDotnetHostHelper dotnetHostHelper,
IEnvironment environment,
IEnvironmentVariableHelper environmentVariableHelper)
{
_processHelper = processHelper;
_fileHelper = fileHelper;
_environment = environment;
_dotnetHostHelper = dotnetHostHelper;
_environment = environment;
_environmentVariableHelper = environmentVariableHelper;
}

/// <inheritdoc/>
Expand Down Expand Up @@ -469,8 +482,31 @@ private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToke
_processHelper.SetExitCallback(processId, ExitCallBack);
}

if (_testHostProcess is null)
{
return false;
}

SetProcessPriority(_testHostProcess, _environmentVariableHelper);
OnHostLaunched(new HostProviderEventArgs("Test Runtime launched", 0, _testHostProcess.Id));
return _testHostProcess != null;

return true;
}

internal static void SetProcessPriority(Process testHostProcess, IEnvironmentVariableHelper environmentVariableHelper)
{
ProcessPriorityClass testHostPriority = ProcessPriorityClass.BelowNormal;
try
{
testHostPriority = environmentVariableHelper.GetEnvironmentVariableAsEnum("VSTEST_HOST_INTERNAL_PRIORITY", testHostPriority);
testHostProcess.PriorityClass = testHostPriority;
EqtTrace.Verbose("Setting test host process priority to {0}", testHostProcess.PriorityClass);
}
// Setting the process Priority can fail with Win32Exception, NotSupportedException or InvalidOperationException.
catch (Exception ex)
{
EqtTrace.Error("Failed to set test host process priority to {0}. Exception: {1}", testHostPriority, ex);
}
}

private string GetUwpSources(string uwpSource)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -688,9 +688,14 @@ private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToke
_processHelper.SetExitCallback(processId, ExitCallBack);
}

OnHostLaunched(new HostProviderEventArgs("Test Runtime launched", 0, _testHostProcess.Id));
if (_testHostProcess is null)
{
return false;
}

return _testHostProcess != null;
DefaultTestHostManager.SetProcessPriority(_testHostProcess, _environmentVariableHelper);
OnHostLaunched(new HostProviderEventArgs("Test Runtime launched", 0, _testHostProcess.Id));
return true;
}

private string GetTestHostPath(string runtimeConfigDevPath, string depsFilePath, string sourceDirectory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Threading.Tasks;

using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Extensions;
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Helpers;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Helpers.Interfaces;
using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting;
Expand Down Expand Up @@ -39,6 +40,7 @@ public class DefaultTestHostManagerTests
private readonly Mock<IFileHelper> _mockFileHelper;
private readonly Mock<IDotnetHostHelper> _mockDotnetHostHelper;
private readonly Mock<IEnvironment> _mockEnvironment;
private readonly Mock<IEnvironmentVariableHelper> _mockEnvironmentVariable;
private readonly DefaultTestHostManager _testHostManager;

private TestableTestHostManager? _testableTestHostManager;
Expand All @@ -53,10 +55,11 @@ public DefaultTestHostManagerTests()
_mockProcessHelper.Setup(ph => ph.GetCurrentProcessFileName()).Returns("vstest.console.exe");
_mockDotnetHostHelper = new Mock<IDotnetHostHelper>();
_mockEnvironment = new Mock<IEnvironment>();
_mockEnvironmentVariable = new Mock<IEnvironmentVariableHelper>();

_mockMessageLogger = new Mock<IMessageLogger>();

_testHostManager = new DefaultTestHostManager(_mockProcessHelper.Object, _mockFileHelper.Object, _mockEnvironment.Object, _mockDotnetHostHelper.Object);
_testHostManager = new DefaultTestHostManager(_mockProcessHelper.Object, _mockFileHelper.Object, _mockDotnetHostHelper.Object, _mockEnvironment.Object, _mockEnvironmentVariable.Object);
_testHostManager.Initialize(_mockMessageLogger.Object, $"<?xml version=\"1.0\" encoding=\"utf-8\"?><RunSettings> <RunConfiguration> <TargetPlatform>{Architecture.X64}</TargetPlatform> <TargetFrameworkVersion>{Framework.DefaultFramework}</TargetFrameworkVersion> <DisableAppDomain>{false}</DisableAppDomain> </RunConfiguration> </RunSettings>");
_startInfo = _testHostManager.GetTestHostProcessStartInfo(Enumerable.Empty<string>(), null, default);
}
Expand Down Expand Up @@ -592,7 +595,7 @@ public TestableTestHostManager(
IProcessHelper processHelper,
bool shared,
IMessageLogger logger)
: base(processHelper, new FileHelper(), new PlatformEnvironment(), new DotnetHostHelper())
: base(processHelper, new FileHelper(), new DotnetHostHelper(), new PlatformEnvironment(), new EnvironmentVariableHelper())
{
Initialize(logger, $"<?xml version=\"1.0\" encoding=\"utf-8\"?><RunSettings> <RunConfiguration> <TargetPlatform>{architecture}</TargetPlatform> <TargetFrameworkVersion>{framework}</TargetFrameworkVersion> <DisableAppDomain>{!shared}</DisableAppDomain> </RunConfiguration> </RunSettings>");
}
Expand Down

0 comments on commit d2fc0fc

Please sign in to comment.