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

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

Issue 2562623004: Making CallStack immutable, so it can be hashable (Closed)
Patch Set: Addressing nits 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.results import AnalysisInfo
14 from crash.results import StackInfo
14 from crash.results import MatchResult 15 from crash.results import MatchResult
15 from crash.stacktrace import CallStack 16 from crash.stacktrace import CallStack
16 from crash.stacktrace import StackFrame 17 from crash.stacktrace import StackFrame
17 from crash.stacktrace import Stacktrace 18 from crash.stacktrace import Stacktrace
18 from crash.test.crash_test_suite import CrashTestSuite 19 from crash.test.crash_test_suite import CrashTestSuite
19 from libs.gitiles.blame import Blame 20 from libs.gitiles.blame import Blame
20 from libs.gitiles.blame import Region 21 from libs.gitiles.blame import Region
21 from libs.gitiles.change_log import ChangeLog 22 from libs.gitiles.change_log import ChangeLog
22 from libs.gitiles.gitiles_repository import GitilesRepository 23 from libs.gitiles.gitiles_repository import GitilesRepository
23 24
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 expected_regression_deps_rolls = copy.deepcopy(dep_rolls) 146 expected_regression_deps_rolls = copy.deepcopy(dep_rolls)
146 147
147 # Regression of a dep added/deleted (old_revision/new_revision is None) can 148 # Regression of a dep added/deleted (old_revision/new_revision is None) can
148 # not be known for sure and this case rarely happens, so just filter them 149 # not be known for sure and this case rarely happens, so just filter them
149 # out. 150 # out.
150 del expected_regression_deps_rolls['src/dep'] 151 del expected_regression_deps_rolls['src/dep']
151 self.assertEqual(passed_in_regression_deps_rolls[0], 152 self.assertEqual(passed_in_regression_deps_rolls[0],
152 expected_regression_deps_rolls) 153 expected_regression_deps_rolls)
153 154
154 def testGetDepsInCrashStack(self): 155 def testGetDepsInCrashStack(self):
155 crash_stack = CallStack(0) 156 crash_stack = CallStack(0, frame_list=[
156 crash_stack.extend([
157 StackFrame(0, 'src/', 'func0', 'f0.cc', 'src/f0.cc', [1]), 157 StackFrame(0, 'src/', 'func0', 'f0.cc', 'src/f0.cc', [1]),
158 StackFrame(1, 'src/', 'func1', 'f1.cc', 'src/f1.cc', [2, 3]), 158 StackFrame(1, 'src/', 'func1', 'f1.cc', 'src/f1.cc', [2, 3]),
159 StackFrame(1, '', 'func2', 'f2.cc', 'src/f2.cc', [2, 3]), 159 StackFrame(1, '', 'func2', 'f2.cc', 'src/f2.cc', [2, 3])])
160 ])
161 crash_deps = {'src/': Dependency('src/', 'https://chromium_repo', '1'), 160 crash_deps = {'src/': Dependency('src/', 'https://chromium_repo', '1'),
162 'src/v8/': Dependency('src/v8/', 'https://v8_repo', '2')} 161 'src/v8/': Dependency('src/v8/', 'https://v8_repo', '2')}
163 162
164 expected_stack_deps = {'src/': crash_deps['src/']} 163 expected_stack_deps = {'src/': crash_deps['src/']}
165 164
166 self.assertDictEqual( 165 self.assertDictEqual(
167 changelist_classifier.GetDepsInCrashStack(crash_stack, crash_deps), 166 changelist_classifier.GetDepsInCrashStack(crash_stack, crash_deps),
168 expected_stack_deps) 167 expected_stack_deps)
169 168
170 def testGetChangeLogsForFilesGroupedByDeps(self): 169 def testGetChangeLogsForFilesGroupedByDeps(self):
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 'src/': { 201 'src/': {
203 'a.cc': [DUMMY_CHANGELOG1.ToDict()], 202 'a.cc': [DUMMY_CHANGELOG1.ToDict()],
204 'f.cc': [DUMMY_CHANGELOG3.ToDict()] 203 'f.cc': [DUMMY_CHANGELOG3.ToDict()]
205 } 204 }
206 } 205 }
207 self.assertDictEqual(dep_file_to_changelogs_json, 206 self.assertDictEqual(dep_file_to_changelogs_json,
208 expected_dep_file_to_changelogs_json) 207 expected_dep_file_to_changelogs_json)
209 self.assertSetEqual(ignore_cls, set(['1'])) 208 self.assertSetEqual(ignore_cls, set(['1']))
210 209
211 def testGetStackInfosForFilesGroupedByDeps(self): 210 def testGetStackInfosForFilesGroupedByDeps(self):
212 main_stack = CallStack(0) 211 main_stack = CallStack(0, frame_list=[
213 main_stack.extend( 212 StackFrame(0, 'src/', 'c(p* &d)', 'a.cc', 'src/a.cc', [177]),
214 [StackFrame(0, 'src/', 'c(p* &d)', 'a.cc', 'src/a.cc', [177]), 213 StackFrame(1, 'src/', 'd(a* c)', 'a.cc', 'src/a.cc', [227, 228, 229]),
215 StackFrame(1, 'src/', 'd(a* c)', 'a.cc', 'src/a.cc', [227, 228, 229]), 214 StackFrame(2, 'src/v8/', 'e(int)', 'b.cc', 'src/v8/b.cc', [89, 90])])
216 StackFrame(2, 'src/v8/', 'e(int)', 'b.cc', 'src/v8/b.cc', [89, 90])])
217 215
218 low_priority_stack = CallStack(1) 216 low_priority_stack = CallStack(1, frame_list=[
219 low_priority_stack.append( 217 StackFrame(0, 'src/dummy/', 'c(p* &d)', 'd.cc', 'src/dummy/d.cc',
220 StackFrame(0, 'src/dummy/', 'c(p* &d)', 'd.cc', 'src/dummy/d.cc', [17])) 218 [17])])
221 219
222 stacktrace = Stacktrace() 220 stacktrace = Stacktrace(stack_list=[main_stack, low_priority_stack])
223 stacktrace.extend([main_stack, low_priority_stack])
224 221
225 crashed_deps = {'src/': Dependency('src/', 'https//repo', '2'), 222 crashed_deps = {'src/': Dependency('src/', 'https//repo', '2'),
226 'src/v8/': Dependency('src/v8', 'https//repo', '1')} 223 'src/v8/': Dependency('src/v8', 'https//repo', '1')}
227 224
228 expected_dep_file_to_stack_infos = { 225 expected_dep_file_to_stack_infos = {
229 'src/': { 226 'src/': {
230 'a.cc': [ 227 'a.cc': [
231 (main_stack[0], 0), 228 StackInfo(main_stack.frames[0], 0),
232 (main_stack[1], 0), 229 StackInfo(main_stack.frames[1], 0),
233 ], 230 ],
234 }, 231 },
235 'src/v8/': { 232 'src/v8/': {
236 'b.cc': [ 233 'b.cc': [
237 (main_stack[2], 0), 234 StackInfo(main_stack.frames[2], 0),
238 ] 235 ]
239 } 236 }
240 } 237 }
241 238
242 dep_file_to_stack_infos = ( 239 dep_file_to_stack_infos = (
243 changelist_classifier.GetStackInfosForFilesGroupedByDeps( 240 changelist_classifier.GetStackInfosForFilesGroupedByDeps(
244 stacktrace, crashed_deps)) 241 stacktrace, crashed_deps))
245 242
246 self.assertEqual(len(dep_file_to_stack_infos), 243 self.assertEqual(len(dep_file_to_stack_infos),
247 len(expected_dep_file_to_stack_infos)) 244 len(expected_dep_file_to_stack_infos))
(...skipping 13 matching lines...) Expand all
261 'src/': { 258 'src/': {
262 'a.cc': [ 259 'a.cc': [
263 DUMMY_CHANGELOG1, 260 DUMMY_CHANGELOG1,
264 ] 261 ]
265 } 262 }
266 } 263 }
267 264
268 dep_file_to_stack_infos = { 265 dep_file_to_stack_infos = {
269 'src/': { 266 'src/': {
270 'a.cc': [ 267 'a.cc': [
271 (StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]), 0), 268 StackInfo(StackFrame(
272 (StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]), 0), 269 0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]), 0),
270 StackInfo(StackFrame(
271 1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]), 0),
273 ], 272 ],
274 'b.cc': [ 273 'b.cc': [
275 (StackFrame(2, 'src/', 'func', 'b.cc', 'src/b.cc', [36]), 0), 274 StackInfo(StackFrame(
275 2, 'src/', 'func', 'b.cc', 'src/b.cc', [36]), 0),
276 ] 276 ]
277 } 277 }
278 } 278 }
279 279
280 dummy_blame = Blame('9', 'a.cc') 280 dummy_blame = Blame('9', 'a.cc')
281 dummy_blame.AddRegion( 281 dummy_blame.AddRegion(
282 Region(1, 5, '6', 'a', 'a@chromium.org', 'Thu Mar 31 21:24:43 2016')) 282 Region(1, 5, '6', 'a', 'a@chromium.org', 'Thu Mar 31 21:24:43 2016'))
283 dummy_blame.AddRegion( 283 dummy_blame.AddRegion(
284 Region(6, 10, '1', 'b', 'b@chromium.org', 'Thu Jun 19 12:11:40 2015')) 284 Region(6, 10, '1', 'b', 'b@chromium.org', 'Thu Jun 19 12:11:40 2015'))
285 285
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 'GetDependency', lambda *_: {}) 327 'GetDependency', lambda *_: {})
328 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), []) 328 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), [])
329 329
330 def testFindItForCrash(self): 330 def testFindItForCrash(self):
331 331
332 def _MockFindMatchResults(*_): 332 def _MockFindMatchResults(*_):
333 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') 333 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '')
334 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) 334 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
335 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) 335 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
336 match_result1.file_to_stack_infos = { 336 match_result1.file_to_stack_infos = {
337 'a.cc': [(frame1, 0), (frame2, 0)] 337 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)]
338 } 338 }
339 match_result1.file_to_analysis_info = { 339 match_result1.file_to_analysis_info = {
340 'a.cc': AnalysisInfo(min_distance=0, min_distance_frame=frame1) 340 'a.cc': AnalysisInfo(min_distance=0, min_distance_frame=frame1)
341 } 341 }
342 342
343 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') 343 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '')
344 frame3 = StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) 344 frame3 = StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1])
345 match_result2.file_to_stack_infos = { 345 match_result2.file_to_stack_infos = {
346 'f.cc': [(frame3, 0)] 346 'f.cc': [StackInfo(frame3, 0)]
347 } 347 }
348 match_result2.file_to_analysis_info = { 348 match_result2.file_to_analysis_info = {
349 'a.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3) 349 'a.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
350 } 350 }
351 351
352 return [match_result1, match_result2] 352 return [match_result1, match_result2]
353 353
354 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 354 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
355 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 355 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
356 'GetDependencyRollsDict', 356 'GetDependencyRollsDict',
(...skipping 17 matching lines...) Expand all
374 ] 374 ]
375 self.assertListEqual([result.ToDict() for result in results], 375 self.assertListEqual([result.ToDict() for result in results],
376 expected_match_results) 376 expected_match_results)
377 377
378 def testFinditForCrashFilterZeroConfidentResults(self): 378 def testFinditForCrashFilterZeroConfidentResults(self):
379 def _MockFindMatchResults(*_): 379 def _MockFindMatchResults(*_):
380 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') 380 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '')
381 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) 381 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1])
382 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) 382 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7])
383 match_result1.file_to_stack_infos = { 383 match_result1.file_to_stack_infos = {
384 'a.cc': [(frame1, 0), (frame2, 0)] 384 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)]
385 } 385 }
386 match_result1.file_to_analysis_info = { 386 match_result1.file_to_analysis_info = {
387 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1) 387 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1)
388 } 388 }
389 389
390 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') 390 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '')
391 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) 391 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1])
392 match_result2.file_to_stack_infos = { 392 match_result2.file_to_stack_infos = {
393 'f.cc': [(frame3, 0)] 393 'f.cc': [StackInfo(frame3, 0)]
394 } 394 }
395 match_result2.file_to_analysis_info = { 395 match_result2.file_to_analysis_info = {
396 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3) 396 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
397 } 397 }
398 398
399 match_result3 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') 399 match_result3 = MatchResult(DUMMY_CHANGELOG3, 'src/', '')
400 frame4 = StackFrame(3, 'src/', 'func', 'ff.cc', 'src/ff.cc', [1]) 400 frame4 = StackFrame(3, 'src/', 'func', 'ff.cc', 'src/ff.cc', [1])
401 match_result3.file_to_stack_infos = { 401 match_result3.file_to_stack_infos = {
402 'f.cc': [(frame4, 0)] 402 'f.cc': [StackInfo(frame4, 0)]
403 } 403 }
404 match_result3.file_to_analysis_info = { 404 match_result3.file_to_analysis_info = {
405 'f.cc': AnalysisInfo(min_distance=60, min_distance_frame=frame4) 405 'f.cc': AnalysisInfo(min_distance=60, min_distance_frame=frame4)
406 } 406 }
407 407
408 return [match_result1, match_result2, match_result3] 408 return [match_result1, match_result2, match_result3]
409 409
410 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 410 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
411 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 411 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
412 'GetDependencyRollsDict', 412 'GetDependencyRollsDict',
(...skipping 26 matching lines...) Expand all
439 ] 439 ]
440 self.assertListEqual([result.ToDict() for result in results], 440 self.assertListEqual([result.ToDict() for result in results],
441 expected_match_results) 441 expected_match_results)
442 442
443 def testFinditForCrashAllMatchResultsWithZeroConfidences(self): 443 def testFinditForCrashAllMatchResultsWithZeroConfidences(self):
444 def _MockFindMatchResults(*_): 444 def _MockFindMatchResults(*_):
445 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') 445 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '')
446 frame1 = StackFrame(20, 'src/', '', 'func', 'a.cc', [1]) 446 frame1 = StackFrame(20, 'src/', '', 'func', 'a.cc', [1])
447 frame2 = StackFrame(21, 'src/', '', 'func', 'a.cc', [7]) 447 frame2 = StackFrame(21, 'src/', '', 'func', 'a.cc', [7])
448 match_result1.file_to_stack_infos = { 448 match_result1.file_to_stack_infos = {
449 'a.cc': [(frame1, 0), (frame2, 0)] 449 'a.cc': [StackInfo(frame1, 0), StackInfo(frame2, 0)]
450 } 450 }
451 match_result1.file_to_analysis_info = { 451 match_result1.file_to_analysis_info = {
452 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1) 452 'a.cc': AnalysisInfo(min_distance=1, min_distance_frame=frame1)
453 } 453 }
454 454
455 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') 455 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '')
456 frame3 = StackFrame(15, 'src/', '', 'func', 'f.cc', [1]) 456 frame3 = StackFrame(15, 'src/', '', 'func', 'f.cc', [1])
457 match_result2.file_to_stack_infos = { 457 match_result2.file_to_stack_infos = {
458 'f.cc': [(frame3, 0)] 458 'f.cc': [StackInfo(frame3, 0)]
459 } 459 }
460 match_result2.min_distance = 20 460 match_result2.min_distance = 20
461 match_result2.file_to_analysis_info = { 461 match_result2.file_to_analysis_info = {
462 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3) 462 'f.cc': AnalysisInfo(min_distance=20, min_distance_frame=frame3)
463 } 463 }
464 464
465 return [match_result1, match_result2] 465 return [match_result1, match_result2]
466 466
467 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults) 467 self.mock(changelist_classifier, 'FindMatchResults', _MockFindMatchResults)
468 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 468 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
469 'GetDependencyRollsDict', 469 'GetDependencyRollsDict',
470 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')}) 470 lambda *_: {'src/': DependencyRoll('src/', 'https://repo', '1', '2')})
471 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, 471 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher,
472 'GetDependency', lambda *_: {}) 472 'GetDependency', lambda *_: {})
473 473
474 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), []) 474 self.assertListEqual(self.changelist_classifier(DUMMY_REPORT), [])
OLDNEW
« no previous file with comments | « appengine/findit/crash/stacktrace.py ('k') | appengine/findit/crash/test/chromecrash_parser_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698