diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs
index 5e61617f1a..08a2a113d5 100644
--- a/src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs
+++ b/src/Microsoft.TestPlatform.CrossPlatEngine/TestEngine.cs
@@ -35,25 +35,31 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine;
public class TestEngine : ITestEngine
{
private readonly ITestRuntimeProviderManager _testHostProviderManager;
- private ITestExtensionManager _testExtensionManager;
private readonly IProcessHelper _processHelper;
+ private readonly IEnvironment _environment;
+
+ private ITestExtensionManager _testExtensionManager;
- public TestEngine() : this(TestRuntimeProviderManager.Instance, new ProcessHelper())
+ public TestEngine()
+ : this(TestRuntimeProviderManager.Instance, new ProcessHelper())
{
}
protected internal TestEngine(
TestRuntimeProviderManager testHostProviderManager,
- IProcessHelper processHelper) : this((ITestRuntimeProviderManager)testHostProviderManager, processHelper)
+ IProcessHelper processHelper)
+ : this(testHostProviderManager, processHelper, new PlatformEnvironment())
{
}
internal TestEngine(
ITestRuntimeProviderManager testHostProviderManager,
- IProcessHelper processHelper)
+ IProcessHelper processHelper,
+ IEnvironment environment)
{
_testHostProviderManager = testHostProviderManager;
_processHelper = processHelper;
+ _environment = environment;
}
#region ITestEngine implementation
@@ -492,15 +498,21 @@ private int VerifyParallelSettingAndCalculateParallelLevel(
// Check the user parallel setting.
int userParallelSetting = RunSettingsUtilities.GetMaxCpuCount(runSettings);
parallelLevelToUse = userParallelSetting == 0
- // TODO: use environment helper so we can control this from tests.
- ? Environment.ProcessorCount
+ ? _environment.ProcessorCount
: userParallelSetting;
- var enableParallel = parallelLevelToUse > 1;
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.
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/System/IEnvironment.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/System/IEnvironment.cs
index 6e3e745cb1..7af77732e5 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/System/IEnvironment.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/Interfaces/System/IEnvironment.cs
@@ -34,4 +34,7 @@ public interface IEnvironment
///
/// Returns the thread Id
int GetCurrentManagedThreadId();
+
+ ///
+ int ProcessorCount { get; }
}
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/PublicAPI.Shipped.txt
index 9a6ec487a0..759b9e899a 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/PublicAPI.Shipped.txt
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/PublicAPI/PublicAPI.Shipped.txt
@@ -36,6 +36,7 @@ Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IAssemblyRes
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IAssemblyResolver.AssemblyResolve -> Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.AssemblyResolveEventHandler?
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IEnvironment
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IEnvironment.Architecture.get -> Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformArchitecture
+Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IEnvironment.ProcessorCount.get -> int
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IEnvironment.Exit(int exitcode) -> void
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IEnvironment.GetCurrentManagedThreadId() -> int
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IEnvironment.OperatingSystem.get -> Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformOperatingSystem
@@ -79,6 +80,7 @@ Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolve
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformAssemblyResolver.PlatformAssemblyResolver() -> void
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformEnvironment
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformEnvironment.Architecture.get -> Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformArchitecture
+Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformEnvironment.ProcessorCount.get -> int
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformEnvironment.Exit(int exitcode) -> void
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformEnvironment.GetCurrentManagedThreadId() -> int
Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformEnvironment.OperatingSystem.get -> Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.PlatformOperatingSystem
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/PlatformEnvironment.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/PlatformEnvironment.cs
index 202263d19f..09fb1ea528 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/PlatformEnvironment.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/PlatformEnvironment.cs
@@ -73,6 +73,9 @@ public PlatformOperatingSystem OperatingSystem
///
public string OperatingSystemVersion => Environment.OSVersion.ToString();
+ ///
+ public int ProcessorCount => Environment.ProcessorCount;
+
///
public void Exit(int exitcode)
{
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/netcore/System/PlatformEnvironment.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/netcore/System/PlatformEnvironment.cs
index 61e73c0455..10d4a61570 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/netcore/System/PlatformEnvironment.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/netcore/System/PlatformEnvironment.cs
@@ -56,6 +56,9 @@ public string OperatingSystemVersion
}
}
+ ///
+ public int ProcessorCount => Environment.ProcessorCount;
+
///
public void Exit(int exitcode)
{
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard/System/PlatformEnvironment.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard/System/PlatformEnvironment.cs
index 61d274b2bd..377cf4b4d4 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard/System/PlatformEnvironment.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/netstandard/System/PlatformEnvironment.cs
@@ -39,6 +39,9 @@ public string OperatingSystemVersion
}
}
+ ///
+ public int ProcessorCount => throw new NotImplementedException();
+
///
public void Exit(int exitcode)
{
diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/System/PlatformEnvironment.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/System/PlatformEnvironment.cs
index 3be2617a80..9c53b9b678 100644
--- a/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/System/PlatformEnvironment.cs
+++ b/src/Microsoft.TestPlatform.PlatformAbstractions/uap10.0/System/PlatformEnvironment.cs
@@ -33,6 +33,9 @@ public PlatformOperatingSystem OperatingSystem
///
public string OperatingSystemVersion => RuntimeInformation.OSDescription;
+ ///
+ public int ProcessorCount => Environment.ProcessorCount;
+
///
public void Exit(int exitcode)
{
diff --git a/test/vstest.ProgrammerTests/Fakes/FakeEnvironment.cs b/test/vstest.ProgrammerTests/Fakes/FakeEnvironment.cs
index ea82d8501b..415c42f5b9 100644
--- a/test/vstest.ProgrammerTests/Fakes/FakeEnvironment.cs
+++ b/test/vstest.ProgrammerTests/Fakes/FakeEnvironment.cs
@@ -16,6 +16,8 @@ internal class FakeEnvironment : IEnvironment
public string OperatingSystemVersion => _environment.OperatingSystemVersion;
+ public int ProcessorCount => _environment.ProcessorCount;
+
public void Exit(int exitcode) => _environment.Exit(exitcode);
public int GetCurrentManagedThreadId() => _environment.GetCurrentManagedThreadId();
diff --git a/test/vstest.ProgrammerTests/Fakes/Fixture.cs b/test/vstest.ProgrammerTests/Fakes/Fixture.cs
index 60a38bfc35..afddd891d9 100644
--- a/test/vstest.ProgrammerTests/Fakes/Fixture.cs
+++ b/test/vstest.ProgrammerTests/Fakes/Fixture.cs
@@ -107,7 +107,7 @@ internal TestRequestManagerTestHelper BuildTestRequestManager(
throw new InvalidOperationException("There are runtime providers registered for FakeTestRuntimeProviderManager.");
- TestEngine = new TestEngine(TestRuntimeProviderManager, ProcessHelper);
+ TestEngine = new TestEngine(TestRuntimeProviderManager, ProcessHelper, Environment);
TestPlatform = new TestPlatform(TestEngine, FileHelper, TestRuntimeProviderManager);
TestRunResultAggregator = new TestRunResultAggregator();