Title: [161440] trunk/Tools
Revision
161440
Author
a...@apple.com
Date
2014-01-07 11:35:29 -0800 (Tue, 07 Jan 2014)

Log Message

Improve display of failed builds at build.webkit.org/dashboard
https://bugs.webkit.org/show_bug.cgi?id=126542
<rdar://problem/15753550>

Reviewed by Timothy Hatcher.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js:
Instead of hardcoding step name, look for the first step that failed.
While at it, added a popover with more links. There are multiple, and it's good
to have a choice of which one to look at in each situation.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotIteration.js:
(BuildbotIteration.prototype.get successful): Being successful is not the opposite
of having failed. Many iterations are interrupted for whatever reason internal to
Buildbot, and these are suppoed to be orange, not red.
(BuildbotIteration.prototype.get productive): Changed to exclude inerrupted iterations,
not only WillRetry ones.
(BuildbotIteration.prototype.get failed): Changed to only include iterations that
actually failed, more likely indicating a problem with code base.
(BuildbotIteration.prototype.get firstFailedStepName):
(BuildbotIteration.prototype.failureLogURL): Expose informaiton about failure.
(BuildbotIteration.prototype.get failureLogs): Ditto.
(BuildbotIteration.prototype.update): Store complete results for the failed step.
Not every failure stops the iteration, so we could have multiple failed steps,
but let's see if seeing just the first one will be enough.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js:
(BuildbotQueue.prototype.get firstRecentUnsuccessfulIteration): Updated to work in
terms of successful iterations.
(BuildbotQueue.prototype.get mostRecentSuccessfulIteration): Ditto.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js:
(BuildbotTesterQueueView.prototype.update.appendBuilderQueueStatus): Updated to work in
terms of successful iterations.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/WebKitBuildbot.js:
Removed code to create a path to build output, we now take it from results JSON.

* BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/QueueView.css:
Added styles for the new popover.

Modified Paths

Diff

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js (161439 => 161440)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js	2014-01-07 19:30:34 UTC (rev 161439)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js	2014-01-07 19:35:29 UTC (rev 161440)
@@ -62,36 +62,43 @@
         {
             this._appendPendingRevisionCount(queue);
 
-            var firstRecentFailedIteration = queue.firstRecentFailedIteration;
-            if (firstRecentFailedIteration && firstRecentFailedIteration.loaded) {
+            var firstRecentUnsuccessfulIteration = queue.firstRecentUnsuccessfulIteration;
+            if (firstRecentUnsuccessfulIteration && firstRecentUnsuccessfulIteration.loaded) {
                 var failureCount = queue.recentFailedIterationCount;
-                var message = this.revisionContentForIteration(firstRecentFailedIteration);
-                if (firstRecentFailedIteration.webkitCompilationFailed) {
-                    // Link directly to compiler output.
-                    // FIXME: Results JSON may contain multiple log links, including one for nicely filtered result.
-                    // Which one is best to use? Do we want the filtered one in a popover?
-                    var url = ""
+                var message = this.revisionContentForIteration(firstRecentUnsuccessfulIteration);
+                if (firstRecentUnsuccessfulIteration.failed) {
+                    // Assume it was a build step that failed, and link directly to output.
+                    var url = "" log");
+                    if (!url)
+                        url = ""
                     var status = StatusLineView.Status.Bad;
-                } else {
-                    // Some other step failed, link to main buildbot page for the iteration.
-                    var url = ""
+                } else
                     var status = StatusLineView.Status.Danger;
-                }
-                var status = new StatusLineView(message, status, failureCount > 1 ? "failures since" : firstRecentFailedIteration.text, failureCount > 1 ? failureCount : null, url);
+
+                // Show a popover when the URL is not a main build page one, because there are usually multiple logs, and it's good to provide a choice.
+                var needsPopover = !!url;
+
+                // Some other step failed, link to main buildbot page for the iteration.
+                if (!url)
+                    url = ""
+                var status = new StatusLineView(message, status, failureCount > 1 ? "failures since" : firstRecentUnsuccessfulIteration.text, failureCount > 1 ? failureCount : null, url);
                 this.element.appendChild(status.element);
+
+                if (needsPopover)
+                    new PopoverTracker(status.statusBubbleElement, this._presentPopoverFailureLogs.bind(this), firstRecentUnsuccessfulIteration);
             }
 
             var mostRecentSuccessfulIteration = queue.mostRecentSuccessfulIteration;
             if (mostRecentSuccessfulIteration && mostRecentSuccessfulIteration.loaded) {
                 var message = this.revisionContentForIteration(mostRecentSuccessfulIteration);
                 var url = ""
-                var status = new StatusLineView(message, StatusLineView.Status.Good, firstRecentFailedIteration ? "last successful build" : "latest build", null, url);
+                var status = new StatusLineView(message, StatusLineView.Status.Good, firstRecentUnsuccessfulIteration ? "last successful build" : "latest build", null, url);
                 this.element.appendChild(status.element);
             } else {
-                var status = new StatusLineView("unknown", StatusLineView.Status.Neutral, firstRecentFailedIteration ? "last successful build" : "latest build");            
+                var status = new StatusLineView("unknown", StatusLineView.Status.Neutral, firstRecentUnsuccessfulIteration ? "last successful build" : "latest build");            
                 this.element.appendChild(status.element);
 
-                if (firstRecentFailedIteration) {
+                if (firstRecentUnsuccessfulIteration) {
                     // We have a failed iteration but no successful. It might be further back in time.
                     // Update all the iterations so we get more history.
                     queue.iterations.forEach(function(iteration) { iteration.update(); });
@@ -120,5 +127,45 @@
         appendBuildArchitecture.call(this, this.universalDebugQueues, this.hasMultipleDebugBuilds ? "Debug (Universal)" : "Debug");
         appendBuildArchitecture.call(this, this.sixtyFourBitDebugQueues, this.hasMultipleDebugBuilds ? "Debug (64-bit)" : "Debug");
         appendBuildArchitecture.call(this, this.thirtyTwoBitDebugQueues, this.hasMultipleDebugBuilds ? "Debug (32-bit)" : "Debug");
+    },
+
+    _presentPopoverFailureLogs: function(element, popover, iteration)
+    {
+        var content = document.createElement("div");
+        content.className = "build-logs-popover";
+
+        function addLog(name, url) {
+            var line = document.createElement("a");
+            line.className = "build-log-link";
+            line.href = ""
+            line.textContent = name;
+            line.target = "_blank";
+            content.appendChild(line);
+        }
+
+        var title = document.createElement("div");
+        title.className = "build-logs-popover-title";
+        title.textContent = iteration.queue.id;
+        content.appendChild(title);
+        
+        var builderPageLine = document.createElement("a");
+        builderPageLine.className = "build-page-link";
+        builderPageLine.href = ""
+        builderPageLine.textContent = "build #" + iteration.id;
+        builderPageLine.target = "_blank";
+        content.appendChild(builderPageLine);
+
+        var logsHeadingLine = document.createElement("div");
+        logsHeadingLine.className = "build-logs-heading";
+        logsHeadingLine.textContent = iteration.firstFailedStepName + " failed";
+        content.appendChild(logsHeadingLine);
+
+        for (var i = 0, end = iteration.failureLogs.length; i < end; ++i)
+            addLog(iteration.failureLogs[i][0], iteration.failureLogs[i][1]);
+
+        var rect = Dashboard.Rect.rectFromClientRect(element.getBoundingClientRect());
+        popover.content = content;
+        popover.present(rect, [Dashboard.RectEdge.MIN_Y, Dashboard.RectEdge.MAX_Y, Dashboard.RectEdge.MAX_X, Dashboard.RectEdge.MIN_X]);
+        return true;
     }
 };

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotIteration.js (161439 => 161440)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotIteration.js	2014-01-07 19:30:34 UTC (rev 161439)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotIteration.js	2014-01-07 19:35:29 UTC (rev 161440)
@@ -76,11 +76,53 @@
         this._finished = x;
     },
 
+    get successful()
+    {
+        return this._result === BuildbotIteration.SUCCESS;
+    },
+
     get productive()
     {
-        return this.loaded && this._finished && !this.willRetry;
+        return this.loaded && this._finished && this._result !== BuildbotIteration.EXCEPTION && this._result !== BuildbotIteration.RETRY;
     },
 
+    // It is not a real failure if Buildbot itself failed with codes like EXCEPTION or RETRY.
+    get failed()
+    {
+        return this._result === BuildbotIteration.FAILURE;
+    },
+
+    get firstFailedStepName()
+    {
+        if (!this._firstFailedStep)
+            return undefined;
+        return this._firstFailedStep.name;
+    },
+
+    failureLogURL: function(kind)
+    {
+        if (!this.failed)
+            return undefined;
+
+        console.assert(this._firstFailedStep);
+
+        for (var i = 0; i < this._firstFailedStep.logs.length; ++i) {
+            if (this._firstFailedStep.logs[i][0] == kind)
+                return this._firstFailedStep.logs[i][1];
+        }
+
+        return undefined;
+    },
+
+    get failureLogs()
+    {
+        if (!this.failed)
+            return undefined;
+
+        console.assert(this._firstFailedStep);
+        return this._firstFailedStep.logs;
+    },
+
     get previousProductiveIteration()
     {
         for (var i = 0; i < this.queue.iterations.length - 1; ++i) {
@@ -164,10 +206,6 @@
             var internalRevisionProperty = data.properties.findFirst(function(property) { return property[0] === "internal_got_revision"; });
             this.internalRevision = internalRevisionProperty ? parseInt(internalRevisionProperty[1], 10) : null;
 
-            var compileWebKitStep = data.steps.findFirst(function(step) { return step.name === "compile-webkit"; });
-            if (compileWebKitStep)
-                this.webkitCompilationFailed = compileWebKitStep.results[0] !== BuildbotIteration.SUCCESS;
-
             var layoutTestResults = collectTestResults.call(this, data, "layout-test");
             this.layoutTestResults = layoutTestResults ? new BuildbotTestResults(this, layoutTestResults) : null;
 
@@ -191,9 +229,11 @@
 
             this.loaded = true;
 
-            this.failed = !!data.results;
-            this.willRetry = data.results === BuildbotIteration.RETRY;
+            this._firstFailedStep = data.steps.findFirst(function(step) { return step.results[0] === BuildbotIteration.FAILURE; });
 
+            console.assert(data.results === null || typeof data.results === "number");
+            this._result = data.results;
+
             this.text = data.text.join(" ");
 
             if (!data.currentStep)

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js (161439 => 161440)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js	2014-01-07 19:30:34 UTC (rev 161439)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js	2014-01-07 19:35:29 UTC (rev 161440)
@@ -88,20 +88,20 @@
         return this.iterations[0];
     },
 
-    get firstRecentFailedIteration()
+    get firstRecentUnsuccessfulIteration()
     {
         if (!this.iterations.length)
             return null;
 
         for (var i = 0; i < this.iterations.length; ++i) {
-            if (!this.iterations[i].finished || this.iterations[i].failed)
+            if (!this.iterations[i].finished || !this.iterations[i].successful)
                 continue;
-            if (this.iterations[i - 1] && this.iterations[i - 1].failed)
+            if (this.iterations[i - 1] && this.iterations[i - 1].finished && !this.iterations[i - 1].successful)
                 return this.iterations[i - 1];
             return null;
         }
 
-        if (this.iterations[this.iterations.length - 1].failed)
+        if (!this.iterations[this.iterations.length - 1].successful)
             return this.iterations[this.iterations.length - 1];
 
         return null;
@@ -121,7 +121,7 @@
     get mostRecentSuccessfulIteration()
     {
         for (var i = 0; i < this.iterations.length; ++i) {
-            if (!this.iterations[i].finished || this.iterations[i].failed)
+            if (!this.iterations[i].finished || !this.iterations[i].successful)
                 continue;
             return this.iterations[i];
         }

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js (161439 => 161440)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js	2014-01-07 19:30:34 UTC (rev 161439)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js	2014-01-07 19:35:29 UTC (rev 161440)
@@ -66,7 +66,7 @@
                 var perlTestResults = iteration.perlTestResults || {failureCount: 0};
                 var bindingTestResults = iteration.bindingTestResults || {errorOccurred: false};
 
-                if (!iteration.failed) {
+                if (iteration.successful) {
                     var status = new StatusLineView(messageElement, StatusLineView.Status.Good, "all tests passed");
                     limit = 0;
                 } else if (!iteration.productive) {

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/WebKitBuildbot.js (161439 => 161440)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/WebKitBuildbot.js	2014-01-07 19:30:34 UTC (rev 161439)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/WebKitBuildbot.js	2014-01-07 19:35:29 UTC (rev 161440)
@@ -59,11 +59,6 @@
     constructor: WebKitBuildbot,
     __proto__: Buildbot.prototype,
 
-    buildLogURLForIteration: function(iteration)
-    {
-        return this.baseURL + "builders/" + encodeURIComponent(iteration.queue.id) + "/builds/" + iteration.id + "/steps/compile-webkit/logs/stdio/text";
-    },
-
     layoutTestResultsDirectoryURLForIteration: function(iteration)
     {
         return this.baseURL + "results/" + encodeURIComponent(iteration.queue.id) + "/" + encodeURIComponent("r" + iteration.openSourceRevision + " (" + iteration.id + ")");

Modified: trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/QueueView.css (161439 => 161440)


--- trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/QueueView.css	2014-01-07 19:30:34 UTC (rev 161439)
+++ trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/QueueView.css	2014-01-07 19:35:29 UTC (rev 161440)
@@ -63,6 +63,26 @@
     height: 7px;
 }
 
+.build-logs-popover {
+    font-family: "HelveticaNeue-Light", "Helvetica Neue", sans-serif;
+    color: rgb(145, 135, 95);
+    font-size: 12px;
+    text-align: left;
+    padding: 1px 6px 1px 6px;
+}
+
+.build-logs-popover .build-logs-heading {
+    display: inline;
+}
+
+.build-logs-popover .build-page-link {
+    display: block;
+}
+
+.build-logs-popover .build-log-link {
+    padding-left: 5px;
+}
+
 .test-results-popover {
     font-family: "HelveticaNeue-Light", "Helvetica Neue", sans-serif;
     color: rgb(145, 135, 95);

Modified: trunk/Tools/ChangeLog (161439 => 161440)


--- trunk/Tools/ChangeLog	2014-01-07 19:30:34 UTC (rev 161439)
+++ trunk/Tools/ChangeLog	2014-01-07 19:35:29 UTC (rev 161440)
@@ -1,3 +1,46 @@
+2014-01-07  Alexey Proskuryakov  <a...@apple.com>
+
+        Improve display of failed builds at build.webkit.org/dashboard
+        https://bugs.webkit.org/show_bug.cgi?id=126542
+        <rdar://problem/15753550>
+
+        Reviewed by Timothy Hatcher.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotBuilderQueueView.js:
+        Instead of hardcoding step name, look for the first step that failed.
+        While at it, added a popover with more links. There are multiple, and it's good
+        to have a choice of which one to look at in each situation.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotIteration.js:
+        (BuildbotIteration.prototype.get successful): Being successful is not the opposite
+        of having failed. Many iterations are interrupted for whatever reason internal to
+        Buildbot, and these are suppoed to be orange, not red.
+        (BuildbotIteration.prototype.get productive): Changed to exclude inerrupted iterations,
+        not only WillRetry ones.
+        (BuildbotIteration.prototype.get failed): Changed to only include iterations that
+        actually failed, more likely indicating a problem with code base.
+        (BuildbotIteration.prototype.get firstFailedStepName):
+        (BuildbotIteration.prototype.failureLogURL): Expose informaiton about failure.
+        (BuildbotIteration.prototype.get failureLogs): Ditto.
+        (BuildbotIteration.prototype.update): Store complete results for the failed step.
+        Not every failure stops the iteration, so we could have multiple failed steps,
+        but let's see if seeing just the first one will be enough.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotQueue.js:
+        (BuildbotQueue.prototype.get firstRecentUnsuccessfulIteration): Updated to work in
+        terms of successful iterations.
+        (BuildbotQueue.prototype.get mostRecentSuccessfulIteration): Ditto.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/BuildbotTesterQueueView.js:
+        (BuildbotTesterQueueView.prototype.update.appendBuilderQueueStatus): Updated to work in
+        terms of successful iterations.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Scripts/WebKitBuildbot.js:
+        Removed code to create a path to build output, we now take it from results JSON.
+
+        * BuildSlaveSupport/build.webkit.org-config/public_html/dashboard/Styles/QueueView.css:
+        Added styles for the new popover.
+
 2014-01-07  Gergo Balogh  <gery...@inf.u-szeged.hu>
 
         defined constants should use all uppercase names with words separated by underscores.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to