| OLD | NEW |
| (Empty) |
| 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 | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 from crash.results import AnalysisInfo | |
| 6 from crash.results import MatchResult | |
| 7 from crash.results import MatchResults | |
| 8 from crash.results import Result | |
| 9 from crash.results import StackInfo | |
| 10 from crash.stacktrace import StackFrame | |
| 11 from crash.test.crash_test_suite import CrashTestSuite | |
| 12 from libs.gitiles.blame import Blame | |
| 13 from libs.gitiles.blame import Region | |
| 14 from libs.gitiles.change_log import ChangeLog | |
| 15 | |
| 16 DUMMY_CHANGELOG1 = ChangeLog.FromDict({ | |
| 17 'author_name': 'r@chromium.org', | |
| 18 'message': 'dummy', | |
| 19 'committer_email': 'r@chromium.org', | |
| 20 'commit_position': 175900, | |
| 21 'author_email': 'r@chromium.org', | |
| 22 'touched_files': [ | |
| 23 { | |
| 24 'change_type': 'modify', | |
| 25 'new_path': 'a.cc', | |
| 26 'old_path': 'a.cc', | |
| 27 }, | |
| 28 { | |
| 29 'change_type': 'modify', | |
| 30 'new_path': 'b.cc', | |
| 31 'old_path': 'b.cc', | |
| 32 }, | |
| 33 ], | |
| 34 'author_time': 'Thu Mar 31 21:24:43 2016', | |
| 35 'committer_time': 'Thu Mar 31 21:28:39 2016', | |
| 36 'commit_url': | |
| 37 'https://repo.test/+/1', | |
| 38 'code_review_url': 'https://codereview.chromium.org/3281', | |
| 39 'committer_name': 'r', | |
| 40 'revision': '1', | |
| 41 'reverted_revision': None | |
| 42 }) | |
| 43 | |
| 44 DUMMY_CHANGELOG2 = ChangeLog.FromDict({ | |
| 45 'author_name': 'e@chromium.org', | |
| 46 'message': 'dummy', | |
| 47 'committer_email': 'e@chromium.org', | |
| 48 'commit_position': 175911, | |
| 49 'author_email': 'e@chromium.org', | |
| 50 'touched_files': [ | |
| 51 { | |
| 52 'change_type': 'modify', | |
| 53 'new_path': 'a.cc', | |
| 54 'old_path': 'a.cc', | |
| 55 }, | |
| 56 ], | |
| 57 'author_time': 'Thu Mar 31 21:24:43 2016', | |
| 58 'committer_time': 'Thu Mar 31 21:28:39 2016', | |
| 59 'commit_url': | |
| 60 'https://repo.test/+/2', | |
| 61 'code_review_url': 'https://codereview.chromium.org/3290', | |
| 62 'committer_name': 'e', | |
| 63 'revision': '2', | |
| 64 'reverted_revision': None | |
| 65 }) | |
| 66 | |
| 67 DUMMY_BLAME = Blame('4', 'a.cc') | |
| 68 DUMMY_BLAME.AddRegion( | |
| 69 Region(1, 5, '2', 'r', 'r@chromium.org', 'Thu Mar 25 21:24:43 2016')) | |
| 70 DUMMY_BLAME.AddRegion( | |
| 71 Region(6, 3, '1', 'e', 'e@chromium.org', 'Thu Mar 31 21:24:43 2016')) | |
| 72 DUMMY_BLAME.AddRegion( | |
| 73 Region(9, 2, '3', 'k', 'k@chromium.org', 'Thu Apr 1 21:24:43 2016')) | |
| 74 | |
| 75 DUMMY_BLAME2 = Blame('4', 'b.cc') | |
| 76 DUMMY_BLAME2.AddRegion( | |
| 77 Region(1, 5, '2', 'r', 'r@chromium.org', 'Thu Mar 25 21:24:43 2016')) | |
| 78 DUMMY_BLAME2.AddRegion( | |
| 79 Region(6, 3, '1', 'e', 'e@chromium.org', 'Thu Mar 31 21:24:43 2016')) | |
| 80 | |
| 81 | |
| 82 class ResultsTest(CrashTestSuite): | |
| 83 | |
| 84 def testResultToDict(self): | |
| 85 | |
| 86 result = Result(DUMMY_CHANGELOG1, 'src/', | |
| 87 confidence=1, reasons=['MinDistance', 0.5, 'some reason'], | |
| 88 changed_files={'file': 'f', 'blame_url': 'http://b', | |
| 89 'info': 'min distance (LOC) 5'}) | |
| 90 | |
| 91 expected_result_json = { | |
| 92 'url': DUMMY_CHANGELOG1.commit_url, | |
| 93 'review_url': DUMMY_CHANGELOG1.code_review_url, | |
| 94 'revision': DUMMY_CHANGELOG1.revision, | |
| 95 'project_path': 'src/', | |
| 96 'author': DUMMY_CHANGELOG1.author_email, | |
| 97 'time': str(DUMMY_CHANGELOG1.author_time), | |
| 98 'reasons': ['MinDistance', 0.5, 'some reason'], | |
| 99 'changed_files': {'file': 'f', 'blame_url': 'http://b', | |
| 100 'info': 'min distance (LOC) 5'}, | |
| 101 'confidence': 1, | |
| 102 } | |
| 103 | |
| 104 self.assertEqual(result.ToDict(), expected_result_json) | |
| 105 | |
| 106 def testResultToString(self): | |
| 107 | |
| 108 result = Result(DUMMY_CHANGELOG1, 'src/', confidence=1) | |
| 109 | |
| 110 expected_result_str = '' | |
| 111 self.assertEqual(result.ToString(), expected_result_str) | |
| 112 | |
| 113 result.file_to_stack_infos = { | |
| 114 'a.cc': [StackInfo( | |
| 115 frame = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', []), | |
| 116 priority = 0)] | |
| 117 } | |
| 118 expected_result_str = 'Changed file a.cc crashed in frame #0' | |
| 119 | |
| 120 self.assertEqual(str(result), expected_result_str) | |
| 121 | |
| 122 def testMatchResultUpdate(self): | |
| 123 # Touched lines have intersection with crashed lines. | |
| 124 result = MatchResult(DUMMY_CHANGELOG1, 'src/', confidence=1) | |
| 125 stack_infos = [StackInfo( | |
| 126 frame = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [7]), | |
| 127 priority = 0)] | |
| 128 | |
| 129 result.Update('a.cc', stack_infos, DUMMY_BLAME) | |
| 130 self.assertEqual(result.file_to_analysis_info['a.cc'].min_distance, 0) | |
| 131 | |
| 132 # Touched lines are before crashed lines. | |
| 133 result = MatchResult(DUMMY_CHANGELOG1, 'src/', confidence=1) | |
| 134 | |
| 135 stack_infos = [StackInfo( | |
| 136 frame = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [3]), | |
| 137 priority = 0)] | |
| 138 | |
| 139 result.Update('a.cc', stack_infos, DUMMY_BLAME) | |
| 140 self.assertEqual(result.file_to_analysis_info['a.cc'].min_distance, 3) | |
| 141 | |
| 142 # Touched lines are after crashed lines. | |
| 143 result = MatchResult(DUMMY_CHANGELOG1, 'src/', confidence=1) | |
| 144 | |
| 145 stack_infos = [StackInfo( | |
| 146 frame = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [10]), | |
| 147 priority = 0)] | |
| 148 | |
| 149 result.Update('a.cc', stack_infos, DUMMY_BLAME) | |
| 150 self.assertEqual(result.file_to_analysis_info['a.cc'].min_distance, 2) | |
| 151 | |
| 152 def testMatchResultUpdateWithEmptyBlame(self): | |
| 153 result = MatchResult(DUMMY_CHANGELOG1, 'src/', confidence=1) | |
| 154 stack_infos = [StackInfo( | |
| 155 frame = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [7]), | |
| 156 priority = 0)] | |
| 157 | |
| 158 result.Update('a.cc', stack_infos, None) | |
| 159 self.assertEqual(result.file_to_stack_infos['a.cc'], stack_infos) | |
| 160 self.assertEqual(result.file_to_analysis_info, {}) | |
| 161 | |
| 162 def testMatchResultUpdateMinimumDistance(self): | |
| 163 result = MatchResult(DUMMY_CHANGELOG1, 'src/', confidence=1) | |
| 164 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) | |
| 165 frame2 = StackFrame(2, 'src/', 'func', 'a.cc', 'src/a.cc', [20]) | |
| 166 stack_infos = [StackInfo(frame1, 0), StackInfo(frame2, 0)] | |
| 167 | |
| 168 result.Update('a.cc', stack_infos, DUMMY_BLAME) | |
| 169 self.assertEqual(result.file_to_stack_infos['a.cc'], stack_infos) | |
| 170 self.assertEqual(result.file_to_analysis_info, | |
| 171 {'a.cc': AnalysisInfo(min_distance = 0, min_distance_frame = frame1)}) | |
| 172 | |
| 173 def testMatchResultsGenerateMatchResults(self): | |
| 174 match_results = MatchResults(ignore_cls=set(['2'])) | |
| 175 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) | |
| 176 frame2 = StackFrame(1, 'src/', 'func', 'b.cc', 'src/b.cc', [11]) | |
| 177 stack_infos1 = [StackInfo(frame1, 0)] | |
| 178 stack_infos2 = [StackInfo(frame2, 0)] | |
| 179 match_results.GenerateMatchResults('a.cc', 'src/', stack_infos1, | |
| 180 [DUMMY_CHANGELOG1, DUMMY_CHANGELOG2], | |
| 181 DUMMY_BLAME) | |
| 182 | |
| 183 match_results.GenerateMatchResults('b.cc', 'src/', stack_infos2, | |
| 184 [DUMMY_CHANGELOG1, DUMMY_CHANGELOG2], | |
| 185 DUMMY_BLAME2) | |
| 186 | |
| 187 expected_match_result = MatchResult(DUMMY_CHANGELOG1, 'src/') | |
| 188 expected_match_result.file_to_stack_infos = { | |
| 189 'a.cc': stack_infos1, | |
| 190 'b.cc': stack_infos2, | |
| 191 } | |
| 192 expected_match_result.file_to_analysis_info = { | |
| 193 'a.cc': AnalysisInfo(min_distance = 0, min_distance_frame = frame1), | |
| 194 'b.cc': AnalysisInfo(min_distance = 3, min_distance_frame = frame2), | |
| 195 } | |
| 196 | |
| 197 expected_match_results = MatchResults(ignore_cls=set(['2'])) | |
| 198 expected_match_results['1'] = expected_match_result | |
| 199 | |
| 200 self._VerifyTwoMatchResultsEqual(match_results, expected_match_results) | |
| OLD | NEW |