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

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

Issue 2673993003: [Predator] Pass config as argument to findit. (Closed)
Patch Set: Created 3 years, 10 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 4
5 import mock 5 import mock
6 6
7 from common import chrome_dependency_fetcher 7 from common import chrome_dependency_fetcher
8 from common.dependency import DependencyRoll 8 from common.dependency import DependencyRoll
9 from crash import chromecrash_parser 9 from crash import chromecrash_parser
10 from crash import detect_regression_range 10 from crash import detect_regression_range
11 from crash import findit 11 from crash import findit
12 from crash import findit_for_chromecrash 12 from crash import findit_for_chromecrash
13 from crash.loglinear.changelist_classifier import LogLinearChangelistClassifier 13 from crash.loglinear.changelist_classifier import LogLinearChangelistClassifier
14 from crash.chromecrash_parser import ChromeCrashParser 14 from crash.chromecrash_parser import ChromeCrashParser
15 from crash.component_classifier import ComponentClassifier 15 from crash.component_classifier import ComponentClassifier
16 from crash.crash_report import CrashReport 16 from crash.crash_report import CrashReport
17 from crash.culprit import Culprit 17 from crash.culprit import Culprit
18 from crash.findit_for_chromecrash import FinditForChromeCrash 18 from crash.findit_for_chromecrash import FinditForChromeCrash
19 from crash.findit_for_chromecrash import FinditForFracas 19 from crash.findit_for_chromecrash import FinditForFracas
20 from crash.project_classifier import ProjectClassifier 20 from crash.project_classifier import ProjectClassifier
21 from crash.suspect import Suspect 21 from crash.suspect import Suspect
22 from crash.stacktrace import CallStack 22 from crash.stacktrace import CallStack
23 from crash.stacktrace import Stacktrace 23 from crash.stacktrace import Stacktrace
24 from crash.test.predator_testcase import PredatorTestCase 24 from crash.test.predator_testcase import PredatorTestCase
25 from crash.type_enums import CrashClient 25 from crash.type_enums import CrashClient
26 from gae_libs.http.http_client_appengine import HttpClientAppengine 26 from gae_libs.http.http_client_appengine import HttpClientAppengine
27 from libs.gitiles.gitiles_repository import GitilesRepository 27 from libs.gitiles.gitiles_repository import GitilesRepository
28 from model import analysis_status 28 from model import analysis_status
29 from model.crash.crash_analysis import CrashAnalysis 29 from model.crash.crash_analysis import CrashAnalysis
30 from model.crash.crash_config import CrashConfig
30 from model.crash.fracas_crash_analysis import FracasCrashAnalysis 31 from model.crash.fracas_crash_analysis import FracasCrashAnalysis
31 32
32 MOCK_GET_REPOSITORY = lambda _: None # pragma: no cover 33 MOCK_GET_REPOSITORY = lambda _: None # pragma: no cover
33 34
35
34 class _FinditForChromeCrash(FinditForChromeCrash): # pylint: disable = W 36 class _FinditForChromeCrash(FinditForChromeCrash): # pylint: disable = W
35 # We allow overriding the default ``get_repository`` because one unittest 37 # We allow overriding the default ``get_repository`` because one unittest
36 # needs to. 38 # needs to.
37 def __init__(self, get_repository=MOCK_GET_REPOSITORY): 39 def __init__(self, get_repository=MOCK_GET_REPOSITORY, config=None):
38 super(_FinditForChromeCrash, self).__init__(get_repository) 40 super(_FinditForChromeCrash, self).__init__(get_repository, config)
39 41
40 @classmethod 42 @classmethod
41 def _ClientID(cls): # pragma: no cover 43 def _ClientID(cls): # pragma: no cover
42 """Avoid throwing a NotImplementedError. 44 """Avoid throwing a NotImplementedError.
43 45
44 Since this method is called from ``FinditForChromeCrash.__init__`` 46 Since this method is called from ``FinditForChromeCrash.__init__``
45 in order to construct the Azalea object, we need to not throw 47 in order to construct the Azalea object, we need to not throw
46 exceptions since we want to be able to test the FinditForChromeCrash 48 exceptions since we want to be able to test the FinditForChromeCrash
47 class itself. 49 class itself.
48 """ 50 """
49 return '' 51 return 'fracas'
50 52
51 @property 53 @property
52 def config(self): 54 def client_config(self):
53 """Avoid returning None. 55 """Avoid returning None.
54 56
55 The default ``Findit.config`` will return None if the client 57 The default ``Findit.client_config`` will return None if the client
56 id is not found in the CrashConfig. This in turn will cause 58 id is not found in the CrashConfig. This in turn will cause
57 ``FinditForChromeCrash.__init__`` to crash, since NoneType doesn't 59 ``FinditForChromeCrash.__init__`` to crash, since NoneType doesn't
58 have a ``get`` method. In general it's fine for things to crash, since 60 have a ``get`` method. In general it's fine for things to crash, since
59 noone should make instances of Findit subclasses which don't define 61 noone should make instances of Findit subclasses which don't define
60 ``_clientID``; but for this test suite, we want to permit instances 62 ``_clientID``; but for this test suite, we want to permit instances
61 of FinditForChromeCrash, so that we can test that class directly. 63 of FinditForChromeCrash, so that we can test that class directly.
62 """ 64 """
63 return {} 65 return {}
64 66
65 67
66 def _FinditForFracas(): 68 def _FinditForFracas(config=None):
67 """A helper to pass in the standard pipeline class.""" 69 """A helper to pass in the standard pipeline class."""
68 return FinditForFracas(MOCK_GET_REPOSITORY) 70 return FinditForFracas(MOCK_GET_REPOSITORY, config or {})
69 71
70 72
71 class FinditForChromeCrashTest(PredatorTestCase): 73 class FinditForChromeCrashTest(PredatorTestCase):
72 74
73 # TODO(wrengr): what was the purpose of this test? As written it's 75 # TODO(wrengr): what was the purpose of this test? As written it's
74 # just testing that mocking works. I'm guessing it was to check that 76 # just testing that mocking works. I'm guessing it was to check that
75 # we fail when the analysis is for the wrong client_id; but if so, 77 # we fail when the analysis is for the wrong client_id; but if so,
76 # then we shouldn't need to mock FindCulprit... 78 # then we shouldn't need to mock FindCulprit...
77 def testFindCulprit(self): 79 def testFindCulprit(self):
78 self.mock(FinditForChromeCrash, 'FindCulprit', lambda self, *_: None) 80 self.mock(FinditForChromeCrash, 'FindCulprit', lambda self, *_: None)
79 81
80 # TODO(wrengr): would be less fragile to call 82 # TODO(wrengr): would be less fragile to call
81 # FinditForFracas.CreateAnalysis instead; though if I'm right about 83 # FinditForFracas.CreateAnalysis instead; though if I'm right about
82 # the original purpose of this test, then this is one of the few 84 # the original purpose of this test, then this is one of the few
83 # places where calling FracasCrashAnalysis directly would actually 85 # places where calling FracasCrashAnalysis directly would actually
84 # make sense. 86 # make sense.
85 analysis = FracasCrashAnalysis.Create({'signature': 'sig'}) 87 analysis = FracasCrashAnalysis.Create({'signature': 'sig'})
86 # TODO(wrengr): shouldn't FracasCrashAnalysis.Create already have set 88 # TODO(wrengr): shouldn't FracasCrashAnalysis.Create already have set
87 # the client_id? 89 # the client_id?
88 analysis.client_id = CrashClient.FRACAS 90 analysis.client_id = CrashClient.FRACAS
89 91
90 findit_client = ( 92 findit_client = _FinditForChromeCrash(
91 _FinditForChromeCrash(GitilesRepository.Factory(HttpClientAppengine()))) 93 GitilesRepository.Factory(HttpClientAppengine()),
94 config=CrashConfig.Get())
92 self.assertIsNone(findit_client.FindCulprit(analysis)) 95 self.assertIsNone(findit_client.FindCulprit(analysis))
93 96
94 97
95 class FinditForFracasTest(PredatorTestCase): 98 class FinditForFracasTest(PredatorTestCase):
96 99
100 def setUp(self):
101 super(FinditForFracasTest, self).setUp()
102 self.findit = _FinditForFracas(config=CrashConfig.Get())
103
97 def testPlatformRename(self): 104 def testPlatformRename(self):
98 self.assertEqual(_FinditForFracas().RenamePlatform('linux'), 'unix') 105 self.assertEqual(self.findit.RenamePlatform('linux'), 'unix')
99 106
100 def testCheckPolicyUnsupportedPlatform(self): 107 def testCheckPolicyUnsupportedPlatform(self):
101 self.assertIsNone(_FinditForFracas().CheckPolicy(self.GetDummyCrashData( 108 self.assertIsNone(self.findit.CheckPolicy(self.GetDummyCrashData(
102 platform = 'unsupported_platform'))) 109 platform = 'unsupported_platform')))
103 110
104 def testCheckPolicyBlacklistedSignature(self): 111 def testCheckPolicyBlacklistedSignature(self):
105 self.assertIsNone(_FinditForFracas().CheckPolicy(self.GetDummyCrashData( 112 self.assertIsNone(self.findit.CheckPolicy(self.GetDummyCrashData(
106 signature = 'Blacklist marker signature'))) 113 signature = 'Blacklist marker signature')))
107 114
108 def testCheckPolicyPlatformRename(self): 115 def testCheckPolicyPlatformRename(self):
109 new_crash_data = _FinditForFracas().CheckPolicy(self.GetDummyCrashData( 116 new_crash_data = self.findit.CheckPolicy(self.GetDummyCrashData(
110 platform = 'linux')) 117 platform = 'linux'))
111 self.assertIsNotNone(new_crash_data, 118 self.assertIsNotNone(new_crash_data,
112 'FinditForFracas.CheckPolicy unexpectedly returned None') 119 'FinditForFracas.CheckPolicy unexpectedly returned None')
113 self.assertEqual(new_crash_data['platform'], 'unix') 120 self.assertEqual(new_crash_data['platform'], 'unix')
114 121
115 def testCreateAnalysis(self): 122 def testCreateAnalysis(self):
116 self.assertIsNotNone(_FinditForFracas().CreateAnalysis( 123 self.assertIsNotNone(self.findit.CreateAnalysis(
117 {'signature': 'sig'})) 124 {'signature': 'sig'}))
118 125
119 def testGetAnalysis(self): 126 def testGetAnalysis(self):
120 crash_identifiers = {'signature': 'sig'} 127 crash_identifiers = {'signature': 'sig'}
121 # TODO(wrengr): would be less fragile to call 128 # TODO(wrengr): would be less fragile to call
122 # FinditForFracas.CreateAnalysis instead. 129 # FinditForFracas.CreateAnalysis instead.
123 analysis = FracasCrashAnalysis.Create(crash_identifiers) 130 analysis = FracasCrashAnalysis.Create(crash_identifiers)
124 analysis.put() 131 analysis.put()
125 self.assertEqual(_FinditForFracas().GetAnalysis(crash_identifiers), 132 self.assertEqual(self.findit.GetAnalysis(crash_identifiers),
126 analysis) 133 analysis)
127 134
128 def testInitializeAnalysisForFracas(self): 135 def testInitializeAnalysisForFracas(self):
129 crash_data = self.GetDummyCrashData(platform = 'linux') 136 crash_data = self.GetDummyCrashData(platform = 'linux')
130 crash_identifiers = crash_data['crash_identifiers'] 137 crash_identifiers = crash_data['crash_identifiers']
131 138
132 findit_client = _FinditForFracas() 139 self.findit = self.findit
133 analysis = findit_client.CreateAnalysis(crash_identifiers) 140 analysis = self.findit.CreateAnalysis(crash_identifiers)
134 findit_client._InitializeAnalysis(analysis, crash_data) 141 self.findit._InitializeAnalysis(analysis, crash_data)
135 analysis.put() 142 analysis.put()
136 analysis = findit_client.GetAnalysis(crash_identifiers) 143 analysis = self.findit.GetAnalysis(crash_identifiers)
137 self.assertIsNotNone(analysis, 144 self.assertIsNotNone(analysis,
138 'FinditForFracas.GetAnalysis unexpectedly returned None') 145 'FinditForFracas.GetAnalysis unexpectedly returned None')
139 146
140 self.assertEqual(analysis.crashed_version, crash_data['chrome_version']) 147 self.assertEqual(analysis.crashed_version, crash_data['chrome_version'])
141 self.assertEqual(analysis.signature, crash_data['signature']) 148 self.assertEqual(analysis.signature, crash_data['signature'])
142 self.assertEqual(analysis.platform, crash_data['platform']) 149 self.assertEqual(analysis.platform, crash_data['platform'])
143 self.assertEqual(analysis.stack_trace, crash_data['stack_trace']) 150 self.assertEqual(analysis.stack_trace, crash_data['stack_trace'])
144 channel = crash_data['customized_data'].get('channel', None) 151 channel = crash_data['customized_data'].get('channel', None)
145 self.assertIsNotNone(channel, 152 self.assertIsNotNone(channel,
146 'channel is unexpectedly not defined in crash_data') 153 'channel is unexpectedly not defined in crash_data')
147 self.assertEqual(analysis.channel, channel) 154 self.assertEqual(analysis.channel, channel)
148 155
149 def testNeedsNewAnalysisIsTrueIfNoAnalysisYet(self): 156 def testNeedsNewAnalysisIsTrueIfNoAnalysisYet(self):
150 self.assertTrue(_FinditForFracas()._NeedsNewAnalysis( 157 self.assertTrue(self.findit._NeedsNewAnalysis(
151 self.GetDummyCrashData())) 158 self.GetDummyCrashData()))
152 159
153 def testNeedsNewAnalysisIsTrueIfLastOneFailed(self): 160 def testNeedsNewAnalysisIsTrueIfLastOneFailed(self):
154 findit_client = _FinditForFracas()
155 crash_data = self.GetDummyCrashData() 161 crash_data = self.GetDummyCrashData()
156 analysis = findit_client.CreateAnalysis(crash_data['crash_identifiers']) 162 analysis = self.findit.CreateAnalysis(crash_data['crash_identifiers'])
157 analysis.status = analysis_status.ERROR 163 analysis.status = analysis_status.ERROR
158 analysis.put() 164 analysis.put()
159 self.assertTrue(findit_client._NeedsNewAnalysis(crash_data)) 165 self.assertTrue(self.findit._NeedsNewAnalysis(crash_data))
160 166
161 def testNeedsNewAnalysisIsFalseIfLastOneIsNotFailed(self): 167 def testNeedsNewAnalysisIsFalseIfLastOneIsNotFailed(self):
162 findit_client = _FinditForFracas()
163 crash_data = self.GetDummyCrashData() 168 crash_data = self.GetDummyCrashData()
164 crash_identifiers = crash_data['crash_identifiers'] 169 crash_identifiers = crash_data['crash_identifiers']
165 for status in (analysis_status.PENDING, analysis_status.RUNNING, 170 for status in (analysis_status.PENDING, analysis_status.RUNNING,
166 analysis_status.COMPLETED, analysis_status.SKIPPED): 171 analysis_status.COMPLETED, analysis_status.SKIPPED):
167 analysis = findit_client.CreateAnalysis(crash_identifiers) 172 analysis = self.findit.CreateAnalysis(crash_identifiers)
168 analysis.status = status 173 analysis.status = status
169 analysis.put() 174 analysis.put()
170 self.assertFalse(findit_client._NeedsNewAnalysis(crash_data)) 175 self.assertFalse(self.findit._NeedsNewAnalysis(crash_data))
171 176
172 def testFindCulpritForChromeCrashEmptyStacktrace(self): 177 def testFindCulpritForChromeCrashEmptyStacktrace(self):
173 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 178 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
174 'GetDependency', lambda *_: {}) 179 'GetDependency', lambda *_: {})
175 self.mock(ChromeCrashParser, 'Parse', lambda *_: None) 180 self.mock(ChromeCrashParser, 'Parse', lambda *_: None)
176 181
177 analysis = CrashAnalysis() 182 analysis = CrashAnalysis()
178 analysis.signature = 'signature' 183 analysis.signature = 'signature'
179 analysis.platform = 'win' 184 analysis.platform = 'win'
180 analysis.stack_trace = 'frame1\nframe2' 185 analysis.stack_trace = 'frame1\nframe2'
181 analysis.crashed_version = '50.0.1234.0' 186 analysis.crashed_version = '50.0.1234.0'
182 analysis.historical_metadata = [ 187 analysis.historical_metadata = [
183 {'chrome_version': '51.0.1234.0', 'cpm': 0.6}] 188 {'chrome_version': '51.0.1234.0', 'cpm': 0.6}]
184 self.assertIsNone(_FinditForChromeCrash().FindCulprit(analysis)) 189 self.assertIsNone(_FinditForChromeCrash(
190 config=CrashConfig.Get()).FindCulprit(analysis))
185 191
186 # TODO(http://crbug.com/659346): why do these mocks give coverage 192 # TODO(http://crbug.com/659346): why do these mocks give coverage
187 # failures? That's almost surely hiding a bug in the tests themselves. 193 # failures? That's almost surely hiding a bug in the tests themselves.
188 def testFindCulpritForChromeCrash(self): # pragma: no cover 194 def testFindCulpritForChromeCrash(self): # pragma: no cover
189 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 195 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
190 'GetDependency', lambda *_: {}) 196 'GetDependency', lambda *_: {})
191 stack = CallStack(0) 197 stack = CallStack(0)
192 self.mock(ChromeCrashParser, 'Parse', 198 self.mock(ChromeCrashParser, 'Parse',
193 lambda *_: Stacktrace([stack], stack)) 199 lambda *_: Stacktrace([stack], stack))
194 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 200 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
(...skipping 22 matching lines...) Expand all
217 self._testFindCulpritForChromeCrashFails() 223 self._testFindCulpritForChromeCrashFails()
218 224
219 def _testFindCulpritForChromeCrashSucceeds(self, dummy_suspect): 225 def _testFindCulpritForChromeCrashSucceeds(self, dummy_suspect):
220 analysis = CrashAnalysis() 226 analysis = CrashAnalysis()
221 analysis.signature = 'signature' 227 analysis.signature = 'signature'
222 analysis.platform = 'win' 228 analysis.platform = 'win'
223 analysis.stack_trace = 'frame1\nframe2' 229 analysis.stack_trace = 'frame1\nframe2'
224 analysis.crashed_version = '50.0.1234.0' 230 analysis.crashed_version = '50.0.1234.0'
225 dummy_regression_range = ('50.0.1233.0', '50.0.1234.0') 231 dummy_regression_range = ('50.0.1233.0', '50.0.1234.0')
226 analysis.regression_range = dummy_regression_range 232 analysis.regression_range = dummy_regression_range
227 culprit = _FinditForChromeCrash().FindCulprit(analysis) 233 culprit = _FinditForChromeCrash(config=CrashConfig.Get()).FindCulprit(
234 analysis)
228 self.assertIsNotNone(culprit, 'FindCulprit failed unexpectedly') 235 self.assertIsNotNone(culprit, 'FindCulprit failed unexpectedly')
229 suspects, tag = culprit.ToDicts() 236 suspects, tag = culprit.ToDicts()
230 237
231 expected_suspects = { 238 expected_suspects = {
232 'found': True, 239 'found': True,
233 'suspected_cls': [dummy_suspect.ToDict()], 240 'suspected_cls': [dummy_suspect.ToDict()],
234 'regression_range': dummy_regression_range 241 'regression_range': dummy_regression_range
235 } 242 }
236 expected_tag = { 243 expected_tag = {
237 'found_suspects': True, 244 'found_suspects': True,
238 'found_project': False, 245 'found_project': False,
239 'found_components': False, 246 'found_components': False,
240 'has_regression_range': True, 247 'has_regression_range': True,
241 'solution': 'core_algorithm', 248 'solution': 'core_algorithm',
242 } 249 }
243 250
244 self.assertDictEqual(expected_suspects, suspects) 251 self.assertDictEqual(expected_suspects, suspects)
245 self.assertDictEqual(expected_tag, tag) 252 self.assertDictEqual(expected_tag, tag)
246 253
247 def _testFindCulpritForChromeCrashFails(self): 254 def _testFindCulpritForChromeCrashFails(self):
248 analysis = CrashAnalysis() 255 analysis = CrashAnalysis()
249 analysis.signature = 'signature' 256 analysis.signature = 'signature'
250 analysis.platform = 'win' 257 analysis.platform = 'win'
251 analysis.stack_trace = 'frame1\nframe2' 258 analysis.stack_trace = 'frame1\nframe2'
252 analysis.crashed_version = '50.0.1234.0' 259 analysis.crashed_version = '50.0.1234.0'
253 # N.B., analysis.regression_range is None 260 # N.B., analysis.regression_range is None
254 suspects, tag = _FinditForChromeCrash().FindCulprit(analysis).ToDicts() 261 suspects, tag = _FinditForChromeCrash(config=CrashConfig.Get()).FindCulprit(
262 analysis).ToDicts()
255 263
256 expected_suspects = {'found': False} 264 expected_suspects = {'found': False}
257 expected_tag = { 265 expected_tag = {
258 'found_suspects': False, 266 'found_suspects': False,
259 'found_project': False, 267 'found_project': False,
260 'found_components': False, 268 'found_components': False,
261 'has_regression_range': False, 269 'has_regression_range': False,
262 'solution': 'core_algorithm', 270 'solution': 'core_algorithm',
263 } 271 }
264 272
265 self.assertDictEqual(expected_suspects, suspects) 273 self.assertDictEqual(expected_suspects, suspects)
266 self.assertDictEqual(expected_tag, tag) 274 self.assertDictEqual(expected_tag, tag)
267 275
268 @mock.patch('google.appengine.ext.ndb.Key.urlsafe') 276 @mock.patch('google.appengine.ext.ndb.Key.urlsafe')
269 @mock.patch('common.appengine_util.GetDefaultVersionHostname') 277 @mock.patch('common.appengine_util.GetDefaultVersionHostname')
270 def testProcessResultForPublishing(self, mocked_get_default_host, 278 def testProcessResultForPublishing(self, mocked_get_default_host,
271 mocked_urlsafe): 279 mocked_urlsafe):
272 mocked_host = 'http://host' 280 mocked_host = 'http://host'
273 mocked_get_default_host.return_value = mocked_host 281 mocked_get_default_host.return_value = mocked_host
274 urlsafe_key = 'abcde' 282 urlsafe_key = 'abcde'
275 mocked_urlsafe.return_value = urlsafe_key 283 mocked_urlsafe.return_value = urlsafe_key
276 284
277 crash_identifiers = {'signature': 'sig'} 285 crash_identifiers = {'signature': 'sig'}
278 analysis = FracasCrashAnalysis.Create(crash_identifiers) 286 analysis = FracasCrashAnalysis.Create(crash_identifiers)
279 analysis.result = {'other': 'data'} 287 analysis.result = {'other': 'data'}
280 findit_object = FinditForFracas(MOCK_GET_REPOSITORY) 288 findit_object = _FinditForFracas(config=CrashConfig.Get())
281 expected_processed_suspect = { 289 expected_processed_suspect = {
282 'client_id': findit_object.client_id, 290 'client_id': findit_object.client_id,
283 'crash_identifiers': {'signature': 'sig'}, 291 'crash_identifiers': {'signature': 'sig'},
284 'result': { 292 'result': {
285 'feedback_url': ( 293 'feedback_url': (
286 findit_for_chromecrash._FRACAS_FEEDBACK_URL_TEMPLATE % ( 294 findit_for_chromecrash._FRACAS_FEEDBACK_URL_TEMPLATE % (
287 mocked_host, urlsafe_key)), 295 mocked_host, urlsafe_key)),
288 'other': 'data' 296 'other': 'data'
289 } 297 }
290 } 298 }
291 299
292 self.assertDictEqual(findit_object.GetPublishableResult(crash_identifiers, 300 self.assertDictEqual(findit_object.GetPublishableResult(crash_identifiers,
293 analysis), 301 analysis),
294 expected_processed_suspect) 302 expected_processed_suspect)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698