示例#1
0
        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);
            }
        }