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

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

Issue 2524633002: [Culprit-Finder] Refactor GitilesRepostory to make http_client required argument. (Closed)
Patch Set: Rebase Created 4 years 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 from collections import defaultdict 5 from collections import defaultdict
6 import copy 6 import copy
7 7
8 from common.dependency import Dependency 8 from common.dependency import Dependency
9 from common.dependency import DependencyRoll 9 from common.dependency import DependencyRoll
10 from common import chrome_dependency_fetcher 10 from common import chrome_dependency_fetcher
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 # taking revision_range apart isn't actually required for the tests, 103 # taking revision_range apart isn't actually required for the tests,
104 # since we mock GetDEPSRollsDict. So, really what we ought to do in the 104 # since we mock GetDEPSRollsDict. So, really what we ought to do in the
105 # long run is redesign things so that GetDEPSRollsDict takes the 105 # long run is redesign things so that GetDEPSRollsDict takes the
106 # CrashReport directly and pulls out the revision_range and platform 106 # CrashReport directly and pulls out the revision_range and platform
107 # itself; that way ChangelistClassifier.__call__ needn't worry about it, 107 # itself; that way ChangelistClassifier.__call__ needn't worry about it,
108 # allowing us to clean up the tests here. 108 # allowing us to clean up the tests here.
109 DUMMY_REPORT = CrashReport(None, None, None, Stacktrace(), (None, None)) 109 DUMMY_REPORT = CrashReport(None, None, None, Stacktrace(), (None, None))
110 110
111 class ChangelistClassifierTest(CrashTestSuite): 111 class ChangelistClassifierTest(CrashTestSuite):
112 112
113 def setUp(self):
114 super(ChangelistClassifierTest, self).setUp()
115 self.changelist_classifier = changelist_classifier.ChangelistClassifier(
116 GitilesRepository(self.GetMockHttpClient()), 7)
117
113 def testSkipAddedAndDeletedRegressionRolls(self): 118 def testSkipAddedAndDeletedRegressionRolls(self):
114 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 119 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
115 'GetDependency', lambda *_: {}) 120 'GetDependency', lambda *_: {})
116 dep_rolls = { 121 dep_rolls = {
117 'src/dep': DependencyRoll('src/dep1', 'https://url_dep1', None, '9'), 122 'src/dep': DependencyRoll('src/dep1', 'https://url_dep1', None, '9'),
118 'src/': DependencyRoll('src/', ('https://chromium.googlesource.com/' 123 'src/': DependencyRoll('src/', ('https://chromium.googlesource.com/'
119 'chromium/src.git'), '4', '5') 124 'chromium/src.git'), '4', '5')
120 } 125 }
121 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 126 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
122 'GetDependencyRollsDict', lambda *_: dep_rolls) 127 'GetDependencyRollsDict', lambda *_: dep_rolls)
123 128
124 passed_in_regression_deps_rolls = [] 129 passed_in_regression_deps_rolls = []
125 def _MockGetChangeLogsForFilesGroupedByDeps(regression_deps_rolls, *_): 130 def _MockGetChangeLogsForFilesGroupedByDeps(regression_deps_rolls, *_):
126 passed_in_regression_deps_rolls.append(regression_deps_rolls) 131 passed_in_regression_deps_rolls.append(regression_deps_rolls)
127 return {}, None 132 return {}, None
128 133
129 self.mock(changelist_classifier, 'GetChangeLogsForFilesGroupedByDeps', 134 self.mock(changelist_classifier, 'GetChangeLogsForFilesGroupedByDeps',
130 _MockGetChangeLogsForFilesGroupedByDeps) 135 _MockGetChangeLogsForFilesGroupedByDeps)
131 self.mock(changelist_classifier, 'GetStackInfosForFilesGroupedByDeps', 136 self.mock(changelist_classifier, 'GetStackInfosForFilesGroupedByDeps',
132 lambda *_: {}) 137 lambda *_: {})
133 self.mock(changelist_classifier, 'FindMatchResults', lambda *_: None) 138 self.mock(changelist_classifier, 'FindMatchResults', lambda *_: None)
134 139
135 cl_classifier = changelist_classifier.ChangelistClassifier( 140 self.changelist_classifier(CrashReport(crashed_version = '5',
136 GitilesRepository(), 7) 141 signature = 'sig',
137 cl_classifier(CrashReport(crashed_version = '5', 142 platform = 'canary',
138 signature = 'sig', 143 stacktrace = Stacktrace([CallStack(0)]),
139 platform = 'canary', 144 regression_range = ['4', '5']))
140 stacktrace = Stacktrace([CallStack(0)]),
141 regression_range = ['4', '5']))
142 expected_regression_deps_rolls = copy.deepcopy(dep_rolls) 145 expected_regression_deps_rolls = copy.deepcopy(dep_rolls)
143 146
144 # Regression of a dep added/deleted (old_revision/new_revision is None) can 147 # Regression of a dep added/deleted (old_revision/new_revision is None) can
145 # not be known for sure and this case rarely happens, so just filter them 148 # not be known for sure and this case rarely happens, so just filter them
146 # out. 149 # out.
147 del expected_regression_deps_rolls['src/dep'] 150 del expected_regression_deps_rolls['src/dep']
148 self.assertEqual(passed_in_regression_deps_rolls[0], 151 self.assertEqual(passed_in_regression_deps_rolls[0],
149 expected_regression_deps_rolls) 152 expected_regression_deps_rolls)
150 153
151 def testGetDepsInCrashStack(self): 154 def testGetDepsInCrashStack(self):
(...skipping 28 matching lines...) Expand all
180 def _MockGetChangeLogs(_, start_rev, end_rev): 183 def _MockGetChangeLogs(_, start_rev, end_rev):
181 if start_rev == '4' and end_rev == '5': 184 if start_rev == '4' and end_rev == '5':
182 return [DUMMY_CHANGELOG1, DUMMY_CHANGELOG2, DUMMY_CHANGELOG3] 185 return [DUMMY_CHANGELOG1, DUMMY_CHANGELOG2, DUMMY_CHANGELOG3]
183 186
184 return [] 187 return []
185 188
186 self.mock(GitilesRepository, 'GetChangeLogs', _MockGetChangeLogs) 189 self.mock(GitilesRepository, 'GetChangeLogs', _MockGetChangeLogs)
187 190
188 dep_file_to_changelogs, ignore_cls = ( 191 dep_file_to_changelogs, ignore_cls = (
189 changelist_classifier.GetChangeLogsForFilesGroupedByDeps( 192 changelist_classifier.GetChangeLogsForFilesGroupedByDeps(
190 regression_deps_rolls, stack_deps, GitilesRepository())) 193 regression_deps_rolls, stack_deps,
194 GitilesRepository(self.GetMockHttpClient())))
191 dep_file_to_changelogs_json = defaultdict(lambda: defaultdict(list)) 195 dep_file_to_changelogs_json = defaultdict(lambda: defaultdict(list))
192 for dep, file_to_changelogs in dep_file_to_changelogs.iteritems(): 196 for dep, file_to_changelogs in dep_file_to_changelogs.iteritems():
193 for file_path, changelogs in file_to_changelogs.iteritems(): 197 for file_path, changelogs in file_to_changelogs.iteritems():
194 for changelog in changelogs: 198 for changelog in changelogs:
195 dep_file_to_changelogs_json[dep][file_path].append(changelog.ToDict()) 199 dep_file_to_changelogs_json[dep][file_path].append(changelog.ToDict())
196 200
197 expected_dep_file_to_changelogs_json = { 201 expected_dep_file_to_changelogs_json = {
198 'src/': { 202 'src/': {
199 'a.cc': [DUMMY_CHANGELOG1.ToDict()], 203 'a.cc': [DUMMY_CHANGELOG1.ToDict()],
200 'f.cc': [DUMMY_CHANGELOG3.ToDict()] 204 'f.cc': [DUMMY_CHANGELOG3.ToDict()]
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 'project_path': 'src/', 296 'project_path': 'src/',
293 'author': 'r@chromium.org', 297 'author': 'r@chromium.org',
294 'time': 'Thu Mar 31 21:24:43 2016', 298 'time': 'Thu Mar 31 21:24:43 2016',
295 'reasons': None, 299 'reasons': None,
296 'confidence': None, 300 'confidence': None,
297 'changed_files': None 301 'changed_files': None
298 }] 302 }]
299 303
300 match_results = changelist_classifier.FindMatchResults( 304 match_results = changelist_classifier.FindMatchResults(
301 dep_file_to_changelogs, dep_file_to_stack_infos, stack_deps, 305 dep_file_to_changelogs, dep_file_to_stack_infos, stack_deps,
302 GitilesRepository()) 306 GitilesRepository(self.GetMockHttpClient()))
303 self.assertListEqual([result.ToDict() for result in match_results], 307 self.assertListEqual([result.ToDict() for result in match_results],
304 expected_match_results) 308 expected_match_results)
305 309
306 # TODO(http://crbug.com/659346): why do these mocks give coverage 310 # TODO(http://crbug.com/659346): why do these mocks give coverage
307 # failures? That's almost surely hiding a bug in the tests themselves. 311 # failures? That's almost surely hiding a bug in the tests themselves.
308 def testFindItForCrashNoRegressionRange(self): # pragma: no cover 312 def testFindItForCrashNoRegressionRange(self): # pragma: no cover
309 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 313 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
310 'GetDependencyRollsDict', lambda *_: {}) 314 'GetDependencyRollsDict', lambda *_: {})
311 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 315 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
312 'GetDependency', lambda *_: {}) 316 'GetDependency', lambda *_: {})
313 cl_classifier = changelist_classifier.ChangelistClassifier(7,
314 GitilesRepository())
315 # N.B., for this one test we really do want regression_range=None. 317 # N.B., for this one test we really do want regression_range=None.
316 report = DUMMY_REPORT._replace(regression_range=None) 318 report = DUMMY_REPORT._replace(regression_range=None)
317 self.assertListEqual(cl_classifier(report), []) 319 self.assertListEqual(self.changelist_classifier(report), [])
318 320
319 def testFindItForCrashNoMatchFound(self): 321 def testFindItForCrashNoMatchFound(self):
320 self.mock(changelist_classifier, 'FindMatchResults', lambda *_: []) 322 self.mock(changelist_classifier, 'FindMatchResults', lambda *_: [])
321 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 323 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
322 'GetDependencyRollsDict', 324 'GetDependencyRollsDict',
323 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 325 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
324 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 326 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
325 'GetDependency', lambda *_: {}) 327 'GetDependency', lambda *_: {})
326 cl_classifier = changelist_classifier.ChangelistClassifier(7, 328 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), [])
327 GitilesRepository())
328 self.assertListEqual(cl_classifier(DUMMY_REPORT), [])
329 329
330 def testFindItForCrash(self): 330 def testFindItForCrash(self):
331 331
332 def _MockFindMatchResults(*_): 332 def _MockFindMatchResults(*_):
333 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') 333 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '')
334 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) 334 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
335 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) 335 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
336 match_result1.file_to_stack_infos = { 336 match_result1.file_to_stack_infos = {
337 'a.cc': [(frame1, 0), (frame2, 0)] 337 'a.cc': [(frame1, 0), (frame2, 0)]
338 } 338 }
(...skipping 11 matching lines...) Expand all
350 } 350 }
351 351
352 return [match_result1, match_result2] 352 return [match_result1, match_result2]
353 353
354 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 354 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
355 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 355 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
356 'GetDependencyRollsDict', 356 'GetDependencyRollsDict',
357 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 357 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
358 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 358 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
359 'GetDependency', lambda *_: {}) 359 'GetDependency', lambda *_: {})
360 cl_classifier = changelist_classifier.ChangelistClassifier(7, 360 results = self.changelist_classifier(DUMMY_REPORT)
361 GitilesRepository())
362 results = cl_classifier(DUMMY_REPORT)
363 expected_match_results = [ 361 expected_match_results = [
364 { 362 {
365 'reasons': [('TopFrameIndex', 1.0, 'Top frame is #0'), 363 'reasons': [('TopFrameIndex', 1.0, 'Top frame is #0'),
366 ('MinDistance', 1, 'Minimum distance is 0')], 364 ('MinDistance', 1, 'Minimum distance is 0')],
367 'changed_files': [{'info': 'Minimum distance (LOC) 0, frame #0', 365 'changed_files': [{'info': 'Minimum distance (LOC) 0, frame #0',
368 'blame_url': None, 'file': 'a.cc'}], 366 'blame_url': None, 'file': 'a.cc'}],
369 'time': 'Thu Mar 31 21:24:43 2016', 367 'time': 'Thu Mar 31 21:24:43 2016',
370 'author': 'r@chromium.org', 368 'author': 'r@chromium.org',
371 'url': 'https://repo.test/+/1', 369 'url': 'https://repo.test/+/1',
372 'project_path': 'src/', 370 'project_path': 'src/',
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 407
410 return [match_result1, match_result2, match_result3] 408 return [match_result1, match_result2, match_result3]
411 409
412 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 410 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
413 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 411 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
414 'GetDependencyRollsDict', 412 'GetDependencyRollsDict',
415 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 413 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
416 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 414 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
417 'GetDependency', lambda *_: {}) 415 'GetDependency', lambda *_: {})
418 416
419 cl_classifier = changelist_classifier.ChangelistClassifier(7, 417 results = self.changelist_classifier(DUMMY_REPORT)
420 GitilesRepository())
421 results = cl_classifier(DUMMY_REPORT)
422 expected_match_results = [ 418 expected_match_results = [
423 { 419 {
424 'author': 'r@chromium.org', 420 'author': 'r@chromium.org',
425 'changed_files': [ 421 'changed_files': [
426 { 422 {
427 'blame_url': None, 423 'blame_url': None,
428 'file': 'a.cc', 424 'file': 'a.cc',
429 'info': 'Minimum distance (LOC) 1, frame #0' 425 'info': 'Minimum distance (LOC) 1, frame #0'
430 } 426 }
431 ], 427 ],
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 464
469 return [match_result1, match_result2] 465 return [match_result1, match_result2]
470 466
471 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 467 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
472 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 468 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
473 'GetDependencyRollsDict', 469 'GetDependencyRollsDict',
474 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 470 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
475 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 471 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
476 'GetDependency', lambda *_: {}) 472 'GetDependency', lambda *_: {})
477 473
478 cl_classifier = changelist_classifier.ChangelistClassifier(7, 474 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), [])
479 GitilesRepository())
480 self.assertListEqual(cl_classifier(DUMMY_REPORT), [])
OLDNEW
« no previous file with comments | « appengine/findit/crash/crash_pipeline.py ('k') | appengine/findit/crash/test/findit_for_chromecrash_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698