Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        /// <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());
        }