Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: Tools/GardeningServer/ui/ct-failure-analyzer.html

Issue 498523002: [Sheriff-o-matic] Use likely_revisions instead of first_failing/last_passing (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase + no sort Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <link href="../model/ct-builder-revisions.html" rel="import"> 6 <link href="../model/ct-builder-revisions.html" rel="import">
7 7
8 <link rel="import" href="../lib/net.html"> 8 <link rel="import" href="../lib/net.html">
9 <link rel="import" href="../model/ct-failure.html"> 9 <link rel="import" href="../model/ct-failure.html">
10 <link rel="import" href="../model/ct-failure-group.html"> 10 <link rel="import" href="../model/ct-failure-group.html">
11 11
12 <polymer-element name="ct-failure-analyzer" attributes="failures builderLatestRe visions lastUpdateDate"> 12 <polymer-element name="ct-failure-analyzer" attributes="commitLog failures build erLatestRevisions lastUpdateDate">
13 <script> 13 <script>
14 // FIXME: Don't use a polymer component for this. Instead use a Failures mod el 14 // FIXME: Don't use a polymer component for this. Instead use a Failures mod el
15 // object that knows how to do the XHR and process the data appropriately. 15 // object that knows how to do the XHR and process the data appropriately.
16 Polymer({ 16 Polymer({
17 commitLog: null,
17 builderLatestRevisions: null, 18 builderLatestRevisions: null,
18 failures: null, 19 failures: null,
19 lastUpdateDate: null, 20 lastUpdateDate: null,
20 21
21 // FIXME: Get this from https://chromium.googlesource.com/chromium/tools/b uild/+/master/scripts/slave/gatekeeper_trees.json?format=text. 22 // FIXME: Get this from https://chromium.googlesource.com/chromium/tools/b uild/+/master/scripts/slave/gatekeeper_trees.json?format=text.
22 _trees: { 23 _trees: {
23 blink: [ 24 blink: [
24 "https://build.chromium.org/p/chromium.webkit", 25 "https://build.chromium.org/p/chromium.webkit",
25 ], 26 ],
26 chromium: [ 27 chromium: [
27 "https://build.chromium.org/p/chromium", 28 "https://build.chromium.org/p/chromium",
28 "https://build.chromium.org/p/chromium.chrome", 29 "https://build.chromium.org/p/chromium.chrome",
29 "https://build.chromium.org/p/chromium.chromiumos", 30 "https://build.chromium.org/p/chromium.chromiumos",
30 "https://build.chromium.org/p/chromium.gpu", 31 "https://build.chromium.org/p/chromium.gpu",
31 "https://build.chromium.org/p/chromium.linux", 32 "https://build.chromium.org/p/chromium.linux",
32 "https://build.chromium.org/p/chromium.mac", 33 "https://build.chromium.org/p/chromium.mac",
33 "https://build.chromium.org/p/chromium.memory", 34 "https://build.chromium.org/p/chromium.memory",
34 "https://build.chromium.org/p/chromium.win" 35 "https://build.chromium.org/p/chromium.win"
35 ], 36 ],
36 }, 37 },
37 38
38 _failureListComparator: function(tree, a, b) { 39 // Reverse sorting order, if a > b, return a negative number.
40 _failureByTreeListComparator: function(tree, a, b) {
39 if (tree === undefined) 41 if (tree === undefined)
40 tree = 'chromium'; 42 tree = 'chromium';
41 43
42 var rev_a = a.failures[0].firstFailingRevisions; 44 var rev_a = a.commitList.revisions;
43 var rev_b = b.failures[0].firstFailingRevisions; 45 var rev_b = b.commitList.revisions;
44 46
45 // Handle missing revision. 47 if (!rev_a || !Object.keys(rev_a).length) {
46 if (!rev_a) { 48 if (!rev_b || !Object.keys(rev_b).length)
47 if (!rev_b) {
48 return 0; 49 return 0;
49 } 50 return 1;
51 } else if (!rev_b || !Object.keys(rev_b).length) {
50 return -1; 52 return -1;
51 } else if (!rev_b) {
52 return 1;
53 } 53 }
54 54
55 // Prioritize the tree's revision. 55 // Prioritize the tree's revision, if they are unequal (else, fallback
56 if (rev_a[tree] != rev_b[tree]) 56 // below).
57 return rev_b[tree] - rev_a[tree]; 57 if (rev_a[tree] && rev_b[tree] &&
58 rev_a[tree].last() != rev_b[tree].last()) {
59 return rev_b[tree].last() - rev_a[tree].last();
60 }
58 61
59 // Compare other revisions in alphabetical order. 62 // Compare other revisions in alphabetical order.
60 var keys = Object.keys(rev_a).sort(); 63 var keys = Object.keys(rev_a).sort();
61 for (var i = 0; i < keys.length; i++) { 64 for (var i = 0; i < keys.length; i++) {
62 if (rev_a[keys[i]] != rev_b[keys[i]]) 65 if (keys[i] == tree) // Already taken care of, above.
63 return rev_b[keys[i]] - rev_a[keys[i]]; 66 continue;
67
68 var a_list = rev_a[keys[i]];
69 var b_list = rev_b[keys[i]];
70 if (!b_list)
71 return -1;
72
73 if (a_list.last() != b_list.last())
74 return b_list.last() - a_list.last();
64 } 75 }
65 return 0; 76 return 0;
66 }, 77 },
67 78
68 update: function() { 79 update: function() {
69 var annotationPromise = CTFailureGroup.fetchAnnotations(); 80 var annotationPromise = CTFailureGroup.fetchAnnotations();
70 net.json('http://sheriff-o-matic.appspot.com/alerts').then(function(data ) { 81 net.json('http://sheriff-o-matic.appspot.com/alerts').then(function(data ) {
71 annotationPromise.then(function(annotations) { 82 annotationPromise.then(function(annotations) {
72 // FIXME: Don't special-case the blink master. 83 // FIXME: Don't special-case the blink master.
73 this.builderLatestRevisions = new CTBuilderRevisions(data.latest_bui lder_info['chromium.webkit']); 84 this.builderLatestRevisions = new CTBuilderRevisions(data.latest_bui lder_info['chromium.webkit']);
74 this.failures = {}; 85 this.failures = {};
75 this.lastUpdateDate = new Date(data.date * 1000); 86 this.lastUpdateDate = new Date(data.date * 1000);
76 data.range_groups.forEach(function(group) { 87 // Update |failures| with the appropriate CTFailureGroup's for each tree.
77 this._processFailuresForGroup(group, data.alerts, annotations); 88 data.range_groups.forEach(function(rangeGroup) {
89 this._processFailuresForRangeGroup(rangeGroup, data.alerts, annota tions);
78 }.bind(this)); 90 }.bind(this));
91 // Sort failure groups so that newer failures are shown at the top o f the UI.
79 Object.keys(this.failures, function (tree, failuresByTree) { 92 Object.keys(this.failures, function (tree, failuresByTree) {
80 this.failures[tree].sort(this._failureListComparator.bind(this, tr ee)); 93 this.failures[tree].sort(this._failureByTreeListComparator.bind(th is, tree));
81 }.bind(this)); 94 }.bind(this));
82 }.bind(this)); 95 }.bind(this));
83 }.bind(this)); 96 }.bind(this));
84 }, 97 },
85 98
86 _failureComparator: function(a, b) { 99 _failureComparator: function(a, b) {
87 if (a.step > b.step) 100 if (a.step > b.step)
88 return 1; 101 return 1;
89 if (a.step < b.step) 102 if (a.step < b.step)
90 return -1 103 return -1
91 if (a.testName > b.testName) 104 if (a.testName > b.testName)
92 return 1; 105 return 1;
93 if (a.testName < b.testName) 106 if (a.testName < b.testName)
94 return -1 107 return -1
95 return 0; 108 return 0;
96 }, 109 },
97 110
98 _processFailuresForGroup: function(group, failures, annotations) { 111 _processFailuresForRangeGroup: function(rangeGroup, alerts, annotations) {
99 var failuresByReason = {};
100
101 var masterToTree = {}; 112 var masterToTree = {};
102 Object.keys(this._trees, function(tree, masters) { 113 Object.keys(this._trees, function(tree, masters) {
103 masters.forEach(function(master) { 114 masters.forEach(function(master) {
104 masterToTree[master] = tree; 115 masterToTree[master] = tree;
105 }); 116 });
106 }); 117 });
107 118
108 group.failure_keys.forEach(function(failure_key) { 119 // A rangeGroup may be related to multiple alerts (via |failure_keys|). Categorize
109 var failure = failures.find(function(item) { return item.key == failur e_key; }); 120 // these failures by reason (cause of failure), so that they can be grou ped in the UI
121 // (via a CTFailureGroup). Failures will be grouped in |failuresByReason |.
122 var failuresByReason = {};
123 rangeGroup.failure_keys.forEach(function(failure_key) {
124 var failure = alerts.find(function(item) { return item.key == failure_ key; });
125 // Establish the key to uniquely identify a failure by reason.
110 var reason, failureType; 126 var reason, failureType;
111 if (failure.reason) { 127 if (failure.reason) {
112 // FIXME: Store the actual failure type in a different field instead of smashing it into the reason. 128 // FIXME: Store the actual failure type in a different field instead of smashing it into the reason.
113 var parts = failure.reason.split(':'); 129 var parts = failure.reason.split(':');
114 reason = parts[0]; 130 reason = parts[0];
115 failureType = parts[1] || 'FAIL'; 131 failureType = parts[1] || 'FAIL';
116 } else { 132 } else {
117 reason = null; 133 reason = null;
118 failureType = 'UNKNOWN'; 134 failureType = 'UNKNOWN';
119 } 135 }
120 136
121 var failureKey = CTFailure.createKey(failure); 137 var failureKey = CTFailure.createKey(failure);
122 138
123 var reasonKey = JSON.stringify({ 139 var reasonKey = JSON.stringify({
124 step: failure.step_name, 140 step: failure.step_name,
125 reason: reason, 141 reason: reason,
126 }); 142 });
127 143
144 // FIXME: Figure out what tree masters that aren't in masterToTree
145 // we should have.
128 var tree = masterToTree[failure.master_url]; 146 var tree = masterToTree[failure.master_url];
129 147
130 // FIXME: Use a model class instead of a dumb object. 148 // FIXME: Use a model class instead of a dumb object.
131 if (!failuresByReason[reasonKey]) 149 if (!failuresByReason[reasonKey])
132 failuresByReason[reasonKey] = {}; 150 failuresByReason[reasonKey] = {};
133 if (!failuresByReason[reasonKey][tree]) 151 if (!failuresByReason[reasonKey][tree])
134 failuresByReason[reasonKey][tree] = {}; 152 failuresByReason[reasonKey][tree] = {};
135 failuresByReason[reasonKey][tree][failure.builder_name] = { 153 failuresByReason[reasonKey][tree][failure.builder_name] = {
136 key: failureKey, 154 key: failureKey,
137 // FIXME: Rename to failureType. 155 // FIXME: Rename to failureType.
138 actual: failureType, 156 actual: failureType,
139 lastFailingBuild: failure.last_failing_build, 157 lastFailingBuild: failure.last_failing_build,
140 earliestFailingBuild: failure.failing_build, 158 earliestFailingBuild: failure.failing_build,
141 masterUrl: failure.master_url, 159 masterUrl: failure.master_url,
142 failingBuildCount: failure.failing_build_count, 160 failingBuildCount: failure.failing_build_count,
143 annotation: annotations[failureKey], 161 annotation: annotations[failureKey],
144 }; 162 };
145 }.bind(this)); 163 }.bind(this));
146 164
165 if (!Object.keys(failuresByReason).length)
166 return;
167
147 var groupedFailures = {}; 168 var groupedFailures = {};
148 Object.keys(failuresByReason, function(reasonKey, resultsByTree) { 169 Object.keys(failuresByReason, function(reasonKey, resultsByTree) {
149 var failure = JSON.parse(reasonKey); 170 var failure = JSON.parse(reasonKey);
150 Object.keys(resultsByTree, function(tree, resultsByBuilder) { 171 Object.keys(resultsByTree, function(tree, resultsByBuilder) {
151 if (!groupedFailures[tree]) 172 if (!groupedFailures[tree])
152 groupedFailures[tree] = []; 173 groupedFailures[tree] = [];
153 groupedFailures[tree].push(new CTFailure(failure.step, failure.reaso n, resultsByBuilder, group.merged_first_failing, group.merged_last_passing)); 174 groupedFailures[tree].push(
175 new CTFailure(failure.step, failure.reason, resultsByBuilder));
154 }) 176 })
155 }); 177 });
156 178
157 Object.keys(groupedFailures, function(tree, failures) { 179 Object.keys(groupedFailures, function(tree, failures) {
158 failures.sort(this._failureComparator); 180 failures.sort(this._failureComparator);
159 181
160 if (!this.failures[tree]) 182 if (!this.failures[tree])
161 this.failures[tree] = []; 183 this.failures[tree] = [];
162 this.failures[tree].push(new CTFailureGroup(failures)); 184 var commitList = new CTCommitList(this.commitLog, rangeGroup.likely_re visions);
185 this.failures[tree].push(new CTFailureGroup(failures, commitList));
163 }.bind(this)); 186 }.bind(this));
164 }, 187 },
165 }); 188 });
166 </script> 189 </script>
167 </polymer-element> 190 </polymer-element>
OLDNEW
« no previous file with comments | « Tools/GardeningServer/model/test/ct-failure-group-tests.html ('k') | Tools/GardeningServer/ui/ct-failure-card.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698