예제 #1
0
        static void Main(string[] args)
        {
            var options = new CommandLineOptions();

            try
            {
                if (!Parser.Default.ParseArguments(args, options))
                {
                    return;
                }

                Console.WriteLine("Start");
                Validate.FileExist(options.TestResultXmlPath, "Test Result Xml Path");
                TestLoadResult   testLoadResult = TestLoadResult.ConvertFrom(options.TestResultXmlPath);
                HtmlReportWriter writer         = new HtmlReportWriter(options.OutputFolderPath, options.OutputName);
                writer.Write(testLoadResult);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                Console.WriteLine(options.GetUsage());
            }
            Console.WriteLine("End");
        }
예제 #2
0
        public void GenerateReport()
        {
            try {
                lock (report_lock) {
                    var report           = Path.Combine(LogDirectory, "index.html");
                    var vsdropsReport    = Path.Combine(LogDirectory, "vsdrops_index.html");
                    var tmpreport        = Path.Combine(LogDirectory, $"index-{Helpers.Timestamp}.tmp.html");
                    var tmpVsdropsReport = Path.Combine(LogDirectory, $"vsdrops_index-{Helpers.Timestamp}.tmp.html");
                    var tmpmarkdown      = string.IsNullOrEmpty(Harness.MarkdownSummaryPath) ? string.Empty : (Harness.MarkdownSummaryPath + $".{Helpers.Timestamp}.tmp");

                    var allSimulatorTasks  = new List <RunSimulatorTask> ();
                    var allExecuteTasks    = new List <MacExecuteTask> ();
                    var allNUnitTasks      = new List <NUnitExecuteTask> ();
                    var allMakeTasks       = new List <MakeTask> ();
                    var allDeviceTasks     = new List <RunDeviceTask> ();
                    var allDotNetTestTasks = new List <DotNetTestTask> ();

                    foreach (var task in Tasks)
                    {
                        var aggregated = task as AggregatedRunSimulatorTask;
                        if (aggregated != null)
                        {
                            allSimulatorTasks.AddRange(aggregated.Tasks);
                            continue;
                        }

                        var execute = task as MacExecuteTask;
                        if (execute != null)
                        {
                            allExecuteTasks.Add(execute);
                            continue;
                        }

                        var nunit = task as NUnitExecuteTask;
                        if (nunit != null)
                        {
                            allNUnitTasks.Add(nunit);
                            continue;
                        }

                        var make = task as MakeTask;
                        if (make != null)
                        {
                            allMakeTasks.Add(make);
                            continue;
                        }

                        var run_device = task as RunDeviceTask;
                        if (run_device != null)
                        {
                            allDeviceTasks.Add(run_device);
                            continue;
                        }

                        if (task is DotNetTestTask dotnet)
                        {
                            allDotNetTestTasks.Add(dotnet);
                            continue;
                        }

                        throw new NotImplementedException();
                    }

                    var allTasks = new List <ITestTask> ();
                    if (!Populating)
                    {
                        allTasks.AddRange(allExecuteTasks);
                        allTasks.AddRange(allSimulatorTasks);
                        allTasks.AddRange(allNUnitTasks);
                        allTasks.AddRange(allMakeTasks);
                        allTasks.AddRange(allDeviceTasks);
                        allTasks.AddRange(allDotNetTestTasks);
                    }

                    // write the html
                    using (var stream = new FileStream(tmpreport, FileMode.Create, FileAccess.ReadWrite))
                        using (var writer = new StreamWriter(stream)) {
                            xamarinStorageHtmlReportWriter.Write(allTasks, writer);
                        }

                    // write the vsdrops report only if needed
                    if (vsdropsHtmlReportWriter != null)
                    {
                        using (var stream = new FileStream(tmpVsdropsReport, FileMode.Create, FileAccess.ReadWrite))
                            using (var writer = new StreamWriter(stream)) {
                                vsdropsHtmlReportWriter.Write(allTasks, writer);
                            }
                    }

                    // optionally, write the markdown
                    if (!string.IsNullOrEmpty(tmpmarkdown))
                    {
                        using (var writer = new StreamWriter(tmpmarkdown)) {
                            markdownReportWriter.Write(allTasks, writer);
                        }
                    }

                    if (File.Exists(report))
                    {
                        File.Delete(report);
                    }
                    File.Move(tmpreport, report);

                    if (vsdropsHtmlReportWriter != null)
                    {
                        if (File.Exists(vsdropsReport))
                        {
                            File.Delete(vsdropsReport);
                        }
                        File.Move(tmpVsdropsReport, vsdropsReport);
                    }

                    if (!string.IsNullOrEmpty(tmpmarkdown))
                    {
                        if (File.Exists(Harness.MarkdownSummaryPath))
                        {
                            File.Delete(Harness.MarkdownSummaryPath);
                        }
                        File.Move(tmpmarkdown, Harness.MarkdownSummaryPath);
                    }

                    var dependentFileLocation = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                    foreach (var file in new string [] { "xharness.js", "xharness.css" })
                    {
                        File.Copy(Path.Combine(dependentFileLocation, file), Path.Combine(LogDirectory, file), true);
                    }
                    File.Copy(Path.Combine(HarnessConfiguration.RootDirectory, "xharness", "favicon.ico"), Path.Combine(LogDirectory, "favicon.ico"), true);
                }
            } catch (Exception e) {
                this.MainLog.WriteLine("Failed to write log: {0}", e);
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        void RenderReport(HttpContext context)
        {
            var type = context.Request.QueryString["type"];

            Report report;

            switch (type)
            {
            case "GdpByYear":
                report = Reports.GdpByYearReport.Generate();
                break;

            case "GdpByCountry":
                report = Reports.GdpByCountryReport.Generate();
                break;

            case "BiggestCountries":
                report = Reports.GdpYearColumnReport.BiggestCountries();
                break;

            case "FastestGrowingCountries":
                report = Reports.GdpYearColumnReport.FastestGrowingCountries();
                break;

            case "BestCountries":
                report = Reports.GdpYearColumnReport.BestCountries();
                break;

            default:
                throw new InvalidOperationException("Invalid report type.");
            }


            try
            {
                switch (context.Request.QueryString["format"])
                {
                case "pdf":
                    var url = context.Request.Url.ToString().Replace("format=pdf", "print=1");
                    PdfConvert.ConvertHtmlToPdf(new PdfDocument {
                        Url = url
                    }, new PdfOutput {
                        OutputStream = context.Response.OutputStream
                    });
                    context.Response.SetFileDownloadHeaders(String.Format("Report{0}.pdf", DateTime.Now.Ticks));
                    break;

                case "text":
                    context.Response.SetFileDownloadHeaders(String.Format("Report{0}.txt", DateTime.Now.Ticks));
                    TextReportWriter.WriteTo(report, context.Response.Output);
                    break;

                case "xlsx":
                    context.Response.SetFileDownloadHeaders(String.Format("Report{0}.xlsx", DateTime.Now.Ticks));
                    XlsxReportWriter.WriteToStream(report, Themes.Default, context.Response.OutputStream);
                    break;

                default:
                    var output     = new HtmlTextWriter(context.Response.Output);
                    var htmlWriter = new HtmlReportWriter(output);
                    htmlWriter.RegisterCss(DextopUtil.AbsolutePath("client/css/report.css"));
                    if (context.Request.QueryString["print"] == null)
                    {
                        htmlWriter.RegisterCss(DextopUtil.AbsolutePath("client/css/report-preview.css"));
                    }
                    htmlWriter.Write(report, new DefaultHtmlReportTheme());
                    break;
                }
            }
            catch (Exception ex)
            {
                context.Response.Write(ex.ToString());
            }
        }