private MlaunchArguments GetCommonArguments( int verbosity, XmlResultJargon xmlResultJargon, string[]?skippedMethods, string[]?skippedTestClasses, ListenerTransport listenerTransport, int listenerPort, string listenerTmpFile) { var args = new MlaunchArguments(); for (var i = -1; i < verbosity; i++) { args.Add(new VerbosityArgument()); } // Environment variables var envVariables = GetEnvVariables(xmlResultJargon, skippedMethods, skippedTestClasses, listenerTransport, listenerPort, listenerTmpFile); args.AddRange(envVariables.Select(pair => new SetEnvVariableArgument(pair.Key, pair.Value))); // Arguments passed to the iOS app bundle args.AddRange(_appArguments.Select(arg => new SetAppArgumentArgument(arg))); return(args); }
private MlaunchArguments GetSimulatorArguments( AppBundleInformation appInformation, ISimulatorDevice simulator, int verbosity, XmlResultJargon xmlResultJargon, string[]?skippedMethods, string[]?skippedTestClasses, ListenerTransport deviceListenerTransport, int deviceListenerPort, string deviceListenerTmpFile) { var args = GetCommonArguments( verbosity, xmlResultJargon, skippedMethods, skippedTestClasses, deviceListenerTransport, deviceListenerPort, deviceListenerTmpFile); args.Add(new SetAppArgumentArgument("-hostname:127.0.0.1", true)); args.Add(new SetEnvVariableArgument(EnviromentVariables.HostName, "127.0.0.1")); args.Add(new SimulatorUDIDArgument(simulator.UDID)); if (appInformation.Extension.HasValue) { switch (appInformation.Extension) { case Extension.TodayExtension: args.Add(new LaunchSimulatorExtensionArgument(appInformation.LaunchAppPath, appInformation.BundleIdentifier)); break; case Extension.WatchKit2: default: throw new NotImplementedException(); } } else { args.Add(new LaunchSimulatorArgument(appInformation.LaunchAppPath)); } return(args); }
private Dictionary <string, object> GetEnvVariables( XmlResultJargon xmlResultJargon, string[]?skippedMethods, string[]?skippedTestClasses, ListenerTransport listenerTransport, int listenerPort, string listenerTmpFile) { var variables = new Dictionary <string, object> { { EnviromentVariables.AutoExit, true }, { EnviromentVariables.HostPort, listenerPort }, // Let the runner know that we want to get an XML output and not plain text { EnviromentVariables.EnableXmlOutput, true }, { EnviromentVariables.XmlVersion, $"{xmlResultJargon}" }, }; if (skippedMethods?.Any() ?? skippedTestClasses?.Any() ?? false) { // Do not run all the tests, we are using filters variables.Add(EnviromentVariables.RunAllTestsByDefault, false); // Add the skipped test classes and methods if (skippedMethods != null && skippedMethods.Length > 0) { var skippedMethodsValue = string.Join(',', skippedMethods); variables.Add(EnviromentVariables.SkippedMethods, skippedMethodsValue); } if (skippedTestClasses != null && skippedTestClasses !.Length > 0) { var skippedClassesValue = string.Join(',', skippedTestClasses); variables.Add(EnviromentVariables.SkippedClasses, skippedClassesValue); } } if (listenerTransport == ListenerTransport.File) { variables.Add(EnviromentVariables.LogFilePath, listenerTmpFile); } return(variables); }
public (ListenerTransport transport, ISimpleListener listener, string listenerTempFile) Create(RunMode mode, ILog log, ILog listenerLog, bool isSimulator, bool autoExit, bool xmlOutput) { string listenerTempFile = null; ISimpleListener listener; ListenerTransport transport; if (mode == RunMode.WatchOS) { transport = isSimulator ? ListenerTransport.File : ListenerTransport.Http; } else { transport = ListenerTransport.Tcp; } switch (transport) { case ListenerTransport.File: listenerTempFile = listenerLog.FullPath + ".tmp"; listener = new SimpleFileListener(listenerTempFile, log, listenerLog, xmlOutput); break; case ListenerTransport.Http: listener = new SimpleHttpListener(log, listenerLog, autoExit, xmlOutput); break; case ListenerTransport.Tcp: listener = new SimpleTcpListener(log, listenerLog, autoExit, xmlOutput); break; default: throw new NotImplementedException("Unknown type of listener"); } return(transport, listener, listenerTempFile); }
private MlaunchArguments GetDeviceArguments( AppBundleInformation appInformation, string deviceName, bool isWatchTarget, int verbosity, XmlResultJargon xmlResultJargon, string[]?skippedMethods, string[]?skippedTestClasses, ListenerTransport deviceListenerTransport, int deviceListenerPort, string deviceListenerTmpFile) { var args = GetCommonArguments( verbosity, xmlResultJargon, skippedMethods, skippedTestClasses, deviceListenerTransport, deviceListenerPort, deviceListenerTmpFile); var ips = string.Join(",", _helpers.GetLocalIpAddresses().Select(ip => ip.ToString())); args.Add(new SetAppArgumentArgument($"-hostname:{ips}", true)); args.Add(new SetEnvVariableArgument(EnviromentVariables.HostName, ips)); args.Add(new DisableMemoryLimitsArgument()); args.Add(new DeviceNameArgument(deviceName)); if (_listenerFactory.UseTunnel) { args.Add(new SetEnvVariableArgument(EnviromentVariables.UseTcpTunnel, true)); } if (appInformation.Extension.HasValue) { switch (appInformation.Extension) { case Extension.TodayExtension: args.Add(new LaunchDeviceExtensionArgument(appInformation.LaunchAppPath, appInformation.BundleIdentifier)); break; case Extension.WatchKit2: default: throw new NotImplementedException(); } } else { args.Add(new LaunchDeviceArgument(appInformation.LaunchAppPath)); } if (isWatchTarget) { args.Add(new AttachNativeDebuggerArgument()); // this prevents the watch from backgrounding the app. } else { args.Add(new WaitForExitArgument()); } return(args); }
private MlaunchArguments GetCommonArguments( int verbosity, XmlResultJargon xmlResultJargon, string[]?skippedMethods, string[]?skippedTestClasses, ListenerTransport listenerTransport, int listenerPort, string listenerTmpFile) { var args = new MlaunchArguments { new SetAppArgumentArgument("-connection-mode"), new SetAppArgumentArgument("none"), // This will prevent the app from trying to connect to any IDEs new SetAppArgumentArgument("-autostart", true), new SetEnvVariableArgument(EnviromentVariables.AutoStart, true), new SetAppArgumentArgument("-autoexit", true), new SetEnvVariableArgument(EnviromentVariables.AutoExit, true), new SetAppArgumentArgument("-enablenetwork", true), new SetEnvVariableArgument(EnviromentVariables.EnableNetwork, true), // On macOS we can't edit the TCC database easily // (it requires adding the mac has to be using MDM: https://carlashley.com/2018/09/28/tcc-round-up/) // So by default ignore any tests that would pop up permission dialogs in CI. new SetEnvVariableArgument(EnviromentVariables.DisableSystemPermissionTests, 1), }; if (skippedMethods?.Any() ?? skippedTestClasses?.Any() ?? false) { // do not run all the tests, we are using filters args.Add(new SetEnvVariableArgument(EnviromentVariables.RunAllTestsByDefault, false)); // add the skipped test classes and methods if (skippedMethods != null && skippedMethods.Length > 0) { var skippedMethodsValue = string.Join(',', skippedMethods); args.Add(new SetEnvVariableArgument(EnviromentVariables.SkippedMethods, skippedMethodsValue)); } if (skippedTestClasses != null && skippedTestClasses !.Length > 0) { var skippedClassesValue = string.Join(',', skippedTestClasses); args.Add(new SetEnvVariableArgument(EnviromentVariables.SkippedClasses, skippedClassesValue)); } } for (int i = -1; i < verbosity; i++) { args.Add(new VerbosityArgument()); } // let the runner now via envars that we want to get a xml output, else the runner will default to plain text args.Add(new SetEnvVariableArgument(EnviromentVariables.EnableXmlOutput, true)); args.Add(new SetEnvVariableArgument(EnviromentVariables.XmlMode, "wrapped")); args.Add(new SetEnvVariableArgument(EnviromentVariables.XmlVersion, $"{xmlResultJargon}")); args.Add(new SetAppArgumentArgument($"-transport:{listenerTransport}", true)); args.Add(new SetEnvVariableArgument(EnviromentVariables.Transport, listenerTransport.ToString().ToUpper())); if (listenerTransport == ListenerTransport.File) { args.Add(new SetEnvVariableArgument(EnviromentVariables.LogFilePath, listenerTmpFile)); } args.Add(new SetAppArgumentArgument($"-hostport:{listenerPort}", true)); args.Add(new SetEnvVariableArgument(EnviromentVariables.HostPort, listenerPort)); // Arguments passed to the iOS app bundle args.AddRange(_appArguments.Select(arg => new SetAppArgumentArgument(arg, true))); return(args); }
/// <summary> /// Runs the MacCatalyst app by executing its binary (or if not found, via `open -W path.to.app`). /// </summary> private async Task <(TestExecutingResult Result, string ResultMessage)> RunMacCatalystTests( ListenerTransport deviceListenerTransport, ISimpleListener deviceListener, string deviceListenerTmpFile, AppBundleInformation appInformation, TimeSpan timeout, TimeSpan testLaunchTimeout, XmlResultJargon xmlResultJargon, string[]?skippedMethods, string[]?skippedTestClasses, CancellationToken cancellationToken) { var deviceListenerPort = deviceListener.InitializeAndGetPort(); deviceListener.StartAsync(); var crashLogs = new Logs(_logs.Directory); ICrashSnapshotReporter crashReporter = _snapshotReporterFactory.Create(_mainLog, crashLogs, isDevice: false, null); ITestReporter testReporter = _testReporterFactory.Create( _mainLog, _mainLog, _logs, crashReporter, deviceListener, _resultParser, appInformation, RunMode.MacOS, xmlResultJargon, null, timeout, null, (level, message) => _mainLog.WriteLine(message)); deviceListener.ConnectedTask .TimeoutAfter(testLaunchTimeout) .ContinueWith(testReporter.LaunchCallback) .DoNotAwait(); _mainLog.WriteLine($"*** Executing '{appInformation.AppName}' on MacCatalyst ***"); try { using var combinedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(testReporter.CancellationToken, cancellationToken); var envVariables = GetEnvVariables( xmlResultJargon, skippedMethods, skippedTestClasses, deviceListenerTransport, deviceListenerPort, deviceListenerTmpFile); envVariables[EnviromentVariables.HostName] = "127.0.0.1"; var arguments = new List <string> { "-W", appInformation.LaunchAppPath, }; arguments.AddRange(_appArguments); await crashReporter.StartCaptureAsync(); var result = await RunMacCatalystApp(appInformation, timeout, _appArguments, envVariables, combinedCancellationToken.Token); await testReporter.CollectSimulatorResult(result); } finally { deviceListener.Cancel(); deviceListener.Dispose(); } return(await testReporter.ParseResult()); }