def testClassifySuspectNoMatch(self): """Tests ``ClassifySuspect`` returns None if there is no file match.""" suspect = Suspect(self.GetDummyChangeLog(), 'dummy') suspect.changelog = suspect.changelog._replace(touched_files=[ FileChangeInfo(ChangeType.MODIFY, 'comp1.cc', 'comp1.cc') ]) self.assertEqual(self.classifier.ClassifySuspect(suspect), [])
def testSuspectToDict(self): suspect = Suspect(DUMMY_CHANGELOG1, 'src/', confidence=1, reasons=['MinDistance', 0.5, 'some reason'], changed_files={ 'file': 'f', 'blame_url': 'http://b', 'info': 'min distance (LOC) 5' }) expected_suspect_json = { 'url': DUMMY_CHANGELOG1.commit_url, 'review_url': DUMMY_CHANGELOG1.code_review_url, 'revision': DUMMY_CHANGELOG1.revision, 'project_path': 'src/', 'author': DUMMY_CHANGELOG1.author.email, 'time': str(DUMMY_CHANGELOG1.author.time), 'reasons': ['MinDistance', 0.5, 'some reason'], 'changed_files': { 'file': 'f', 'blame_url': 'http://b', 'info': 'min distance (LOC) 5' }, 'confidence': 1, 'description': 'dummy', } self.assertDictEqual(suspect.ToDict(), expected_suspect_json)
def testClassifySuspectNoTouchedFileMatch(self): """Tests ``ClassifySuspect`` returns None if there is no file match.""" suspect = Suspect(self.GetDummyChangeLog(), 'dummy') suspect.touched_files = [ FileChangeInfo(ChangeType.MODIFY, 'a/b.h', 'a/b.h') ] self.assertIsNone(self.classifier.ClassifySuspect(suspect))
def testClassifySuspect(self): """Tests ``ClassifySuspect`` method.""" suspect = Suspect(self.GetDummyChangeLog(), 'src/') suspect.changelog = suspect.changelog._replace(touched_files=[ FileChangeInfo(ChangeType.MODIFY, 'comp1/a.cc', 'comp1/b.cc') ]) self.assertEqual(self.classifier.ClassifySuspect(suspect), ['Comp1>Dummy'])
def testClassifySuspects(self): """Tests ``ClassifySuspects`` classify a list of ``Suspect``s.""" suspect1 = Suspect(self.GetDummyChangeLog(), 'src/') suspect2 = Suspect(self.GetDummyChangeLog(), 'src/dep') suspect3 = Suspect(self.GetDummyChangeLog(), 'src/dep') self.assertEqual(self.classifier.ClassifySuspects( [suspect1, suspect2, suspect3]), 'chromium-dep')
def testFilterSuspectWithLessConfidenceThanLowerThreshold(self): """Tests filter suspect if it is with lower confidence than threshold.""" suspect = Suspect(self.GetDummyChangeLog(), 'src/') suspect.confidence = 2 self.assertListEqual( suspect_filters.FilterLessLikelySuspects(0.5, lower_threshold=5)( [suspect]), [])
def testIsSuspectFromRobotAuthor(self): """Tests that ``_IsSuspectFromRobotAuthor`` method returns True.""" suspect = Suspect(self.GetDummyChangeLog(), 'src/') robot_author = suspect.changelog.author._replace( email='*****@*****.**') robot_cl = suspect.changelog._replace(author=robot_author) suspect.changelog = robot_cl suspect_filter = suspect_filters.FilterSuspectFromRobotAuthor() self.assertTrue(suspect_filter._IsSuspectFromRobotAuthor(suspect))
def testCall(self): """Tests ``__call__`` method.""" suspect = Suspect(self.GetDummyChangeLog(), 'src/') touched_file = FileChangeInfo.FromDict({'old_path': None, 'new_path': 'a.cc', 'change_type': 'add'}) suspect.changelog = suspect.changelog._replace( touched_files=[touched_file]*15) self.assertEqual(self._feature(None)(suspect).value, 0.0)
def testClassifySuspects(self): dummy_classifier = DummyClassifier() suspect = Suspect(self.GetDummyChangeLog(), 'src/') suspect.file_to_stack_infos = { 'f0.cc': [(StackFrame(0, 'src/', 'a::c(p* &d)', 'f0.cc', 'src/f0.cc', [177]), 0)] } self.assertEqual(dummy_classifier.Classify([suspect], CallStack(0)), 'class_3')
def testRankSuspects(self): """Tests ``RankSuspects`` method.""" self.changelist_classifier._model.Features = mock.Mock( return_value=lambda _: MetaFeatureValue('dummy', {})) suspect = Suspect(DUMMY_CHANGELOG1, 'src/') self.changelist_classifier._model.Score = mock.Mock( return_value=lambda _: 1.0) suspects = self.changelist_classifier.RankSuspects( DUMMY_REPORT, [suspect]) self.assertEqual(suspects[0].ToDict(), suspect.ToDict())
def testCallOneSuspect(self, mock_generate_suspects, mock_rank_suspects): """Tests that ``__call__`` returns immediately when there's one suspect.""" suspect = Suspect(DUMMY_CHANGELOG1, 'src/') mock_generate_suspects.return_value = [suspect] suspects = self.changelist_classifier(DUMMY_REPORT) expected_suspects = [suspect.ToDict()] self.assertListEqual([suspect.ToDict() for suspect in suspects], expected_suspects) self.assertFalse(mock_rank_suspects.called)
def testRankSuspectsAllLogZeros(self): """Tests ``RankSuspects`` method.""" self.mock(self.changelist_classifier._model, 'Features', lambda _: lambda _: MetaFeatureValue('dummy', {})) suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/') suspect2 = Suspect(DUMMY_CHANGELOG2, 'src/') self.mock(self.changelist_classifier._model, 'Score', lambda _: lambda _: lmath.LOG_ZERO) suspects = self.changelist_classifier.RankSuspects( DUMMY_REPORT, [suspect1, suspect2]) self.assertEqual(suspects, [])
def testCall(self): """Tests ``__call__`` method.""" suspect1 = Suspect(self.GetDummyChangeLog(), 'src/') suspect2 = Suspect(self.GetDummyChangeLog(), 'src/') robot_author = suspect2.changelog.author._replace( email='*****@*****.**') robot_cl = suspect2.changelog._replace(author=robot_author) suspect2.changelog = robot_cl suspect_filter = suspect_filters.FilterSuspectFromRobotAuthor() self.assertListEqual(suspect_filter([suspect1, suspect2]), [suspect1])
def testRankSuspectsAllLogZeros(self): """Tests ``RankSuspects`` method.""" # the return value of _model.Features isn't used in this case so there's no # need to set one self.changelist_classifier._model.Features = mock.Mock() suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/') suspect2 = Suspect(DUMMY_CHANGELOG2, 'src/') self.changelist_classifier._model.Score = mock.Mock( return_value=lambda _: lmath.LOG_ZERO) suspects = self.changelist_classifier.RankSuspects( DUMMY_REPORT, [suspect1, suspect2]) self.assertEqual(suspects, [])
def testCallFindsSuspects(self): """Tests that ``__call__`` method finds suspects.""" suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/') suspect2 = Suspect(DUMMY_CHANGELOG2, 'src/') self.mock(self.changelist_classifier, 'GenerateSuspects', lambda *_: [suspect1, suspect2]) self.mock(self.changelist_classifier, 'RankSuspects', lambda report, suspects: [suspects[0]]) suspects = self.changelist_classifier(DUMMY_REPORT) expected_suspects = [suspect1.ToDict()] self.assertListEqual([suspect.ToDict() for suspect in suspects], expected_suspects)
def testTopFrameIndexNone(self): """Test that the feature returns 0 when there are no matched files.""" report = self._GetDummyReport() suspect = Suspect(self.GetDummyChangeLog(), 'src/') self.assertEqual( 0.0, top_frame_index.TopFrameIndexFeature(3)(report)(suspect, {}).value)
def testMinDistanceFeatureIsLogZero(self): """Test that the feature returns log(0) when there are no matched files.""" report = self._GetDummyReport() suspect = Suspect(self.GetDummyChangeLog(), 'src/') self.assertEqual( 0.0, min_distance.MinDistanceFeature(None, _MAXIMUM)(report)(suspect, {}).value)
def testFilterLessLikelySuspects(self): """Tests ``FilterLessLikelySuspects`` filter.""" suspect1 = Suspect(self.GetDummyChangeLog(), 'src/') suspect2 = Suspect(self.GetDummyChangeLog(), 'src/') suspect3 = Suspect(self.GetDummyChangeLog(), 'src/') suspect1.confidence = 2 suspect2.confidence = 2 self.assertListEqual( suspect_filters.FilterLessLikelySuspects(0.5)([suspect1, suspect2]), []) suspect2.confidence = 1.8 suspect3.confidence = 1.0 self.assertListEqual( suspect_filters.FilterLessLikelySuspects(0.5)([suspect1, suspect2, suspect3]), [suspect1, suspect2])
def testCall(self): """Tests ``__call__`` of the filter.""" suspect1 = Suspect(self.GetDummyChangeLog(), 'src/') suspect2 = Suspect(self.GetDummyChangeLog(), 'src/') suspect3 = Suspect(self.GetDummyChangeLog(), 'src/') suspect1.changelog = suspect1.changelog._replace(revision='rev1') suspect2.changelog = suspect2.changelog._replace(revision='rev2') suspect3.changelog = suspect3.changelog._replace(revision='rev3') ignore_revisions = set(['rev1', 'rev2']) suspect_filter = suspect_filters.FilterIgnoredRevisions( _MockGitRepository(ignore_revisions=ignore_revisions)) self.assertSetEqual(set(suspect_filter([suspect1, suspect2, suspect3])), set([suspect3]))
def testFeatureValueIsOneWhenThereIsMatchedDirectory(self): """Test that feature value is 1 when there is matched directory.""" changelog = self.GetDummyChangeLog()._replace(touched_files=[ FileChangeInfo.FromDict({ 'change_type': 'add', 'new_path': 'p/a.cc', 'old_path': None, }) ]) suspect = Suspect(changelog, 'src/') feature_value = self._feature(self._report)(suspect) self.assertEqual(1.0, feature_value.value)
def testSortAndFilterSuspects(self): """Tests ``SortAndFilterSuspects`` method.""" suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/') suspect2 = Suspect(DUMMY_CHANGELOG1, 'src/') suspect3 = Suspect(DUMMY_CHANGELOG1, 'src/') suspect1.confidence = 2 self.assertListEqual( self.changelist_classifier.SortAndFilterSuspects([suspect1]), [suspect1]) suspect2.confidence = 2 self.assertListEqual( self.changelist_classifier.SortAndFilterSuspects( [suspect1, suspect2]), []) suspect2.confidence = 1.8 suspect3.confidence = 1.0 self.assertListEqual( self.changelist_classifier.SortAndFilterSuspects( [suspect1, suspect2, suspect3]), [suspect1, suspect2])
def testFilterSuspects(self): """Tests ``SortAndFilterSuspects`` method.""" suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/') suspect2 = Suspect(DUMMY_CHANGELOG1, 'src/') def MockFilter(suspects): return suspects[:1] self.assertListEqual( self.changelist_classifier._FilterSuspects([suspect1], [MockFilter]), [suspect1]) self.assertListEqual( self.changelist_classifier._FilterSuspects([suspect1, suspect2], [MockFilter]), [suspect1]) self.assertListEqual( self.changelist_classifier._FilterSuspects([suspect1, suspect2], []), [suspect1, suspect2])
def testFeatureValueIsZeroWhenNoMatchedComponent(self): """Test that the feature returns 0 when there no matched component.""" frame = StackFrame(0, 'src/', 'func', 'dir/f.cc', 'src/dir/f.cc', [2, 3], 'h://repo') stack = CallStack(0, frame_list=[frame]) stack_trace = Stacktrace([stack], stack) deps = {'src/': Dependency('src/', 'h://repo', '8')} dep_rolls = {'src/': DependencyRoll('src/', 'h://repo', '2', '6')} report = CrashReport('8', 'sig', 'linux', stack_trace, ('2', '6'), deps, dep_rolls) suspect = Suspect(_DUMMY_CHANGELOG, 'src/') feature_value = self.feature(report)(suspect) self.assertEqual(0.0, feature_value.value)
def testFeatureValueIsZeroWhenAFileIsDeleted(self): """Tests that the feature returns 0 when a file is deleted.""" changelog = self.GetDummyChangeLog()._replace( # File deleted in the same directory: touched_files=[ FileChangeInfo.FromDict({ 'change_type': 'delete', 'new_path': None, 'old_path': 'p/a.cc', }) ]) suspect = Suspect(changelog, 'src/') feature_value = self._feature(self._report)(suspect) self.assertEqual(0.0, feature_value.value)
def testFeatureValueIsOneWhenThereIsMatchedComponent(self): """Test that feature value is 1 when there no matched component.""" # One dummy component in config is ['src/comp1.*', '', 'Comp1>Dummy']. frame1 = StackFrame(0, 'src/', 'func', 'comp1/f.cc', 'src/comp1/f.cc', [2, 3], 'h://repo') stack = CallStack(0, frame_list=[frame1]) stack_trace = Stacktrace([stack], stack) deps = {'src/': Dependency('src/', 'h://repo', '8')} dep_rolls = {'src/': DependencyRoll('src/', 'h://repo', '2', '6')} report = CrashReport('8', 'sig', 'linux', stack_trace, ('2', '6'), deps, dep_rolls) suspect = Suspect(_DUMMY_CHANGELOG, 'src/') feature_value = self.feature(report)(suspect) self.assertEqual(1.0, feature_value.value)
def testCallFindsSuspects(self, mock_generate_suspects, mock_rank_suspects): """Tests that ``__call__`` method finds suspects.""" suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/') suspect2 = Suspect(DUMMY_CHANGELOG2, 'src/') suspect1.confidence = 2.0 suspect2.confidence = 1.0 mock_generate_suspects.return_value = [suspect1, suspect2] mock_rank_suspects.side_effect = lambda report, suspects: [suspects[0]] suspects = self.changelist_classifier(DUMMY_REPORT) expected_suspects = [suspect1.ToDict()] self.assertListEqual([suspect.ToDict() for suspect in suspects], expected_suspects)
def testLogFailedToParseStacktraceMessage(self, mock_generate_suspects): """Tests that ``__call__`` log messages if stacktrace is None.""" suspect = Suspect(DUMMY_CHANGELOG1, 'src/') mock_generate_suspects.return_value = [suspect, suspect] report = CrashReport(None, None, None, None, (None, None), None, None) self.changelist_classifier(report) self.assertIsNone(self.changelist_classifier._log) self.changelist_classifier.SetLog(self.GetMockLog()) self.changelist_classifier(report) self.assertEqual(self.changelist_classifier._log.logs, [{ 'level': 'error', 'name': 'FailedToParseStacktrace', 'message': ('Can\'t find culprits because Predator ' 'failed to parse stacktrace.') }])
def testClassifySuspects(self): """Tests ``ClassifySuspects`` classify a list of ``Suspect``s.""" suspect1 = Suspect(self.GetDummyChangeLog(), 'src/') suspect1.changelog = suspect1.changelog._replace(touched_files=[ FileChangeInfo(ChangeType.MODIFY, 'comp1/a.cc', 'comp1/b.cc') ]) suspect2 = Suspect(self.GetDummyChangeLog(), 'src/') suspect2.changelog = suspect2.changelog._replace(touched_files=[ FileChangeInfo(ChangeType.MODIFY, 'comp2/a.cc', 'comp2/b.cc') ]) self.assertEqual( self.classifier.ClassifySuspects([suspect1, suspect2]), ['Comp1>Dummy', 'Comp2>Dummy'])
def testFeatureValueIsOneWhenThereIsMatchedDirectory(self): """Test that feature value is 1 when there is matched directory.""" frame1 = StackFrame(0, 'src/', 'func', 'p/f.cc', 'src/p/f.cc', [2, 3], 'h://repo') stack = CallStack(0, frame_list=[frame1]) stack_trace = Stacktrace([stack], stack) deps = {'src/': Dependency('src/', 'h://repo', '8')} dep_rolls = {'src/': DependencyRoll('src/', 'h://repo', '2', '6')} report = CrashReport('8', 'sig', 'linux', stack_trace, ('2', '6'), deps, dep_rolls) changelog = self.GetDummyChangeLog()._replace(touched_files=[ FileChangeInfo.FromDict({ 'change_type': 'add', 'new_path': 'p/a.cc', 'old_path': None, }) ]) suspect = Suspect(changelog, 'src/') feature_value = self._feature(report)(suspect) self.assertEqual(1.0, feature_value.value)
def testMatchSuspectWithFrameInfos(self): """Tests ``MatchSuspectWithFrameInfos`` function.""" frame1 = StackFrame(0, 'src/', 'func', 'f.cc', 'src/f.cc', [2, 3], 'h://repo') frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [31, 32], 'h://repo') grouped_frame_infos = { MockCrashedGroup('src/f.cc'): [FrameInfo(frame1, 0)], MockCrashedGroup('src/a.cc'): [FrameInfo(frame2, 0)] } suspect = Suspect(_CHANGELOG, 'src/') matches = crash_util.MatchSuspectWithFrameInfos( suspect, grouped_frame_infos, Match) crashed = MockCrashedGroup('src/a.cc') expected_matches = { crashed: CrashMatch(crashed, _CHANGELOG.touched_files, [FrameInfo(frame2, 0)]) } self.assertDictEqual(matches, expected_matches)