Chromium Code Reviews| Index: Tools/TestResultServer/static-dashboards/flakiness_dashboard.js |
| diff --git a/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js b/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js |
| index 3120ed478b34b09b27b5176c8aab6b6983606783..6bb52323dddd22e83a24680edb09b4b0fb2a1280 100644 |
| --- a/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js |
| +++ b/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js |
| @@ -537,12 +537,18 @@ function showPopupForBuild(e, builder, index, opt_testName) |
| ui.popup.show(e.target, html); |
| } |
| +function showPopupForInterpolatedResult(e, revision) |
| +{ |
| + var html = 'This bot did not run the test for r' + revision + '.'; |
| + ui.popup.show(e.target, html); |
| +} |
| + |
| function classNameForFailureString(failure) |
| { |
| return failure.replace(/(\+|\ )/, ''); |
| } |
| -function htmlForTestResults(test) |
| +function htmlForTestResults(test, blinkRevisions) |
| { |
| var html = ''; |
| var testResults = test.rawResults.concat(); |
| @@ -551,10 +557,14 @@ function htmlForTestResults(test) |
| var master = builders.master(builder); |
| var buildNumbers = g_resultsByBuilder[builder].buildNumbers; |
| + var cells = []; |
| + for (var index = 0; index < blinkRevisions.length; index++) |
| + cells.push({revision: blinkRevisions[index]}); |
| + |
| var indexToReplaceCurrentResult = -1; |
| var indexToReplaceCurrentTime = -1; |
| for (var i = 0; i < buildNumbers.length; i++) { |
| - var currentResultArray, currentTimeArray, innerHTML, resultString; |
| + var currentResultArray, currentTimeArray, currentTime, resultString; |
| if (i > indexToReplaceCurrentResult) { |
| currentResultArray = testResults.shift(); |
| @@ -569,22 +579,75 @@ function htmlForTestResults(test) |
| if (i > indexToReplaceCurrentTime) { |
| currentTimeArray = times.shift(); |
| - var currentTime = 0; |
|
ojan
2014/07/14 23:40:39
I think deleting this caused the bug we found earl
pdr.
2014/07/17 14:50:28
Ack. Fixed.
|
| if (currentResultArray) { |
| currentTime = currentTimeArray[results.RLE.VALUE]; |
| indexToReplaceCurrentTime += currentTimeArray[results.RLE.LENGTH]; |
| } else |
| indexToReplaceCurrentTime += buildNumbers.length; |
| + } |
| - innerHTML = currentTime || ' '; |
| + var revision = parseInt( |
| + g_resultsByBuilder[builder][results.BLINK_REVISIONS][i], 10); |
| + |
| + // Locate the empty cell corresponding to this blink revision. |
| + var cell = undefined; |
|
ojan
2014/07/14 23:40:38
nit: use find and get rid of the comment.
var cel
pdr.
2014/07/17 14:50:28
Unfortunately, it looks like find isn't available
|
| + for (var index = 0; index < cells.length; index++) { |
| + if (cells[index].revision == revision && !cells[index].html) { |
| + cell = cells[index]; |
| + break; |
| + } |
| } |
| - html += '<td title="' + resultString + '. Click for more info." class="results ' + classNameForFailureString(resultString) + |
| - '" onclick=\'showPopupForBuild(event, "' + builder + '",' + i + ',"' + test.test + '")\'>' + innerHTML; |
| + cell.className = classNameForFailureString(resultString); |
| + cell.hasResult = |
| + resultString !== results.NO_DATA && resultString !== results.NOTRUN; |
| + cell.html = '<td' |
| + + ' title="' + resultString + '. Click for more info."' |
| + + ' class="results ' + cell.className + '"' |
| + + ' onclick=\'showPopupForBuild(event,' |
| + + ' "' + builder + '",' + i + ',"' + test.test + '")\'>' |
| + + (currentTime || (cell.hasResult ? ' ' : '?')) + '</td>'; |
|
ojan
2014/07/14 23:40:38
As discussed in person, lets show a #bbb question
pdr.
2014/07/17 14:50:28
Done.
|
| } |
| + |
| + populateEmptyCells(cells); |
| + |
| + for (var index = 0; index < cells.length; index++) |
| + html += cells[index].html; |
| + |
| return html; |
| } |
| +// Fill in cells where no test data is available with a question mark. |
| +// If the next and previous runs were equal, an "interpolated" result is shown. |
| +function populateEmptyCells(cells) |
| +{ |
| + for (var index = 1; index < cells.length; index++) { |
| + var prevCell = cells[index - 1]; |
| + cells[index].nextClassName = |
| + prevCell.hasResult ? prevCell.className : prevCell.nextClassName; |
| + } |
| + |
| + for (var index = cells.length - 2; index >= 0; --index) { |
| + var nextCell = cells[index + 1]; |
| + cells[index].prevClassName = |
| + nextCell.hasResult ? nextCell.className : nextCell.prevClassName; |
| + } |
| + |
| + cells.forEach(function(cell) { |
| + if (!cell.html) { |
| + var interpolateResult = |
| + cell.nextClassName && cell.nextClassName == cell.prevClassName; |
| + cell.className = interpolateResult ? cell.nextClassName : "NODATA"; |
| + cell.html = '<td' |
| + + ' title="Unknown result. Did not run tests."' |
| + + ' onclick=\'showPopupForInterpolatedResult(event,' |
| + + ' ' + cell.revision + ')\'' |
| + + ' class="results interpolatedResults ' + cell.className + '"' |
| + + ' >?</td>'; |
| + } |
| + }); |
| +} |
| + |
| function shouldShowTest(testResult) |
| { |
| if (!g_history.isLayoutTestResults()) |
| @@ -649,7 +712,7 @@ function linkifyBugs(bugs) |
| return html; |
| } |
| -function htmlForSingleTestRow(test, showBuilderNames) |
| +function htmlForSingleTestRow(test, showBuilderNames, revisions) |
| { |
| var headers = tableHeaders(); |
| var html = ''; |
| @@ -667,7 +730,7 @@ function htmlForSingleTestRow(test, showBuilderNames) |
| else if (string.startsWith(header, 'slowest')) |
| html += '<td>' + (test.slowestTime ? test.slowestTime + 's' : ''); |
| else if (string.startsWith(header, 'flakiness')) |
| - html += htmlForTestResults(test); |
| + html += htmlForTestResults(test, revisions); |
| } |
| return html; |
| } |
| @@ -783,6 +846,41 @@ function sortTests(tests, column, order) |
| tests.sort(sortFunctionGetter(resultsProperty, order == BACKWARD)); |
| } |
| +// Return an array of the unique blink build revisions across all builders. |
| +// Each entry will correspond to one column of results. Note that the revisions |
| +// may not be unique: a builder can test the same blink revision but with |
| +// different chrome revisions and this will result in multiple entries of a |
| +// single blink revision in the returned array. |
| +function blinkBuildRevisions(testResults) |
|
ojan
2014/07/14 23:40:39
As discussed in person, we should only do this for
pdr.
2014/07/17 14:50:28
Done.
|
| +{ |
| + var revisionsCountedSet = {}; |
| + for (var resultIndex = 0; resultIndex < testResults.length; resultIndex++) { |
| + var builder = testResults[resultIndex].builder; |
| + var build = g_resultsByBuilder[builder]; |
| + var buildNumbers = build.buildNumbers; |
| + var builderRevisionsCountedSet = {}; |
| + for (var i = 0; i < buildNumbers.length; i++) { |
| + var blinkRevision = build[results.BLINK_REVISIONS][i]; |
| + builderRevisionsCountedSet[blinkRevision] = (builderRevisionsCountedSet[blinkRevision] || 0) + 1; |
| + } |
| + |
| + // Join the builder's revisions with the total revisions for all builders. |
| + for (var revision in builderRevisionsCountedSet) |
| + revisionsCountedSet[revision] = Math.max(revisionsCountedSet[revision] || 0, builderRevisionsCountedSet[revision]); |
| + } |
| + |
| + var revisionsArray = []; |
| + for (var revision in revisionsCountedSet) { |
| + for (var i = revisionsCountedSet[revision] - 1; i >= 0; --i) |
| + revisionsArray.push(revision); |
| + } |
| + |
| + revisionsArray.sort(function(a, b) { |
| + return (b - a); |
| + }); |
| + return revisionsArray; |
| +} |
| + |
| function htmlForIndividualTestOnAllBuilders(test) |
| { |
| processTestRunsForAllBuilders(); |
| @@ -793,10 +891,11 @@ function htmlForIndividualTestOnAllBuilders(test) |
| var html = ''; |
| var shownBuilders = []; |
| + var blinkRevisions = blinkBuildRevisions(testResults); |
| for (var j = 0; j < testResults.length; j++) { |
| shownBuilders.push(testResults[j].builder); |
| var showBuilderNames = true; |
| - html += htmlForSingleTestRow(testResults[j], showBuilderNames); |
| + html += htmlForSingleTestRow(testResults[j], showBuilderNames, blinkRevisions); |
| } |
| var skippedBuilders = [] |
| @@ -1261,8 +1360,9 @@ function generatePageForBuilder(builderName) |
| if (filteredResults.length) { |
| var tableRowsHTML = ''; |
| var showBuilderNames = false; |
| + var blinkRevisions = blinkBuildRevisions(filteredResults); |
| for (var i = 0; i < filteredResults.length; i++) |
| - tableRowsHTML += htmlForSingleTestRow(filteredResults[i], showBuilderNames) |
| + tableRowsHTML += htmlForSingleTestRow(filteredResults[i], showBuilderNames, blinkRevisions) |
| testsHTML = htmlForTestTable(tableRowsHTML); |
| } else { |
| if (g_history.isLayoutTestResults()) |