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

Side by Side Diff: appengine/findit/handlers/handlers_util.py

Issue 1797093002: [Findit] Fix bug when display try job result for non-swarming step. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « no previous file | appengine/findit/handlers/swarming_task.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 from collections import defaultdict
6
7 from model import wf_analysis_status
8 from model.wf_analysis import WfAnalysis
9 from model.wf_swarming_task import WfSwarmingTask
10 from model.wf_try_job import WfTryJob
11 from waterfall import buildbot
12 from waterfall import waterfall_config
13
14
15 FLAKY = 'Flaky'
16
17
18 def GenerateSwarmingTasksData(master_name, builder_name, build_number):
19 """Collects info for all related swarming tasks.
20
21 Returns: A dict as below:
22 {
23 'step1': {
24 'swarming_tasks': [
25 {
26 'status': 'Completed',
27 'task_id': 'task1',
28 'task_url': (
29 'https://chromium-swarm.appspot.com/user/task/task1')
30 },
31 {
32 'status': 'Completed',
33 'task_id': 'task0',
34 'task_url': (
35 'https://chromium-swarm.appspot.com/user/task/task0')
36 }
37 ],
38 'tests': {
39 'test1': {
40 'status': 'Completed',
41 'task_id': 'task0',
42 'task_url': (
43 'https://chromium-swarm.appspot.com/user/task/task0')
44 },
45 'test2': {
46 'status': 'Completed',
47 'task_id': 'task1',
48 'task_url': (
49 'https://chromium-swarm.appspot.com/user/task/task1')
50 }
51 }
52 },
53 'step2': {
54 'swarming_tasks': [
55 {
56 'status': 'Pending'
57 }
58 ],
59 'tests': {
60 'test1': {
61 'status': 'Pending'
62 }
63 }
64 }
65 }
66 """
67 tasks_info = defaultdict(dict)
68
69 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
70 if not analysis:
71 return tasks_info
72
73 failure_result_map = analysis.failure_result_map
74 if failure_result_map:
75 for step_name, failure in failure_result_map.iteritems():
76 if isinstance(failure, dict):
77 # Only trigger swarming task for swarming test failures.
78 key_test_map = defaultdict(list)
79 for test_name, first_failure_key in failure.iteritems():
80 key_test_map[first_failure_key].append(test_name)
81
82 tasks_info[step_name]['swarming_tasks'] = []
83 tasks_info[step_name]['tests'] = defaultdict(dict)
84 step_tasks_info = tasks_info[step_name]['swarming_tasks']
85 tests = tasks_info[step_name]['tests']
86 for key in key_test_map:
87 referred_build_keys = key.split('/')
88 task = WfSwarmingTask.Get(*referred_build_keys, step_name=step_name)
89 if not task:
90 continue
91 task_info = {
92 'status': wf_analysis_status.SWARMING_STATUS_TO_DESCRIPTION.get(
93 task.status)
94 }
95 if task.task_id:
96 task_info['task_id'] = task.task_id
97 task_info['task_url'] = 'https://%s/user/task/%s' % (
98 waterfall_config.GetSwarmingSettings()['server_host'],
99 task.task_id)
100
101 step_tasks_info.append(task_info)
102 for test_name in key_test_map[key]:
103 tests[test_name] = task_info
104
105 return tasks_info
106
107
108 def _GetTryJobBuildNumber(url):
109 build_keys = buildbot.ParseBuildUrl(url)
110 return build_keys[2]
111
112
113 def _GetCulpritInfoForTryJobResult(try_job_key, culprits_info):
114 referred_build_keys = try_job_key.split('/')
115 try_job = WfTryJob.Get(*referred_build_keys)
116 if not try_job:
117 return
118
119 if try_job.compile_results:
120 try_job_result = try_job.compile_results[-1]
121 elif try_job.test_results:
122 try_job_result = try_job.test_results[-1]
123 else:
124 try_job_result = None
125
126 additional_tests_culprit_info = {}
127 for culprit_info in culprits_info.values():
128 if culprit_info['try_job_key'] != try_job_key:
129 continue
130
131 # Only include try job result for reliable tests.
132 # Flaky tests have been marked as 'Flaky'.
133 culprit_info['status'] = (
134 wf_analysis_status.TRY_JOB_STATUS_TO_DESCRIPTION[try_job.status]
135 if not culprit_info.get('status') else culprit_info['status'])
136
137 if try_job_result and culprit_info['status'] != FLAKY:
138 if try_job_result.get('url'):
139 culprit_info['try_job_url'] = try_job_result['url']
140 culprit_info['try_job_build_number'] = (
141 _GetTryJobBuildNumber(try_job_result['url']))
142 if try_job_result.get('culprit'):
143 try_job_culprits = try_job_result['culprit']
144 step = culprit_info['step']
145 test = culprit_info['test']
146
147 if test == 'N/A': # Only step level.
148 if try_job_culprits.get(step, {}).get('tests'):
stgao 2016/03/15 17:19:40 Note: for some script-based test like checklicense
149 # try job results has specified tests.
150 step_culprits = try_job_culprits[step]['tests']
151 for test_name, try_job_culprit in step_culprits.iteritems():
152 additional_test_key = '%s-%s' % (step, test_name)
153 additional_tests_culprit_info[additional_test_key] = {
154 'step': step,
155 'test': test_name,
156 'try_job_key': try_job_key,
157 'status': culprit_info['status'],
158 'try_job_url': culprit_info['try_job_url'],
159 'try_job_build_number': culprit_info['try_job_build_number'],
160 'revision': try_job_culprit.get('revision'),
161 'commit_position': try_job_culprit.get('commit_position'),
162 'review_url': try_job_culprit.get('review_url')
163 }
164 continue
165 else:
166 # For historical culprit found by try job for compile,
167 # step name is not recorded.
168 culprit = try_job_culprits.get(step) or try_job_culprits
169 elif test in try_job_culprits.get(step, {}).get('tests'):
170 culprit = try_job_culprits[step]['tests'][test]
171 else: # pragma: no cover
172 continue # No culprit for test found.
173
174 culprit_info['revision'] = culprit.get('revision')
175 culprit_info['commit_position'] = culprit.get('commit_position')
176 culprit_info['review_url'] = culprit.get('review_url')
177
178 if additional_tests_culprit_info:
179 for key, test_culprit_info in additional_tests_culprit_info.iteritems():
180 culprits_info.pop(test_culprit_info['step'], None)
181 culprits_info[key] = test_culprit_info
182
183
184 def _UpdateFlakiness(step_name, failure_key_set, culprits_info):
185 for failure_key in failure_key_set:
186 build_keys = failure_key.split('/')
187 task = WfSwarmingTask.Get(*build_keys, step_name=step_name)
188 if not task:
189 continue
190 classified_tests = task.classified_tests
191 for culprit_info in culprits_info.values():
192 if (culprit_info['try_job_key'] == failure_key and
193 culprit_info['test'] in classified_tests.get('flaky_tests', [])):
194 culprit_info['status'] = 'Flaky'
stgao 2016/03/15 17:19:40 nit: no hard code here. Use the var at the top.
chanli 2016/03/15 17:34:05 Done.
195
196
197 def GetAllTryJobResults(master_name, builder_name, build_number):
198 culprits_info = {}
199 try_job_keys = set()
200
201 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
202 if not analysis:
203 return culprits_info
204
205 failure_result_map = analysis.failure_result_map
206 if failure_result_map:
207 # failure_result_map uses step_names as keys and saves referred try_job_keys
208 # If non-swarming, step_name and referred_try_job_key match directly as:
209 # step_name: try_job_key
210 # If swarming, add one more layer of tests, so the format would be:
211 # step_name: {
212 # test_name1: try_job_key1,
213 # test_name2: try_job_key2,
214 # ...
215 # }
216 for step_name, step_failure_result_map in failure_result_map.iteritems():
217 if isinstance(step_failure_result_map, dict):
218 step_refering_keys = set()
219 for failed_test, try_job_key in step_failure_result_map.iteritems():
220 step_test_key = '%s-%s' % (step_name, failed_test)
221 culprits_info[step_test_key] = {
222 'step': step_name,
223 'test': failed_test,
224 'try_job_key': try_job_key
225 }
226 step_refering_keys.add(try_job_key)
227
228 _UpdateFlakiness(step_name, step_refering_keys, culprits_info)
229 try_job_keys.update(step_refering_keys)
230 else:
231 culprits_info[step_name] = {
232 'step': step_name,
233 'test': 'N/A',
234 'try_job_key': step_failure_result_map
235 }
236 try_job_keys.add(step_failure_result_map)
237
238 for try_job_key in try_job_keys:
239 _GetCulpritInfoForTryJobResult(try_job_key, culprits_info)
240
241 return culprits_info
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/handlers/swarming_task.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698