| Index: Tools/GardeningServer/ui/ct-failure-analyzer.html
|
| diff --git a/Tools/GardeningServer/ui/ct-failure-analyzer.html b/Tools/GardeningServer/ui/ct-failure-analyzer.html
|
| index a4c6a26e22a98a7bd97f1f072441c9742b0d5b82..36db63217f2fdb8a8ee6c9a932fe451f720d97c1 100644
|
| --- a/Tools/GardeningServer/ui/ct-failure-analyzer.html
|
| +++ b/Tools/GardeningServer/ui/ct-failure-analyzer.html
|
| @@ -9,11 +9,12 @@ found in the LICENSE file.
|
| <link rel="import" href="../model/ct-failure.html">
|
| <link rel="import" href="../model/ct-failure-group.html">
|
|
|
| -<polymer-element name="ct-failure-analyzer" attributes="failures builderLatestRevisions lastUpdateDate">
|
| +<polymer-element name="ct-failure-analyzer" attributes="commitLog failures builderLatestRevisions lastUpdateDate">
|
| <script>
|
| // FIXME: Don't use a polymer component for this. Instead use a Failures model
|
| // object that knows how to do the XHR and process the data appropriately.
|
| Polymer({
|
| + commitLog: null,
|
| builderLatestRevisions: null,
|
| failures: null,
|
| lastUpdateDate: null,
|
| @@ -35,32 +36,42 @@ found in the LICENSE file.
|
| ],
|
| },
|
|
|
| - _failureListComparator: function(tree, a, b) {
|
| + // Reverse sorting order, if a > b, return a negative number.
|
| + _failureByTreeListComparator: function(tree, a, b) {
|
| if (tree === undefined)
|
| tree = 'chromium';
|
|
|
| - var rev_a = a.failures[0].firstFailingRevisions;
|
| - var rev_b = b.failures[0].firstFailingRevisions;
|
| + var rev_a = a.commitList.revisions;
|
| + var rev_b = b.commitList.revisions;
|
|
|
| - // Handle missing revision.
|
| - if (!rev_a) {
|
| - if (!rev_b) {
|
| + if (!rev_a || !Object.keys(rev_a).length) {
|
| + if (!rev_b || !Object.keys(rev_b).length)
|
| return 0;
|
| - }
|
| - return -1;
|
| - } else if (!rev_b) {
|
| return 1;
|
| + } else if (!rev_b || !Object.keys(rev_b).length) {
|
| + return -1;
|
| }
|
|
|
| - // Prioritize the tree's revision.
|
| - if (rev_a[tree] != rev_b[tree])
|
| - return rev_b[tree] - rev_a[tree];
|
| + // Prioritize the tree's revision, if they are unequal (else, fallback
|
| + // below).
|
| + if (rev_a[tree] && rev_b[tree] &&
|
| + rev_a[tree].last() != rev_b[tree].last()) {
|
| + return rev_b[tree].last() - rev_a[tree].last();
|
| + }
|
|
|
| // Compare other revisions in alphabetical order.
|
| var keys = Object.keys(rev_a).sort();
|
| for (var i = 0; i < keys.length; i++) {
|
| - if (rev_a[keys[i]] != rev_b[keys[i]])
|
| - return rev_b[keys[i]] - rev_a[keys[i]];
|
| + if (keys[i] == tree) // Already taken care of, above.
|
| + continue;
|
| +
|
| + var a_list = rev_a[keys[i]];
|
| + var b_list = rev_b[keys[i]];
|
| + if (!b_list)
|
| + return -1;
|
| +
|
| + if (a_list.last() != b_list.last())
|
| + return b_list.last() - a_list.last();
|
| }
|
| return 0;
|
| },
|
| @@ -73,11 +84,13 @@ found in the LICENSE file.
|
| this.builderLatestRevisions = new CTBuilderRevisions(data.latest_builder_info['chromium.webkit']);
|
| this.failures = {};
|
| this.lastUpdateDate = new Date(data.date * 1000);
|
| - data.range_groups.forEach(function(group) {
|
| - this._processFailuresForGroup(group, data.alerts, annotations);
|
| + // Update |failures| with the appropriate CTFailureGroup's for each tree.
|
| + data.range_groups.forEach(function(rangeGroup) {
|
| + this._processFailuresForRangeGroup(rangeGroup, data.alerts, annotations);
|
| }.bind(this));
|
| + // Sort failure groups so that newer failures are shown at the top of the UI.
|
| Object.keys(this.failures, function (tree, failuresByTree) {
|
| - this.failures[tree].sort(this._failureListComparator.bind(this, tree));
|
| + this.failures[tree].sort(this._failureByTreeListComparator.bind(this, tree));
|
| }.bind(this));
|
| }.bind(this));
|
| }.bind(this));
|
| @@ -95,9 +108,7 @@ found in the LICENSE file.
|
| return 0;
|
| },
|
|
|
| - _processFailuresForGroup: function(group, failures, annotations) {
|
| - var failuresByReason = {};
|
| -
|
| + _processFailuresForRangeGroup: function(rangeGroup, alerts, annotations) {
|
| var masterToTree = {};
|
| Object.keys(this._trees, function(tree, masters) {
|
| masters.forEach(function(master) {
|
| @@ -105,8 +116,13 @@ found in the LICENSE file.
|
| });
|
| });
|
|
|
| - group.failure_keys.forEach(function(failure_key) {
|
| - var failure = failures.find(function(item) { return item.key == failure_key; });
|
| + // A rangeGroup may be related to multiple alerts (via |failure_keys|). Categorize
|
| + // these failures by reason (cause of failure), so that they can be grouped in the UI
|
| + // (via a CTFailureGroup). Failures will be grouped in |failuresByReason|.
|
| + var failuresByReason = {};
|
| + rangeGroup.failure_keys.forEach(function(failure_key) {
|
| + var failure = alerts.find(function(item) { return item.key == failure_key; });
|
| + // Establish the key to uniquely identify a failure by reason.
|
| var reason, failureType;
|
| if (failure.reason) {
|
| // FIXME: Store the actual failure type in a different field instead of smashing it into the reason.
|
| @@ -125,6 +141,8 @@ found in the LICENSE file.
|
| reason: reason,
|
| });
|
|
|
| + // FIXME: Figure out what tree masters that aren't in masterToTree
|
| + // we should have.
|
| var tree = masterToTree[failure.master_url];
|
|
|
| // FIXME: Use a model class instead of a dumb object.
|
| @@ -144,13 +162,17 @@ found in the LICENSE file.
|
| };
|
| }.bind(this));
|
|
|
| + if (!Object.keys(failuresByReason).length)
|
| + return;
|
| +
|
| var groupedFailures = {};
|
| Object.keys(failuresByReason, function(reasonKey, resultsByTree) {
|
| var failure = JSON.parse(reasonKey);
|
| Object.keys(resultsByTree, function(tree, resultsByBuilder) {
|
| if (!groupedFailures[tree])
|
| groupedFailures[tree] = [];
|
| - groupedFailures[tree].push(new CTFailure(failure.step, failure.reason, resultsByBuilder, group.merged_first_failing, group.merged_last_passing));
|
| + groupedFailures[tree].push(
|
| + new CTFailure(failure.step, failure.reason, resultsByBuilder));
|
| })
|
| });
|
|
|
| @@ -159,7 +181,8 @@ found in the LICENSE file.
|
|
|
| if (!this.failures[tree])
|
| this.failures[tree] = [];
|
| - this.failures[tree].push(new CTFailureGroup(failures));
|
| + var commitList = new CTCommitList(this.commitLog, rangeGroup.likely_revisions);
|
| + this.failures[tree].push(new CTFailureGroup(failures, commitList));
|
| }.bind(this));
|
| },
|
| });
|
|
|