Skip to content

Commit 6dc4b13

Browse files
prefactor for grouping huge number of tests + fix build break
1 parent 38ff6a0 commit 6dc4b13

File tree

3 files changed

+53
-43
lines changed

3 files changed

+53
-43
lines changed

src/RustAnalyzer.TestAdapter/Common/StringExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Text;
45
using System.Text.RegularExpressions;
@@ -41,4 +42,9 @@ public static string RegexReplace(this string @this, string pattern, string repl
4142
{
4243
return Regex.Replace(@this, pattern, replacement);
4344
}
45+
46+
public static IEnumerable<IEnumerable<string>> PartitionBasedOnMaxCombinedLength(this IEnumerable<string> @this, int maxLength)
47+
{
48+
return new[] { @this };
49+
}
4450
}

src/RustAnalyzer.TestAdapter/TestExecutor.cs

Lines changed: 46 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrame
3737
.Select(async x =>
3838
{
3939
var (c, tcs) = await x;
40-
var ts = c.TestExes.Select(async exe => await RunAndRecordTestResultsFromOneExe(exe, tcs, TestRunParams.FromContainer(c), runContext.IsBeingDebugged, frameworkHandle, tl, ct));
41-
Task.WaitAll(ts.ToArray());
40+
c.TestExes.ForEach(exe => RunAndRecordTestResultsFromOneExe(exe, tcs, TestRunParams.FromContainer(c), runContext.IsBeingDebugged, frameworkHandle, tl, ct));
4241
});
4342

4443
Task.WaitAll(tasks.ToArray());
@@ -61,7 +60,7 @@ public static async Task RunTestsTestsFromOneSourceAsync(TestContainer container
6160
{
6261
foreach (var (tsi, tcs) in await container.DiscoverTestCasesFromOneSourceAsync(tl, ct))
6362
{
64-
await RunAndRecordTestResultsFromOneExe(tsi.Exe, tcs, TestRunParams.FromContainer(container), runContext.IsBeingDebugged, fh, tl, ct);
63+
RunAndRecordTestResultsFromOneExe(tsi.Exe, tcs, TestRunParams.FromContainer(container), runContext.IsBeingDebugged, fh, tl, ct);
6564
}
6665
}
6766

@@ -70,15 +69,30 @@ public void Cancel()
7069
_cancelled = true;
7170
}
7271

73-
private static async Task RunAndRecordTestResultsFromOneExe(PathEx exe, IEnumerable<TestCase> testCases, TestRunParams trp, bool isBeingDebugged, IFrameworkHandle fh, TL tl, CancellationToken ct)
72+
private static void RunAndRecordTestResultsFromOneExe(PathEx exe, IEnumerable<TestCase> testCases, TestRunParams trp, bool isBeingDebugged, IFrameworkHandle fh, TL tl, CancellationToken ct)
7473
{
74+
tl.L.WriteLine("RunTestsFromOneExe starting with {0}, {1}, {2}", trp.Source, exe, testCases.Count());
75+
if (!testCases.Any())
76+
{
77+
tl.L.WriteError("RunTestsFromOneSourceAsync: Something has gone wrong. Asking to run empty set of test cases. {0}, {1}", trp.Source, exe);
78+
}
79+
7580
try
7681
{
77-
var testResults = await RunTestsFromOneExe(exe, testCases, trp, tl, isBeingDebugged, fh, ct);
78-
foreach (var testResult in testResults)
79-
{
80-
fh.RecordResult(testResult);
81-
}
82+
var envDict = trp.TestExecutionEnvironment.OverrideProcessEnvironment();
83+
var testCasesMap = testCases.ToImmutableDictionary(x => x.FullyQualifiedNameRustFormat());
84+
var args = testCases.Select(tc => tc.FullyQualifiedNameRustFormat());
85+
var grps = args
86+
.PartitionBasedOnMaxCombinedLength(20000)
87+
.Select(x =>
88+
x
89+
.Concat(new[] { "--exact", "--format", "json", "-Zunstable-options", "--report-time" })
90+
.Concat(trp.AdditionalTestExecutionArguments.FromNullSeparatedArray()));
91+
Parallel.Invoke(
92+
grps
93+
.Select(args => RunTestsFromOneExe(exe, args.ToArray(), testCasesMap, envDict, tl, isBeingDebugged, fh, ct))
94+
.Select(t => (Action)(() => t.Wait()))
95+
.ToArray());
8296
}
8397
catch (Exception e)
8498
{
@@ -88,21 +102,10 @@ private static async Task RunAndRecordTestResultsFromOneExe(PathEx exe, IEnumera
88102
}
89103
}
90104

91-
private static async Task<IEnumerable<TestResult>> RunTestsFromOneExe(PathEx exe, IEnumerable<TestCase> testCases, TestRunParams trp, TL tl, bool isBeingDebugged, IFrameworkHandle fh, CancellationToken ct)
105+
private static async Task RunTestsFromOneExe(PathEx exe, string[] args, IReadOnlyDictionary<string, TestCase> testCasesMap, IDictionary<string, string> envDict, TL tl, bool isBeingDebugged, IFrameworkHandle fh, CancellationToken ct)
92106
{
93-
tl.L.WriteLine("RunTestsFromOneExe starting with {0}, {1}", trp.Source, exe);
94-
if (!testCases.Any())
95-
{
96-
tl.L.WriteError("RunTestsFromOneSourceAsync: Something has gone wrong. Asking to run empty set of test cases. {0}, {1}", trp.Source, exe);
97-
}
98-
99-
var args = testCases
100-
.Select(tc => tc.FullyQualifiedNameRustFormat())
101-
.Concat(new[] { "--exact", "--format", "json", "-Zunstable-options", "--report-time" })
102-
.Concat(trp.AdditionalTestExecutionArguments.FromNullSeparatedArray())
103-
.ToArray();
104-
var envDict = trp.TestExecutionEnvironment.OverrideProcessEnvironment();
105-
tl.T.TrackEvent("RunTestsFromOneSourceAsync", ("IsBeingDebugged", $"{isBeingDebugged}"), ("Args", string.Join("|", args)), ("Env", trp.TestExecutionEnvironment.ReplaceNullWithBar()));
107+
tl.T.TrackEvent("RunTestsFromOneSourceAsync", ("IsBeingDebugged", $"{isBeingDebugged}"), ("Args", string.Join("|", args)));
108+
var trs = Enumerable.Empty<TestResult>();
106109
if (isBeingDebugged)
107110
{
108111
tl.L.WriteLine("RunTestsFromOneSourceAsync launching test under debugger.");
@@ -111,30 +114,31 @@ private static async Task<IEnumerable<TestResult>> RunTestsFromOneExe(PathEx exe
111114
{
112115
tl.L.WriteError("RunTestsFromOneSourceAsync launching test under debugger - returned {0}.", rc);
113116
}
117+
}
118+
else
119+
{
120+
using var testExeProc = await ProcessRunner.RunWithLogging(exe, args, exe.GetDirectoryName(), envDict, ct, tl.L, @throw: false);
121+
trs = testExeProc.StandardOutputLines
122+
.Skip(1)
123+
.Take(testExeProc.StandardOutputLines.Count() - 2)
124+
.Select(JsonConvert.DeserializeObject<TestRunInfo>)
125+
.Where(x => x.Event != TestRunInfo.EventType.Started)
126+
.OrderBy(x => x.FQN)
127+
.Select(x => ToTestResult(exe, x, testCasesMap));
128+
var ec = testExeProc.ExitCode ?? 0;
129+
if (ec != 0 && !trs.Any())
130+
{
131+
tl.L.WriteError("RunTestsFromOneSourceAsync test executable exited with code {0}.", ec);
132+
throw new ApplicationException($"Test executable returned {ec}. Check above for the arguments passed to test executable by running it on the command line.");
133+
}
114134

115-
return Enumerable.Empty<TestResult>();
135+
tl.T.TrackEvent("RunTestsFromOneSourceAsync", ("Results", $"{trs.Count()}"));
116136
}
117137

118-
using var testExeProc = await ProcessRunner.RunWithLogging(exe, args, exe.GetDirectoryName(), envDict, ct, tl.L, @throw: false);
119-
120-
var testCasesMap = testCases.ToImmutableDictionary(x => x.FullyQualifiedNameRustFormat());
121-
var tris = testExeProc.StandardOutputLines
122-
.Skip(1)
123-
.Take(testExeProc.StandardOutputLines.Count() - 2)
124-
.Select(JsonConvert.DeserializeObject<TestRunInfo>)
125-
.Where(x => x.Event != TestRunInfo.EventType.Started)
126-
.OrderBy(x => x.FQN)
127-
.Select(x => ToTestResult(exe, x, testCasesMap));
128-
var ec = testExeProc.ExitCode ?? 0;
129-
if (ec != 0 && !tris.Any())
138+
foreach (var tr in trs)
130139
{
131-
tl.L.WriteError("RunTestsFromOneSourceAsync test executable exited with code {0}.", ec);
132-
throw new ApplicationException($"Test executable returned {ec}. Check above for the arguments passed to test executable by running it on the command line.");
140+
fh.RecordResult(tr);
133141
}
134-
135-
tl.T.TrackEvent("RunTestsFromOneSourceAsync", ("Results", $"{tris.Count()}"));
136-
137-
return tris;
138142
}
139143

140144
private static TestResult ToTestResult(PathEx exe, TestRunInfo tri, IReadOnlyDictionary<string, TestCase> testCasesMap)

src/TestProjects/workspace_with_tests/integrationtests.approved.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1313
[Passed] add_one.tests.multiplication_tests.when_operands_are_swapped
1414
[Passed] add_one.tests.should_fail
1515
[Passed] add_one.tests.should_success
16-
[Failed] adder.tests.it_works_failing thread 'tests::it_works_failing' panicked at adder\src/main.rs:34:9:
16+
[Failed] adder.tests.it_works_failing thread 'tests::it_works_failing' panicked at adder\src\main.rs:34:9:
1717
assertion `left == right` failed
1818
left: 3
1919
right: 5

0 commit comments

Comments
 (0)