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

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

Issue 2663063007: [Predator] Switch from anonymous dict to CrashData. (Closed)
Patch Set: Rebase and fix delta test. Created 3 years, 10 months 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 import copy 5 import copy
6 import logging 6 import logging
7 import math 7 import math
8 import pprint 8 import pprint
9 9
10 from common.dependency import Dependency 10 from common.dependency import Dependency
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 'code_review_url': 'https://codereview.chromium.org/3281', 113 'code_review_url': 'https://codereview.chromium.org/3281',
114 'revision': '3', 114 'revision': '3',
115 'reverted_revision': None 115 'reverted_revision': None
116 }) 116 })
117 117
118 DUMMY_CALLSTACKS = [ 118 DUMMY_CALLSTACKS = [
119 CallStack(0, [], CallStackFormatType.DEFAULT, LanguageType.CPP), 119 CallStack(0, [], CallStackFormatType.DEFAULT, LanguageType.CPP),
120 CallStack(1, [], CallStackFormatType.DEFAULT, LanguageType.CPP)] 120 CallStack(1, [], CallStackFormatType.DEFAULT, LanguageType.CPP)]
121 DUMMY_REPORT = CrashReport( 121 DUMMY_REPORT = CrashReport(
122 None, None, None, Stacktrace(DUMMY_CALLSTACKS, DUMMY_CALLSTACKS[0]), 122 None, None, None, Stacktrace(DUMMY_CALLSTACKS, DUMMY_CALLSTACKS[0]),
123 (None, None)) 123 (None, None), None, None)
124 124
125 125
126 class LogLinearChangelistClassifierTest(CrashTestSuite): 126 class LogLinearChangelistClassifierTest(CrashTestSuite):
127 127
128 def setUp(self): 128 def setUp(self):
129 super(LogLinearChangelistClassifierTest, self).setUp() 129 super(LogLinearChangelistClassifierTest, self).setUp()
130 meta_weight = MetaWeight({ 130 meta_weight = MetaWeight({
131 'TouchCrashedFileMeta': MetaWeight({ 131 'TouchCrashedFileMeta': MetaWeight({
132 'MinDistance': Weight(1.), 132 'MinDistance': Weight(1.),
133 'TopFrameIndex': Weight(1.), 133 'TopFrameIndex': Weight(1.),
134 'TouchCrashedFile': Weight(1.), 134 'TouchCrashedFile': Weight(1.),
135 }) 135 })
136 }) 136 })
137 get_repository = GitilesRepository.Factory(self.GetMockHttpClient()) 137 get_repository = GitilesRepository.Factory(self.GetMockHttpClient())
138 meta_feature = WrapperMetaFeature( 138 meta_feature = WrapperMetaFeature(
139 [TouchCrashedFileMetaFeature(get_repository)]) 139 [TouchCrashedFileMetaFeature(get_repository)])
140 140
141 self.changelist_classifier = LogLinearChangelistClassifier( 141 self.changelist_classifier = LogLinearChangelistClassifier(
142 get_repository, meta_feature, meta_weight) 142 get_repository, meta_feature, meta_weight)
143 143
144 # TODO(http://crbug.com/659346): why do these mocks give coverage 144 # TODO(http://crbug.com/659346): why do these mocks give coverage
145 # failures? That's almost surely hiding a bug in the tests themselves. 145 # failures? That's almost surely hiding a bug in the tests themselves.
146 def testFindItForCrashNoRegressionRange(self): # pragma: no cover 146 def testFindItForCrashNoRegressionRange(self): # pragma: no cover
147 self.mock(ChromeDependencyFetcher, 'GetDependencyRollsDict', lambda *_: {})
148 self.mock(ChromeDependencyFetcher, 'GetDependency', lambda *_: {})
149 # N.B., for this one test we really do want regression_range=None. 147 # N.B., for this one test we really do want regression_range=None.
150 report = CrashReport(None, None, None, Stacktrace(DUMMY_CALLSTACKS, 148 report = CrashReport(None, None, None, Stacktrace(DUMMY_CALLSTACKS,
151 DUMMY_CALLSTACKS[0]), 149 DUMMY_CALLSTACKS[0]),
152 None) 150 None, {}, {})
153 self.assertListEqual(self.changelist_classifier(report), []) 151 self.assertListEqual(self.changelist_classifier(report), [])
154 152
155 def testFindItForCrashNoMatchFound(self): 153 def testFindItForCrashNoMatchFound(self):
156 self.mock(scorer_changelist_classifier, 'FindSuspects', lambda *_: []) 154 self.mock(scorer_changelist_classifier, 'FindSuspects', lambda *_: [])
157 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), []) 155 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), [])
158 156
159 self.mock(scorer_changelist_classifier, 'FindSuspects', lambda *_: None) 157 self.mock(scorer_changelist_classifier, 'FindSuspects', lambda *_: None)
160 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), []) 158 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), [])
161 159
162 def testFindItForCrash(self): 160 def testFindItForCrash(self):
(...skipping 22 matching lines...) Expand all
185 'GetChangeLogsForFilesGroupedByDeps', 183 'GetChangeLogsForFilesGroupedByDeps',
186 lambda *_: (None, None)) 184 lambda *_: (None, None))
187 self.mock(scorer_changelist_classifier, 'FindSuspects', 185 self.mock(scorer_changelist_classifier, 'FindSuspects',
188 lambda *_: [suspect1, suspect2]) 186 lambda *_: [suspect1, suspect2])
189 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) 187 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
190 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) 188 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
191 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) 189 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1])
192 frame4 = StackFrame(3, 'src/dep1', 'func', 'f.cc', 'src/dep1/f.cc', [1]) 190 frame4 = StackFrame(3, 'src/dep1', 'func', 'f.cc', 'src/dep1/f.cc', [1])
193 stacks = [CallStack(0, frame_list=[frame1, frame2, frame3, frame4])] 191 stacks = [CallStack(0, frame_list=[frame1, frame2, frame3, frame4])]
194 stacktrace = Stacktrace(stacks, stacks[0]) 192 stacktrace = Stacktrace(stacks, stacks[0])
195 report = CrashReport('6', 'sig', 'win', stacktrace, ('0', '4')) 193 report = CrashReport(
196 self.mock(ChromeDependencyFetcher, 'GetDependency', 194 '6', 'sig', 'win', stacktrace, ('0', '4'),
197 lambda *_: {'src/': Dependency('src/', 'https://repo', '6')}) 195 {'src/': Dependency('src/', 'https://repo', '6')},
198 self.mock(ChromeDependencyFetcher, 'GetDependencyRollsDict', 196 {'src/': DependencyRoll('src/', 'https://repo', '0', '4')} )
199 lambda *_: {'src/': DependencyRoll('src/', 'https://repo',
200 '0', '4')})
201 197
202 suspects = self.changelist_classifier(report) 198 suspects = self.changelist_classifier(report)
203 self.assertTrue(suspects, 199 self.assertTrue(suspects,
204 'Expected suspects, but the classifier didn\'t return any')
205
206 expected_suspects = [
207 {
208 'author': 'r@chromium.org',
209 'changed_files': [
210 {
211 'blame_url': None,
212 'file': 'a.cc',
213 'info': ('Distance from touched lines and crashed lines is '
214 '0, in frame #0')
215 }
216 ],
217 'confidence': 0.,
218 'project_path': 'src/',
219 'reasons': ('MinDistance: 0.000000 -- Minimum distance is '
220 '0\nTopFrameIndex: 0.000000 -- Top frame is #0\n'
221 'TouchCrashedFile: 0.000000 -- Touched files - a.cc'),
222 'review_url': 'https://codereview.chromium.org/3281',
223 'revision': '1',
224 'time': 'Thu Mar 31 21:24:43 2016',
225 'url': 'https://repo.test/+/1'
226 },
227 ]
228 self.assertListEqual([suspect.ToDict() for suspect in suspects],
229 expected_suspects)
230
231 def testFinditForCrashFilterZeroConfidenceSuspects(self):
232 suspect1 = Suspect(DUMMY_CHANGELOG1, 'src/')
233 suspect2 = Suspect(DUMMY_CHANGELOG3, 'src/')
234
235 a_cc_blame = Blame('6', 'src/')
236 a_cc_blame.AddRegions([Region(0, 10, suspect1.changelog.revision,
237 suspect1.changelog.author.name,
238 suspect1.changelog.author.email,
239 suspect1.changelog.author.time)])
240 f_cc_blame = Blame('6', 'src/')
241 f_cc_blame.AddRegions([Region(21, 10, suspect2.changelog.revision,
242 suspect2.changelog.author.name,
243 suspect2.changelog.author.email,
244 suspect2.changelog.author.time)])
245 url_to_blame = {'6/a.cc': a_cc_blame,
246 '6/f.cc': f_cc_blame}
247
248 def _MockGetBlame(_, path, revision):
249 revision_path = '%s/%s' % (revision, path)
250 return url_to_blame.get(revision_path)
251
252 self.mock(GitilesRepository, 'GetBlame', _MockGetBlame)
253 self.mock(scorer_changelist_classifier,
254 'GetChangeLogsForFilesGroupedByDeps',
255 lambda *_: (None, None))
256 self.mock(scorer_changelist_classifier, 'FindSuspects',
257 lambda *_: [suspect1, suspect2])
258 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
259 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
260 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1])
261 stacks = [CallStack(0, frame_list=[frame1, frame2, frame3])]
262 stacktrace = Stacktrace(stacks, stacks[0])
263 report = CrashReport('6', 'sig', 'win', stacktrace, ('0', '4'))
264 self.mock(ChromeDependencyFetcher, 'GetDependency',
265 lambda *_: {'src/': Dependency('src/', 'https://repo', '6')})
266 self.mock(ChromeDependencyFetcher, 'GetDependencyRollsDict',
267 lambda *_: {'src/': DependencyRoll('src/', 'https://repo',
268 '0', '4')})
269
270 suspects = self.changelist_classifier(report)
271 self.assertTrue(suspects,
272 'Expected suspects, but the classifier didn\'t return any') 200 'Expected suspects, but the classifier didn\'t return any')
273 201
274 expected_suspects = [ 202 expected_suspects = [
275 { 203 {
276 'author': 'r@chromium.org', 204 'author': 'r@chromium.org',
277 'changed_files': [ 205 'changed_files': [
278 { 206 {
279 'blame_url': None, 207 'blame_url': None,
280 'file': 'a.cc', 208 'file': 'a.cc',
281 'info': ('Distance from touched lines and crashed lines is ' 209 'info': ('Distance from touched lines and crashed lines is '
282 '0, in frame #0') 210 '0, in frame #0')
283 } 211 }
284 ], 212 ],
285 'confidence': 0., 213 'confidence': 0.,
286 'project_path': 'src/', 214 'project_path': 'src/',
287 'reasons': ('MinDistance: 0.000000 -- Minimum distance is ' 215 'reasons': ('MinDistance: 0.000000 -- Minimum distance is '
288 '0\nTopFrameIndex: 0.000000 -- Top frame is #0\n' 216 '0\nTopFrameIndex: 0.000000 -- Top frame is #0\n'
289 'TouchCrashedFile: 0.000000 -- Touched files - a.cc'), 217 'TouchCrashedFile: 0.000000 -- Touched files - a.cc'),
290 'review_url': 'https://codereview.chromium.org/3281', 218 'review_url': 'https://codereview.chromium.org/3281',
291 'revision': '1', 219 'revision': '1',
292 'time': 'Thu Mar 31 21:24:43 2016', 220 'time': 'Thu Mar 31 21:24:43 2016',
293 'url': 'https://repo.test/+/1' 221 'url': 'https://repo.test/+/1'
294 }, 222 },
295 ] 223 ]
296 self.assertListEqual([suspect.ToDict() for suspect in suspects], 224 self.assertListEqual([suspect.ToDict() for suspect in suspects],
297 expected_suspects) 225 expected_suspects)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698