| OLD | NEW |
| 1 <!-- | 1 <!-- |
| 2 Copyright 2014 The Chromium Authors. All rights reserved. | 2 Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 Use of this source code is governed by a BSD-style license that can be | 3 Use of this source code is governed by a BSD-style license that can be |
| 4 found in the LICENSE file. | 4 found in the LICENSE file. |
| 5 --> | 5 --> |
| 6 | 6 |
| 7 <link rel="import" href="../model/ct-failure.html"> |
| 8 |
| 7 <polymer-element name="ct-failure-analyzer" attributes="failures builderLatestRe
visions"> | 9 <polymer-element name="ct-failure-analyzer" attributes="failures builderLatestRe
visions"> |
| 8 <script> | 10 <script> |
| 9 // FIXME: Don't use a polymer component for this. Instead use a Failures mod
el | 11 // FIXME: Don't use a polymer component for this. Instead use a Failures mod
el |
| 10 // object that knows how to do the XHR and process the data appropriately. | 12 // object that knows how to do the XHR and process the data appropriately. |
| 11 Polymer({ | 13 Polymer({ |
| 12 builderLatestRevisions: {}, | 14 builderLatestRevisions: {}, |
| 13 failures: {}, | 15 failures: {}, |
| 14 | 16 |
| 15 update: function() { | 17 update: function() { |
| 16 net.json('http://auto-sheriff.appspot.com/data').then(function(data) { | 18 net.json('http://auto-sheriff.appspot.com/data').then(function(data) { |
| 17 // FIXME: Don't special-case the blink master. | 19 // FIXME: Don't special-case the blink master. |
| 18 this.builderLatestRevisions = data.latest_revisions['chromium.webkit']
; | 20 this.builderLatestRevisions = data.latest_revisions['chromium.webkit']
; |
| 19 this.failures.builders = {}; | 21 this.failures = []; |
| 20 this.failures.unexpected = []; | |
| 21 data.range_groups.forEach(function(group) { | 22 data.range_groups.forEach(function(group) { |
| 22 this._processFailuresForGroup(group, data.alerts); | 23 this._processFailuresForGroup(group, data.alerts); |
| 23 }.bind(this)); | 24 }.bind(this)); |
| 25 // FIXME: Sort this.failures by severity of regression, then by oldest
FailingRevision. |
| 24 }.bind(this)); | 26 }.bind(this)); |
| 25 }, | 27 }, |
| 26 | 28 |
| 29 _failureComparator: function(a, b) { |
| 30 if (a.step > b.step) |
| 31 return 1; |
| 32 if (a.step < b.step) |
| 33 return -1 |
| 34 if (a.testName > b.testName) |
| 35 return 1; |
| 36 if (a.testName < b.testName) |
| 37 return -1 |
| 38 return 0; |
| 39 }, |
| 40 |
| 27 _processFailuresForGroup: function(group, failures) { | 41 _processFailuresForGroup: function(group, failures) { |
| 28 var failuresByReason = {}; | 42 var failuresByReason = {}; |
| 29 var failingBuildersWithoutReasons = {}; | |
| 30 | 43 |
| 31 group.failure_keys.forEach(function(failure_key) { | 44 group.failure_keys.forEach(function(failure_key) { |
| 32 var failure = failures.find(function(item) { return item.key == failur
e_key; }); | 45 var failure = failures.find(function(item) { return item.key == failur
e_key; }); |
| 33 if (failure.ignored_by.length) | 46 if (failure.ignored_by.length) |
| 34 return; | 47 return; |
| 35 | 48 |
| 36 // FIXME: Make sheriff-o-matic work for all waterfalls. | 49 // FIXME: Make sheriff-o-matic work for all waterfalls. |
| 37 if (!failure.master_url.endsWith('chromium.webkit')) | 50 if (!failure.master_url.endsWith('chromium.webkit')) |
| 38 return; | 51 return; |
| 39 | 52 |
| 40 // FIXME: Have sheriff-o-matic show non-webkit_tests failures by reaso
n. | 53 var reason, failureType; |
| 41 if (!failure.reason || failure.step_name != 'webkit_tests') { | 54 if (failure.reason) { |
| 42 var builder = failure.builder_name; | 55 // FIXME: Store the actual failure type in a different field instead
of smashing it into the reason. |
| 43 if (!failingBuildersWithoutReasons[builder]) | 56 var parts = failure.reason.split(':'); |
| 44 failingBuildersWithoutReasons[builder] = {}; | 57 reason = parts[0]; |
| 45 failingBuildersWithoutReasons[builder][failure.step_name] = 1; | 58 failureType = parts[1] || 'FAIL'; |
| 46 return; | 59 } else { |
| 60 reason = null; |
| 61 failureType = 'UNKNOWN'; |
| 47 } | 62 } |
| 48 | 63 |
| 49 // FIXME: Store the actual failure type in a different field instead o
f smashing it into the reason. | 64 var failureKey = JSON.stringify({ |
| 50 var parts = failure.reason.split(':'); | 65 step: failure.step_name, |
| 51 var reason = parts[0]; | 66 reason: reason, |
| 52 var failureType = parts[1]; | 67 }); |
| 53 | 68 |
| 54 if (!failuresByReason[reason]) | 69 // FIXME: Use a model class instead of a dumb object. |
| 55 failuresByReason[reason] = {} | 70 if (!failuresByReason[failureKey]) |
| 56 failuresByReason[reason][failure.builder_name] = { | 71 failuresByReason[failureKey] = {}; |
| 72 // FIXME: If we have multiple builders with the same name across maste
rs in |
| 73 // a failure group, then this will incorrectly overwrite one of the va
lues. |
| 74 failuresByReason[failureKey][failure.builder_name] = { |
| 75 // FIXME: Rename to failureType. |
| 57 actual: failureType, | 76 actual: failureType, |
| 77 lastFailingBuild: failure.last_failing_build, |
| 78 masterUrl: failure.master_url, |
| 58 }; | 79 }; |
| 59 }.bind(this)); | 80 }.bind(this)); |
| 60 | 81 |
| 61 var groupedFailures = []; | 82 var groupedFailures = []; |
| 62 var oldestFailingRevision = Number(group.merged_first_failing.blink); | |
| 63 var newestPassingRevision = group.merged_last_passing ? Number(group.mer
ged_last_passing.blink) : undefined; | |
| 64 | 83 |
| 65 Object.keys(failuresByReason, function(reason, resultNodesByBuilder) { | 84 var oldestFailingRevision, newestPassingRevision; |
| 66 groupedFailures.push({ | 85 // FIXME: This is a workaround for the backend's bogus data when the bli
nk |
| 67 testName: reason, | 86 // regression ranges have no overlap. |
| 68 resultNodesByBuilder: resultNodesByBuilder, | 87 if (group.merged_last_passing && group.merged_first_failing.blink > grou
p.merged_last_passing.blink) { |
| 69 oldestFailingRevision: oldestFailingRevision, | 88 oldestFailingRevision = Number(group.merged_first_failing.blink); |
| 70 newestPassingRevision: newestPassingRevision, | 89 newestPassingRevision = Number(group.merged_last_passing.blink); |
| 71 }); | 90 } |
| 91 |
| 92 Object.keys(failuresByReason, function(failureKey, resultByBuilder) { |
| 93 var failure = JSON.parse(failureKey); |
| 94 groupedFailures.push(new CTFailure(failure.step, failure.reason, resul
tByBuilder, oldestFailingRevision, newestPassingRevision)); |
| 72 }); | 95 }); |
| 73 | 96 |
| 97 // FIXME: Make this a model class intead of a dumb object. |
| 98 groupedFailures.sort(this._failureComparator); |
| 99 |
| 74 if (groupedFailures.length) | 100 if (groupedFailures.length) |
| 75 this.failures.unexpected.push(groupedFailures); | 101 this.failures.push(groupedFailures); |
| 76 | |
| 77 // FIXME: Show these in the failure stream with regression ranges like | |
| 78 // any other kind of failure. | |
| 79 Object.keys(failingBuildersWithoutReasons, function(builder, steps) { | |
| 80 this.failures.builders[builder] = Object.keys(steps); | |
| 81 }.bind(this)); | |
| 82 }, | 102 }, |
| 83 }); | 103 }); |
| 84 </script> | 104 </script> |
| 85 </polymer-element> | 105 </polymer-element> |
| OLD | NEW |