static async Task <int> Main(string[] args) { Console.WriteLine("Running test suite"); int maxConcurrency = Int32.TryParse(Environment.GetEnvironmentVariable("TESTS_CONCURRENCY"), out int mc) ? mc : 1; // load test items var testSuite = GetVariable("TEST_SUITE"); GetVariable("TEST_CLOUD"); GetVariable("TEST_IMAGE"); var binDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var suitePath = Path.GetFullPath(Path.Combine("..", "..", "..", "..", "test-suites", $"{testSuite}.json"), binDir); var suiteFailed = false; if (!File.Exists(suitePath)) { Console.WriteLine($"Test suite {suitePath} not found."); Environment.Exit(1); } var tests = JsonConvert.DeserializeObject <TestItem[]>(File.ReadAllText(suitePath)); // add all tests to AppVeyor foreach (var test in tests) { await BuildWorkerApi.AddTest(test.TestName); } int testNum = 1; using (SemaphoreSlim concurrencySemaphore = new SemaphoreSlim(maxConcurrency)) { List <Task> tasks = new List <Task>(); foreach (var test in tests) { concurrencySemaphore.Wait(); Console.WriteLine($"Running test [{testNum++}/{tests.Length}]"); var worker = new TestBuildWorker(test); tasks.Add(worker.Start().ContinueWith(ct => { concurrencySemaphore.Release(); if (ct.IsFaulted) { suiteFailed = true; } })); } Task.WaitAll(tasks.ToArray()); } return(suiteFailed ? 1 : 0); }
public async Task Start() { string error = null; bool downloadLog = false; string jobId = null; var MaxProvisioningTime = 10; // minutes var MaxRunTime = 10; // minutes DateTime started = DateTime.MinValue; DateTime finished = DateTime.MinValue; try { await BuildWorkerApi.UpdateTest(_item.TestName, "Running"); // start new build var build = await StartNewBuild(_item.AccountName, _item.ProjectSlug, _item.Branch, _item.EnvironmentVariables); string buildVersion = build.Value <string>("version"); WriteLog("Build version: " + buildVersion); DateTime buildStarted = DateTime.UtcNow; WriteLog("Build started"); string previousStatus = null; while (true) { await Task.Delay(TimeSpan.FromSeconds(10)); var elapsed = DateTime.UtcNow - buildStarted; build = await GetBuildDetails(_item.AccountName, _item.ProjectSlug, buildVersion); var job = build["build"]["jobs"].First(); jobId = job.Value <string>("jobId"); started = job.Value <DateTime>("started"); finished = job.Value <DateTime>("finished"); var status = job.Value <string>("status"); WriteLog("Build status at " + elapsed.ToString() + " - " + status); if ((status == "queued" || status == "starting") && elapsed.TotalMinutes > MaxProvisioningTime) { string message = "Build has not started in allotted time."; WriteLog(message); await CancelBuild(_item.AccountName, _item.ProjectSlug, buildVersion); throw new Exception(message); } else if (status == "running" && (previousStatus == "queued" || previousStatus == "starting")) { buildStarted = DateTime.UtcNow; } else if (status == "running" && elapsed.TotalMinutes > MaxRunTime) { string message = "Build has not finished in allotted time."; downloadLog = true; WriteLog(message); await CancelBuild(_item.AccountName, _item.ProjectSlug, buildVersion); throw new Exception(message); } else if (status == "failed") { if (_item.ShouldSucceed) { string message = "Build has failed."; downloadLog = true; WriteLog(message); throw new Exception(message); } else { break; } } else if (status == "cancelled") { string message = "Build has been cancelled."; downloadLog = true; WriteLog(message); throw new Exception(message); } else if (status == "success") { if (!_item.ShouldSucceed) { string message = "Build should have failed."; downloadLog = true; WriteLog(message); throw new Exception(message); } else { break; } } previousStatus = status; } // while } catch (Exception ex) { error = ex.Message; WriteLog(ex.Message); if (ex.InnerException != null) { WriteLog(" + " + ex.InnerException.Message); } } WriteLog(String.Format("Build duration: {0}", (finished - started))); // download build log if there was an error string buildLog = null; try { if (error != null && downloadLog) { // download build log buildLog = await DownloadBuildLog(jobId); } } catch (Exception ex) { WriteLog("Cannot download build log: " + ex.Message); } await BuildWorkerApi.UpdateTest(_item.TestName, error != null? "Failed" : "Passed", stdOut : buildLog); if (error != null) { throw new Exception(error); } }