2016-05-26 16:06:52 +03:00
using System ;
using Mono.Options ;
2020-04-01 20:32:21 +03:00
using Microsoft.DotNet.XHarness.iOS.Shared.Utilities ;
2020-11-13 19:05:10 +03:00
using Microsoft.DotNet.XHarness.iOS.Shared.XmlResults ;
using Microsoft.DotNet.XHarness.Common ;
2016-05-26 16:06:52 +03:00
2020-03-03 21:59:44 +03:00
namespace Xharness {
class MainClass {
public static int Main ( string [ ] args )
2016-05-26 16:06:52 +03:00
{
2020-04-01 20:32:21 +03:00
Microsoft . DotNet . XHarness . iOS . Shared . SdkVersions . OverrideVersions (
xcode : Xamarin . SdkVersions . Xcode ,
oSX : Xamarin . SdkVersions . OSX ,
iOS : Xamarin . SdkVersions . iOS ,
watchOS : Xamarin . SdkVersions . WatchOS ,
tVOS : Xamarin . SdkVersions . TVOS ,
minOSX : Xamarin . SdkVersions . MinOSX ,
miniOS : Xamarin . SdkVersions . MiniOS ,
minWatchOS : Xamarin . SdkVersions . MinWatchOS ,
minTVOS : Xamarin . SdkVersions . MinTVOS ,
miniOSSimulator : Xamarin . SdkVersions . MiniOSSimulator ,
minWatchOSSimulator : Xamarin . SdkVersions . MinWatchOSSimulator ,
minWatchOSCompanionSimulator : Xamarin . SdkVersions . MinWatchOSCompanionSimulator ,
minTVOSSimulator : Xamarin . SdkVersions . MinTVOSSimulator ,
maxiOSSimulator : Xamarin . SdkVersions . MaxiOSSimulator ,
maxWatchOSSimulator : Xamarin . SdkVersions . MaxWatchOSSimulator ,
maxWatchOSCompanionSimulator : Xamarin . SdkVersions . MaxWatchOSCompanionSimulator ,
maxTVOSSimulator : Xamarin . SdkVersions . MaxTVOSSimulator ,
maxiOSDeploymentTarget : Xamarin . SdkVersions . MaxiOSDeploymentTarget ,
maxWatchDeploymentTarget : Xamarin . SdkVersions . MaxWatchDeploymentTarget ,
maxTVOSDeploymentTarget : Xamarin . SdkVersions . MaxTVOSDeploymentTarget ) ;
2016-05-26 16:06:52 +03:00
Action showHelp = null ;
2020-03-13 17:41:02 +03:00
var action = HarnessAction . None ;
var configuration = new HarnessConfiguration ( ) ;
2016-05-26 16:06:52 +03:00
var os = new OptionSet ( ) {
{ "h|?|help" , "Displays the help" , ( v ) = > showHelp ( ) } ,
2020-03-13 17:41:02 +03:00
{ "v|verbose" , "Show verbose output" , ( v ) = > configuration . Verbosity + + } ,
{ "use-system:" , "Use the system version of Xamarin.iOS/Xamarin.Mac or the locally build version. Default: the locally build version." , ( v ) = > configuration . UseSystemXamarinIOSMac = v = = "1" | | v = = "true" | | string . IsNullOrEmpty ( v ) } ,
2016-05-26 16:06:52 +03:00
// Configure
2020-03-13 17:41:02 +03:00
{ "mac" , "Configure for Xamarin.Mac instead of iOS." , ( v ) = > configuration . Mac = true } ,
{ "configure" , "Creates project files and makefiles." , ( v ) = > action = HarnessAction . Configure } ,
{ "autoconf" , "Automatically decide what to configure." , ( v ) = > configuration . AutoConf = true } ,
2020-06-16 23:04:38 +03:00
{ "rootdir=" , "The root directory for the tests." , ( v ) = > HarnessConfiguration . RootDirectory = v } ,
2020-03-13 17:41:02 +03:00
{ "project=" , "Add a project file to process. This can be specified multiple times." , ( v ) = > configuration . IOSTestProjects . Add ( new iOSTestProject ( v ) ) } ,
{ "watchos-container-template=" , "The directory to use as a template for a watchos container app." , ( v ) = > configuration . WatchOSContainerTemplate = v } ,
{ "watchos-app-template=" , "The directory to use as a template for a watchos app." , ( v ) = > configuration . WatchOSAppTemplate = v } ,
2016-05-26 16:06:52 +03:00
// Run
{ "run=" , "Executes a project." , ( v ) = >
{
2020-03-13 17:41:02 +03:00
action = HarnessAction . Run ;
configuration . IOSTestProjects . Add ( new iOSTestProject ( v ) ) ;
2016-05-26 16:06:52 +03:00
}
} ,
{ "install=" , "Installs a project." , ( v ) = >
{
2020-03-13 17:41:02 +03:00
action = HarnessAction . Install ;
configuration . IOSTestProjects . Add ( new iOSTestProject ( v ) ) ;
2016-05-26 16:06:52 +03:00
}
} ,
2017-01-02 10:58:46 +03:00
{ "uninstall=" , "Uninstalls a project." , ( v ) = >
{
2020-03-13 17:41:02 +03:00
action = HarnessAction . Uninstall ;
configuration . IOSTestProjects . Add ( new iOSTestProject ( v ) ) ;
2017-01-02 10:58:46 +03:00
}
} ,
2020-03-13 17:41:02 +03:00
{ "sdkroot=" , "Where Xcode is" , ( v ) = > configuration . SdkRoot = v } ,
2019-06-17 09:03:58 +03:00
{ "sdkroot94=" , "Where Xcode 9.4 is" , ( v ) = > Console . WriteLine ( "--sdkroot94 is deprecated" ) , true } ,
2020-03-13 17:41:02 +03:00
{ "target=" , "Where to run the project ([ios|watchos|tvos]-[device|simulator|simulator-32|simulator-64])." , ( v ) = > configuration . Target = v . ParseAsAppRunnerTarget ( ) } ,
2020-03-17 21:42:21 +03:00
{ "configuration=" , "Which configuration to run (defaults to Debug)." , ( v ) = > configuration . BuildConfiguration = v } ,
2020-03-13 17:41:02 +03:00
{ "logdirectory=" , "Where to store logs." , ( v ) = > configuration . LogDirectory = v } ,
{ "logfile=" , "Where to store the log." , ( v ) = > Console . WriteLine ( "The logfile option is deprecated. Please use logdirectory." ) , true } ,
{ "timeout=" , $"Timeout for a test run (in minutes). Default is {configuration.TimeoutInMinutes} minutes." , ( v ) = > configuration . TimeoutInMinutes = double . Parse ( v ) } ,
2016-06-06 13:48:53 +03:00
{ "jenkins:" , "Execute test run for jenkins." , ( v ) = >
{
2020-03-13 17:41:02 +03:00
configuration . JenkinsConfiguration = v ;
action = HarnessAction . Jenkins ;
2016-06-06 13:48:53 +03:00
}
} ,
2020-03-13 17:41:02 +03:00
{ "dry-run" , "Only print what would be done." , ( v ) = > configuration . DryRun = true } ,
2016-08-05 23:28:13 +03:00
{ "setenv:" , "Set the specified environment variable when running apps." , ( v ) = >
{
var split = v . Split ( '=' ) ;
2020-03-13 17:41:02 +03:00
configuration . EnvironmentVariables [ split [ 0 ] ] = split [ 1 ] ;
2016-08-05 23:28:13 +03:00
}
} ,
2017-08-03 15:31:02 +03:00
{ "label=" , "Comma-separated list of labels to select which tests to run." , ( v ) = >
{
2020-03-13 17:41:02 +03:00
configuration . Labels . UnionWith ( v . Split ( new char [ ] { ',' } , StringSplitOptions . RemoveEmptyEntries ) ) ;
2017-08-03 15:31:02 +03:00
}
} ,
2020-03-13 17:41:02 +03:00
{ "markdown-summary=" , "The path where a summary (in Markdown format) will be written." , ( v ) = > configuration . MarkdownSummaryPath = v } ,
{ "periodic-command=" , "A command to execute periodically." , ( v ) = > configuration . PeriodicCommand = v } ,
{ "periodic-command-arguments=" , "Arguments to the command to execute periodically." , ( v ) = > configuration . PeriodicCommandArguments = v } ,
{ "periodic-interval=" , "An interval (in minutes) between every attempt to execute the periodic command." , ( v ) = > configuration . PeriodicCommandInterval = TimeSpan . FromMinutes ( double . Parse ( v ) ) } ,
{ "include-system-permission-tests:" , "If tests that require system permissions (which could cause the OS to launch dialogs that hangs the test) should be executed or not. Default is to include such tests." , ( v ) = > configuration . IncludeSystemPermissionTests = ParseBool ( v , "include-system-permission-tests" ) } ,
2020-02-28 04:10:48 +03:00
{ "xml-jargon:" , "The xml format to be used for test results. Values can be nunitv2, nunitv3, xunit." , ( v ) = >
{
if ( Enum . TryParse < XmlResultJargon > ( v , out var jargon ) )
2020-03-13 17:41:02 +03:00
configuration . XmlJargon = jargon ;
2020-02-28 04:10:48 +03:00
else
2020-03-13 17:41:02 +03:00
configuration . XmlJargon = XmlResultJargon . Missing ;
2020-02-28 04:10:48 +03:00
}
} ,
2016-05-26 16:06:52 +03:00
} ;
showHelp = ( ) = > {
os . WriteOptionDescriptions ( Console . Out ) ;
System . Environment . Exit ( 0 ) ;
} ;
var input = os . Parse ( args ) ;
if ( input . Count > 0 )
throw new Exception ( string . Format ( "Unknown arguments: {0}" , string . Join ( ", " , input . ToArray ( ) ) ) ) ;
2020-03-13 17:41:02 +03:00
if ( action = = HarnessAction . None )
2016-05-26 16:06:52 +03:00
showHelp ( ) ;
2016-12-24 18:55:51 +03:00
2020-03-13 17:41:02 +03:00
if ( configuration . XmlJargon = = XmlResultJargon . Missing ) {
2020-02-28 04:10:48 +03:00
Console . WriteLine ( "Unknown xml-jargon value provided. Values can be nunitv2, nunitv3, xunit" ) ;
return 1 ;
}
2020-03-13 17:41:02 +03:00
2016-12-24 18:55:51 +03:00
// XS sets this, which breaks pretty much everything if it doesn't match what was passed to --sdkroot.
Environment . SetEnvironmentVariable ( "XCODE_DEVELOPER_DIR_PATH" , null ) ;
2021-05-26 21:36:48 +03:00
// MSBuild gets confused sometimes, and runs into some sort of deadlock. Disable node re-use to try to mitigate that.
// Ref: https://github.com/xamarin/maccore/issues/2444
Environment . SetEnvironmentVariable ( "MSBUILDDISABLENODEREUSE" , "1" ) ;
2020-03-27 19:41:31 +03:00
var harness = new Harness ( new XmlResultParser ( ) , action , configuration ) ;
2020-03-13 17:41:02 +03:00
2016-05-26 16:06:52 +03:00
return harness . Execute ( ) ;
}
2017-11-28 21:16:46 +03:00
internal static bool TryParseBool ( string value , out bool result )
{
if ( string . IsNullOrEmpty ( value ) ) {
result = true ;
return true ;
}
switch ( value . ToLowerInvariant ( ) ) {
case "1" :
case "yes" :
case "true" :
case "enable" :
result = true ;
return true ;
case "0" :
case "no" :
case "false" :
case "disable" :
result = false ;
return true ;
default :
return bool . TryParse ( value , out result ) ;
}
}
internal static bool ParseBool ( string value , string name , bool show_error = true )
{
bool result ;
if ( ! TryParseBool ( value , out result ) )
throw new Exception ( $"Could not parse the command line argument '-{name}:{value}'" ) ;
return result ;
}
2016-05-26 16:06:52 +03:00
}
}