Skip to content

Commit b8be108

Browse files
committed
Add multiplier format support to RunSettings
1 parent 3c2e493 commit b8be108

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

src/xunit.runner.visualstudio/Utility/RunSettings.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Globalization;
23
using System.Text.RegularExpressions;
34

45
namespace Xunit.Runner.VisualStudio;
@@ -94,8 +95,28 @@ public static RunSettings Parse(string? settingsXml)
9495
result.LongRunningTestSeconds = longRunningTestSeconds;
9596

9697
var maxParallelThreadsString = xunitElement.Element(Constants.Xunit.MaxParallelThreads)?.Value;
97-
if (int.TryParse(maxParallelThreadsString, out var maxParallelThreads) && maxParallelThreads >= -1)
98-
result.MaxParallelThreads = maxParallelThreads;
98+
if (maxParallelThreadsString is not null)
99+
switch (maxParallelThreadsString)
100+
{
101+
case "default":
102+
result.MaxParallelThreads = 0;
103+
break;
104+
105+
case "unlimited":
106+
result.MaxParallelThreads = -1;
107+
break;
108+
109+
default:
110+
var match = ConfigUtility.MultiplierStyleMaxParallelThreadsRegex.Match(maxParallelThreadsString);
111+
// Use invariant format and convert ',' to '.' so we can always support both formats, regardless of locale
112+
// If we stick to locale-only parsing, we could break people when moving from one locale to another (for example,
113+
// from people running tests on their desktop in a comma locale vs. running them in CI with a decimal locale).
114+
if (match.Success && decimal.TryParse(match.Groups[1].Value.Replace(',', '.'), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var maxThreadMultiplier))
115+
result.MaxParallelThreads = (int)(maxThreadMultiplier * Environment.ProcessorCount);
116+
else if (int.TryParse(maxParallelThreadsString, out var threadValue) && threadValue >= -1)
117+
result.MaxParallelThreads = threadValue;
118+
break;
119+
}
99120

100121
var methodDisplayString = xunitElement.Element(Constants.Xunit.MethodDisplay)?.Value;
101122
if (Enum.TryParse<TestMethodDisplay>(methodDisplayString, ignoreCase: true, out var methodDisplay))

test/test.xunit.runner.visualstudio/RunSettingsTests.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using Xunit;
23
using Xunit.Runner.VisualStudio;
34

@@ -16,6 +17,7 @@ void AssertDefaultValues(RunSettings runSettings)
1617
Assert.Null(runSettings.MethodDisplay);
1718
Assert.Null(runSettings.MethodDisplayOptions);
1819
Assert.Null(runSettings.NoAutoReporters);
20+
Assert.Null(runSettings.ParallelAlgorithm);
1921
Assert.Null(runSettings.ParallelizeAssembly);
2022
Assert.Null(runSettings.ParallelizeTestCollections);
2123
Assert.Null(runSettings.PreEnumerateTheories);
@@ -182,11 +184,21 @@ public void LongRunningTestSeconds(int value, int? expected)
182184
Assert.Equal(expected, runSettings.LongRunningTestSeconds);
183185
}
184186

187+
public static readonly TheoryData<string, int?> MaxParallelThreadData = new()
188+
{
189+
{ "blarch", null },
190+
{ "-2", null },
191+
{ "-1", -1 },
192+
{ "0", 0 },
193+
{ "42", 42 },
194+
{ "unlimited", -1 },
195+
{ "default", 0 },
196+
{ "2.0x", Environment.ProcessorCount * 2 },
197+
};
198+
185199
[Theory]
186-
[InlineData(-2, null)]
187-
[InlineData(-1, -1)]
188-
[InlineData(42, 42)]
189-
public void MaxParallelThreads(int value, int? expected)
200+
[MemberData(nameof(MaxParallelThreadData))]
201+
public void MaxParallelThreads(string value, int? expected)
190202
{
191203
string settingsXml =
192204
$@"<?xml version=""1.0"" encoding=""utf-8""?>

0 commit comments

Comments
 (0)