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

Side by Side Diff: appengine/findit/crash/test/crash_pipeline_test.py

Issue 2414523002: [Findit] Reorganizing findit_for_*.py (Closed)
Patch Set: Fixing call to ScheduleNewAnalysis in handlers/crash/crash_handler.py Created 4 years, 2 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 2016 The Chromium Authors. All rights reserved. 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 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 import copy 4 import copy
5 import json 5 import json
6 6
7 from google.appengine.api import app_identity 7 from google.appengine.api import app_identity
8 from webtest.app import AppError
8 9
9 from common.pipeline_wrapper import pipeline_handlers 10 from common.pipeline_wrapper import pipeline_handlers
10 from crash import crash_pipeline 11 from crash import crash_pipeline
11 from crash import findit_for_chromecrash 12 from crash import findit_for_chromecrash
13 from crash.culprit import Culprit
14 from crash.crash_report import CrashReport
15 from crash.findit_for_chromecrash import FinditForFracas
16 from crash.stacktrace import Stacktrace
12 from crash.test.crash_testcase import CrashTestCase 17 from crash.test.crash_testcase import CrashTestCase
18 from crash.type_enums import CrashClient
13 from model import analysis_status 19 from model import analysis_status
14 from model.crash.fracas_crash_analysis import FracasCrashAnalysis 20 from model.crash.fracas_crash_analysis import FracasCrashAnalysis
15 21
16 22
23 def DummyCrashData(
24 version='1',
25 signature='signature',
26 platform='win',
27 stack_trace=None,
28 regression_range=None,
29 crash_identifiers=True,
30 channel='canary',
31 process_type='browser'):
32 if crash_identifiers is True:
33 crash_identifiers = {
34 'chrome_version': version,
35 'signature': signature,
36 'channel': channel,
37 'platform': platform,
38 'process_type': process_type,
39 }
40 return {
41 'crashed_version': version,
42 'signature': signature,
43 'platform': platform,
44 'stack_trace': stack_trace,
45 'crash_identifiers': crash_identifiers,
46 'customized_data': {
47 'regression_range': regression_range,
48 'historical_metadata': None,
49 'channel': channel,
50 },
51 }
52
53
17 class CrashPipelineTest(CrashTestCase): 54 class CrashPipelineTest(CrashTestCase):
18 app_module = pipeline_handlers._APP 55 app_module = pipeline_handlers._APP
19 56
20 def testNoAnalysisIfLastOneIsNotFailed(self): 57 def testNoAnalysisIfLastOneIsNotFailed(self):
21 chrome_version = '1' 58 crash_data = DummyCrashData()
22 signature = 'signature' 59 crash_identifiers = crash_data['crash_identifiers']
23 platform = 'win'
24 crash_identifiers = {
25 'chrome_version': chrome_version,
26 'signature': signature,
27 'channel': 'canary',
28 'platform': platform,
29 'process_type': 'browser',
30 }
31 for status in (analysis_status.PENDING, analysis_status.RUNNING, 60 for status in (analysis_status.PENDING, analysis_status.RUNNING,
32 analysis_status.COMPLETED, analysis_status.SKIPPED): 61 analysis_status.COMPLETED, analysis_status.SKIPPED):
33 analysis = FracasCrashAnalysis.Create(crash_identifiers) 62 analysis = FracasCrashAnalysis.Create(crash_identifiers)
34 analysis.status = status 63 analysis.status = status
35 analysis.put() 64 analysis.put()
36 self.assertFalse(crash_pipeline._NeedsNewAnalysis( 65 self.assertFalse(FinditForFracas()._NeedsNewAnalysis(crash_data))
37 crash_identifiers, chrome_version, signature, 'fracas',
38 platform, None, {'channel': 'canary'}))
39 66
40 def testAnalysisNeededIfLastOneFailed(self): 67 def testAnalysisNeededIfLastOneFailed(self):
41 chrome_version = '1' 68 crash_data = DummyCrashData()
42 signature = 'signature' 69 crash_identifiers = crash_data['crash_identifiers']
43 platform = 'win'
44 crash_identifiers = {
45 'chrome_version': chrome_version,
46 'signature': signature,
47 'channel': 'canary',
48 'platform': platform,
49 'process_type': 'browser',
50 }
51 analysis = FracasCrashAnalysis.Create(crash_identifiers) 70 analysis = FracasCrashAnalysis.Create(crash_identifiers)
52 analysis.status = analysis_status.ERROR 71 analysis.status = analysis_status.ERROR
53 analysis.put() 72 analysis.put()
54 self.assertTrue(crash_pipeline._NeedsNewAnalysis( 73 self.assertTrue(FinditForFracas()._NeedsNewAnalysis(crash_data))
55 crash_identifiers, chrome_version, signature, 'fracas',
56 platform, None, {'channel': 'canary'}))
57 74
58 def testAnalysisNeededIfNoAnalysisYet(self): 75 def testAnalysisNeededIfNoAnalysisYet(self):
59 chrome_version = '1' 76 crash_data = DummyCrashData()
60 signature = 'signature' 77 self.assertTrue(FinditForFracas()._NeedsNewAnalysis(crash_data))
61 platform = 'win'
62 crash_identifiers = {
63 'chrome_version': chrome_version,
64 'signature': signature,
65 'channel': 'canary',
66 'platform': platform,
67 'process_type': 'browser',
68 }
69 self.assertTrue(crash_pipeline._NeedsNewAnalysis(
70 crash_identifiers, chrome_version, signature, 'fracas',
71 platform, None, {'channel': 'canary'}))
72 78
73 def testUnsupportedChannelOrPlatformSkipped(self): 79 def testUnsupportedChannelOrPlatformSkipped(self):
74 self.assertFalse( 80 crash_data = DummyCrashData(
75 crash_pipeline.ScheduleNewAnalysisForCrash( 81 version=None,
76 {}, None, None, 'fracas', 'win', 82 signature=None,
77 None, {'channel': 'unsupported_channel', 83 regression_range=None,
78 'historical_metadata': None})) 84 crash_identifiers={},
79 self.assertFalse( 85 channel=None)
80 crash_pipeline.ScheduleNewAnalysisForCrash( 86 self.assertFalse(FinditForFracas().ScheduleNewAnalysis(crash_data))
81 {}, None, None, 'fracas', 'unsupported_platform', 87 crash_data['platform'] = 'unsupported_platform'
82 None, {'channel': 'unsupported_channel', 88 self.assertFalse(FinditForFracas().ScheduleNewAnalysis(crash_data))
83 'historical_metadata': None}))
84 89
85 def testBlackListSignatureSipped(self): 90 def testBlackListSignatureSipped(self):
86 self.assertFalse( 91 crash_data = DummyCrashData(
87 crash_pipeline.ScheduleNewAnalysisForCrash( 92 version=None,
88 {}, None, 'Blacklist marker signature', 'fracas', 'win', 93 signature='Blacklist marker signature',
89 None, {'channel': 'canary', 94 regression_range=None,
90 'historical_metadata': None})) 95 crash_identifiers={},
96 channel=None)
97 self.assertFalse(FinditForFracas().ScheduleNewAnalysis(crash_data))
91 98
92 def testPlatformRename(self): 99 def testPlatformRename(self):
93 def _MockNeedsNewAnalysis(*args): 100 old_crash_data = DummyCrashData(
94 self.assertEqual(args, 101 version=None,
95 ({}, None, 'signature', 'fracas', 'unix', None, 102 platform='unix',
96 {'channel': 'canary'})) 103 regression_range=None,
97 return False 104 crash_identifiers={})
98 105
99 self.mock(crash_pipeline, '_NeedsNewAnalysis', _MockNeedsNewAnalysis) 106 testcase = self
107 class _MockFinditForFracas(FinditForFracas):
108 def _NeedsNewAnalysis(self, new_crash_data):
109 testcase.assertEqual(self.client_id, CrashClient.FRACAS)
110 testcase.assertDictEqual(new_crash_data, old_crash_data)
111 return False
100 112
101 crash_pipeline.ScheduleNewAnalysisForCrash( 113 new_crash_data = copy.deepcopy(old_crash_data)
102 {}, None, 'signature', 'fracas', 'linux', 114 new_crash_data['platform'] = 'linux'
103 None, {'channel': 'canary'}) 115 _MockFinditForFracas().ScheduleNewAnalysis(new_crash_data)
104 116
105 def testNoAnalysisNeeded(self): 117 def testNoAnalysisNeeded(self):
106 chrome_version = '1' 118 crash_data = DummyCrashData()
107 signature = 'signature' 119 crash_identifiers = crash_data['crash_identifiers']
108 platform = 'win'
109 channel = 'canary'
110 crash_identifiers = {
111 'chrome_version': chrome_version,
112 'signature': signature,
113 'channel': channel,
114 'platform': platform,
115 'process_type': 'browser',
116 }
117 analysis = FracasCrashAnalysis.Create(crash_identifiers) 120 analysis = FracasCrashAnalysis.Create(crash_identifiers)
118 analysis.status = analysis_status.COMPLETED 121 analysis.status = analysis_status.COMPLETED
119 analysis.put() 122 analysis.put()
120 123 self.assertFalse(FinditForFracas().ScheduleNewAnalysis(crash_data))
121 self.assertFalse(
122 crash_pipeline.ScheduleNewAnalysisForCrash(
123 crash_identifiers, chrome_version, signature, 'fracas',
124 platform, None, {'channel': channel,
125 'historical_metadata': None}))
126 124
127 def _TestRunningAnalysisForResult(self, analysis_result, analysis_tags): 125 def _TestRunningAnalysisForResult(self, analysis_result, analysis_tags):
126 # Reconstruct the culprit that gives rise to the analysis_{result,tags}
127 mock_culprit = Culprit(
128 project = analysis_result.get('suspected_project', None),
129 components = analysis_result.get('suspected_components', None),
130 cls = analysis_result.get('suspected_cls', None),
131 regression_range = analysis_result.get('regression_range', (None, None)) ,
132 algorithm = analysis_tags.get('solution', None),
133 )
134
128 pubsub_publish_requests = [] 135 pubsub_publish_requests = []
129 def Mocked_PublishMessagesToTopic(messages_data, topic): 136 def Mocked_PublishMessagesToTopic(messages_data, topic):
130 pubsub_publish_requests.append((messages_data, topic)) 137 pubsub_publish_requests.append((messages_data, topic))
131 self.mock(crash_pipeline.pubsub_util, 'PublishMessagesToTopic', 138 self.mock(crash_pipeline.pubsub_util, 'PublishMessagesToTopic',
132 Mocked_PublishMessagesToTopic) 139 Mocked_PublishMessagesToTopic)
133 140
134 analyzed_crashes = [] 141 analyzed_crashes = []
135 class Mocked_FinditForChromeCrash(object): 142 class _MockFinditForFracas(FinditForFracas):
136 def __init__(self, *_):
137 pass
138 def FindCulprit(self, *args): 143 def FindCulprit(self, *args):
139 analyzed_crashes.append(args) 144 analyzed_crashes.append(args)
140 return analysis_result, analysis_tags 145 return mock_culprit
141 self.mock(findit_for_chromecrash, 'FinditForChromeCrash',
142 Mocked_FinditForChromeCrash)
143
144 chrome_version = '1'
145 signature = 'signature'
146 platform = 'win'
147 channel = 'canary'
148 crash_identifiers = {
149 'chrome_version': chrome_version,
150 'signature': signature,
151 'channel': channel,
152 'platform': platform,
153 'process_type': 'browser',
154 }
155 stack_trace = 'frame1\nframe2\nframe3'
156 chrome_version = '50.2500.0.1'
157 historical_metadata = None
158 146
159 mock_host = 'https://host.com' 147 mock_host = 'https://host.com'
160 self.mock(app_identity, 'get_default_version_hostname', lambda: mock_host) 148 self.mock(app_identity, 'get_default_version_hostname', lambda: mock_host)
161 149
162 self.assertTrue( 150 crash_data = DummyCrashData(
163 crash_pipeline.ScheduleNewAnalysisForCrash( 151 version = '50.2500.0.1',
164 crash_identifiers, chrome_version, signature, 'fracas', 152 stack_trace = 'frame1\nframe2\nframe3')
165 platform, stack_trace, 153 historical_metadata = None
166 {'channel': channel, 'historical_metadata': historical_metadata})) 154 self.assertTrue(_MockFinditForFracas().ScheduleNewAnalysis(crash_data))
wrengr 2016/10/18 23:28:10 This line ultimately causes a bunch of tests to fa
167 155
168 self.execute_queued_tasks() 156 # We catch and re-raise to clean up the callstack that's reported.
157 try:
158 self.execute_queued_tasks()
159 except AppError, e:
160 raise e
169 161
170 self.assertEqual(1, len(pubsub_publish_requests)) 162 self.assertEqual(1, len(pubsub_publish_requests))
171 163
172 processed_analysis_result = copy.deepcopy(analysis_result) 164 processed_analysis_result = copy.deepcopy(analysis_result)
173 processed_analysis_result['feedback_url'] = ( 165 processed_analysis_result['feedback_url'] = (
174 mock_host + '/crash/fracas-result-feedback?' 166 mock_host + '/crash/fracas-result-feedback?'
175 'key=agx0ZXN0YmVkLXRlc3RyQQsSE0ZyYWNhc0NyYXNoQW5hbHlzaXMiKGU2ZWIyNj' 167 'key=agx0ZXN0YmVkLXRlc3RyQQsSE0ZyYWNhc0NyYXNoQW5hbHlzaXMiKGU2ZWIyNj'
176 'A2OTBlYTAyMjVjNWNjYTM3ZTNjYTlmYWExOGVmYjVlM2UM') 168 'A2OTBlYTAyMjVjNWNjYTM3ZTNjYTlmYWExOGVmYjVlM2UM')
177 169
178 if 'suspected_cls' in processed_analysis_result: 170 if 'suspected_cls' in processed_analysis_result:
179 for cl in processed_analysis_result['suspected_cls']: 171 for cl in processed_analysis_result['suspected_cls']:
180 cl['confidence'] = round(cl['confidence'], 2) 172 cl['confidence'] = round(cl['confidence'], 2)
181 cl.pop('reason', None) 173 cl.pop('reason', None)
182 174
183 expected_messages_data = [json.dumps({ 175 expected_messages_data = [json.dumps({
184 'crash_identifiers': crash_identifiers, 176 'crash_identifiers': crash_data['crash_identifiers'],
185 'client_id': 'fracas', 177 'client_id': 'fracas',
186 'result': processed_analysis_result, 178 'result': processed_analysis_result,
187 }, sort_keys=True)] 179 }, sort_keys=True)]
188 self.assertEqual(expected_messages_data, pubsub_publish_requests[0][0]) 180 self.assertEqual(expected_messages_data, pubsub_publish_requests[0][0])
189 181
190 self.assertEqual(1, len(analyzed_crashes)) 182 self.assertEqual(1, len(analyzed_crashes))
191 self.assertEqual( 183 self.assertEqual(
192 (signature, platform, stack_trace, chrome_version, None), 184 (crash_data['signature'], crash_data['platform'],
185 crash_data['stack_trace'], crash_data['chrome_version'], None),
193 analyzed_crashes[0]) 186 analyzed_crashes[0])
194 187
195 analysis = FracasCrashAnalysis.Get(crash_identifiers) 188 analysis = FracasCrashAnalysis.Get(crash_data['crash_identifiers'])
196 self.assertEqual(analysis_result, analysis.result) 189 self.assertEqual(analysis_result, analysis.result)
197 return analysis 190 return analysis
198 191
199
200 def testRunningAnalysis(self): 192 def testRunningAnalysis(self):
201 analysis_result = { 193 analysis_result = {
202 'found': True, 194 'found': True,
203 'suspected_cls': [], 195 'suspected_cls': [],
204 'other_data': 'data', 196 'other_data': 'data',
205 } 197 }
206 analysis_tags = { 198 analysis_tags = {
207 'found_suspects': True, 199 'found_suspects': True,
208 'has_regression_range': True, 200 'has_regression_range': True,
209 'solution': 'core', 201 'solution': 'core',
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 'unsupported_tag': '', 242 'unsupported_tag': '',
251 } 243 }
252 244
253 analysis = self._TestRunningAnalysisForResult( 245 analysis = self._TestRunningAnalysisForResult(
254 analysis_result, analysis_tags) 246 analysis_result, analysis_tags)
255 self.assertTrue(analysis.has_regression_range) 247 self.assertTrue(analysis.has_regression_range)
256 self.assertTrue(analysis.found_suspects) 248 self.assertTrue(analysis.found_suspects)
257 self.assertEqual('core', analysis.solution) 249 self.assertEqual('core', analysis.solution)
258 250
259 def testAnalysisAborted(self): 251 def testAnalysisAborted(self):
260 chrome_version = '1' 252 crash_data = DummyCrashData()
261 signature = 'signature' 253 crash_identifiers = crash_data['crash_identifiers']
262 platform = 'win'
263 crash_identifiers = {
264 'chrome_version': chrome_version,
265 'signature': signature,
266 'channel': 'canary',
267 'platform': platform,
268 'process_type': 'browser',
269 }
270 analysis = FracasCrashAnalysis.Create(crash_identifiers) 254 analysis = FracasCrashAnalysis.Create(crash_identifiers)
271 analysis.status = analysis_status.RUNNING 255 analysis.status = analysis_status.RUNNING
272 analysis.put() 256 analysis.put()
273 257
274 pipeline = crash_pipeline.CrashAnalysisPipeline(crash_identifiers, 'fracas') 258 pipeline = crash_pipeline.CrashAnalysisPipeline(FinditForFracas(),
275 pipeline._SetErrorIfAborted(True) 259 crash_identifiers)
260 pipeline._PutAbortedError()
276 analysis = FracasCrashAnalysis.Get(crash_identifiers) 261 analysis = FracasCrashAnalysis.Get(crash_identifiers)
277 self.assertEqual(analysis_status.ERROR, analysis.status) 262 self.assertEqual(analysis_status.ERROR, analysis.status)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698