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 background option for testhosts #3772

Merged
merged 3 commits into from
Jun 17, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -513,28 +513,42 @@ private int VerifyParallelSettingAndCalculateParallelLevel(
try
{
// Check the user parallel setting.
int userParallelSetting = RunSettingsUtilities.GetMaxCpuCount(runSettings);
parallelLevelToUse = userParallelSetting == 0
int maxCpuCount = RunSettingsUtilities.GetMaxCpuCount(runSettings);
parallelLevelToUse = maxCpuCount == 0
? _environment.ProcessorCount
: userParallelSetting;
: maxCpuCount;

EqtTrace.Verbose(
"TestEngine: Initializing Parallel Execution as MaxCpuCount is set to: {0}",
parallelLevelToUse);

// TODO: EXPERIMENTAL FEATURE - will need to be removed or strengthen/tested.
// A negative value is used to indicate that the value should be used as a percentage of the number of cores.
if (parallelLevelToUse < 0)
{
parallelLevelToUse = (int)Math.Max(1, Math.Round((double)-parallelLevelToUse * _environment.ProcessorCount / 100.0, MidpointRounding.AwayFromZero));
}

var enableParallel = parallelLevelToUse > 1;
// Verify if the number of sources is less than user setting of parallel.
// We should use number of sources as the parallel level, if sources count is less
// than parallel level.
if (enableParallel)
{
// In case of a background discovery we want to reduce the number of cores utilized
// to leave enough power for other tasks.
var runSettingsEnvVariables = InferRunSettingsHelper.GetEnvironmentVariables(runSettings);
string isBackgroundDiscoveryEnabled = null;
if (runSettingsEnvVariables is not null
&& runSettingsEnvVariables.TryGetValue("VSTEST_BACKGROUND_DISCOVERY", out isBackgroundDiscoveryEnabled)
&& isBackgroundDiscoveryEnabled == "1"
&& maxCpuCount == 0) // If user specifies a CPU count, respect it
{
// Dummy logic based on some observations, might need to be tweaked/improved.
parallelLevelToUse = parallelLevelToUse switch
{
1 => 1,
< 8 => (int)Math.Round(parallelLevelToUse / 2.0, MidpointRounding.AwayFromZero),
_ => (int)Math.Round(0.75 * parallelLevelToUse, MidpointRounding.AwayFromZero),
};
}

EqtTrace.Verbose("TestEngine.VerifyParallelSettingAndCalculateParallelLevel: Parallel execution is enabled (cpu count: {0}, max cpu count is {1}, calculated cpu count is {2}, background mode is {3}, number of sources is {4})", _environment.ProcessorCount, maxCpuCount, parallelLevelToUse, isBackgroundDiscoveryEnabled == "1" ? "enabled" : "disabled", sourceCount);


parallelLevelToUse = Math.Min(sourceCount, parallelLevelToUse);
Evangelink marked this conversation as resolved.
Show resolved Hide resolved

// If only one source, no need to use parallel service client.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ public void Initialize(IMessageLogger logger, string runsettingsXml)

Shared = !runConfiguration.DisableAppDomain;
_hostExitedEventRaised = false;

IsInitialized = true;
}

Expand Down Expand Up @@ -506,20 +507,24 @@ private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToke
return false;
}

SetProcessPriority(_testHostProcess, _environmentVariableHelper);
AdjustProcessPriorityBasedOnSettings(_testHostProcess, testHostStartInfo.EnvironmentVariables);
OnHostLaunched(new HostProviderEventArgs("Test Runtime launched", 0, _testHostProcess.Id));

return true;
}

internal static void SetProcessPriority(Process testHostProcess, IEnvironmentVariableHelper environmentVariableHelper)
internal static void AdjustProcessPriorityBasedOnSettings(Process testHostProcess, IDictionary<string, string?>? testHostEnvironmentVariables)
{
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);
if (testHostEnvironmentVariables is not null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Evangelink @nohwnd I am not familiar with the code base - but is DefaultTestHostManager also used when parallel is not in play?

Just want to make sure that it is possible to create low prio test hosts -
a) regardless of whether parallel is turned on and
b) regardless of whether the operation requested is execution versus discovery

Also if the answer to b) above is yes, then it may be better to rename this to something more general like VSTEST_BACKGROUND_OPERATION or VSTEST_BACKGROUND_PRIORITY :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that code is used even in "sequential". This is used to decide on the level of parallelism (including sequential) to use.

&& testHostEnvironmentVariables.TryGetValue("VSTEST_BACKGROUND_DISCOVERY", out var isBackgroundDiscoveryEnabled)
&& isBackgroundDiscoveryEnabled == "1")
{
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToke
return false;
}

DefaultTestHostManager.SetProcessPriority(_testHostProcess, _environmentVariableHelper);
DefaultTestHostManager.AdjustProcessPriorityBasedOnSettings(_testHostProcess, testHostStartInfo.EnvironmentVariables);
OnHostLaunched(new HostProviderEventArgs("Test Runtime launched", 0, _testHostProcess.Id));
return true;
}
Expand Down