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

Side by Side Diff: appengine/findit/waterfall/identify_try_job_culprit_pipeline.py

Issue 1591003002: [Findit] Modify tryjob pipelines to trigger try jobs for test failure. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 4 years, 11 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
OLDNEW
1 # Copyright 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 from common.git_repository import GitRepository 5 from common.git_repository import GitRepository
6 from common.http_client_appengine import HttpClientAppengine as HttpClient 6 from common.http_client_appengine import HttpClientAppengine as HttpClient
7 from model import wf_analysis_status 7 from model import wf_analysis_status
8 from model.wf_try_job import WfTryJob 8 from model.wf_try_job import WfTryJob
9 from pipeline_wrapper import BasePipeline 9 from pipeline_wrapper import BasePipeline
10 10
11 11
12 GIT_REPO = GitRepository(
13 'https://chromium.googlesource.com/chromium/src.git', HttpClient())
14
15
12 class IdentifyTryJobCulpritPipeline(BasePipeline): 16 class IdentifyTryJobCulpritPipeline(BasePipeline):
13 """A pipeline to identify culprit CL info based on try job compile results.""" 17 """A pipeline to identify culprit CL info based on try job compile results."""
14 18
19 def _GetCulpritInfo(self, failed_revisions):
20 """Gets commit_positions and review_urls for revisions."""
21 culprits = {}
22 for failed_revision in failed_revisions:
23 change_log = GIT_REPO.GetChangeLog(failed_revision)
24 if change_log:
25 culprits[failed_revision] = {
26 'revision': failed_revision,
27 'commit_position': change_log.commit_position,
28 'review_url': change_log.code_review_url
29 }
30 return culprits
31
15 # Arguments number differs from overridden method - pylint: disable=W0221 32 # Arguments number differs from overridden method - pylint: disable=W0221
16 def run( 33 def run(
17 self, master_name, builder_name, build_number, try_job_id, 34 self, master_name, builder_name, build_number, blame_list, try_job_type,
18 compile_result): 35 try_job_id, result):
19 culprit = None 36 """Identify the information for failed revisions.
20 37
21 if compile_result and len(compile_result.get('result', [])) > 0: 38 The format for final try-job result for compile failures is:
22 # For compile failures, the try job will stop if one revision fails, so 39 {
23 # the culprit will be the last revision in the result. 40 'result': [
24 result_for_last_checked_revision = compile_result['result'][-1] 41 ['rev1', 'passed'],
25 failed_revision = ( 42 ['rev2', 'failed']
26 result_for_last_checked_revision[0] if 43 ],
27 result_for_last_checked_revision[1].lower() == 'failed' else None) 44 'url': 'url',
45 'try_job_id': '1',
46 'culprit': {
47 'revision': 'rev2',
48 'commit_position': '2',
49 'review_url': 'url_2'
50 }
51 }
28 52
29 if failed_revision: 53 The format for final try-job result for test failures is:
30 git_repo = GitRepository( 54 {
31 'https://chromium.googlesource.com/chromium/src.git', HttpClient()) 55 'result': {
32 change_log = git_repo.GetChangeLog(failed_revision) 56 'rev1': {
33 if change_log: 57 'a_test': {
34 culprit = { 58 'status': 'failed',
35 'revision': failed_revision, 59 'valid': True,
36 'commit_position': change_log.commit_position, 60 'failures': ['a_test1']
37 'review_url': change_log.code_review_url 61 },
38 } 62 'b_test': {
39 compile_result['culprit'] = culprit 63 'status': 'failed',
64 'valid': True,
65 'failures': ['b_test1']
66 }
67 },
68 'rev2': {
69 'a_test': {
70 'status': 'failed',
71 'valid': True,
72 'failures': ['a_test2']
73 },
74 'b_test': {
75 'status': 'passed',
76 'valid': True
77 }
78 }
79 },
80 'url': 'url',
81 'try_job_id': '1',
82 'culprit': {
83 'a_test': {
84 'revision': 'rev1',
85 'commit_position': '1',
86 'review_url': 'url_1',
87 'tests': {
88 'a_test1': {
89 'revision': 'rev1',
90 'commit_position': '1',
91 'review_url': 'url_1'
92 },
93 'a_test2': {
94 'revision': 'rev2',
95 'commit_position': '2',
96 'review_url': 'url_2'
97 }
98 }
99 },
100 'b_test': {
101 'revision': 'rev1',
102 'commit_position': '1',
103 'review_url': 'url_1',
104 'tests': {
105 'b_test1': {
106 'revision': 'rev1',
107 'commit_position': '1',
108 'review_url': 'url_1'
109 }
110 }
111 }
112 }
113 }
114 """
115 culprits = None
116
117 if try_job_type == 'compile':
118 if result and len(result.get('result', [])) > 0:
lijeffrey 2016/01/16 00:27:12 I think this can be reduced to just result.get('re
chanli 2016/01/20 18:28:04 Done.
119 # For compile failures, the try job will stop if one revision fails, so
120 # the culprit will be the last revision in the result.
121 result_for_last_checked_revision = result['result'][-1]
122 failed_revision = (
123 result_for_last_checked_revision[0] if
124 result_for_last_checked_revision[1].lower() == 'failed' else None)
125
126 if failed_revision:
127 culprits = self._GetCulpritInfo([failed_revision])
128 if culprits:
129 result['culprit'] = culprits[failed_revision]
130 else:
131 if result and result.get('result'):
lijeffrey 2016/01/16 00:27:12 it looks like this if statement can be moved outsi
chanli 2016/01/20 18:28:04 Done.
132 # For test failures, the try job will run against every revision,
133 # so we need to traverse the result dict in order to identify the
134 # culprits to each failed step or test.
135 culprit_map = {}
136 failed_revisions = []
137 for revision in blame_list:
138 for step, step_result in result['result'][revision].iteritems():
139 if step_result['valid'] and step_result['status'] == 'failed':
140 if revision not in failed_revisions:
141 failed_revisions.append(revision)
142
143 if step not in culprit_map:
144 culprit_map[step] = {}
145 culprit_map[step]['revision'] = revision
146 culprit_map[step]['tests'] = {}
147 for failed_test in step_result['failures']:
148 if failed_test not in culprit_map[step]['tests']:
149 culprit_map[step]['tests'][failed_test] = {}
150 culprit_map[step]['tests'][failed_test]['revision'] = (
151 revision)
152
153 if failed_revisions:
lijeffrey 2016/01/16 00:27:12 nit: maybe add if failed_revisions to _GetCulpritI
chanli 2016/01/20 18:28:04 Done.
154 culprits = self._GetCulpritInfo(failed_revisions)
155 if culprits:
156 for step_culprit in culprit_map.values():
157 step_revision = step_culprit['revision']
158 step_culprit['commit_position'] = (
159 culprits[step_revision]['commit_position'])
160 step_culprit['review_url'] = culprits[step_revision]['review_url']
161 for test_culprit in step_culprit.get('tests', {}).values():
162 test_revision = test_culprit['revision']
163 test_culprit.update(culprits[test_revision])
164 result['culprit'] = culprit_map
40 165
41 # Store try job results. 166 # Store try job results.
42 try_job_result = WfTryJob.Get(master_name, builder_name, build_number) 167 try_job_result = WfTryJob.Get(master_name, builder_name, build_number)
43 if culprit: 168 if culprits:
44 if (try_job_result.compile_results and 169 result_needs_update = (
45 try_job_result.compile_results[-1]['try_job_id'] == try_job_id): 170 try_job_result.compile_results if
46 try_job_result.compile_results[-1].update(compile_result) 171 try_job_type == 'compile' else try_job_result.test_results)
172 if (result_needs_update and
173 result_needs_update[-1]['try_job_id'] == try_job_id):
174 result_needs_update[-1].update(result)
47 else: # pragma: no cover 175 else: # pragma: no cover
48 try_job_result.compile_results.append(compile_result) 176 result_needs_update.append(result)
49 177
50 try_job_result.status = wf_analysis_status.ANALYZED 178 try_job_result.status = wf_analysis_status.ANALYZED
51 try_job_result.put() 179 try_job_result.put()
52 180
53 return culprit 181 return result.get('culprit', None) if result else None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698