summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorojan@chromium.org <ojan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-01 18:28:52 +0000
committerojan@chromium.org <ojan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-01 18:28:52 +0000
commit53b891fee34d1db4f5f0b036c1009f4ad46ef673 (patch)
treec86eb1bc67212b9df5e6d75d2f757f6b28a1e4ea /webkit
parent83d97626f0235f4f1b14daf47ec8456bafb21257 (diff)
downloadchromium_src-53b891fee34d1db4f5f0b036c1009f4ad46ef673.zip
chromium_src-53b891fee34d1db4f5f0b036c1009f4ad46ef673.tar.gz
chromium_src-53b891fee34d1db4f5f0b036c1009f4ad46ef673.tar.bz2
Add an individual tests view to the dashboard for viewing a list
of tests over all the builders. BUG=none TEST=manual git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25061 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/tools/layout_tests/flakiness_dashboard.html281
1 files changed, 185 insertions, 96 deletions
diff --git a/webkit/tools/layout_tests/flakiness_dashboard.html b/webkit/tools/layout_tests/flakiness_dashboard.html
index 364359b..5a8bfe8 100644
--- a/webkit/tools/layout_tests/flakiness_dashboard.html
+++ b/webkit/tools/layout_tests/flakiness_dashboard.html
@@ -15,6 +15,9 @@
font-size: 16px;
margin-bottom: .25em;
}
+ form {
+ margin: 3px 0;
+ }
.test-link {
white-space: normal;
}
@@ -38,11 +41,9 @@
-webkit-user-select: none;
-moz-user-select: none;
}
- .link {
+ .link, .sortable .header-text {
color: blue;
text-decoration: underline;
- white-space: nowrap;
- display: inline-block;
cursor: pointer;
}
.table-header-content,
@@ -71,6 +72,10 @@
.builders * {
margin: 0 5px;
}
+ .builders .link {
+ display: inline-block;
+ white-space: nowrap;
+ }
.test-table .wrong-expectations,
.wrong-expectations {
background-color: #afdaff;
@@ -118,6 +123,10 @@
-moz-column-gap: 25px;
-moz-column-rule: 1px dashed black;
}
+ .not-found {
+ color: red;
+ font-size: large;
+ }
</style>
<style id="wont-fix-style">
@@ -172,6 +181,8 @@
};
var resultsByBuilder = {};
+ // Maps test path to an array of {builder, testResults} objects.
+ var testToResultsMap = {};
var expectationsByTest = {};
function ADD_RESULTS(builds) {
for (var builderName in builds) {
@@ -219,13 +230,15 @@
'O': 'OTHER',
'N': 'NO DATA'
};
- var TABLE_HEADERS = ['test', 'modifiers', 'expectations',
- 'missing', 'extra', 'slowest run',
- 'flakiness (numbers are runtimes in seconds)'];
var PLATFORMS = {'MAC': 'MAC', 'LINUX': 'LINUX', 'WIN': 'WIN'};
var BUILD_TYPES = {'DEBUG': 'DBG', 'RELEASE': 'RELEASE'};
// GLOBALS
+ // The DUMMYVALUE gets shifted off the array in the first call to
+ // generatePage.
+ var tableHeaders = ['DUMMYVALUE', 'modifiers', 'expectations',
+ 'missing', 'extra', 'slowest run',
+ 'flakiness (numbers are runtimes in seconds)'];
var currentState = {builder: null, sortOrder: FORWARD, sortColumn: 'test'};
var perBuilderPlatformAndBuildType = {};
var oldLocation;
@@ -548,9 +561,14 @@
var times = resultsByBuilder[builderName].tests[test].times;
resultsForTest.slowestTime = Math.max.apply(null, times)
- resultsForTest.html = getHtmlForIndividualTest(builderName, test);
+ resultsForTest.html = getHtmlForTestResults(builderName, test);
failures.push(resultsForTest);
+
+ if (!testToResultsMap[test])
+ testToResultsMap[test] = [];
+ testToResultsMap[test].push(
+ {builder: builderName, results: resultsForTest});
}
perBuilderFailures[builderName] = failures;
@@ -595,7 +613,7 @@
window.open(BUILDERS_BASE_PATH + builderName + '/builds/' + buildNumber);
}
- function getHtmlForIndividualTest(builderName, testPath) {
+ function getHtmlForTestResults(builderName, testPath) {
var html = '';
var test = resultsByBuilder[builderName].tests[testPath];
var results = test.results.split('');
@@ -611,100 +629,76 @@
return html;
}
- function getHTMLForTestTable(results, id, sort, order) {
- var html = '<div class=legend>';
- for (var expectation in EXPECTATIONS_MAP) {
- html += '<span class=' + expectation + '>' +
- EXPECTATIONS_MAP[expectation] + '</span>';
- }
- html += '<span class=wrong-expectations>WRONG EXPECTATIONS</span></div>' +
- '<table id=' + id + ' class=test-table>' +
- getTableHeaders(sort, order) + '<tbody>';
+ function getHTMLForTestsWithExpectationsButNoFailures(builder) {
+ var tests = perBuilderWithExpectationsButNoFailures[builder];
+ if (!tests.length)
+ return '';
- sortTests(results, sort, order);
- for (var i = 0; i < results.length; i++) {
- var test = results[i];
+ var buildInfo = getPlatFormAndBuildType(builder);
+ return '<h2>Have expectations for ' + buildInfo.platform + '-' +
+ buildInfo.buildType + ' but have not failed in last ' +
+ resultsByBuilder[builderName].buildNumbers.length +
+ ' runs.</h2><div id="passing-tests"><div>' +
+ tests.join('</div><div>') + '</div></div>';
+ }
- var classes = [];
- if (!test.meetsExpectations)
- classes.push('wrong-expectations');
+ function getHTMLForSingleTestRow(test, opt_builder) {
+ var classes = [];
+ if (!test.meetsExpectations)
+ classes.push('expectation-mismatch');
- if (test.isWontFix)
- classes.push('wontfix');
+ if (test.isWontFix)
+ classes.push('wontfix');
- html += '<tr class="' + classes.join(' ') +
- // TODO(ojan): If a test is a chrome/ or a pending/ test, point to
- // src.chromium.org instead of trac.webkit.org.
- '"><td class=test-link><a href="' + TEST_URL_BASE_PATH + test.test +
- '">' + test.test + '</a>' +
- '</td><td class=options-container>' + test.modifiersHTML +
- '</td><td class=options-container>' + test.expectationsHTML +
- '</td><td>' + test.missing +
- '</td><td>' + test.extra +
- '</td><td>' + (test.slowestTime ? test.slowestTime + 's' : '') +
- '</td>' +
- test.html +
- '</tr>';
- }
+ // If opt_builder is provided, we're just viewing a single test
+ // with results for many builders.
+ var testCellHTML = opt_builder ? opt_builder :
+ '<span class="link" onclick="setState(\'tests\', \'' + test.test +
+ '\');return false;">' + test.test + '</span>';
- return html + "</tbody></table>"
+ return '<tr class="' + classes.join(' ') +
+ // TODO(ojan): If a test is a chrome/ or a pending/ test, point to
+ // src.chromium.org instead of trac.webkit.org.
+ '"><td class=test-link>' + testCellHTML +
+ '</td><td class=options-container>' + test.modifiersHTML +
+ '</td><td class=options-container>' + test.expectationsHTML +
+ '</td><td>' + test.missing +
+ '</td><td>' + test.extra +
+ '</td><td>' + (test.slowestTime ? test.slowestTime + 's' : '') +
+ '</td>' +
+ test.html +
+ '</tr>';
}
- function getTableHeaders(sort, order) {
- var html = '<thead><tr>';
- for (var i = 0; i < TABLE_HEADERS.length; i++) {
+ function getHTMLForTestTable(rowsHTML) {
+ var html = '<div class=legend>';
+ for (var expectation in EXPECTATIONS_MAP) {
+ html += '<span class=' + expectation + '>' +
+ EXPECTATIONS_MAP[expectation] + '</span>';
+ }
+ html += '<span class=wrong-expectations>WRONG EXPECTATIONS</span>' +
+ '</div><table class=test-table><thead><tr>';
+ for (var i = 0; i < tableHeaders.length; i++) {
// Use the first word of the header title as the sortkey
- var thisSortValue = TABLE_HEADERS[i].split(' ')[0];
- var arrowHTML = thisSortValue == sort ?
- '<span class=' + order + '>' +
- (order == FORWARD ? '&uarr;' : '&darr;' ) + '</span>' :
+ var thisSortValue = tableHeaders[i].split(' ')[0];
+ var arrowHTML = thisSortValue == currentState.sortColumn ?
+ '<span class=' + currentState.sortOrder + '>' +
+ (currentState.sortOrder == FORWARD ? '&uarr;' : '&darr;' ) +
+ '</span>' :
'';
html += '<th sortValue=' + thisSortValue +
// Extend last th through all the rest of the columns.
- (i == TABLE_HEADERS.length - 1 ? ' colspan=10000' : '') +
+ (i == tableHeaders.length - 1 ? ' colspan=10000' : '') +
// Extra span here is so flex boxing actually centers.
// There's probably a better way to do this with CSS only though.
'><div class=table-header-content><span></span>' + arrowHTML +
- '<span class=link>' + TABLE_HEADERS[i] + '</span>' +
+ '<span class=header-text>' + tableHeaders[i] + '</span>' +
arrowHTML + '</div></th>';
}
- html += '</tr></thead>';
- return html;
- }
-
- function getHTMLForTestsWithExpectationsButNoFailures(builder) {
- var tests = perBuilderWithExpectationsButNoFailures[builder];
- if (!tests.length)
- return '';
-
- var buildInfo = getPlatFormAndBuildType(builder);
- return '<h2>Have expectations for ' + buildInfo.platform + '-' +
- buildInfo.buildType + ' but have not failed in last 100 ' +
- 'runs.</h2><div id="passing-tests"><div>' +
- tests.join('</div><div>') + '</div></div>';
- }
-
- function getHTMLForNavBar() {
- var html = '<div class=builders>';
- for (var builder in builders) {
- var className = builder == currentState.builder ?
- 'current-builder' : 'link';
- html += '<span class=' + className +
- ' onclick=\'setState("builder", "' + builder + '")\'>' +
- builder + '</span>';
- }
- return html + '</div>';
+ return html + '</tr></thead><tbody>' + rowsHTML + '</tbody></table>';
}
- function setFullPageHTML() {
- var html = getHTMLForNavBar() +
- getHTMLForTestsWithExpectationsButNoFailures(currentState.builder) +
- '<h2>Failing tests</h2><input type=checkbox id=wont-fix-input ' +
- 'onclick="updateWontFixDisplay()">Show WONTFIX tests.' +
- '<b> | All columns are sortable. | Skipped tests are not listed. | ' +
- 'Flakiness reader order is newer --> older runs.</b>' +
- getHTMLForTestTable(perBuilderFailures[currentState.builder],
- 'failures', currentState.sortColumn, currentState.sortOrder);
+ function setFullPageHTML(html) {
var startTime = Date.now();
// InnerHTML to a div that's not in the document. This is
// ~300ms faster in Safari 4 and Chrome 4 on mac.
@@ -787,15 +781,12 @@
var hash = window.location.hash;
if (hash) {
var hashParts = hash.slice(1).split('&');
+ var urlHasTests = false;
for (var i = 0; i < hashParts.length; i++) {
var itemParts = hashParts[i].split('=');
currentState[itemParts[0]] = decodeURIComponent(itemParts[1]);
- }
- }
- if (!currentState.builder) {
- for (var builder in builders) {
- currentState.builder = builder;
- break;
+ if (itemParts[0] == 'tests')
+ urlHasTests = true;
}
}
@@ -808,18 +799,100 @@
return;
}
- processTestRunsForBuilder(currentState.builder);
- setFullPageHTML();
+ tableHeaders.shift();
+ if (urlHasTests) {
+ tableHeaders.unshift('builder');
+
+ generatePageForIndividualTests(currentState.tests.split(','));
+ } else {
+ tableHeaders.unshift('test');
+
+ if (!currentState.builder) {
+ for (var builder in builders) {
+ currentState.builder = builder;
+ break;
+ }
+ }
+ generatePageForBuilder(currentState.builder);
+ }
+ logTime('Time to generate page', startTime);
+ }
+
+ function generatePageForIndividualTests(tests) {
+ // TODO: Add link to trac from individual test page
+ // TODO: Make links on builder pages to tests be to the individual test page
+ for (var builder in builders)
+ processTestRunsForBuilder(builder);
+
+ var html = getHTMLForNavBar() +
+ '<b>IF A BUILDER IS NOT LISTED THAT MEANS THE ' +
+ 'BUILDER DOES NOT RUN THAT TEST OR ALL RUNS OF THE TEST PASSED.</b>';
+
+ for (var i = 0; i < tests.length; i++) {
+ html += '<h2>' + tests[i] + '</h2>';
+
+ var testResults = testToResultsMap[tests[i]];
+ if (testResults && testResults.length) {
+ var tableRowsHTML = '';
+ for (var j = 0; j < testResults.length; j++) {
+ tableRowsHTML += getHTMLForSingleTestRow(testResults[j].results,
+ testResults[j].builder);
+ }
+ html += getHTMLForTestTable(tableRowsHTML);
+ } else {
+ html +='<div class="not-found">Test not found. Either it does not ' +
+ 'exist or it passes on all platforms.</div>';
+ }
+ }
+ setFullPageHTML(html);
+
+ document.getElementById('tests-input').value = currentState.tests;
+ }
+
+ function getHTMLForNavBar(opt_builderName) {
+ var html = '<div class=builders>';
+ for (var builder in builders) {
+ var className = builder == opt_builderName ? 'current-builder' : 'link';
+ html += '<span class=' + className +
+ ' onclick=\'setState("builder", "' + builder + '")\'>' +
+ builder + '</span>';
+ }
+ return html + '</div>' +
+ '<form onsubmit="setState(\'tests\', tests.value);return false;">' +
+ 'Show tests on all platforms (slow): <input name=tests ' +
+ 'placeholder="LayoutTests/foo/bar.html,LayoutTests/foo/baz.html" ' +
+ 'id=tests-input style="width:60%"></form>';
+ }
+
+ function generatePageForBuilder(builderName) {
+ processTestRunsForBuilder(builderName);
+
+ var tableRowsHTML = '';
+ var results = perBuilderFailures[builderName];
+ sortTests(results, currentState.sortColumn, currentState.sortOrder);
+ for (var i = 0; i < results.length; i++) {
+ tableRowsHTML += getHTMLForSingleTestRow(results[i]);
+ }
+
+ var html = getHTMLForNavBar(builderName) +
+ getHTMLForTestsWithExpectationsButNoFailures(builderName) +
+ '<h2>Failing tests</h2><input type=checkbox id=wont-fix-input ' +
+ 'onclick="updateWontFixDisplay()">Show WONTFIX tests.' +
+ '<b> | All columns are sortable. | Skipped tests are not listed. | ' +
+ 'Flakiness reader order is newer --> older runs.</b>' +
+ getHTMLForTestTable(tableRowsHTML);
+
+ setFullPageHTML(html);
var ths = document.getElementsByTagName('th');
for (var i = 0; i < ths.length; i++) {
ths[i].addEventListener('click', changeSort, false);
+ ths[i].className = "sortable";
}
document.getElementById('wont-fix-input').checked =
currentState.showWontFix == 'true';
updateWontFixDisplay();
- logTime('Time to generate page', startTime);
}
function updateWontFixDisplay() {
@@ -836,11 +909,27 @@
function setState(key, value) {
currentState[key] = value;
- window.location.replace(window.location.pathname + '#' +
- 'builder=' + currentState.builder + '&' +
+
+ if (key == 'tests') {
+ currentState.builder = null;
+ currentState.sortColumn = null;
+ currentState.sortOrder = null;
+ currentState.showWontFix = null;
+ } else {
+ currentState.tests = null;
+ }
+
+ var newLocation = window.location.pathname + '#';
+ if (currentState.tests) {
+ newLocation += 'tests=' + currentState.tests;
+ } else {
+ newLocation += 'builder=' + currentState.builder + '&' +
'sortColumn=' + currentState.sortColumn + '&' +
'sortOrder=' + currentState.sortOrder + '&' +
- 'showWontFix=' + currentState.showWontFix);
+ 'showWontFix=' + currentState.showWontFix;
+ }
+
+ window.location.replace(newLocation);
// We don't need to regenerate the page if showWontFix is modified
// since we only need to modify a style element for that.
if (key != 'showWontFix')