New flakiness dashboard should align results by revision numbers
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 Oct 2013 01:51:37 +0000 (01:51 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 22 Oct 2013 01:51:37 +0000 (01:51 +0000)
https://bugs.webkit.org/show_bug.cgi?id=123129

Reviewed by Tim Horton.

* include/config.json: Specify the default cache time to be 10 minutes.
* include/json-shared.php: Added Expires and Cache-Control headers. It's configurable via config.json.
* index.html:
(TestResultsView._createResultCell): Don't put '-' in a result cell without time.
(TestResultsView._populateTestPane): Create an array of build times ordered from the newest to the oldest.
Not that build.time() is the newest commit time among all repository for each result. e.g. if we had
both WebKit and Safari repository information in a given result, the newer of the two will be used.
(TestResultsView._createTestResultHeader): Added.
(TestResultsView._createBuildsAndComputeSlownessOfResults): Extracted from _createTestResultRow so
that _populateTestPane could use Build object before calling _createTestResultRow.
(TestResultsView._createTestResultRow): Takes buildTimes. Insert an empty cell for a build time if
the current row doesn't contain that a result for that build time.
(TestResultsView._populateBuilderPane):
* main.css: Tweaked the style so that bubbles are aligned vertically without '-'.
(.resultsTable):
(.resultsTable thead th):
(.resultsTable .resultCell):
(.resultsTable a):
(.resultsTable span a):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@157772 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Websites/test-results/ChangeLog
Websites/test-results/include/config.json
Websites/test-results/include/json-shared.php
Websites/test-results/index.html
Websites/test-results/main.css

index 15aabd327f06e2aed5cb4d7112e01fd9c4e430c9..bbc0f2024e4ef93a8d9d0050b2623c12cdfa6bdf 100644 (file)
@@ -1,3 +1,30 @@
+2013-10-21  Ryosuke Niwa  <rniwa@webkit.org>
+
+        New flakiness dashboard should align results by revision numbers
+        https://bugs.webkit.org/show_bug.cgi?id=123129
+
+        Reviewed by Tim Horton.
+
+        * include/config.json: Specify the default cache time to be 10 minutes.
+        * include/json-shared.php: Added Expires and Cache-Control headers. It's configurable via config.json.
+        * index.html:
+        (TestResultsView._createResultCell): Don't put '-' in a result cell without time.
+        (TestResultsView._populateTestPane): Create an array of build times ordered from the newest to the oldest.
+        Not that build.time() is the newest commit time among all repository for each result. e.g. if we had
+        both WebKit and Safari repository information in a given result, the newer of the two will be used.
+        (TestResultsView._createTestResultHeader): Added.
+        (TestResultsView._createBuildsAndComputeSlownessOfResults): Extracted from _createTestResultRow so
+        that _populateTestPane could use Build object before calling _createTestResultRow.
+        (TestResultsView._createTestResultRow): Takes buildTimes. Insert an empty cell for a build time if
+        the current row doesn't contain that a result for that build time.
+        (TestResultsView._populateBuilderPane):
+        * main.css: Tweaked the style so that bubbles are aligned vertically without '-'.
+        (.resultsTable):
+        (.resultsTable thead th):
+        (.resultsTable .resultCell):
+        (.resultsTable a):
+        (.resultsTable span a):
+
 2013-10-21  Ryosuke Niwa  <rniwa@webkit.org>
 
         New flakiness dashboard show test time, modifiers, and flaky tests
 2013-10-21  Ryosuke Niwa  <rniwa@webkit.org>
 
         New flakiness dashboard show test time, modifiers, and flaky tests
index 147919406455bf50d12c36fd78bdb56932ae75fe..a407f465613990926773a4bcd5254fc47658f4ed 100644 (file)
@@ -1,5 +1,6 @@
 {
     "debug": true,
 {
     "debug": true,
+    "jsonCacheMaxAge": 600,
     "database": {
         "host": "localhost",
         "port": "5432",
     "database": {
         "host": "localhost",
         "port": "5432",
index 3ed00fc56ee7a881981025bdd01418b945fc1415..a99921736f91576c309deba3e3ee5f3b83fa4b14 100644 (file)
@@ -3,6 +3,9 @@
 require_once('../include/db.php');
 
 header('Content-type: application/json');
 require_once('../include/db.php');
 
 header('Content-type: application/json');
+$maxage = config('jsonCacheMaxAge');
+header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $maxage) . ' GMT');
+header("Cache-Control: maxage=$maxage");
 
 function exit_with_error($status, $details = array()) {
     $details['status'] = $status;
 
 function exit_with_error($status, $details = array()) {
     $details['status'] = $status;
index 48e20a54f57d0cb2f72b8caf9aeea1a0820dc1cb..2dd04290143efefe5508f698d38e600f02c7bb92 100644 (file)
@@ -111,7 +111,7 @@ TestResultsView._createResultCell = function (master, builder, result, previousR
     var build = result['buildNumber'];
     var actual = result['actual'];
     var expected = result['expected'];
     var build = result['buildNumber'];
     var actual = result['actual'];
     var expected = result['expected'];
-    var timeIfSlow = result.isSlow ? result.roundedTime : '-';
+    var timeIfSlow = result.isSlow ? result.roundedTime : '';
     var anchor = element('a', {'href': this._urlFromBuilder('result', master, builder, revision, build)}, [timeIfSlow]);
     anchor.onmouseenter = function () {
         var repositoryById = TestResultsView._repositories;
     var anchor = element('a', {'href': this._urlFromBuilder('result', master, builder, revision, build)}, [timeIfSlow]);
     anchor.onmouseenter = function () {
         var repositoryById = TestResultsView._repositories;
@@ -145,41 +145,71 @@ TestResultsView._createResultCell = function (master, builder, result, previousR
 
 TestResultsView._populateTestPane = function(testName, results, section) {
     var table = element('table', {'class': 'resultsTable'}, [element('caption', [testName])]);
 
 TestResultsView._populateTestPane = function(testName, results, section) {
     var table = element('table', {'class': 'resultsTable'}, [element('caption', [testName])]);
+    table.appendChild(this._createTestResultHeader('Builder'));
+
     var resultsByBuilder = results['builders'];
     var resultsByBuilder = results['builders'];
+    var buildTimes = new Array();
     for (var builderId in resultsByBuilder) {
     for (var builderId in resultsByBuilder) {
-        var resultsByTest = resultsByBuilder[builderId];
-        var results;
-        for (var testId in resultsByTest)
-            results = resultsByTest[testId];
-        if (!results)
-            continue;
+        var results = resultsByBuilder[builderId];
+        this._createBuildsAndComputeSlownessOfResults(results);
+        for (var i = 0; i < results.length; i++) {
+            var time = results[i].build.time();
+            if (buildTimes.indexOf(time) < 0)
+                buildTimes.push(time);
+        }
+    }
+    buildTimes.sort(function (a, b) { return b - a; });
 
 
+    for (var builderId in resultsByBuilder) {
         var builder = this._builders[builderId];
         // FIXME: Add a master name if there is more than one.
         var builder = this._builders[builderId];
         // FIXME: Add a master name if there is more than one.
-        table.appendChild(this._createTestResultRow(builder.name, results, builder));
+        table.appendChild(this._createTestResultRow(builder.name, resultsByBuilder[builderId], builder, buildTimes));
     }
     section.appendChild(table);
 }
 
     }
     section.appendChild(table);
 }
 
-TestResultsView._createTestResultRow = function (title, results, builder) {
-    var slowestTime = 0;
+TestResultsView._createTestResultHeader = function (labelForFirstColumn) {
+    return element('thead', [element('tr', [
+        element('th', [labelForFirstColumn]),
+        element('th', ['Bug']),
+        element('th', ['Expectations']),
+        element('th', ['Slowest'])])]);
+}
+
+TestResultsView._createBuildsAndComputeSlownessOfResults = function (results) {
     for (var i = 0; i < results.length; i++) {
         var result = results[i];
         result.build = new TestBuild(this._repositories, this._builders, result);
         result.roundedTime = result.time > 10000 ? Math.round(result.time / 1000) : Math.round(result.time / 100) / 10;
         result.isSlow = result.time > 1000;
     for (var i = 0; i < results.length; i++) {
         var result = results[i];
         result.build = new TestBuild(this._repositories, this._builders, result);
         result.roundedTime = result.time > 10000 ? Math.round(result.time / 1000) : Math.round(result.time / 100) / 10;
         result.isSlow = result.time > 1000;
-        if (result.isSlow)
-            slowestTime = Math.max(slowestTime, result.roundedTime);
     }
     }
-    if (slowestTime)
-        slowestTime += 's';
-    else
-        slowestTime = '';
+}
 
 
+TestResultsView._createTestResultRow = function (title, results, builder, buildTimes) {
     var sortedResults = results.sort(function (result1, result2) { return result2.build.time() - result1.build.time(); });
     var sortedResults = results.sort(function (result1, result2) { return result2.build.time() - result1.build.time(); });
-    var cells = new Array(sortedResults.length);
-    for (var i = 0; i < sortedResults.length; i++)
-        cells[i] = this._createResultCell(builder.master, builder.name, sortedResults[i], sortedResults[i - 1]);
+    var cells = new Array();
+
+    function addEmptyCell() { cells.push(element('span', {'class': 'resultCell'}, [element('a')])); }
+
+    var buildTimeIndex = 0;
+    for (var i = 0; i < sortedResults.length; i++) {
+        var result = sortedResults[i];
+        if (buildTimes) {
+            while (buildTimes[buildTimeIndex] > result.build.time()) {
+                addEmptyCell();
+                buildTimeIndex++;
+            }
+            if (buildTimes[buildTimeIndex] == result.build.time())
+                buildTimeIndex++;
+        }
+        cells.push(this._createResultCell(builder.master, builder.name, result, sortedResults[i - 1]));
+    }
+    if (buildTimes) {
+        while (buildTimeIndex < buildTimes.length) {
+            addEmptyCell();
+            buildTimeIndex++;
+        }
+    }
 
     var formattedModifiers = sortedResults[0].modifiers.split(' ').map(function (modifier) {
         if (modifier.indexOf('/') > 0)
 
     var formattedModifiers = sortedResults[0].modifiers.split(' ').map(function (modifier) {
         if (modifier.indexOf('/') > 0)
@@ -187,6 +217,12 @@ TestResultsView._createTestResultRow = function (title, results, builder) {
         return modifier;
     });
 
         return modifier;
     });
 
+    var slowestTime = Math.max.apply(Math, results.map(function (result) { return result.roundedTime; }));
+    if (slowestTime >= 1)
+        slowestTime += 's';
+    else
+        slowestTime = '';
+
     return element('tr', [
         element('th', ['' + title]),
         element('td', {'class': 'modifiers'}, formattedModifiers),
     return element('tr', [
         element('th', ['' + title]),
         element('td', {'class': 'modifiers'}, formattedModifiers),
@@ -287,11 +323,14 @@ TestResultsView._populateBuilderPane = function(builderName, failureType, result
     if (!resultsByTests)
         return;
 
     if (!resultsByTests)
         return;
 
+    table.appendChild(this._createTestResultHeader('Test'));
+
     var builder = this._builders[builderId];
     for (var testId in resultsByTests) {
         var results = resultsByTests[testId];
         if (!results.length || !this._matchesFailureType(results, failureType, this._availableTests[testId].name))
             continue;
     var builder = this._builders[builderId];
     for (var testId in resultsByTests) {
         var results = resultsByTests[testId];
         if (!results.length || !this._matchesFailureType(results, failureType, this._availableTests[testId].name))
             continue;
+        this._createBuildsAndComputeSlownessOfResults(resultsByTests[testId]);
         table.appendChild(this._createTestResultRow(this._availableTests[testId].name, resultsByTests[testId], builder));
     }
     section.appendChild(table);
         table.appendChild(this._createTestResultRow(this._availableTests[testId].name, resultsByTests[testId], builder));
     }
     section.appendChild(table);
index 84aabdb179cf0e4095328045ee124dd791993850..cede3bfe0218edecbc74fb62e2c9202a61e763e8 100644 (file)
@@ -34,7 +34,6 @@
     border: 0px solid #fff;
     padding: 0;
     margin: 0;
     border: 0px solid #fff;
     padding: 0;
     margin: 0;
-    width: 100%;
 }
 
 .resultsTable caption {
 }
 
 .resultsTable caption {
     white-space: pre;
 }
 
     white-space: pre;
 }
 
+.resultsTable thead th {
+    font-weight: bold;
+}
+
 .resultsTable td,
 .resultsTable th {
     white-space: pre;
 .resultsTable td,
 .resultsTable th {
     white-space: pre;
@@ -71,6 +74,7 @@
 .resultsTable .resultCell {
     display: inline-block;
     padding: 0.2em 0.2em;
 .resultsTable .resultCell {
     display: inline-block;
     padding: 0.2em 0.2em;
+    vertical-align: bottom;
 }
 
 .resultsTable tr:hover,
 }
 
 .resultsTable tr:hover,
@@ -81,6 +85,7 @@
 .resultsTable a {
     color: #00f;
     text-shadow: none;
 .resultsTable a {
     color: #00f;
     text-shadow: none;
+    text-decoration: underline;
 }
 
 .resultsTable a:visited {
 }
 
 .resultsTable a:visited {
 
 .resultsTable span a {
     display: block;
 
 .resultsTable span a {
     display: block;
-    width: 1.4em;
-    height: 2em;
-    border-radius: 3px;
-    font-size: 0.5em;
-    padding: 0.3em;
+    width: 1.5em;
+    height: 2.5em;
+    border-radius: 5px;
+    font-size: 0.7em;
     text-align: center;
     text-align: center;
-    line-height: 1.9em;
+    line-height: 2.5em;
+    padding: 0.1em;
     color: inherit;
     color: inherit;
+    text-decoration: none;
 }
 
 .resultsTable .PASS a {
 }
 
 .resultsTable .PASS a {