@@ -133,7 +133,72 @@ void CleanResults(string resultsDir)
133133 }
134134}
135135
136- void HandleTestResults ( string resultsDir , bool testsFailed , bool needsNameFix )
136+ List < string > GetTestCategoriesToRunSeparately ( string projectPath )
137+ {
138+
139+ if ( ! string . IsNullOrEmpty ( testFilter ) )
140+ {
141+ return new List < string > { testFilter } ;
142+ }
143+
144+ if ( ! projectPath . EndsWith ( "Controls.DeviceTests.csproj" ) && ! projectPath . EndsWith ( "Core.DeviceTests.csproj" ) )
145+ {
146+ return new List < string >
147+ {
148+ ""
149+ } ;
150+ }
151+
152+ var file = Context . GetCallerInfo ( ) . SourceFilePath ;
153+ var directoryPath = file . GetDirectory ( ) . FullPath ;
154+ Information ( $ "Directory: { directoryPath } ") ;
155+ Information ( directoryPath ) ;
156+
157+ // Search for files that match the pattern
158+ List < FilePath > dllFilePath = null ;
159+
160+ if ( projectPath . EndsWith ( "Controls.DeviceTests.csproj" ) )
161+ dllFilePath = GetFiles ( $ "{ directoryPath } /../../**/Microsoft.Maui.Controls.DeviceTests.dll") . ToList ( ) ;
162+
163+ if ( projectPath . EndsWith ( "Core.DeviceTests.csproj" ) )
164+ dllFilePath = GetFiles ( $ "{ directoryPath } /../../**/Microsoft.Maui.Core.DeviceTests.dll") . ToList ( ) ;
165+
166+ System . Reflection . Assembly loadedAssembly = null ;
167+
168+ foreach ( var filePath in dllFilePath )
169+ {
170+ try
171+ {
172+ loadedAssembly = System . Reflection . Assembly . LoadFrom ( filePath . FullPath ) ;
173+ Information ( $ "Loaded assembly from { filePath } : { loadedAssembly . FullName } ") ;
174+ break ; // Exit the loop if the assembly is loaded successfully
175+ }
176+ catch ( Exception ex )
177+ {
178+ Warning ( $ "Failed to load assembly from { filePath } : { ex . Message } ") ;
179+ }
180+ }
181+
182+ if ( loadedAssembly == null )
183+ {
184+ throw new Exception ( "No test assembly found." ) ;
185+ }
186+ var testCategoryType = loadedAssembly . GetType ( "Microsoft.Maui.DeviceTests.TestCategory" ) ;
187+
188+ var values = new List < string > ( ) ;
189+
190+ foreach ( var field in testCategoryType . GetFields ( System . Reflection . BindingFlags . Public | System . Reflection . BindingFlags . Static ) )
191+ {
192+ if ( field . FieldType == typeof ( string ) )
193+ {
194+ values . Add ( $ "Category={ ( string ) field . GetValue ( null ) } ") ;
195+ }
196+ }
197+
198+ return values . ToList ( ) ;
199+ }
200+
201+ void HandleTestResults ( string resultsDir , bool testsFailed , bool needsNameFix , string suffix = null )
137202{
138203 Information ( $ "Handling test results: { resultsDir } ") ;
139204
@@ -145,10 +210,24 @@ void HandleTestResults(string resultsDir, bool testsFailed, bool needsNameFix)
145210 {
146211 throw new Exception ( "No test results found." ) ;
147212 }
213+
148214 if ( FileExists ( resultsFile ) )
149215 {
150216 Information ( $ "Test results found on { resultsDir } ") ;
151- CopyFile ( resultsFile , resultsFile . GetDirectory ( ) . CombineWithFilePath ( "TestResults.xml" ) ) ;
217+ MoveFile ( resultsFile , resultsFile . GetDirectory ( ) . CombineWithFilePath ( $ "TestResults{ suffix } .xml") ) ;
218+ var logFiles = GetFiles ( $ "{ resultsDir } /*.log") ;
219+
220+ foreach ( var logFile in logFiles )
221+ {
222+ if ( logFile . GetFilename ( ) . ToString ( ) . StartsWith ( "TestResults" ) )
223+ {
224+ // These are log files that have already been renamed
225+ continue ;
226+ }
227+
228+ Information ( $ "Log file found: { logFile . GetFilename ( ) . ToString ( ) } ") ;
229+ MoveFile ( logFile , resultsFile . GetDirectory ( ) . CombineWithFilePath ( $ "TestResults{ suffix } -{ logFile . GetFilename ( ) } ") ) ;
230+ }
152231 }
153232 }
154233
@@ -158,12 +237,21 @@ void HandleTestResults(string resultsDir, bool testsFailed, bool needsNameFix)
158237 EnsureDirectoryExists ( failurePath ) ;
159238 // The tasks will retry the tests and overwrite the failed results each retry
160239 // we want to retain the failed results for diagnostic purposes
161- CopyFiles ( $ "{ resultsDir } /*.*", failurePath ) ;
240+
241+ var searchQuery = "*.*" ;
242+
243+ if ( ! string . IsNullOrWhiteSpace ( suffix ) )
244+ {
245+ searchQuery = $ "*{ suffix } *.*";
246+ }
247+
248+ // Only copy files from this suffix set of failures
249+ CopyFiles ( $ "{ resultsDir } /{ searchQuery } ", failurePath ) ;
162250
163251 // We don't want these to upload
164- MoveFile ( $ "{ failurePath } /TestResults.xml", $ "{ failurePath } /Results.xml") ;
252+ MoveFile ( $ "{ failurePath } /TestResults{ suffix } .xml", $ "{ failurePath } /Results{ suffix } .xml") ;
165253 }
166- FailRunOnOnlyInconclusiveTests ( $ "{ resultsDir } /TestResults.xml") ;
254+ FailRunOnOnlyInconclusiveTests ( $ "{ resultsDir } /TestResults{ suffix } .xml") ;
167255}
168256
169257DirectoryPath DetermineBinlogDirectory ( string projectPath , string binlogArg )
@@ -185,6 +273,67 @@ DirectoryPath DetermineBinlogDirectory(string projectPath, string binlogArg)
185273 }
186274}
187275
276+ void RunMacAndiOSTests (
277+ string project , string device , string resultsDir , string config , string tfm , string rid , string toolPath , string projectPath ,
278+ Func < string , DotNetToolSettings > getSettings )
279+ {
280+ Exception exception = null ;
281+ foreach ( var category in GetTestCategoriesToRunSeparately ( projectPath ) )
282+ {
283+ bool testsFailed = true ;
284+ Information ( $ "Running tests for category: { category } ") ;
285+ var settings = getSettings ( category ) ;
286+ var suffix = category . Split ( '=' ) . Skip ( 1 ) . FirstOrDefault ( ) ;
287+
288+ try
289+ {
290+ for ( int i = 0 ; i < 2 ; i ++ )
291+ {
292+ Information ( $ "Running test attempt { i } ") ;
293+ try
294+ {
295+ DotNetTool ( "tool" , settings ) ;
296+ testsFailed = false ;
297+ break ;
298+ }
299+ catch ( Exception ex )
300+ {
301+ Information ( $ "Test attempt { i } failed: { ex . Message } ") ;
302+ if ( i == 1 )
303+ {
304+ throw ;
305+ }
306+ else
307+ {
308+ // delete any log files created so it's fresh for the rerun
309+ HandleTestResults ( resultsDir , false , true , "-" + suffix ) ;
310+ var logFiles = GetFiles ( $ "{ resultsDir } /*-{ suffix } *") ;
311+
312+ foreach ( var logFile in logFiles )
313+ {
314+ DeleteFile ( logFile ) ;
315+ }
316+ }
317+ }
318+ }
319+ }
320+ catch ( Exception ex )
321+ {
322+ exception = ex ;
323+ }
324+ finally
325+ {
326+ HandleTestResults ( resultsDir , testsFailed , true , "-" + suffix ) ;
327+ }
328+ }
329+
330+ Information ( "Testing completed." ) ;
331+ if ( exception is not null )
332+ {
333+ throw exception ;
334+ }
335+ }
336+
188337void LogSetupInfo ( string toolPath )
189338{
190339 Information ( $ "DOTNET_TOOL_PATH: { toolPath } ") ;
0 commit comments