Index: master/public_html/buildbots_self_analysis.html |
diff --git a/master/public_html/buildbots_self_analysis.html b/master/public_html/buildbots_self_analysis.html |
deleted file mode 100644 |
index 42140fce15d0a6d29a4e7362fc554467001f2605..0000000000000000000000000000000000000000 |
--- a/master/public_html/buildbots_self_analysis.html |
+++ /dev/null |
@@ -1,396 +0,0 @@ |
-<html> |
- <head> |
- <title>Skia Buildbot Self-Analysis</title> |
- <link rel="icon" href="favicon.ico"> |
- <script type="text/javascript" src="https://www.google.com/jsapi"></script> |
- <script type="text/javascript" src="skia_tools.js"></script> |
- <script language="JavaScript"> |
- "use strict"; |
- |
- var selectedMaster = null; |
- |
- // Build result codes. |
- var SUCCESS = 0; |
- |
- // Number of builds which should be loaded. |
- var DEFAULT_BUILDS_TO_LOAD = 50; |
- |
- // Object to manage Git revision history. |
- var gitHistory = new skiaTools.GitHistory(); |
- |
- // Configuration options for the charts |
- var LINE_CHART_OPTIONS = { |
- "title": "Build Times", |
- "width": "100%", |
- "height": "100%", |
- "chartArea": {left: "9%", top: "9%", width: "86%", |
- height: "70%"}, |
- "interpolateNulls": true, |
- "hAxis": {"title": "Revision"}, |
- "vAxis": {"title": "Build Time (s)"}, |
- "legend": {"textStyle": {"fontSize": 12}, |
- "position": "bottom"}, |
- }; |
- |
- var LINE_CHART_RANGE_FILTER_OPTIONS = { |
- "filterColumnIndex": 0, |
- "ui": { |
- "chartType": "AreaChart", |
- "minRangeSize": 1, |
- "chartOptions": { |
- "chartArea": {"width": "86%", |
- "height": "75%", |
- "left": "9%", |
- "right": "6%"}, |
- "width": "100%", |
- "height": "100%", |
- "colors": ["grey"], |
- "hAxis": {"baselineColor": "none"}, |
- "vAxis": {"baselineColor": "none"}, |
- "interpolateNulls": true, |
- }, |
- }, |
- }; |
- |
- var BAR_CHART_OPTIONS = { |
- "width": "100%", |
- "height": "100%", |
- "chartArea": {left: "17%", top: "9%", width: "65%", height: "70%"}, |
- "hAxis": {"title": "Time (s)"}, |
- "vAxis": {"title": "Build Step"}, |
- "tooltip": {"isHtml": true}, |
- "legend": {"position": "none"}, |
- }; |
- |
- // High-level information about each builder. |
- var builderData = null; |
- |
- var loadStart = null; |
- |
- // Load the Visualization API |
- google.load("visualization", "1.0", {"packages":["corechart", "controls"]}); |
- |
- // Set a callback to run when the Google Visualization API is loaded. |
- google.setOnLoadCallback(init); |
- |
- /** |
- * Display text or HTML in the logging div. |
- * @param {string} msg The HTML or text to display. |
- */ |
- function setMessage(msg) { |
- console.log(msg); |
- document.getElementById("logging_div").innerHTML = msg; |
- } |
- |
- /** |
- * Set the HTML content in the pane on the right side of the page. |
- * @param {string} content HTML to display. |
- */ |
- function setRightContent(content) { |
- document.getElementById("right_content_div").innerHTML = content; |
- } |
- |
- /** |
- * Clear the divs containing charts. Useful when charts need to be updated. |
- */ |
- function clearCharts() { |
- document.getElementById("line_chart_div").innerHTML = ""; |
- document.getElementById("line_chart_range_filter_div").innerHTML = ""; |
- document.getElementById("bar_chart_div").innerHTML = ""; |
- } |
- |
- /** |
- * Convert a duration in seconds to an easily-readable string. |
- * @param {number} seconds The duration to convert. |
- * @return {string} The duration in HH:MM:SS format. |
- */ |
- function formatTime(secondsParam) { |
- var seconds = Math.round(secondsParam); |
- var minutes = Math.floor(seconds / 60); |
- seconds -= seconds * 60; |
- var hours = Math.floor(minutes / 60); |
- minutes -= hours * 60; |
- var totalTime = ""; |
- if (seconds > 9) { |
- totalTime = seconds; |
- } else { |
- totalTime = "0" + seconds; |
- } |
- if (minutes > 9) { |
- totalTime = minutes + ":" + totalTime; |
- } else { |
- totalTime = "0" + minutes + ":" + totalTime; |
- } |
- if (hours > 9) { |
- totalTime = hours + ":" + totalTime; |
- } else { |
- totalTime = "0" + hours + ":" + totalTime; |
- } |
- return totalTime; |
- } |
- |
- /** |
- * Draw a line chart illustrating build times for a number of revisions for |
- * a set of builders. |
- * @param {Array.<string>} displayBuilders List of builders which should be |
- * included in the chart. |
- * @param {object} data Dictionary containing builds for various builders, |
- * indexed by commit hash. |
- */ |
- function drawLineChart(displayBuilders, data) { |
- var message = ""; |
- if (loadStart) { |
- var elapsedSeconds = (new Date().getTime() - loadStart) / 1000; |
- message = "Loaded data in " + elapsedSeconds + " seconds."; |
- } |
- setMessage(message); |
- var table = new google.visualization.DataTable(); |
- table.addColumn("string", "Revision"); |
- for (var i = 0; i < displayBuilders.length; i++) { |
- table.addColumn("number", displayBuilders[i]); |
- table.addColumn({"type": "string", "role": "annotation"}); |
- } |
- var lineChartColsPerBuilder = 2; |
- var longestBuildTime = -1; |
- var rows = []; |
- var allRevs = gitHistory.getRevList(); |
- for (var revIdx = 0; revIdx < allRevs.length; revIdx++) { |
- var rev = allRevs[revIdx]; |
- var row = [rev]; |
- var rowHasData = false; |
- for (var builderIdx = 0; builderIdx < displayBuilders.length; |
- builderIdx++) { |
- var builder = displayBuilders[builderIdx]; |
- if (data[rev] != undefined && data[rev][builder] != undefined) { |
- rowHasData = true; |
- var time = data[rev][builder].getElapsedTime(); |
- if (time > longestBuildTime) { |
- longestBuildTime = time; |
- } |
- row.push(time); |
- if (data[rev][builder].getResult() != SUCCESS) { |
- row.push("failed"); |
- } else { |
- row.push(null); |
- } |
- } else { |
- row.push(null); |
- row.push(null); |
- } |
- } |
- // Skip revisions which have no builds. |
- if (rowHasData) { |
- rows.push(row); |
- } |
- } |
- table.addRows(rows); |
- |
- var lineChart = new google.visualization.LineChart(document.getElementById( |
- "line_chart_div")); |
- google.visualization.events.addListener(lineChart, 'select', |
- function() { |
- var selected = lineChart.getSelection()[0]; |
- if (selected && |
- selected.column != undefined && |
- selected.row != undefined) { |
- var builder = null; |
- var builderIdx = Math.floor( |
- (selected.column - 1) / lineChartColsPerBuilder); |
- builder = displayBuilders[builderIdx]; |
- var rev = rows[selected.row][0] |
- var buildNum = data[rev][builder].getNumber(); |
- console.log("Selected: " + builder + " @ " + rev); |
- var url = "http://" + selectedMaster.getHost() + ":" + |
- selectedMaster.getPort() + "/buildstatus?builder=" + builder + |
- "&number=" + buildNum; |
- var rightContent = "<iframe style=\"width:100%; height:100%; " |
- + "padding:0px; margin=0px; overflow:scroll;\" src=\"" |
- + url + "\"></iframe>"; |
- setRightContent(rightContent); |
- drawBarChart(builder, rev, longestBuildTime, data); |
- } |
- }); |
- lineChart.draw(table, LINE_CHART_OPTIONS); |
- setRightContent(""); |
- } |
- |
- /** |
- * Draw a bar chart illustrating the running times of each step in a given |
- * build for a given builder. |
- * @param {string} builder The builder whose build should be displayed. |
- * @param {string} revision The revision of the build to display. |
- * @param {number} viewWindowMax The width of the viewing window. This is |
- * provided instead of being determined from the data so that each bar |
- * graph can be displayed with the same scale. |
- * @param {object} data Dictionary containing builds for various builders, |
- * indexed by commit hash. |
- */ |
- function drawBarChart(builder, revision, viewWindowMax, data) { |
- var table = new google.visualization.DataTable(); |
- table.addColumn("string", "Step"); |
- table.addColumn("number", "Time"); |
- table.addColumn({"type": "string", "role": "tooltip", "p": {"html": true}}); |
- var buildData = data[revision][builder]; |
- for (var stepIdx = 0; stepIdx < buildData.getSteps().length; stepIdx++) { |
- var step = buildData.getSteps()[stepIdx]; |
- var stepName = step.getName(); |
- var time = step.getElapsedTime(); |
- var stdio = step.getStdio(); |
- var result = step.getResult(); |
- var percent = time / buildData.getElapsedTime() * 100.0; |
- table.addRow(); |
- table.setValue(stepIdx, 0, stepName); |
- table.setValue(stepIdx, 1, time); |
- var tooltip = "<div style=\"font-family:Arial;font-size:14px;" |
- + "padding:10px;\">" + stepName; |
- if (result != 0) { |
- tooltip += " <span style=\"background-color:red;\">Failed</span>"; |
- } |
- tooltip += "<br/>" + formatTime(time) + " (" + percent.toFixed(2) |
- + "%)<br/>Log: <a href=\"" + stdio |
- + "\" target=\"_blank\">stdout</a></div>"; |
- table.setFormattedValue(stepIdx, 2, tooltip); |
- } |
- |
- // Instantiate and draw our chart, passing in some options. |
- var barChart = new google.visualization.BarChart( |
- document.getElementById("bar_chart_div")); |
- var options = BAR_CHART_OPTIONS; |
- options["title"] = builder + ": Build #" + buildData.getNumber() + " (" + |
- buildData.getRevision() + ")"; |
- options["hAxis"]["viewWindow"] = {"max": viewWindowMax}; |
- barChart.draw(table, BAR_CHART_OPTIONS); |
- } |
- |
- /** |
- * Callback function to use when the selected items of the listbox have |
- * changed. This causes data to be loaded for the selected builders and charts |
- * to be created for that data. |
- */ |
- function selectBuilders() { |
- if (!selectedMaster) { |
- console.warn("selectBuilders: No master selected!"); |
- return; |
- } |
- loadStart = new Date().getTime(); |
- var displayBuilders = []; |
- var msg = "<p style=\"font-size:0.8em;\">Loading builds for builders:<ul>"; |
- var menu = document.getElementById("builder_menu"); |
- for (var i = 0; i < menu.options.length; i++) { |
- if (menu.options[i].selected) { |
- var builder = menu.options[i].text; |
- if (displayBuilders.indexOf(builder) == -1) { |
- displayBuilders.push(builder); |
- msg += "<li style=\"font-size:0.8em;\">" + builder; |
- } |
- } |
- } |
- msg += "</ul></p>"; |
- clearCharts(); |
- setMessage(msg); |
- var data = {}; |
- |
- var revsToLoad = []; |
- var buildsToLoad = document.getElementById("builds_to_load").value; |
- var buildersToLoad = Array.prototype.slice.call(displayBuilders); |
- for (var i = 0; i < displayBuilders.length; i++) { |
- var builder = displayBuilders[i]; |
- var builderObj = builderData[builder]; |
- builderObj.loadBuilds(buildsToLoad, function(builder, dataForBuilder) { |
- for (var buildNum in dataForBuilder) { |
- var rev = dataForBuilder[buildNum].getRevision(); |
- if (revsToLoad.indexOf(rev) == -1) { |
- revsToLoad.push(rev); |
- } |
- if (!data[rev]) { |
- data[rev] = {}; |
- } |
- data[rev][builder] = dataForBuilder[buildNum]; |
- } |
- console.log("Got builds for " + builder); |
- buildersToLoad.splice(buildersToLoad.indexOf(builder), 1); |
- if (buildersToLoad.length == 0) { |
- // Ensure that all revision data has been loaded, draw the chart. |
- gitHistory.ensureLoaded(revsToLoad, function() { |
- drawLineChart(displayBuilders, data); |
- }); |
- } |
- }); |
- } |
- } |
- |
- /** |
- * Callback function called when the selected build master has changed. Loads |
- * the builders for the master in the master_menu dropdown. |
- */ |
- function selectMaster() { |
- selectedMaster = new skiaTools.Master( |
- document.getElementById("master_menu").value); |
- setMessage("Loading builders for " + selectedMaster.getName() + |
- " master..."); |
- selectedMaster.loadBuilders(function(builders) { |
- builderData = {}; |
- for (var builderNum = 0; builderNum < builders.length; builderNum++) { |
- var builder = builders[builderNum]; |
- builderData[builder.getName()] = builder; |
- } |
- skiaTools.populateMenu("builder_menu", Object.keys(builderData)); |
- setMessage("Loaded builders."); |
- setMessage("Select one or more builders."); |
- }); |
- } |
- |
- /** |
- * Callback function to use on page load. This causes the high-level builder |
- * data to be loaded and the builder menu populated. |
- */ |
- function init() { |
- setMessage("Loading masters..."); |
- document.getElementById("builds_to_load").value = DEFAULT_BUILDS_TO_LOAD; |
- skiaTools.loadMasterList(function(masters) { |
- skiaTools.populateMenu("master_menu", masters); |
- document.getElementById("master_menu").selectedIndex = -1; |
- setMessage("Loaded masters."); |
- setMessage("Please select a build master."); |
- }); |
- } |
- </script> |
- </head> |
- <body> |
- <div id="heading" style="font-size:2.5em; text-align:center; height:7%;"> |
- Skia Buildbots Self-Analysis |
- </div> |
- <div id="main_content_area" style="width:100%; height:90%; padding:0px; margin:0px;"> |
- <div id="builder_menu_div" style="float:left; width:18%; height:100%; padding:0px; margin:0px;"> |
- <div style="width:100%;"> |
- <div style="float:left; width:50%;"> |
- Master:<br/> |
- <select id="master_menu" onChange="selectMaster();"> |
- <option value="" noselect></option> |
- </select> |
- </div> |
- <div> |
- <nobr>Builds to load:</nobr><br/> |
- <input type="text" id="builds_to_load" value="" /> |
- </div> |
- </div> |
- <div> |
- Builders:<br/> |
- <select id="builder_menu" multiple="multiple" |
- style="width:100%; height:90%; margin:0px; padding:0px;"> |
- </select> |
- <br/> |
- <input type="button" onClick="selectBuilders()" |
- value="Update Selection"/> |
- </div> |
- </div> |
- <div id="charts_div" style="float:left; width:67%; padding:0px; margin:0px"> |
- <div id="logging_div" style="width:100%; padding:0px; margin:0px"></div> |
- <div id="line_chart_div" style="width:100%; height: 40%; padding:0px; margin:0px"></div> |
- <div id="line_chart_range_filter_div" style="width:100%; height: 10%; padding:0px; margin:0px"></div> |
- <div id="bar_chart_div" style="width:100%; height: 50%; padding:0px; margin:0px"></div> |
- </div> |
- <div id="right_content_div" style="float:right; width:15%; height:100%"></div> |
- </div> |
- </body> |
-</html> |