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

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

Issue 2449853012: [Predator] Fix bug in min_distance after refactor and add back skip added/deleted deps. (Closed)
Patch Set: Add culprit test. Created 4 years, 1 month 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 7
7 from common.dependency import Dependency 8 from common.dependency import Dependency
8 from common.dependency import DependencyRoll 9 from common.dependency import DependencyRoll
9 from common.http_client_appengine import HttpClientAppengine
10 from common import chrome_dependency_fetcher 10 from common import chrome_dependency_fetcher
11 from crash import changelist_classifier
11 from crash.crash_report import CrashReport 12 from crash.crash_report import CrashReport
12 from crash import changelist_classifier 13 from crash.results import AnalysisInfo
13 from crash.results import MatchResult 14 from crash.results import MatchResult
14 from crash.stacktrace import CallStack 15 from crash.stacktrace import CallStack
15 from crash.stacktrace import StackFrame 16 from crash.stacktrace import StackFrame
16 from crash.stacktrace import Stacktrace 17 from crash.stacktrace import Stacktrace
17 from crash.test.crash_test_suite import CrashTestSuite 18 from crash.test.crash_test_suite import CrashTestSuite
18 from lib.gitiles.blame import Blame 19 from lib.gitiles.blame import Blame
19 from lib.gitiles.blame import Region 20 from lib.gitiles.blame import Region
20 from lib.gitiles.change_log import ChangeLog 21 from lib.gitiles.change_log import ChangeLog
21 from lib.gitiles.gitiles_repository import GitilesRepository 22 from lib.gitiles.gitiles_repository import GitilesRepository
22 23
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 # taking revision_range apart isn't actually required for the tests, 103 # taking revision_range apart isn't actually required for the tests,
103 # 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
104 # long run is redesign things so that GetDEPSRollsDict takes the 105 # long run is redesign things so that GetDEPSRollsDict takes the
105 # CrashReport directly and pulls out the revision_range and platform 106 # CrashReport directly and pulls out the revision_range and platform
106 # itself; that way ChangelistClassifier.__call__ needn't worry about it, 107 # itself; that way ChangelistClassifier.__call__ needn't worry about it,
107 # allowing us to clean up the tests here. 108 # allowing us to clean up the tests here.
108 DUMMY_REPORT = CrashReport(None, None, None, Stacktrace(), (None, None)) 109 DUMMY_REPORT = CrashReport(None, None, None, Stacktrace(), (None, None))
109 110
110 class ChangelistClassifierTest(CrashTestSuite): 111 class ChangelistClassifierTest(CrashTestSuite):
111 112
113 def testSkipAddedAndDeletedRegressionRolls(self):
114 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
115 'GetDependency', lambda *_: {})
116 dep_rolls = {
117 'src/dep': DependencyRoll('src/dep1', 'https://url_dep1', None, '9'),
118 'src/': DependencyRoll('src/', ('https://chromium.googlesource.com/'
119 'chromium/src.git'), '4', '5')
120 }
121 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
122 'GetDependencyRollsDict', lambda *_: dep_rolls)
123
124 passed_in_regression_deps_rolls = []
125 def _MockGetChangeLogsForFilesGroupedByDeps(regression_deps_rolls, *_):
126 passed_in_regression_deps_rolls.append(regression_deps_rolls)
127 return {}, None
128
129 self.mock(changelist_classifier, 'GetChangeLogsForFilesGroupedByDeps',
130 _MockGetChangeLogsForFilesGroupedByDeps)
131 self.mock(changelist_classifier, 'GetStackInfosForFilesGroupedByDeps',
132 lambda *_: {})
133 self.mock(changelist_classifier, 'FindMatchResults', lambda *_: None)
134
135 cl_classifier = changelist_classifier.ChangelistClassifier(
136 GitilesRepository(), 7)
137 cl_classifier(CrashReport(crashed_version = '5',
138 signature = 'sig',
139 platform = 'canary',
140 stacktrace = Stacktrace([CallStack(0)]),
141 regression_range = ['4', '5']))
142 expected_regression_deps_rolls = copy.deepcopy(dep_rolls)
143 del expected_regression_deps_rolls['src/dep']
wrengr 2016/10/31 23:48:35 Could you add a comment about why this ``del`` is
Sharu Jiang 2016/11/01 23:54:09 Done.
144 self.assertEqual(passed_in_regression_deps_rolls[0],
145 expected_regression_deps_rolls)
146
112 def testGetDepsInCrashStack(self): 147 def testGetDepsInCrashStack(self):
113 crash_stack = CallStack(0) 148 crash_stack = CallStack(0)
114 crash_stack.extend([ 149 crash_stack.extend([
115 StackFrame(0, 'src/', 'func0', 'f0.cc', 'src/f0.cc', [1]), 150 StackFrame(0, 'src/', 'func0', 'f0.cc', 'src/f0.cc', [1]),
116 StackFrame(1, 'src/', 'func1', 'f1.cc', 'src/f1.cc', [2, 3]), 151 StackFrame(1, 'src/', 'func1', 'f1.cc', 'src/f1.cc', [2, 3]),
117 StackFrame(1, '', 'func2', 'f2.cc', 'src/f2.cc', [2, 3]), 152 StackFrame(1, '', 'func2', 'f2.cc', 'src/f2.cc', [2, 3]),
118 ]) 153 ])
119 crash_deps = {'src/': Dependency('src/', 'https://chromium_repo', '1'), 154 crash_deps = {'src/': Dependency('src/', 'https://chromium_repo', '1'),
120 'src/v8/': Dependency('src/v8/', 'https://v8_repo', '2')} 155 'src/v8/': Dependency('src/v8/', 'https://v8_repo', '2')}
121 156
122 expected_stack_deps = {'src/': crash_deps['src/']} 157 expected_stack_deps = {'src/': crash_deps['src/']}
123 158
124 self.assertDictEqual( 159 self.assertDictEqual(
125 changelist_classifier.GetDepsInCrashStack(crash_stack, crash_deps), 160 changelist_classifier.GetDepsInCrashStack(crash_stack, crash_deps),
126 expected_stack_deps) 161 expected_stack_deps)
127 162
128 def testGetChangeLogsForFilesGroupedByDeps(self): 163 def testGetChangeLogsForFilesGroupedByDeps(self):
129 regression_deps_rolls = { 164 regression_deps_rolls = {
130 'src/dep1': DependencyRoll('src/dep1', 'https://url_dep1', '7', '9'), 165 'src/dep': DependencyRoll('src/dep1', 'https://url_dep1', '7', '9'),
131 'src/dep2': DependencyRoll('src/dep2', 'repo_url', '3', None),
132 'src/': DependencyRoll('src/', ('https://chromium.googlesource.com/' 166 'src/': DependencyRoll('src/', ('https://chromium.googlesource.com/'
133 'chromium/src.git'), '4', '5') 167 'chromium/src.git'), '4', '5')
134 } 168 }
135 169
136 stack_deps = { 170 stack_deps = {
137 'src/': Dependency('src/', 'https://url_src', 'rev1', 'DEPS'), 171 'src/': Dependency('src/', 'https://url_src', 'rev1', 'DEPS'),
138 'src/new': Dependency('src/new', 'https://new', 'rev2', 'DEPS'), 172 'src/new': Dependency('src/new', 'https://new', 'rev2', 'DEPS'),
173 'src/dep': Dependency('src/dep', 'https://url_dep', 'rev', 'DEPS'),
139 } 174 }
140 175
141 def _MockGetChangeLogs(*_): 176 def _MockGetChangeLogs(_, start_rev, end_rev):
142 return [DUMMY_CHANGELOG1, DUMMY_CHANGELOG2, DUMMY_CHANGELOG3] 177 if start_rev == '4' and end_rev == '5':
178 return [DUMMY_CHANGELOG1, DUMMY_CHANGELOG2, DUMMY_CHANGELOG3]
179
180 return []
143 181
144 self.mock(GitilesRepository, 'GetChangeLogs', _MockGetChangeLogs) 182 self.mock(GitilesRepository, 'GetChangeLogs', _MockGetChangeLogs)
145 183
146 dep_file_to_changelogs, ignore_cls = ( 184 dep_file_to_changelogs, ignore_cls = (
147 changelist_classifier.GetChangeLogsForFilesGroupedByDeps( 185 changelist_classifier.GetChangeLogsForFilesGroupedByDeps(
148 regression_deps_rolls, stack_deps, GitilesRepository())) 186 regression_deps_rolls, stack_deps, GitilesRepository()))
149 dep_file_to_changelogs_json = defaultdict(lambda: defaultdict(list)) 187 dep_file_to_changelogs_json = defaultdict(lambda: defaultdict(list))
150 for dep, file_to_changelogs in dep_file_to_changelogs.iteritems(): 188 for dep, file_to_changelogs in dep_file_to_changelogs.iteritems():
151 for file_path, changelogs in file_to_changelogs.iteritems(): 189 for file_path, changelogs in file_to_changelogs.iteritems():
152 for changelog in changelogs: 190 for changelog in changelogs:
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 def testFindItForCrash(self): 326 def testFindItForCrash(self):
289 327
290 def _MockFindMatchResults(*_): 328 def _MockFindMatchResults(*_):
291 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') 329 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '')
292 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) 330 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
293 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) 331 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
294 match_result1.file_to_stack_infos = { 332 match_result1.file_to_stack_infos = {
295 'a.cc': [(frame1, 0), (frame2, 0)] 333 'a.cc': [(frame1, 0), (frame2, 0)]
296 } 334 }
297 match_result1.file_to_analysis_info = { 335 match_result1.file_to_analysis_info = {
298 'a.cc': {'min_distance': 0, 'min_distance_frame': frame1} 336 'a.cc': AnalysisInfo(min_distance=0, min_distance_frame=frame1)
299 } 337 }
300 338
301 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') 339 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '')
302 frame3 = StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) 340 frame3 = StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1])
303 match_result2.file_to_stack_infos = { 341 match_result2.file_to_stack_infos = {
304 'f.cc': [(frame3, 0)] 342 'f.cc': [(frame3, 0)]
305 } 343 }
306 match_result2.file_to_analysis_info = { 344 match_result2.file_to_analysis_info = {
307 'a.cc': {'min_distance': 20, 'min_distance_frame': frame3} 345 'a.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
308 } 346 }
309 347
310 return [match_result1, match_result2] 348 return [match_result1, match_result2]
311 349
312 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 350 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
313 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 351 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
314 'GetDependencyRollsDict', 352 'GetDependencyRollsDict',
315 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 353 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
316 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 354 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
317 'GetDependency', lambda *_: {}) 355 'GetDependency', lambda *_: {})
(...skipping 19 matching lines...) Expand all
337 375
338 def testFinditForCrashFilterZeroConfidentResults(self): 376 def testFinditForCrashFilterZeroConfidentResults(self):
339 def _MockFindMatchResults(*_): 377 def _MockFindMatchResults(*_):
340 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') 378 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '')
341 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) 379 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
342 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) 380 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
343 match_result1.file_to_stack_infos = { 381 match_result1.file_to_stack_infos = {
344 'a.cc': [(frame1, 0), (frame2, 0)] 382 'a.cc': [(frame1, 0), (frame2, 0)]
345 } 383 }
346 match_result1.file_to_analysis_info = { 384 match_result1.file_to_analysis_info = {
347 'a.cc': {'min_distance': 1, 'min_distance_frame': frame1} 385 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1)
348 } 386 }
349 387
350 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') 388 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '')
351 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) 389 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1])
352 match_result2.file_to_stack_infos = { 390 match_result2.file_to_stack_infos = {
353 'f.cc': [(frame3, 0)] 391 'f.cc': [(frame3, 0)]
354 } 392 }
355 match_result2.file_to_analysis_info = { 393 match_result2.file_to_analysis_info = {
356 'f.cc': {'min_distance': 20, 'min_distance_frame': frame3} 394 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
357 } 395 }
358 396
359 match_result3 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') 397 match_result3 = MatchResult(DUMMY_CHANGELOG3, 'src/', '')
360 frame4 = StackFrame(3, 'src/', 'func', 'ff.cc', 'src/ff.cc', [1]) 398 frame4 = StackFrame(3, 'src/', 'func', 'ff.cc', 'src/ff.cc', [1])
361 match_result3.file_to_stack_infos = { 399 match_result3.file_to_stack_infos = {
362 'f.cc': [(frame4, 0)] 400 'f.cc': [(frame4, 0)]
363 } 401 }
364 match_result3.file_to_analysis_info = { 402 match_result3.file_to_analysis_info = {
365 'f.cc': {'min_distance': 60, 'min_distance_frame': frame4} 403 'f.cc': AnalysisInfo(min_distance=60, min_distance_frame=frame4)
366 } 404 }
367 405
368 return [match_result1, match_result2, match_result3] 406 return [match_result1, match_result2, match_result3]
369 407
370 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 408 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
371 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 409 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
372 'GetDependencyRollsDict', 410 'GetDependencyRollsDict',
373 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 411 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
374 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 412 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
375 'GetDependency', lambda *_: {}) 413 'GetDependency', lambda *_: {})
(...skipping 28 matching lines...) Expand all
404 442
405 def testFinditForCrashAllMatchResultsWithZeroConfidences(self): 443 def testFinditForCrashAllMatchResultsWithZeroConfidences(self):
406 def _MockFindMatchResults(*_): 444 def _MockFindMatchResults(*_):
407 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') 445 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '')
408 frame1 = StackFrame(20, 'src/', '', 'func', 'a.cc', [1]) 446 frame1 = StackFrame(20, 'src/', '', 'func', 'a.cc', [1])
409 frame2 = StackFrame(21, 'src/', '', 'func', 'a.cc', [7]) 447 frame2 = StackFrame(21, 'src/', '', 'func', 'a.cc', [7])
410 match_result1.file_to_stack_infos = { 448 match_result1.file_to_stack_infos = {
411 'a.cc': [(frame1, 0), (frame2, 0)] 449 'a.cc': [(frame1, 0), (frame2, 0)]
412 } 450 }
413 match_result1.file_to_analysis_info = { 451 match_result1.file_to_analysis_info = {
414 'a.cc': {'min_distance': 1, 'min_distance_frame': frame1} 452 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1)
415 } 453 }
416 454
417 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') 455 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '')
418 frame3 = StackFrame(15, 'src/', '', 'func', 'f.cc', [1]) 456 frame3 = StackFrame(15, 'src/', '', 'func', 'f.cc', [1])
419 match_result2.file_to_stack_infos = { 457 match_result2.file_to_stack_infos = {
420 'f.cc': [(frame3, 0)] 458 'f.cc': [(frame3, 0)]
421 } 459 }
422 match_result2.min_distance = 20 460 match_result2.min_distance = 20
423 match_result2.file_to_analysis_info = { 461 match_result2.file_to_analysis_info = {
424 'f.cc': {'min_distance': 20, 'min_distance_frame': frame3} 462 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
425 } 463 }
426 464
427 return [match_result1, match_result2] 465 return [match_result1, match_result2]
428 466
429 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 467 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
430 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 468 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
431 'GetDependencyRollsDict', 469 'GetDependencyRollsDict',
432 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 470 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
433 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 471 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
434 'GetDependency', lambda *_: {}) 472 'GetDependency', lambda *_: {})
435 473
436 cl_classifier = changelist_classifier.ChangelistClassifier(7, 474 cl_classifier = changelist_classifier.ChangelistClassifier(7,
437 GitilesRepository()) 475 GitilesRepository())
438 self.assertListEqual(cl_classifier(DUMMY_REPORT), []) 476 self.assertListEqual(cl_classifier(DUMMY_REPORT), [])
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698