Chromium Code Reviews| Index: Tools/GardeningServer/model/ct-failures.html |
| diff --git a/Tools/GardeningServer/model/ct-failures.html b/Tools/GardeningServer/model/ct-failures.html |
| index 962708cedf34f7a966caf0e41373fcf07b92c841..c1c063f4f94338d2dc417f2346206b59757249b2 100644 |
| --- a/Tools/GardeningServer/model/ct-failures.html |
| +++ b/Tools/GardeningServer/model/ct-failures.html |
| @@ -38,6 +38,9 @@ function CTFailures(commitLog) { |
| }; |
| } |
| +(function() { |
| +'use strict'; |
| + |
| // Reverse sorting order, if a > b, return a negative number. |
| CTFailures.prototype._failureByTreeListComparator = function(tree, a, b) { |
| if (tree === undefined) |
| @@ -77,6 +80,36 @@ CTFailures.prototype._failureByTreeListComparator = function(tree, a, b) { |
| return 0; |
| }; |
| +// Updates the format of the alerts array to be easier to parse. |
| +CTFailures.prototype._mungeAlerts = function(alerts) { |
|
ojan
2014/09/05 00:56:42
Mind writing basic unit tests for this function? I
Jeffrey Yasskin
2014/09/09 01:00:32
Done.
|
| + var masterToTree = {}; |
| + Object.keys(this._trees, function(tree, masters) { |
| + masters.forEach(function(master) { |
| + masterToTree[master] = tree; |
| + }); |
| + }); |
| + |
| + alerts.forEach(function(failure) { |
| + // FIXME: Have the server store the actual failure type in a different |
| + // field instead of smashing it into the reason. |
| + if (failure.failureType) { |
| + // The server has been fixed. |
|
ojan
2014/09/05 00:56:42
<3
|
| + } else { |
| + if (failure.reason) { |
| + var parts = failure.reason.split(':'); |
| + failure.reason = parts[0]; |
| + failure.failureType = parts[1] || 'FAIL'; |
| + } else { |
| + failure.failureType = 'UNKNOWN'; |
| + } |
| + } |
| + |
| + // FIXME: Figure out what tree masters that aren't in masterToTree |
| + // we should have. |
| + failure.tree = masterToTree[failure.master_url]; |
| + }); |
| +}; |
| + |
| CTFailures.prototype.update = function() { |
| var annotationPromise = CTFailureGroup.fetchAnnotations(); |
| @@ -86,10 +119,15 @@ CTFailures.prototype.update = function() { |
| this.builderLatestRevisions = new CTBuilderRevisions(data.latest_builder_info['chromium.webkit']); |
| var newFailures = {}; |
| this.lastUpdateDate = new Date(data.date * 1000); |
| + this._mungeAlerts(data.alerts); |
| + var alertsByKey = {} |
|
ojan
2014/09/05 00:56:42
Add a FIXME to change builder_alerts to just have
Jeffrey Yasskin
2014/09/09 01:00:33
Done.
|
| + data.alerts.forEach(function(alert) { |
| + alertsByKey[alert.key] = alert; |
| + }); |
| // Update |failures| with the appropriate CTFailureGroup's for each |
| // tree. |
| data.range_groups.forEach(function(rangeGroup) { |
| - this._processFailuresForRangeGroup(newFailures, rangeGroup, data.alerts, annotations); |
| + this._processFailuresForRangeGroup(newFailures, rangeGroup, alertsByKey, annotations); |
| }.bind(this)); |
| // Sort failure groups so that newer failures are shown at the top |
| // of the UI. |
| @@ -113,83 +151,63 @@ CTFailures.prototype._failureComparator = function(a, b) { |
| return 0; |
| }; |
| -CTFailures.prototype._processFailuresForRangeGroup = function(newFailures, rangeGroup, alerts, annotations) { |
| - var masterToTree = {}; |
| - Object.keys(this._trees, function(tree, masters) { |
| - masters.forEach(function(master) { |
| - masterToTree[master] = tree; |
| - }); |
| - }); |
| - |
| - // 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; }); |
| +function groupFailuresByTreeAndReason(failures, annotations) { |
|
ojan
2014/09/05 00:56:42
Ditto. You'll need to make this a function on CTFa
Jeffrey Yasskin
2014/09/09 01:00:32
To do the refactoring that Elliott asked for in ht
Jeffrey Yasskin
2014/09/09 01:00:33
Tested.
|
| + var failuresByTree = {}; |
| + failures.forEach(function(failure) { |
| // 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. |
| - var parts = failure.reason.split(':'); |
| - reason = parts[0]; |
| - failureType = parts[1] || 'FAIL'; |
| - } else { |
| - reason = null; |
| - failureType = 'UNKNOWN'; |
| - } |
| - |
| var failureKey = CTFailure.createKey(failure); |
| var reasonKey = JSON.stringify({ |
| step: failure.step_name, |
| - reason: reason, |
| + reason: failure.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. |
| - if (!failuresByReason[reasonKey]) |
| - failuresByReason[reasonKey] = {}; |
| - if (!failuresByReason[reasonKey][tree]) |
| - failuresByReason[reasonKey][tree] = {}; |
| - failuresByReason[reasonKey][tree][failure.builder_name] = { |
| + if (!failuresByTree[failure.tree]) |
| + failuresByTree[failure.tree] = {}; |
| + if (!failuresByTree[failure.tree][reasonKey]) |
| + failuresByTree[failure.tree][reasonKey] = {}; |
| + failuresByTree[failure.tree][reasonKey][failure.builder_name] = { |
| key: failureKey, |
| // FIXME: Rename to failureType. |
| - actual: failureType, |
| + actual: failure.failureType, |
| lastFailingBuild: failure.last_failing_build, |
| earliestFailingBuild: failure.failing_build, |
| masterUrl: failure.master_url, |
| failingBuildCount: failure.failing_build_count, |
| annotation: annotations[failureKey], |
| }; |
| - }.bind(this)); |
| + }); |
| + return failuresByTree |
| +}; |
| + |
| +CTFailures.prototype._processFailuresForRangeGroup = function(newFailures, rangeGroup, alerts, annotations) { |
| + // 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). |
| + var failures = rangeGroup.failure_keys.map(function(failure_key) { |
| + return alerts[failure_key]; |
| + }); |
| + var failuresByTree = groupFailuresByTreeAndReason(failures, annotations); |
| - if (!Object.keys(failuresByReason).length) |
| + if (Object.isEmpty(failuresByTree)) |
| return; |
| - // Maps a tree id to a list of CTFailures in that tree. |
| - 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( |
| + Object.keys(failuresByTree, function(tree, resultsByReason) { |
| + var treeFailures = []; |
| + Object.keys(resultsByReason, function(reasonKey, resultsByBuilder) { |
| + var failure = JSON.parse(reasonKey); |
| + treeFailures.push( |
| new CTFailure(failure.step, failure.reason, resultsByBuilder)); |
| }) |
| - }); |
| - |
| - Object.keys(groupedFailures, function(tree, failures) { |
| - failures.sort(this._failureComparator); |
| + treeFailures.sort(this._failureComparator); |
| if (!newFailures[tree]) |
| newFailures[tree] = []; |
| var commitList = new CTCommitList(this.commitLog, rangeGroup.likely_revisions); |
| - newFailures[tree].push(new CTFailureGroup(rangeGroup.sort_key, failures, commitList)); |
| + newFailures[tree].push(new CTFailureGroup(rangeGroup.sort_key, treeFailures, commitList)); |
| }.bind(this)); |
| }; |
| +})(); |
| </script> |