@@ -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 )
0 commit comments