public void TearDown() { processManager = null; resultParser = null; configuration = null; harness = null; jenkins = null; factory = null; }
public MacTestTasksEnumerable(Jenkins jenkins, IMlaunchProcessManager processManager, ICrashSnapshotReporterFactory crashReportSnapshotFactory, ITestVariationsFactory testVariationsFactory) { this.jenkins = jenkins ?? throw new ArgumentNullException(nameof(jenkins)); this.processManager = processManager ?? throw new ArgumentNullException(nameof(processManager)); this.crashReportSnapshotFactory = crashReportSnapshotFactory ?? throw new ArgumentNullException(nameof(crashReportSnapshotFactory)); this.testVariationsFactory = testVariationsFactory ?? throw new ArgumentNullException(nameof(testVariationsFactory)); }
public void SetUp() { processManager = new Mock <IMlaunchProcessManager> (); resultParser = new Mock <IResultParser> (); tunnel = new Mock <ITunnelBore> (); configuration = new HarnessConfiguration(); harness = new Harness(resultParser.Object, HarnessAction.Jenkins, configuration); jenkins = new Xharness.Jenkins.Jenkins(harness, processManager.Object, resultParser.Object, tunnel.Object); factory = new MakeTestTaskEnumerable(jenkins, processManager.Object); }
public void SetUp() { processManager = new Mock <IMlaunchProcessManager> (); resultParser = new Mock <IResultParser> (); tunnel = new Mock <ITunnelBore> (); log = new Mock <IFileBackedLog> (); configuration = new HarnessConfiguration(); harness = new Harness(resultParser.Object, HarnessAction.Jenkins, configuration); jenkins = new Xharness.Jenkins.Jenkins(harness, processManager.Object, resultParser.Object, tunnel.Object); jenkins.MainLog = log.Object; factory = new NUnitTestTasksEnumerable(jenkins, processManager.Object); }
public int Jenkins() { if (autoConf) { AutoConfigureIOS(); AutoConfigureMac(false); } var jenkins = new Jenkins.Jenkins() { Harness = this, }; return(jenkins.Run()); }
public Task <IEnumerable <ITestTask> > CreateAsync(Jenkins jenkins, IProcessManager processManager, TestVariationsFactory testVariationsFactory) { var rv = new List <RunDeviceTask> (); var projectTasks = new List <RunDeviceTask> (); foreach (var project in jenkins.Harness.IOSTestProjects) { if (!project.IsExecutableProject) { continue; } if (project.SkipDeviceVariations) { continue; } bool ignored = !jenkins.IncludeDevice; if (!jenkins.IsIncluded(project)) { ignored = true; } projectTasks.Clear(); bool createiOS; bool createTodayExtension; bool createtvOS; bool createwatchOS; if (project.GenerateVariations) { createiOS = !project.SkipiOSVariation; createTodayExtension = !project.SkipTodayExtensionVariation; createtvOS = !project.SkiptvOSVariation; createwatchOS = !project.SkipwatchOSVariation; } else { createiOS = project.TestPlatform == TestPlatform.iOS_Unified; createTodayExtension = project.TestPlatform == TestPlatform.iOS_TodayExtension64; createtvOS = project.TestPlatform == TestPlatform.tvOS; createwatchOS = project.TestPlatform == TestPlatform.watchOS; } if (createiOS) { var build64 = new MSBuildTask(jenkins: jenkins, testProject: project, processManager: processManager) { ProjectConfiguration = "Debug64", ProjectPlatform = "iPhone", Platform = TestPlatform.iOS_Unified64, TestName = project.Name, }; build64.CloneTestProject(jenkins.MainLog, processManager, project); projectTasks.Add(new RunDeviceTask( jenkins: jenkins, devices: jenkins.Devices, buildTask: build64, processManager: processManager, tunnelBore: jenkins.TunnelBore, errorKnowledgeBase: jenkins.ErrorKnowledgeBase, useTcpTunnel: jenkins.Harness.UseTcpTunnel, candidates: jenkins.Devices.Connected64BitIOS.Where(d => project.IsSupported(d.DevicePlatform, d.ProductVersion))) { Ignored = !jenkins.IncludeiOS64 }); var build32 = new MSBuildTask(jenkins: jenkins, testProject: project, processManager: processManager) { ProjectConfiguration = project.Name != "dont link" ? "Debug32" : "Release32", ProjectPlatform = "iPhone", Platform = TestPlatform.iOS_Unified32, TestName = project.Name, }; build32.CloneTestProject(jenkins.MainLog, processManager, project); projectTasks.Add(new RunDeviceTask( jenkins: jenkins, devices: jenkins.Devices, buildTask: build32, processManager: processManager, tunnelBore: jenkins.TunnelBore, errorKnowledgeBase: jenkins.ErrorKnowledgeBase, useTcpTunnel: jenkins.Harness.UseTcpTunnel, candidates: jenkins.Devices.Connected32BitIOS.Where(d => project.IsSupported(d.DevicePlatform, d.ProductVersion))) { Ignored = !jenkins.IncludeiOS32 }); if (createTodayExtension) { var todayProject = project.GenerateVariations ? project.AsTodayExtensionProject() : project; var buildToday = new MSBuildTask(jenkins: jenkins, testProject: todayProject, processManager: processManager) { ProjectConfiguration = "Debug64", ProjectPlatform = "iPhone", Platform = TestPlatform.iOS_TodayExtension64, TestName = project.Name, }; buildToday.CloneTestProject(jenkins.MainLog, processManager, todayProject); projectTasks.Add(new RunDeviceTask( jenkins: jenkins, devices: jenkins.Devices, buildTask: buildToday, processManager: processManager, tunnelBore: jenkins.TunnelBore, errorKnowledgeBase: jenkins.ErrorKnowledgeBase, useTcpTunnel: jenkins.Harness.UseTcpTunnel, candidates: jenkins.Devices.Connected64BitIOS.Where(d => project.IsSupported(d.DevicePlatform, d.ProductVersion))) { Ignored = !jenkins.IncludeiOSExtensions, BuildOnly = jenkins.ForceExtensionBuildOnly }); } } if (createtvOS) { var tvOSProject = project.GenerateVariations ? project.AsTvOSProject() : project; var buildTV = new MSBuildTask(jenkins: jenkins, testProject: tvOSProject, processManager: processManager) { ProjectConfiguration = "Debug", ProjectPlatform = "iPhone", Platform = TestPlatform.tvOS, TestName = project.Name, }; buildTV.CloneTestProject(jenkins.MainLog, processManager, tvOSProject); projectTasks.Add(new RunDeviceTask( jenkins: jenkins, devices: jenkins.Devices, buildTask: buildTV, processManager: processManager, tunnelBore: jenkins.TunnelBore, errorKnowledgeBase: jenkins.ErrorKnowledgeBase, useTcpTunnel: jenkins.Harness.UseTcpTunnel, candidates: jenkins.Devices.ConnectedTV.Where(d => project.IsSupported(d.DevicePlatform, d.ProductVersion))) { Ignored = !jenkins.IncludetvOS }); } if (createwatchOS) { var watchOSProject = project.GenerateVariations ? project.AsWatchOSProject() : project; if (!project.SkipwatchOS32Variation) { var buildWatch32 = new MSBuildTask(jenkins: jenkins, testProject: watchOSProject, processManager: processManager) { ProjectConfiguration = "Debug32", ProjectPlatform = "iPhone", Platform = TestPlatform.watchOS_32, TestName = project.Name, }; buildWatch32.CloneTestProject(jenkins.MainLog, processManager, watchOSProject); projectTasks.Add(new RunDeviceTask( jenkins: jenkins, devices: jenkins.Devices, buildTask: buildWatch32, processManager: processManager, tunnelBore: jenkins.TunnelBore, errorKnowledgeBase: jenkins.ErrorKnowledgeBase, useTcpTunnel: jenkins.Harness.UseTcpTunnel, candidates: jenkins.Devices.ConnectedWatch) { Ignored = !jenkins.IncludewatchOS }); } if (!project.SkipwatchOSARM64_32Variation) { var buildWatch64_32 = new MSBuildTask(jenkins: jenkins, testProject: watchOSProject, processManager: processManager) { ProjectConfiguration = "Release64_32", // We don't support Debug for ARM64_32 yet. ProjectPlatform = "iPhone", Platform = TestPlatform.watchOS_64_32, TestName = project.Name, }; buildWatch64_32.CloneTestProject(jenkins.MainLog, processManager, watchOSProject); projectTasks.Add(new RunDeviceTask( jenkins: jenkins, devices: jenkins.Devices, buildTask: buildWatch64_32, processManager: processManager, tunnelBore: jenkins.TunnelBore, errorKnowledgeBase: jenkins.ErrorKnowledgeBase, useTcpTunnel: jenkins.Harness.UseTcpTunnel, candidates: jenkins.Devices.ConnectedWatch32_64.Where(d => project.IsSupported(d.DevicePlatform, d.ProductVersion))) { Ignored = !jenkins.IncludewatchOS }); } } foreach (var task in projectTasks) { task.TimeoutMultiplier = project.TimeoutMultiplier; task.BuildOnly |= project.BuildOnly; task.Ignored |= ignored; } rv.AddRange(projectTasks); } return(Task.FromResult <IEnumerable <ITestTask> > (testVariationsFactory.CreateTestVariations(rv, (buildTask, test, candidates) => new RunDeviceTask( jenkins: jenkins, devices: jenkins.Devices, buildTask: buildTask, processManager: processManager, tunnelBore: jenkins.TunnelBore, errorKnowledgeBase: jenkins.ErrorKnowledgeBase, useTcpTunnel: jenkins.Harness.UseTcpTunnel, candidates: candidates?.Cast <IHardwareDevice> () ?? test.Candidates)))); }
public TestSelector(Jenkins jenkins, IProcessManager processManager, IVersionControlSystem versionControlSystem) { this.jenkins = jenkins; this.processManager = processManager; this.vcs = versionControlSystem; }
public TestVariationsFactory(Jenkins jenkins, IProcessManager processManager) { this.jenkins = jenkins ?? throw new ArgumentNullException(nameof(jenkins)); this.processManager = processManager ?? throw new ArgumentNullException(nameof(processManager)); }
public NUnitTestTasksEnumerable(Jenkins jenkins, IProcessManager processManager) { this.jenkins = jenkins ?? throw new ArgumentNullException(nameof(jenkins)); this.processManager = processManager ?? throw new ArgumentNullException(nameof(processManager)); }
public Task RunAsync(Jenkins jenkins, HtmlReportWriter htmlReportWriter) { var server = new HttpListener(); // Try and find an unused port int attemptsLeft = 50; int port = 51234; // Try this port first, to try to not vary between runs just because. Random r = new Random((int)DateTime.Now.Ticks); while (attemptsLeft-- > 0) { var newPort = port != 0 ? port : r.Next(49152, 65535); // The suggested range for dynamic ports is 49152-65535 (IANA) server.Prefixes.Clear(); server.Prefixes.Add("http://*:" + newPort + "/"); try { server.Start(); port = newPort; break; } catch (Exception ex) { jenkins.MainLog.WriteLine("Failed to listen on port {0}: {1}", newPort, ex.Message); port = 0; } } jenkins.MainLog.WriteLine($"Created server on localhost:{port}"); var tcs = new TaskCompletionSource <bool> (); var thread = new System.Threading.Thread(() => { while (server.IsListening) { var context = server.GetContext(); var request = context.Request; var response = context.Response; var arguments = System.Web.HttpUtility.ParseQueryString(request.Url.Query); try { var allTasks = jenkins.Tasks.SelectMany((v) => { var rv = new List <ITestTask> (); var runsim = v as AggregatedRunSimulatorTask; if (runsim != null) { rv.AddRange(runsim.Tasks); } rv.Add(v); return(rv); }); IEnumerable <ITestTask> find_tasks(StreamWriter writer, string ids) { IEnumerable <ITestTask> tasks; switch (request.Url.Query) { case "?all": tasks = jenkins.Tasks; break; case "?selected": tasks = allTasks.Where((v) => !v.Ignored); break; case "?failed": tasks = allTasks.Where((v) => v.Failed); break; case "?": writer.WriteLine("No tasks specified"); return(Array.Empty <AppleTestTask> ()); default: var id_inputs = ids.Substring(1).Split(','); var rv = new List <ITestTask> (id_inputs.Length); foreach (var id_input in id_inputs) { if (int.TryParse(id_input, out var id)) { var task = jenkins.Tasks.FirstOrDefault((t) => t.ID == id); if (task == null) { task = jenkins.Tasks.Where((v) => v is AggregatedRunSimulatorTask).Cast <AggregatedRunSimulatorTask> ().SelectMany((v) => v.Tasks).FirstOrDefault((t) => t.ID == id); } if (task == null) { writer.WriteLine($"Could not find test {id}"); } else { rv.Add(task); } } else { writer.WriteLine($"Could not parse {arguments ["id"]}"); } } tasks = rv; break; } return(tasks); } string serveFile = null; switch (request.Url.LocalPath) { case "/": response.ContentType = System.Net.Mime.MediaTypeNames.Text.Html; using (var writer = new StreamWriter(response.OutputStream)) { htmlReportWriter.Write(jenkins.Tasks, writer); } break; case "/set-option": response.ContentType = System.Net.Mime.MediaTypeNames.Text.Plain; switch (request.Url.Query) { case "?clean": jenkins.CleanSuccessfulTestRuns = true; break; case "?do-not-clean": jenkins.CleanSuccessfulTestRuns = false; break; case "?uninstall-test-app": jenkins.UninstallTestApp = true; break; case "?do-not-uninstall-test-app": jenkins.UninstallTestApp = false; break; case "?skip-permission-tests": jenkins.Harness.IncludeSystemPermissionTests = false; break; case "?include-permission-tests": jenkins.Harness.IncludeSystemPermissionTests = true; break; case "?clear-permission-tests": jenkins.Harness.IncludeSystemPermissionTests = null; break; default: throw new NotImplementedException(request.Url.Query); } using (var writer = new StreamWriter(response.OutputStream)) { writer.WriteLine("OK"); } break; case "/select": case "/deselect": response.ContentType = System.Net.Mime.MediaTypeNames.Text.Plain; using (var writer = new StreamWriter(response.OutputStream)) { foreach (var task in allTasks) { bool?is_match = null; if (!(task.Ignored || task.NotStarted)) { continue; } switch (request.Url.Query) { case "?all": is_match = true; break; case "?all-device": is_match = task is RunDeviceTask; break; case "?all-simulator": is_match = task is RunSimulatorTask; break; case "?all-ios": switch (task.Platform) { case TestPlatform.iOS: case TestPlatform.iOS_TodayExtension64: case TestPlatform.iOS_Unified: case TestPlatform.iOS_Unified32: case TestPlatform.iOS_Unified64: is_match = true; break; default: if (task.Platform.ToString().StartsWith("iOS", StringComparison.Ordinal)) { throw new NotImplementedException(); } break; } break; case "?all-tvos": switch (task.Platform) { case TestPlatform.tvOS: is_match = true; break; default: if (task.Platform.ToString().StartsWith("tvOS", StringComparison.Ordinal)) { throw new NotImplementedException(); } break; } break; case "?all-watchos": switch (task.Platform) { case TestPlatform.watchOS: case TestPlatform.watchOS_32: case TestPlatform.watchOS_64_32: is_match = true; break; default: if (task.Platform.ToString().StartsWith("watchOS", StringComparison.Ordinal)) { throw new NotImplementedException(); } break; } break; case "?all-mac": switch (task.Platform) { case TestPlatform.Mac: case TestPlatform.Mac_Modern: case TestPlatform.Mac_Full: case TestPlatform.Mac_System: is_match = true; break; default: if (task.Platform.ToString().StartsWith("Mac", StringComparison.Ordinal)) { throw new NotImplementedException(); } break; } break; default: writer.WriteLine("unknown query: {0}", request.Url.Query); break; } if (request.Url.LocalPath == "/select") { if (is_match.HasValue && is_match.Value) { task.Ignored = false; } } else if (request.Url.LocalPath == "/deselect") { if (is_match.HasValue && is_match.Value) { task.Ignored = true; } } } writer.WriteLine("OK"); } break; case "/stop": response.ContentType = System.Net.Mime.MediaTypeNames.Text.Plain; using (var writer = new StreamWriter(response.OutputStream)) { foreach (var task in find_tasks(writer, request.Url.Query)) { if (!task.Waiting) { writer.WriteLine($"Test '{task.TestName}' is not in a waiting state."); } else { task.Reset(); } } writer.WriteLine("OK"); } break; case "/run": response.ContentType = System.Net.Mime.MediaTypeNames.Text.Plain; using (var writer = new StreamWriter(response.OutputStream)) { // We want to randomize the order the tests are added, so that we don't build first the test for one device, // then for another, since that would not take advantage of running tests on several devices in parallel. foreach (var task in find_tasks(writer, request.Url.Query).Shuffle()) { if (task.InProgress || task.Waiting) { writer.WriteLine($"Test '{task.TestName}' is already executing."); } else { task.Reset(); task.BuildOnly = false; task.RunAsync(); } } writer.WriteLine("OK"); } break; case "/build": response.ContentType = System.Net.Mime.MediaTypeNames.Text.Plain; using (var writer = new StreamWriter(response.OutputStream)) { foreach (var task in find_tasks(writer, request.Url.Query)) { if (task.InProgress || task.Waiting) { writer.WriteLine($"Test '{task.TestName}' is already executing."); } else if (task is RunTestTask rtt) { rtt.Reset(); rtt.BuildAsync().ContinueWith((z) => { if (rtt.ExecutionResult == TestExecutingResult.Built) { rtt.ExecutionResult = TestExecutingResult.BuildSucceeded; } }); } else { writer.WriteLine($"Test '{task.TestName}' is not a test that can be only built."); } } writer.WriteLine("OK"); } break; case "/reload-devices": jenkins.DeviceLoader.LoadDevicesAsync().DoNotAwait(); break; case "/reload-simulators": jenkins.DeviceLoader.LoadSimulatorsAsync().DoNotAwait(); break; case "/quit": using (var writer = new StreamWriter(response.OutputStream)) { writer.WriteLine("<!DOCTYPE html>"); writer.WriteLine("<html>"); writer.WriteLine("<body onload='close ();'>Closing web page...</body>"); writer.WriteLine("</html>"); } server.Stop(); break; case "/favicon.ico": serveFile = Path.Combine(HarnessConfiguration.RootDirectory, "xharness", "favicon.ico"); goto default; case "/index.html": var redirect_to = request.Url.AbsoluteUri.Replace("/index.html", "/" + Path.GetFileName(jenkins.LogDirectory) + "/index.html"); response.Redirect(redirect_to); break; default: var filename = Path.GetFileName(request.Url.LocalPath); if (filename == "index.html" && Path.GetFileName(jenkins.LogDirectory) == Path.GetFileName(Path.GetDirectoryName(request.Url.LocalPath))) { // We're asked for the report for the current test run, so re-generate it. jenkins.GenerateReport(); } if (serveFile == null) { serveFile = Path.Combine(Path.GetDirectoryName(jenkins.LogDirectory), request.Url.LocalPath.Substring(1)); } var path = serveFile; if (File.Exists(path)) { var buffer = new byte [4096]; using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { int read; response.ContentLength64 = fs.Length; switch (Path.GetExtension(path).ToLowerInvariant()) { case ".html": response.ContentType = System.Net.Mime.MediaTypeNames.Text.Html; break; case ".css": response.ContentType = "text/css"; break; case ".js": response.ContentType = "text/javascript"; break; case ".ico": response.ContentType = "image/png"; break; default: response.ContentType = System.Net.Mime.MediaTypeNames.Text.Plain + ";charset=UTF-8"; break; } while ((read = fs.Read(buffer, 0, buffer.Length)) > 0) { response.OutputStream.Write(buffer, 0, read); } } } else { Console.WriteLine($"404: {request.Url.LocalPath}"); response.StatusCode = 404; response.OutputStream.WriteByte((byte)'?'); } break; } } catch (IOException ioe) { Console.WriteLine(ioe.Message); } catch (Exception e) { Console.WriteLine(e); } response.Close(); } tcs.SetResult(true); }) { IsBackground = true, }; thread.Start(); var url = $"http://localhost:{port}/" + Path.GetFileName(jenkins.LogDirectory) + "/index.html"; Console.WriteLine($"Launching {url} in the system's default browser."); Process.Start("open", url); return(tcs.Task); }
public async Task <IEnumerable <ITestTask> > CreateAsync(Jenkins jenkins, IMlaunchProcessManager processManager, TestVariationsFactory testVariationsFactory) { var runSimulatorTasks = new List <RunSimulatorTask> (); foreach (var project in jenkins.Harness.IOSTestProjects) { if (!project.IsExecutableProject) { continue; } bool ignored = project.Ignore ?? !jenkins.IncludeSimulator; if (!jenkins.IsIncluded(project)) { ignored = true; } var ps = new List <Tuple <TestProject, TestPlatform, bool> > (); if (!project.GenerateVariations) { ps.Add(new Tuple <TestProject, TestPlatform, bool> (project, project.TestPlatform, ignored)); } else { if (!project.SkipiOSVariation) { ps.Add(new Tuple <TestProject, TestPlatform, bool> (project, TestPlatform.iOS_Unified, ignored)); } if (project.MonoNativeInfo != null) { ps.Add(new Tuple <TestProject, TestPlatform, bool> (project, TestPlatform.iOS_TodayExtension64, ignored)); } if (!project.SkiptvOSVariation) { ps.Add(new Tuple <TestProject, TestPlatform, bool> (project.AsTvOSProject(), TestPlatform.tvOS, ignored)); } if (!project.SkipwatchOSVariation) { ps.Add(new Tuple <TestProject, TestPlatform, bool> (project.AsWatchOSProject(), TestPlatform.watchOS, ignored)); } } var configurations = project.Configurations; if (configurations == null) { configurations = new string [] { "Debug" } } ; foreach (var config in configurations) { foreach (var pair in ps) { var configIgnored = pair.Item3; var testPlatform = pair.Item2; switch (testPlatform) { case TestPlatform.iOS_Unified: case TestPlatform.iOS_TodayExtension64: configIgnored |= !jenkins.IncludeiOS64; break; case TestPlatform.tvOS: configIgnored |= !jenkins.IncludetvOS; break; case TestPlatform.watchOS: configIgnored |= !jenkins.IncludewatchOS; break; default: Console.WriteLine("Unknown test platform for ignore check: {0}", testPlatform); break; } configIgnored |= project.IsDotNetProject && !jenkins.IncludeDotNet; var derived = new MSBuildTask(jenkins: jenkins, testProject: project, processManager: processManager); derived.ProjectConfiguration = config; derived.ProjectPlatform = "iPhoneSimulator"; derived.Platform = testPlatform; derived.Ignored = configIgnored; derived.TestName = project.Name; derived.Dependency = project.Dependency; derived.CloneTestProject(jenkins.MainLog, processManager, pair.Item1, HarnessConfiguration.RootDirectory); var simTasks = CreateAsync(jenkins, processManager, derived); runSimulatorTasks.AddRange(simTasks); foreach (var task in simTasks) { if (configurations.Length > 1) { task.Variation = config; } task.TimeoutMultiplier = project.TimeoutMultiplier; } } } } var testVariations = testVariationsFactory.CreateTestVariations(runSimulatorTasks, (buildTask, test, candidates) => new RunSimulatorTask( jenkins: jenkins, simulators: jenkins.Simulators, buildTask: buildTask, processManager: processManager, candidates: candidates?.Cast <SimulatorDevice> () ?? test.Candidates)).ToList(); if (jenkins.IsServerMode) { return(testVariations); } foreach (var tv in testVariations) { if (!tv.Ignored) { await tv.FindSimulatorAsync(); } } var rv = new List <AggregatedRunSimulatorTask> (); foreach (var taskGroup in testVariations.GroupBy((RunSimulatorTask task) => task.Device?.UDID ?? task.Candidates.ToString())) { rv.Add(new AggregatedRunSimulatorTask(jenkins: jenkins, tasks: taskGroup) { TestName = $"Tests for {taskGroup.Key}", }); } return(rv); } IEnumerable <RunSimulatorTask> CreateAsync(Jenkins jenkins, IMlaunchProcessManager processManager, MSBuildTask buildTask) { var runtasks = new List <RunSimulatorTask> (); TestTarget [] targets = buildTask.Platform.GetAppRunnerTargets(); TestPlatform [] platforms; bool [] ignored; switch (buildTask.Platform) { case TestPlatform.tvOS: platforms = new TestPlatform [] { TestPlatform.tvOS }; ignored = new [] { false }; break; case TestPlatform.watchOS: platforms = new TestPlatform [] { TestPlatform.watchOS_32 }; ignored = new [] { false }; break; case TestPlatform.iOS_Unified: platforms = new TestPlatform [] { TestPlatform.iOS_Unified64 }; ignored = new [] { false }; break; case TestPlatform.iOS_TodayExtension64: platforms = new TestPlatform [] { TestPlatform.iOS_TodayExtension64 }; ignored = new [] { false }; break; default: throw new NotImplementedException(); } for (int i = 0; i < targets.Length; i++) { var sims = jenkins.Simulators.SelectDevices(targets [i], jenkins.SimulatorLoadLog, false); runtasks.Add(new RunSimulatorTask( jenkins: jenkins, simulators: jenkins.Simulators, buildTask: buildTask, processManager: processManager, candidates: sims) { Platform = platforms [i], Ignored = ignored [i] || buildTask.Ignored }); } return(runtasks); } }