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

Side by Side Diff: appengine/findit/waterfall/test/analyze_build_failure_pipeline_test.py

Issue 2158533002: [Findit] Use unittest.mock for testing and create a shared method to mock pipeline. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 4 years, 5 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 import os 5 import os
6 6
7 from common import constants 7 from common import constants
8 from common import chromium_deps 8 from common import chromium_deps
9 from common.pipeline_wrapper import pipeline_handlers 9 from common.pipeline_wrapper import pipeline_handlers
10 from model import analysis_status 10 from model import analysis_status
11 from model.wf_analysis import WfAnalysis 11 from model.wf_analysis import WfAnalysis
12 from waterfall import analyze_build_failure_pipeline
12 from waterfall import buildbot 13 from waterfall import buildbot
13 from waterfall import lock_util 14 from waterfall import lock_util
14 from waterfall.analyze_build_failure_pipeline import AnalyzeBuildFailurePipeline 15 from waterfall.analyze_build_failure_pipeline import AnalyzeBuildFailurePipeline
15 from waterfall.test import wf_testcase 16 from waterfall.test import wf_testcase
16 17
17 18
18 class AnalyzeBuildFailurePipelineTest(wf_testcase.WaterfallTestCase): 19 class AnalyzeBuildFailurePipelineTest(wf_testcase.WaterfallTestCase):
19 app_module = pipeline_handlers._APP 20 app_module = pipeline_handlers._APP
20 21
21 def _MockChangeLog( 22 def _Setup(self, master_name, builder_name, build_number,
22 self, urlfetch, user_name, revision, commit_position, file_path): 23 status=analysis_status.PENDING):
23 url = ('https://chromium.googlesource.com/chromium/src.git/+/%s?format=json'
24 % revision)
25
26 COMMIT_LOG_TEMPLATE = """)]}'
27 {
28 "commit": "REVISION",
29 "tree": "tree_rev",
30 "parents": [
31 "revX"
32 ],
33 "author": {
34 "name": "USER_NAME@chromium.org",
35 "email": "USER_NAME@chromium.org",
36 "time": "Wed Jun 11 19:35:32 2014"
37 },
38 "committer": {
39 "name": "USER_NAME@chromium.org",
40 "email": "USER_NAME@chromium.org",
41 "time": "Wed Jun 11 19:35:32 2014"
42 },
43 "message":
44 "git-svn-id: svn://svn.chromium.org/chromium/src@COMMIT_POSITION bla",
45 "tree_diff": [
46 {
47 "type": "modify",
48 "old_id": "idX",
49 "old_mode": 33188,
50 "old_path": "FILE_PATH",
51 "new_id": "idY",
52 "new_mode": 33188,
53 "new_path": "FILE_PATH"
54 }
55 ]
56 }
57 """
58 commit_log = COMMIT_LOG_TEMPLATE.replace(
59 'REVISION', revision).replace('USER_NAME', user_name).replace(
60 'COMMIT_POSITION', str(commit_position)).replace(
61 'FILE_PATH', file_path)
62 urlfetch.register_handler(url, commit_log)
63
64 def _Setup(self, master_name, builder_name, build_number):
65 analysis = WfAnalysis.Create(master_name, builder_name, build_number) 24 analysis = WfAnalysis.Create(master_name, builder_name, build_number)
66 analysis.status = analysis_status.RUNNING 25 analysis.status = status
67 analysis.put() 26 analysis.put()
68 27
69 def MockWaitUntilDownloadAllowed(*_): 28 def testBuildFailurePipelineFlow(self):
70 return True
71 self.mock(
72 lock_util, 'WaitUntilDownloadAllowed', MockWaitUntilDownloadAllowed)
73
74 with self.mock_urlfetch() as urlfetch:
75 # Mock build data.
76 for i in range(2):
77 build_url = buildbot.CreateBuildUrl(
78 master_name, builder_name, build_number - i, json_api=True)
79 file_name = os.path.join(os.path.dirname(__file__), 'data',
80 'm_b_%s.json' % (build_number - i))
81 with open(file_name, 'r') as f:
82 urlfetch.register_handler(build_url, f.read())
83 # Mock step log.
84 step_log_url = buildbot.CreateStdioLogUrl(
85 master_name, builder_name, build_number, 'a')
86 urlfetch.register_handler(
87 step_log_url, 'error in file a/b/x.cc:89 ...')
88
89 # Mock change logs.
90 self._MockChangeLog(urlfetch, 'user1', 'some_git_hash', 8888, 'a/b/x.cc')
91 self._MockChangeLog(
92 urlfetch, 'user1', '64c72819e898e952103b63eabc12772f9640af07',
93 8887, 'd/e/y.cc')
94
95 def MockGetChromeDependency(*_):
96 return {}
97 self.mock(chromium_deps, 'GetChromeDependency', MockGetChromeDependency)
98
99 def testBuildFailurePipeline(self):
100 master_name = 'm' 29 master_name = 'm'
101 builder_name = 'b' 30 builder_name = 'b'
102 build_number = 124 31 build_number = 124
103 32
104 self._Setup(master_name, builder_name, build_number) 33 self._Setup(master_name, builder_name, build_number)
105 34
35 self.MockPipeline(analyze_build_failure_pipeline.DetectFirstFailurePipeline,
36 'failure_info',
37 expected_args=[master_name, builder_name, build_number],
38 expected_kwargs={})
39 self.MockPipeline(analyze_build_failure_pipeline.PullChangelogPipeline,
40 'change_logs',
41 expected_args=['failure_info'],
42 expected_kwargs={})
43 self.MockPipeline(analyze_build_failure_pipeline.ExtractDEPSInfoPipeline,
44 'deps_info',
45 expected_args=['failure_info', 'change_logs'],
46 expected_kwargs={})
47 self.MockPipeline(analyze_build_failure_pipeline.ExtractSignalPipeline,
48 'signals',
49 expected_args=['failure_info'],
50 expected_kwargs={})
51 self.MockPipeline(analyze_build_failure_pipeline.IdentifyCulpritPipeline,
52 'heuristic_result',
53 expected_args=[
54 'failure_info', 'change_logs', 'deps_info',
55 'signals', False],
56 expected_kwargs={})
57 self.MockPipeline(
58 analyze_build_failure_pipeline.TriggerSwarmingTasksPipeline,
59 None,
60 expected_args=[
61 master_name, builder_name, build_number,
62 'failure_info'],
63 expected_kwargs={})
64 self.MockPipeline(
65 analyze_build_failure_pipeline.StartTryJobOnDemandPipeline,
66 None,
67 expected_args=[
68 'failure_info', 'signals', False, True,
69 'heuristic_result'],
70 expected_kwargs={})
71
106 root_pipeline = AnalyzeBuildFailurePipeline(master_name, 72 root_pipeline = AnalyzeBuildFailurePipeline(master_name,
107 builder_name, 73 builder_name,
108 build_number, 74 build_number,
109 False, 75 False,
110 False) 76 True)
111 root_pipeline.start(queue_name=constants.DEFAULT_QUEUE) 77 root_pipeline.start(queue_name=constants.DEFAULT_QUEUE)
112 self.execute_queued_tasks() 78 self.execute_queued_tasks()
113 79
114 expected_analysis_result = {
115 'failures': [
116 {
117 'step_name': 'a',
118 'supported': True,
119 'first_failure': 124,
120 'last_pass': 123,
121 'suspected_cls': [
122 {
123 'build_number': 124,
124 'repo_name': 'chromium',
125 'revision': 'some_git_hash',
126 'commit_position': 8888,
127 'url': ('https://chromium.googlesource.com/chromium'
128 '/src.git/+/some_git_hash'),
129 'score': 2,
130 'hints': {
131 'modified x.cc (and it was in log)': 2,
132 },
133 }
134 ],
135 }
136 ]
137 }
138
139 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
140 self.assertIsNotNone(analysis)
141 self.assertEqual(analysis_status.COMPLETED, analysis.status)
142 self.assertEqual(expected_analysis_result, analysis.result)
143 self.assertIsNotNone(analysis.result_status)
144
145 def testBuildFailurePipelineStartWithNoneResultStatus(self): 80 def testBuildFailurePipelineStartWithNoneResultStatus(self):
146 master_name = 'm' 81 master_name = 'm'
147 builder_name = 'b' 82 builder_name = 'b'
148 build_number = 124 83 build_number = 124
149 84
150 self._Setup(master_name, builder_name, build_number) 85 self._Setup(master_name, builder_name, build_number)
151 86
152 root_pipeline = AnalyzeBuildFailurePipeline(master_name, 87 root_pipeline = AnalyzeBuildFailurePipeline(master_name,
153 builder_name, 88 builder_name,
154 build_number, 89 build_number,
155 False, 90 False,
156 False) 91 False)
157 root_pipeline._ResetAnalysis(master_name, builder_name, build_number) 92 root_pipeline._ResetAnalysis(master_name, builder_name, build_number)
158 analysis = WfAnalysis.Get(master_name, builder_name, build_number) 93 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
159 self.assertIsNotNone(analysis) 94 self.assertIsNotNone(analysis)
160 self.assertEqual(analysis_status.RUNNING, analysis.status) 95 self.assertEqual(analysis_status.RUNNING, analysis.status)
161 self.assertIsNone(analysis.result_status) 96 self.assertIsNone(analysis.result_status)
162 97
163 def testAnalyzeBuildFailurePipelineAbortedWithAnalysis(self): 98 def testAnalyzeBuildFailurePipelineAbortedIfWithError(self):
164 master_name = 'm' 99 master_name = 'm'
165 builder_name = 'b' 100 builder_name = 'b'
166 build_number = 124 101 build_number = 124
167 102
168 self._Setup(master_name, builder_name, build_number) 103 self._Setup(master_name, builder_name, build_number,
104 status=analysis_status.RUNNING)
169 105
170 root_pipeline = AnalyzeBuildFailurePipeline(master_name, 106 root_pipeline = AnalyzeBuildFailurePipeline(master_name,
171 builder_name, 107 builder_name,
172 build_number, 108 build_number,
173 False, 109 False,
174 False) 110 False)
175 root_pipeline._LogUnexpectedAborting(True) 111 root_pipeline._LogUnexpectedAborting(True)
176 112
177 analysis = WfAnalysis.Get(master_name, builder_name, build_number) 113 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
178 self.assertIsNotNone(analysis) 114 self.assertIsNotNone(analysis)
179 self.assertEqual(analysis_status.ERROR, analysis.status) 115 self.assertEqual(analysis_status.ERROR, analysis.status)
180 self.assertIsNone(analysis.result_status) 116 self.assertIsNone(analysis.result_status)
181 117
182 def testAnalyzeBuildFailurePipelineAbortedWithoutAnalysis(self): 118 def testAnalyzeBuildFailurePipelineNotAbortedIfWithoutError(self):
183 master_name = 'm' 119 master_name = 'm'
184 builder_name = 'b' 120 builder_name = 'b'
185 build_number = 124 121 build_number = 124
186 122
123 self._Setup(master_name, builder_name, build_number,
124 status=analysis_status.COMPLETED)
125
187 root_pipeline = AnalyzeBuildFailurePipeline(master_name, 126 root_pipeline = AnalyzeBuildFailurePipeline(master_name,
188 builder_name, 127 builder_name,
189 build_number, 128 build_number,
190 False, 129 False,
191 False) 130 False)
192 root_pipeline._LogUnexpectedAborting(True) 131 root_pipeline._LogUnexpectedAborting(True)
193 132
194 analysis = WfAnalysis.Get(master_name, builder_name, build_number) 133 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
195 self.assertIsNone(analysis)
196
197 def testAnalyzeBuildFailurePipelineNotAborted(self):
198 master_name = 'm'
199 builder_name = 'b'
200 build_number = 124
201
202 self._Setup(master_name, builder_name, build_number)
203
204 root_pipeline = AnalyzeBuildFailurePipeline(master_name,
205 builder_name,
206 build_number,
207 False,
208 False)
209 root_pipeline._LogUnexpectedAborting(False)
210
211 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
212 self.assertIsNotNone(analysis) 134 self.assertIsNotNone(analysis)
213 self.assertNotEqual(analysis_status.ERROR, analysis.status) 135 self.assertNotEqual(analysis_status.ERROR, analysis.status)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698