Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(803)

Side by Side Diff: master/public_html/buildbots_self_analysis.html

Issue 648353002: Remove Skia's forked buildbot code (Closed) Base URL: https://skia.googlesource.com/buildbot.git@master
Patch Set: Address comment Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « master/public_html/bug_graphs.html ('k') | master/public_html/buildslave_idle.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 <html>
2 <head>
3 <title>Skia Buildbot Self-Analysis</title>
4 <link rel="icon" href="favicon.ico">
5 <script type="text/javascript" src="https://www.google.com/jsapi"></script>
6 <script type="text/javascript" src="skia_tools.js"></script>
7 <script language="JavaScript">
8 "use strict";
9
10 var selectedMaster = null;
11
12 // Build result codes.
13 var SUCCESS = 0;
14
15 // Number of builds which should be loaded.
16 var DEFAULT_BUILDS_TO_LOAD = 50;
17
18 // Object to manage Git revision history.
19 var gitHistory = new skiaTools.GitHistory();
20
21 // Configuration options for the charts
22 var LINE_CHART_OPTIONS = {
23 "title": "Build Times",
24 "width": "100%",
25 "height": "100%",
26 "chartArea": {left: "9%", top: "9%", width: "86%",
27 height: "70%"},
28 "interpolateNulls": true,
29 "hAxis": {"title": "Revision"},
30 "vAxis": {"title": "Build Time (s)"},
31 "legend": {"textStyle": {"fontSize": 12},
32 "position": "bottom"},
33 };
34
35 var LINE_CHART_RANGE_FILTER_OPTIONS = {
36 "filterColumnIndex": 0,
37 "ui": {
38 "chartType": "AreaChart",
39 "minRangeSize": 1,
40 "chartOptions": {
41 "chartArea": {"width": "86%",
42 "height": "75%",
43 "left": "9%",
44 "right": "6%"},
45 "width": "100%",
46 "height": "100%",
47 "colors": ["grey"],
48 "hAxis": {"baselineColor": "none"},
49 "vAxis": {"baselineColor": "none"},
50 "interpolateNulls": true,
51 },
52 },
53 };
54
55 var BAR_CHART_OPTIONS = {
56 "width": "100%",
57 "height": "100%",
58 "chartArea": {left: "17%", top: "9%", width: "65%", height: "70%"},
59 "hAxis": {"title": "Time (s)"},
60 "vAxis": {"title": "Build Step"},
61 "tooltip": {"isHtml": true},
62 "legend": {"position": "none"},
63 };
64
65 // High-level information about each builder.
66 var builderData = null;
67
68 var loadStart = null;
69
70 // Load the Visualization API
71 google.load("visualization", "1.0", {"packages":["corechart", "controls"]});
72
73 // Set a callback to run when the Google Visualization API is loaded.
74 google.setOnLoadCallback(init);
75
76 /**
77 * Display text or HTML in the logging div.
78 * @param {string} msg The HTML or text to display.
79 */
80 function setMessage(msg) {
81 console.log(msg);
82 document.getElementById("logging_div").innerHTML = msg;
83 }
84
85 /**
86 * Set the HTML content in the pane on the right side of the page.
87 * @param {string} content HTML to display.
88 */
89 function setRightContent(content) {
90 document.getElementById("right_content_div").innerHTML = content;
91 }
92
93 /**
94 * Clear the divs containing charts. Useful when charts need to be updated.
95 */
96 function clearCharts() {
97 document.getElementById("line_chart_div").innerHTML = "";
98 document.getElementById("line_chart_range_filter_div").innerHTML = "";
99 document.getElementById("bar_chart_div").innerHTML = "";
100 }
101
102 /**
103 * Convert a duration in seconds to an easily-readable string.
104 * @param {number} seconds The duration to convert.
105 * @return {string} The duration in HH:MM:SS format.
106 */
107 function formatTime(secondsParam) {
108 var seconds = Math.round(secondsParam);
109 var minutes = Math.floor(seconds / 60);
110 seconds -= seconds * 60;
111 var hours = Math.floor(minutes / 60);
112 minutes -= hours * 60;
113 var totalTime = "";
114 if (seconds > 9) {
115 totalTime = seconds;
116 } else {
117 totalTime = "0" + seconds;
118 }
119 if (minutes > 9) {
120 totalTime = minutes + ":" + totalTime;
121 } else {
122 totalTime = "0" + minutes + ":" + totalTime;
123 }
124 if (hours > 9) {
125 totalTime = hours + ":" + totalTime;
126 } else {
127 totalTime = "0" + hours + ":" + totalTime;
128 }
129 return totalTime;
130 }
131
132 /**
133 * Draw a line chart illustrating build times for a number of revisions for
134 * a set of builders.
135 * @param {Array.<string>} displayBuilders List of builders which should be
136 * included in the chart.
137 * @param {object} data Dictionary containing builds for various builders,
138 * indexed by commit hash.
139 */
140 function drawLineChart(displayBuilders, data) {
141 var message = "";
142 if (loadStart) {
143 var elapsedSeconds = (new Date().getTime() - loadStart) / 1000;
144 message = "Loaded data in " + elapsedSeconds + " seconds.";
145 }
146 setMessage(message);
147 var table = new google.visualization.DataTable();
148 table.addColumn("string", "Revision");
149 for (var i = 0; i < displayBuilders.length; i++) {
150 table.addColumn("number", displayBuilders[i]);
151 table.addColumn({"type": "string", "role": "annotation"});
152 }
153 var lineChartColsPerBuilder = 2;
154 var longestBuildTime = -1;
155 var rows = [];
156 var allRevs = gitHistory.getRevList();
157 for (var revIdx = 0; revIdx < allRevs.length; revIdx++) {
158 var rev = allRevs[revIdx];
159 var row = [rev];
160 var rowHasData = false;
161 for (var builderIdx = 0; builderIdx < displayBuilders.length;
162 builderIdx++) {
163 var builder = displayBuilders[builderIdx];
164 if (data[rev] != undefined && data[rev][builder] != undefined) {
165 rowHasData = true;
166 var time = data[rev][builder].getElapsedTime();
167 if (time > longestBuildTime) {
168 longestBuildTime = time;
169 }
170 row.push(time);
171 if (data[rev][builder].getResult() != SUCCESS) {
172 row.push("failed");
173 } else {
174 row.push(null);
175 }
176 } else {
177 row.push(null);
178 row.push(null);
179 }
180 }
181 // Skip revisions which have no builds.
182 if (rowHasData) {
183 rows.push(row);
184 }
185 }
186 table.addRows(rows);
187
188 var lineChart = new google.visualization.LineChart(document.getElementById(
189 "line_chart_div"));
190 google.visualization.events.addListener(lineChart, 'select',
191 function() {
192 var selected = lineChart.getSelection()[0];
193 if (selected &&
194 selected.column != undefined &&
195 selected.row != undefined) {
196 var builder = null;
197 var builderIdx = Math.floor(
198 (selected.column - 1) / lineChartColsPerBuilder);
199 builder = displayBuilders[builderIdx];
200 var rev = rows[selected.row][0]
201 var buildNum = data[rev][builder].getNumber();
202 console.log("Selected: " + builder + " @ " + rev);
203 var url = "http://" + selectedMaster.getHost() + ":" +
204 selectedMaster.getPort() + "/buildstatus?builder=" + builder +
205 "&number=" + buildNum;
206 var rightContent = "<iframe style=\"width:100%; height:100%; "
207 + "padding:0px; margin=0px; overflow:scroll;\" src=\""
208 + url + "\"></iframe>";
209 setRightContent(rightContent);
210 drawBarChart(builder, rev, longestBuildTime, data);
211 }
212 });
213 lineChart.draw(table, LINE_CHART_OPTIONS);
214 setRightContent("");
215 }
216
217 /**
218 * Draw a bar chart illustrating the running times of each step in a given
219 * build for a given builder.
220 * @param {string} builder The builder whose build should be displayed.
221 * @param {string} revision The revision of the build to display.
222 * @param {number} viewWindowMax The width of the viewing window. This is
223 * provided instead of being determined from the data so that each bar
224 * graph can be displayed with the same scale.
225 * @param {object} data Dictionary containing builds for various builders,
226 * indexed by commit hash.
227 */
228 function drawBarChart(builder, revision, viewWindowMax, data) {
229 var table = new google.visualization.DataTable();
230 table.addColumn("string", "Step");
231 table.addColumn("number", "Time");
232 table.addColumn({"type": "string", "role": "tooltip", "p": {"html": true}});
233 var buildData = data[revision][builder];
234 for (var stepIdx = 0; stepIdx < buildData.getSteps().length; stepIdx++) {
235 var step = buildData.getSteps()[stepIdx];
236 var stepName = step.getName();
237 var time = step.getElapsedTime();
238 var stdio = step.getStdio();
239 var result = step.getResult();
240 var percent = time / buildData.getElapsedTime() * 100.0;
241 table.addRow();
242 table.setValue(stepIdx, 0, stepName);
243 table.setValue(stepIdx, 1, time);
244 var tooltip = "<div style=\"font-family:Arial;font-size:14px;"
245 + "padding:10px;\">" + stepName;
246 if (result != 0) {
247 tooltip += " <span style=\"background-color:red;\">Failed</span>";
248 }
249 tooltip += "<br/>" + formatTime(time) + " (" + percent.toFixed(2)
250 + "%)<br/>Log: <a href=\"" + stdio
251 + "\" target=\"_blank\">stdout</a></div>";
252 table.setFormattedValue(stepIdx, 2, tooltip);
253 }
254
255 // Instantiate and draw our chart, passing in some options.
256 var barChart = new google.visualization.BarChart(
257 document.getElementById("bar_chart_div"));
258 var options = BAR_CHART_OPTIONS;
259 options["title"] = builder + ": Build #" + buildData.getNumber() + " (" +
260 buildData.getRevision() + ")";
261 options["hAxis"]["viewWindow"] = {"max": viewWindowMax};
262 barChart.draw(table, BAR_CHART_OPTIONS);
263 }
264
265 /**
266 * Callback function to use when the selected items of the listbox have
267 * changed. This causes data to be loaded for the selected builders and charts
268 * to be created for that data.
269 */
270 function selectBuilders() {
271 if (!selectedMaster) {
272 console.warn("selectBuilders: No master selected!");
273 return;
274 }
275 loadStart = new Date().getTime();
276 var displayBuilders = [];
277 var msg = "<p style=\"font-size:0.8em;\">Loading builds for builders:<ul>";
278 var menu = document.getElementById("builder_menu");
279 for (var i = 0; i < menu.options.length; i++) {
280 if (menu.options[i].selected) {
281 var builder = menu.options[i].text;
282 if (displayBuilders.indexOf(builder) == -1) {
283 displayBuilders.push(builder);
284 msg += "<li style=\"font-size:0.8em;\">" + builder;
285 }
286 }
287 }
288 msg += "</ul></p>";
289 clearCharts();
290 setMessage(msg);
291 var data = {};
292
293 var revsToLoad = [];
294 var buildsToLoad = document.getElementById("builds_to_load").value;
295 var buildersToLoad = Array.prototype.slice.call(displayBuilders);
296 for (var i = 0; i < displayBuilders.length; i++) {
297 var builder = displayBuilders[i];
298 var builderObj = builderData[builder];
299 builderObj.loadBuilds(buildsToLoad, function(builder, dataForBuilder) {
300 for (var buildNum in dataForBuilder) {
301 var rev = dataForBuilder[buildNum].getRevision();
302 if (revsToLoad.indexOf(rev) == -1) {
303 revsToLoad.push(rev);
304 }
305 if (!data[rev]) {
306 data[rev] = {};
307 }
308 data[rev][builder] = dataForBuilder[buildNum];
309 }
310 console.log("Got builds for " + builder);
311 buildersToLoad.splice(buildersToLoad.indexOf(builder), 1);
312 if (buildersToLoad.length == 0) {
313 // Ensure that all revision data has been loaded, draw the chart.
314 gitHistory.ensureLoaded(revsToLoad, function() {
315 drawLineChart(displayBuilders, data);
316 });
317 }
318 });
319 }
320 }
321
322 /**
323 * Callback function called when the selected build master has changed. Loads
324 * the builders for the master in the master_menu dropdown.
325 */
326 function selectMaster() {
327 selectedMaster = new skiaTools.Master(
328 document.getElementById("master_menu").value);
329 setMessage("Loading builders for " + selectedMaster.getName() +
330 " master...");
331 selectedMaster.loadBuilders(function(builders) {
332 builderData = {};
333 for (var builderNum = 0; builderNum < builders.length; builderNum++) {
334 var builder = builders[builderNum];
335 builderData[builder.getName()] = builder;
336 }
337 skiaTools.populateMenu("builder_menu", Object.keys(builderData));
338 setMessage("Loaded builders.");
339 setMessage("Select one or more builders.");
340 });
341 }
342
343 /**
344 * Callback function to use on page load. This causes the high-level builder
345 * data to be loaded and the builder menu populated.
346 */
347 function init() {
348 setMessage("Loading masters...");
349 document.getElementById("builds_to_load").value = DEFAULT_BUILDS_TO_LOAD;
350 skiaTools.loadMasterList(function(masters) {
351 skiaTools.populateMenu("master_menu", masters);
352 document.getElementById("master_menu").selectedIndex = -1;
353 setMessage("Loaded masters.");
354 setMessage("Please select a build master.");
355 });
356 }
357 </script>
358 </head>
359 <body>
360 <div id="heading" style="font-size:2.5em; text-align:center; height:7%;">
361 Skia Buildbots Self-Analysis
362 </div>
363 <div id="main_content_area" style="width:100%; height:90%; padding:0px; marg in:0px;">
364 <div id="builder_menu_div" style="float:left; width:18%; height:100%; padd ing:0px; margin:0px;">
365 <div style="width:100%;">
366 <div style="float:left; width:50%;">
367 Master:<br/>
368 <select id="master_menu" onChange="selectMaster();">
369 <option value="" noselect></option>
370 </select>
371 </div>
372 <div>
373 <nobr>Builds to load:</nobr><br/>
374 <input type="text" id="builds_to_load" value="" />
375 </div>
376 </div>
377 <div>
378 Builders:<br/>
379 <select id="builder_menu" multiple="multiple"
380 style="width:100%; height:90%; margin:0px; padding:0px;">
381 </select>
382 <br/>
383 <input type="button" onClick="selectBuilders()"
384 value="Update Selection"/>
385 </div>
386 </div>
387 <div id="charts_div" style="float:left; width:67%; padding:0px; margin:0px ">
388 <div id="logging_div" style="width:100%; padding:0px; margin:0px"></div>
389 <div id="line_chart_div" style="width:100%; height: 40%; padding:0px; ma rgin:0px"></div>
390 <div id="line_chart_range_filter_div" style="width:100%; height: 10%; pa dding:0px; margin:0px"></div>
391 <div id="bar_chart_div" style="width:100%; height: 50%; padding:0px; mar gin:0px"></div>
392 </div>
393 <div id="right_content_div" style="float:right; width:15%; height:100%"></ div>
394 </div>
395 </body>
396 </html>
OLDNEW
« no previous file with comments | « master/public_html/bug_graphs.html ('k') | master/public_html/buildslave_idle.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698