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

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

Issue 2588513002: [Predator] renamed "Result" to "Suspect" (Closed)
Patch Set: Removing redundant import 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
11 from crash import changelist_classifier 11 from crash import changelist_classifier
12 from crash.crash_report import CrashReport 12 from crash.crash_report import CrashReport
13 from crash.results import AnalysisInfo 13 from crash.suspect import AnalysisInfo
14 from crash.results import StackInfo 14 from crash.suspect import StackInfo
15 from crash.results import MatchResult 15 from crash.suspect import Suspect
16 from crash.stacktrace import CallStack 16 from crash.stacktrace import CallStack
17 from crash.stacktrace import StackFrame 17 from crash.stacktrace import StackFrame
18 from crash.stacktrace import Stacktrace 18 from crash.stacktrace import Stacktrace
19 from crash.test.crash_test_suite import CrashTestSuite 19 from crash.test.crash_test_suite import CrashTestSuite
20 from libs.gitiles.blame import Blame 20 from libs.gitiles.blame import Blame
21 from libs.gitiles.blame import Region 21 from libs.gitiles.blame import Region
22 from libs.gitiles.change_log import ChangeLog 22 from libs.gitiles.change_log import ChangeLog
23 from libs.gitiles.gitiles_repository import GitilesRepository 23 from libs.gitiles.gitiles_repository import GitilesRepository
24 24
25 DUMMY_CHANGELOG1 = ChangeLog.FromDict({ 25 DUMMY_CHANGELOG1 = ChangeLog.FromDict({
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 'code_review_url': 'https://codereview.chromium.org/3281', 93 'code_review_url': 'https://codereview.chromium.org/3281',
94 'committer_name': 'example@chromium.org', 94 'committer_name': 'example@chromium.org',
95 'revision': '3', 95 'revision': '3',
96 'reverted_revision': None 96 'reverted_revision': None
97 }) 97 })
98 98
99 # TODO(wrengr): re crrev.com/2414523002: we need to have a specified 99 # TODO(wrengr): re crrev.com/2414523002: we need to have a specified
100 # revision_range (even if the versions therein are None), because 100 # revision_range (even if the versions therein are None), because
101 # ChangelistClassifier.__call__ will take it apart in order to call 101 # ChangelistClassifier.__call__ will take it apart in order to call
102 # GetDEPSRollsDict; if it can't then it will immediately return the 102 # GetDEPSRollsDict; if it can't then it will immediately return the
103 # empty list of results, breaking many of the tests here. Of course, 103 # empty list of suspects, breaking many of the tests here. Of course,
104 # taking revision_range apart isn't actually required for the tests, 104 # taking revision_range apart isn't actually required for the tests,
105 # since we mock GetDEPSRollsDict. So, really what we ought to do in the 105 # since we mock GetDEPSRollsDict. So, really what we ought to do in the
106 # long run is redesign things so that GetDEPSRollsDict takes the 106 # long run is redesign things so that GetDEPSRollsDict takes the
107 # CrashReport directly and pulls out the revision_range and platform 107 # CrashReport directly and pulls out the revision_range and platform
108 # itself; that way ChangelistClassifier.__call__ needn't worry about it, 108 # itself; that way ChangelistClassifier.__call__ needn't worry about it,
109 # allowing us to clean up the tests here. 109 # allowing us to clean up the tests here.
110 # TODO(wrengr): this empty stacktrace causes the unittests to emit 110 # TODO(wrengr): this empty stacktrace causes the unittests to emit
111 # logging warnings about the fact that we can't get the crash_stack. Would 111 # logging warnings about the fact that we can't get the crash_stack. Would
112 # be nice to avoid that. 112 # be nice to avoid that.
113 DUMMY_REPORT = CrashReport(None, None, None, Stacktrace(), (None, None)) 113 DUMMY_REPORT = CrashReport(None, None, None, Stacktrace(), (None, None))
(...skipping 18 matching lines...) Expand all
132 132
133 passed_in_regression_deps_rolls = [] 133 passed_in_regression_deps_rolls = []
134 def _MockGetChangeLogsForFilesGroupedByDeps(regression_deps_rolls, *_): 134 def _MockGetChangeLogsForFilesGroupedByDeps(regression_deps_rolls, *_):
135 passed_in_regression_deps_rolls.append(regression_deps_rolls) 135 passed_in_regression_deps_rolls.append(regression_deps_rolls)
136 return {}, None 136 return {}, None
137 137
138 self.mock(changelist_classifier, 'GetChangeLogsForFilesGroupedByDeps', 138 self.mock(changelist_classifier, 'GetChangeLogsForFilesGroupedByDeps',
139 _MockGetChangeLogsForFilesGroupedByDeps) 139 _MockGetChangeLogsForFilesGroupedByDeps)
140 self.mock(changelist_classifier, 'GetStackInfosForFilesGroupedByDeps', 140 self.mock(changelist_classifier, 'GetStackInfosForFilesGroupedByDeps',
141 lambda *_: {}) 141 lambda *_: {})
142 self.mock(changelist_classifier, 'FindMatchResults', lambda *_: None) 142 self.mock(changelist_classifier, 'FindSuspects', lambda *_: None)
143 143
144 self.changelist_classifier(CrashReport(crashed_version = '5', 144 self.changelist_classifier(CrashReport(crashed_version = '5',
145 signature = 'sig', 145 signature = 'sig',
146 platform = 'canary', 146 platform = 'canary',
147 stacktrace = Stacktrace([CallStack(0)]), 147 stacktrace = Stacktrace([CallStack(0)]),
148 regression_range = ['4', '5'])) 148 regression_range = ['4', '5']))
149 expected_regression_deps_rolls = copy.deepcopy(dep_rolls) 149 expected_regression_deps_rolls = copy.deepcopy(dep_rolls)
150 150
151 # Regression of a dep added/deleted (old_revision/new_revision is None) can 151 # Regression of a dep added/deleted (old_revision/new_revision is None) can
152 # not be known for sure and this case rarely happens, so just filter them 152 # not be known for sure and this case rarely happens, so just filter them
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 for dep, file_to_stack_infos in dep_file_to_stack_infos.iteritems(): 249 for dep, file_to_stack_infos in dep_file_to_stack_infos.iteritems():
250 self.assertTrue(dep in expected_dep_file_to_stack_infos) 250 self.assertTrue(dep in expected_dep_file_to_stack_infos)
251 expected_file_to_stack_infos = expected_dep_file_to_stack_infos[dep] 251 expected_file_to_stack_infos = expected_dep_file_to_stack_infos[dep]
252 252
253 for file_path, stack_infos in file_to_stack_infos.iteritems(): 253 for file_path, stack_infos in file_to_stack_infos.iteritems():
254 self.assertTrue(file_path in expected_file_to_stack_infos) 254 self.assertTrue(file_path in expected_file_to_stack_infos)
255 expected_stack_infos = expected_file_to_stack_infos[file_path] 255 expected_stack_infos = expected_file_to_stack_infos[file_path]
256 256
257 self._VerifyTwoStackInfosEqual(stack_infos, expected_stack_infos) 257 self._VerifyTwoStackInfosEqual(stack_infos, expected_stack_infos)
258 258
259 def testFindMatchResults(self): 259 def testFindSuspects(self):
260 dep_file_to_changelogs = { 260 dep_file_to_changelogs = {
261 'src/': { 261 'src/': {
262 'a.cc': [ 262 'a.cc': [
263 DUMMY_CHANGELOG1, 263 DUMMY_CHANGELOG1,
264 ] 264 ]
265 } 265 }
266 } 266 }
267 267
268 dep_file_to_stack_infos = { 268 dep_file_to_stack_infos = {
269 'src/': { 269 'src/': {
(...skipping 15 matching lines...) Expand all
285 Region(1, 5, '6', 'a', 'a@chromium.org', 'Thu Mar 31 21:24:43 2016')) 285 Region(1, 5, '6', 'a', 'a@chromium.org', 'Thu Mar 31 21:24:43 2016'))
286 dummy_blame.AddRegion( 286 dummy_blame.AddRegion(
287 Region(6, 10, '1', 'b', 'b@chromium.org', 'Thu Jun 19 12:11:40 2015')) 287 Region(6, 10, '1', 'b', 'b@chromium.org', 'Thu Jun 19 12:11:40 2015'))
288 288
289 self.mock(GitilesRepository, 'GetBlame', lambda *_: dummy_blame) 289 self.mock(GitilesRepository, 'GetBlame', lambda *_: dummy_blame)
290 290
291 stack_deps = { 291 stack_deps = {
292 'src/': Dependency('src/', 'https://url_src', 'rev1', 'DEPS'), 292 'src/': Dependency('src/', 'https://url_src', 'rev1', 'DEPS'),
293 } 293 }
294 294
295 expected_match_results = [{ 295 expected_suspects = [{
296 'url': 'https://repo.test/+/1', 296 'url': 'https://repo.test/+/1',
297 'review_url': 'https://codereview.chromium.org/3281', 297 'review_url': 'https://codereview.chromium.org/3281',
298 'revision': '1', 298 'revision': '1',
299 'project_path': 'src/', 299 'project_path': 'src/',
300 'author': 'r@chromium.org', 300 'author': 'r@chromium.org',
301 'time': 'Thu Mar 31 21:24:43 2016', 301 'time': 'Thu Mar 31 21:24:43 2016',
302 'reasons': None, 302 'reasons': None,
303 'confidence': None, 303 'confidence': None,
304 'changed_files': None 304 'changed_files': None
305 }] 305 }]
306 306
307 match_results = changelist_classifier.FindMatchResults( 307 suspects = changelist_classifier.FindSuspects(
308 dep_file_to_changelogs, dep_file_to_stack_infos, stack_deps, 308 dep_file_to_changelogs, dep_file_to_stack_infos, stack_deps,
309 GitilesRepository(self.GetMockHttpClient())) 309 GitilesRepository(self.GetMockHttpClient()))
310 self.assertListEqual([result.ToDict() for result in match_results], 310 self.assertListEqual([suspect.ToDict() for suspect in suspects],
311 expected_match_results) 311 expected_suspects)
312 312
313 # TODO(http://crbug.com/659346): why do these mocks give coverage 313 # TODO(http://crbug.com/659346): why do these mocks give coverage
314 # failures? That's almost surely hiding a bug in the tests themselves. 314 # failures? That's almost surely hiding a bug in the tests themselves.
315 def testFindItForCrashNoRegressionRange(self): # pragma: no cover 315 def testFindItForCrashNoRegressionRange(self): # pragma: no cover
316 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 316 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
317 'GetDependencyRollsDict', lambda *_: {}) 317 'GetDependencyRollsDict', lambda *_: {})
318 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 318 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
319 'GetDependency', lambda *_: {}) 319 'GetDependency', lambda *_: {})
320 # N.B., for this one test we really do want regression_range=None. 320 # N.B., for this one test we really do want regression_range=None.
321 report = DUMMY_REPORT._replace(regression_range=None) 321 report = DUMMY_REPORT._replace(regression_range=None)
322 self.assertListEqual(self.changelist_classifier(report), []) 322 self.assertListEqual(self.changelist_classifier(report), [])
323 323
324 def testFindItForCrashNoMatchFound(self): 324 def testFindItForCrashNoMatchFound(self):
325 self.mock(changelist_classifier, 'FindMatchResults', lambda *_: []) 325 self.mock(changelist_classifier, 'FindSuspects', lambda *_: [])
326 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 326 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
327 'GetDependencyRollsDict', 327 'GetDependencyRollsDict',
328 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 328 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
329 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 329 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
330 'GetDependency', lambda *_: {}) 330 'GetDependency', lambda *_: {})
331 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), []) 331 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), [])
332 332
333 def testFindItForCrash(self): 333 def testFindItForCrash(self):
334 334
335 def _MockFindMatchResults(*_): 335 def _MockFindSuspects(*_):
336 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', confidence=0.) 336 suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/', confidence=0.)
337 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) 337 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
338 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) 338 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
339 match_result1.file_to_stack_infos = { 339 suspect1.file_to_stack_infos = {
340 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)] 340 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)]
341 } 341 }
342 match_result1.file_to_analysis_info = { 342 suspect1.file_to_analysis_info = {
343 'a.cc': AnalysisInfo(min_distance=0, min_distance_frame=frame1) 343 'a.cc': AnalysisInfo(min_distance=0, min_distance_frame=frame1)
344 } 344 }
345 345
346 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', confidence=0.) 346 suspect2 = Suspect(DUMMY_CHANGELOG3, 'src/', confidence=0.)
347 frame3 = StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) 347 frame3 = StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1])
348 match_result2.file_to_stack_infos = { 348 suspect2.file_to_stack_infos = {
349 'f.cc': [StackInfo(frame3, 0)] 349 'f.cc': [StackInfo(frame3, 0)]
350 } 350 }
351 match_result2.file_to_analysis_info = { 351 suspect2.file_to_analysis_info = {
352 'a.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3) 352 'a.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
353 } 353 }
354 354
355 return [match_result1, match_result2] 355 return [suspect1, suspect2]
356 356
357 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 357 self.mock(changelist_classifier, 'FindSuspects', _MockFindSuspects)
358 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 358 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
359 'GetDependencyRollsDict', 359 'GetDependencyRollsDict',
360 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 360 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
361 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 361 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
362 'GetDependency', lambda *_: {}) 362 'GetDependency', lambda *_: {})
363 results = self.changelist_classifier(DUMMY_REPORT) 363 suspects = self.changelist_classifier(DUMMY_REPORT)
364 expected_match_results = [ 364 expected_suspects = [
365 { 365 {
366 'reasons': [('TopFrameIndex', 1.0, 'Top frame is #0'), 366 'reasons': [('TopFrameIndex', 1.0, 'Top frame is #0'),
367 ('MinDistance', 1, 'Minimum distance is 0')], 367 ('MinDistance', 1, 'Minimum distance is 0')],
368 'changed_files': [{'info': 'Minimum distance (LOC) 0, frame #0', 368 'changed_files': [{'info': 'Minimum distance (LOC) 0, frame #0',
369 'blame_url': None, 'file': 'a.cc'}], 369 'blame_url': None, 'file': 'a.cc'}],
370 'time': 'Thu Mar 31 21:24:43 2016', 370 'time': 'Thu Mar 31 21:24:43 2016',
371 'author': 'r@chromium.org', 371 'author': 'r@chromium.org',
372 'url': 'https://repo.test/+/1', 372 'url': 'https://repo.test/+/1',
373 'project_path': 'src/', 373 'project_path': 'src/',
374 'review_url': 'https://codereview.chromium.org/3281', 374 'review_url': 'https://codereview.chromium.org/3281',
375 'confidence': 1.0, 'revision': '1' 375 'confidence': 1.0, 'revision': '1'
376 }, 376 },
377 ] 377 ]
378 self.assertListEqual([result.ToDict() for result in results], 378 self.assertListEqual([suspect.ToDict() for suspect in suspects],
379 expected_match_results) 379 expected_suspects)
380 380
381 def testFinditForCrashFilterZeroConfidentResults(self): 381 def testFinditForCrashFilterZeroConfidentResults(self):
382 def _MockFindMatchResults(*_): 382 def _MockFindSuspects(*_):
383 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', confidence=0.) 383 suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/', confidence=0.)
384 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) 384 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
385 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) 385 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
386 match_result1.file_to_stack_infos = { 386 suspect1.file_to_stack_infos = {
387 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)] 387 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)]
388 } 388 }
389 match_result1.file_to_analysis_info = { 389 suspect1.file_to_analysis_info = {
390 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1) 390 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1)
391 } 391 }
392 392
393 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', confidence=0.) 393 suspect2 = Suspect(DUMMY_CHANGELOG3, 'src/', confidence=0.)
394 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) 394 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1])
395 match_result2.file_to_stack_infos = { 395 suspect2.file_to_stack_infos = {
396 'f.cc': [StackInfo(frame3, 0)] 396 'f.cc': [StackInfo(frame3, 0)]
397 } 397 }
398 match_result2.file_to_analysis_info = { 398 suspect2.file_to_analysis_info = {
399 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3) 399 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
400 } 400 }
401 401
402 match_result3 = MatchResult(DUMMY_CHANGELOG3, 'src/', confidence=0.) 402 suspect3 = Suspect(DUMMY_CHANGELOG3, 'src/', confidence=0.)
403 frame4 = StackFrame(3, 'src/', 'func', 'ff.cc', 'src/ff.cc', [1]) 403 frame4 = StackFrame(3, 'src/', 'func', 'ff.cc', 'src/ff.cc', [1])
404 match_result3.file_to_stack_infos = { 404 suspect3.file_to_stack_infos = {
405 'f.cc': [StackInfo(frame4, 0)] 405 'f.cc': [StackInfo(frame4, 0)]
406 } 406 }
407 match_result3.file_to_analysis_info = { 407 suspect3.file_to_analysis_info = {
408 'f.cc': AnalysisInfo(min_distance=60, min_distance_frame=frame4) 408 'f.cc': AnalysisInfo(min_distance=60, min_distance_frame=frame4)
409 } 409 }
410 410
411 return [match_result1, match_result2, match_result3] 411 return [suspect1, suspect2, suspect3]
412 412
413 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 413 self.mock(changelist_classifier, 'FindSuspects', _MockFindSuspects)
414 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 414 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
415 'GetDependencyRollsDict', 415 'GetDependencyRollsDict',
416 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 416 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
417 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 417 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
418 'GetDependency', lambda *_: {}) 418 'GetDependency', lambda *_: {})
419 419
420 results = self.changelist_classifier(DUMMY_REPORT) 420 suspects = self.changelist_classifier(DUMMY_REPORT)
421 expected_match_results = [ 421 expected_suspects = [
422 { 422 {
423 'author': 'r@chromium.org', 423 'author': 'r@chromium.org',
424 'changed_files': [ 424 'changed_files': [
425 { 425 {
426 'blame_url': None, 426 'blame_url': None,
427 'file': 'a.cc', 427 'file': 'a.cc',
428 'info': 'Minimum distance (LOC) 1, frame #0' 428 'info': 'Minimum distance (LOC) 1, frame #0'
429 } 429 }
430 ], 430 ],
431 'confidence': 0.8, 431 'confidence': 0.8,
432 'project_path': 'src/', 432 'project_path': 'src/',
433 'reasons': [ 433 'reasons': [
434 ('TopFrameIndex', 1.0, 'Top frame is #0'), 434 ('TopFrameIndex', 1.0, 'Top frame is #0'),
435 ('MinDistance', 0.8, 'Minimum distance is 1') 435 ('MinDistance', 0.8, 'Minimum distance is 1')
436 ], 436 ],
437 'review_url': 'https://codereview.chromium.org/3281', 437 'review_url': 'https://codereview.chromium.org/3281',
438 'revision': '1', 438 'revision': '1',
439 'time': 'Thu Mar 31 21:24:43 2016', 439 'time': 'Thu Mar 31 21:24:43 2016',
440 'url': 'https://repo.test/+/1' 440 'url': 'https://repo.test/+/1'
441 } 441 }
442 ] 442 ]
443 self.assertListEqual([result.ToDict() for result in results], 443 self.assertListEqual([suspect.ToDict() for suspect in suspects],
444 expected_match_results) 444 expected_suspects)
445 445
446 def testFinditForCrashAllMatchResultsWithZeroConfidences(self): 446 def testFinditForCrashAllSuspectsWithZeroConfidences(self):
447 """Test that we filter out results with too-large frame indices. 447 """Test that we filter out suspects with too-large frame indices.
448 448
449 In the mock results below we return frames with indices 449 In the mock suspects below we return frames with indices
450 15, 20, 21 which are all larger than the ``max_top_n`` of 450 15, 20, 21 which are all larger than the ``max_top_n`` of
451 ``TopFrameIndexScorer``. Therefore we should get a score of zero 451 ``TopFrameIndexScorer``. Therefore we should get a score of zero
452 for that feature, which causes the total score to be zero, and so 452 for that feature, which causes the total score to be zero, and so
453 we should not return these results. 453 we should not return these suspects.
454 """ 454 """
455 def _MockFindMatchResults(*_): 455 def _MockFindSuspects(*_):
456 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', confidence=0.) 456 suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/', confidence=0.)
457 frame1 = StackFrame(20, 'src/', '', 'func', 'a.cc', [1]) 457 frame1 = StackFrame(20, 'src/', '', 'func', 'a.cc', [1])
458 frame2 = StackFrame(21, 'src/', '', 'func', 'a.cc', [7]) 458 frame2 = StackFrame(21, 'src/', '', 'func', 'a.cc', [7])
459 match_result1.file_to_stack_infos = { 459 suspect1.file_to_stack_infos = {
460 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)] 460 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)]
461 } 461 }
462 match_result1.file_to_analysis_info = { 462 suspect1.file_to_analysis_info = {
463 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1) 463 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1)
464 } 464 }
465 465
466 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', confidence=0.) 466 suspect2 = Suspect(DUMMY_CHANGELOG3, 'src/', confidence=0.)
467 frame3 = StackFrame(15, 'src/', '', 'func', 'f.cc', [1]) 467 frame3 = StackFrame(15, 'src/', '', 'func', 'f.cc', [1])
468 match_result2.file_to_stack_infos = { 468 suspect2.file_to_stack_infos = {
469 'f.cc': [StackInfo(frame3, 0)] 469 'f.cc': [StackInfo(frame3, 0)]
470 } 470 }
471 match_result2.min_distance = 20 471 suspect2.min_distance = 20
472 match_result2.file_to_analysis_info = { 472 suspect2.file_to_analysis_info = {
473 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3) 473 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
474 } 474 }
475 475
476 return [match_result1, match_result2] 476 return [suspect1, suspect2]
477 477
478 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 478 self.mock(changelist_classifier, 'FindSuspects', _MockFindSuspects)
479 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 479 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
480 'GetDependencyRollsDict', 480 'GetDependencyRollsDict',
481 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 481 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
482 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 482 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
483 'GetDependency', lambda *_: {}) 483 'GetDependency', lambda *_: {})
484 484
485 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), []) 485 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), [])
OLDNEW
« no previous file with comments | « appengine/findit/crash/suspect.py ('k') | appengine/findit/crash/test/component_classifier_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698