| OLD | NEW |
| 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 | 6 |
| 7 from common.blame import Region, Blame | 7 from common.blame import Region, Blame |
| 8 from common.change_log import ChangeLog | 8 from common.change_log import ChangeLog |
| 9 from common.dependency import Dependency, DependencyRoll | 9 from common.dependency import Dependency, DependencyRoll |
| 10 from common.git_repository import GitRepository | 10 from common.git_repository import GitRepository |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 'src/': Dependency('src/', 'https://url_src', 'rev1', 'DEPS'), | 230 'src/': Dependency('src/', 'https://url_src', 'rev1', 'DEPS'), |
| 231 } | 231 } |
| 232 | 232 |
| 233 expected_match_results = [{ | 233 expected_match_results = [{ |
| 234 'url': 'https://repo.test/+/1', | 234 'url': 'https://repo.test/+/1', |
| 235 'review_url': 'https://codereview.chromium.org/3281', | 235 'review_url': 'https://codereview.chromium.org/3281', |
| 236 'revision': '1', | 236 'revision': '1', |
| 237 'project_path': 'src/', | 237 'project_path': 'src/', |
| 238 'author': 'r@chromium.org', | 238 'author': 'r@chromium.org', |
| 239 'time': 'Thu Mar 31 21:24:43 2016', | 239 'time': 'Thu Mar 31 21:24:43 2016', |
| 240 'reason': None, | 240 'reasons': None, |
| 241 'confidence': None, | 241 'confidence': None, |
| 242 'changed_files': None |
| 242 }] | 243 }] |
| 243 | 244 |
| 244 match_results = findit_for_crash.FindMatchResults( | 245 match_results = findit_for_crash.FindMatchResults( |
| 245 dep_file_to_changelogs, dep_file_to_stack_infos, stack_deps) | 246 dep_file_to_changelogs, dep_file_to_stack_infos, stack_deps) |
| 246 self.assertEqual([result.ToDict() for result in match_results], | 247 self.assertEqual([result.ToDict() for result in match_results], |
| 247 expected_match_results) | 248 expected_match_results) |
| 248 | 249 |
| 249 def testFindItForCrashNoRegressionRange(self): | 250 def testFindItForCrashNoRegressionRange(self): |
| 250 self.assertEqual( | 251 self.assertEqual( |
| 251 findit_for_crash.FindItForCrash(Stacktrace(), {}, {}), | 252 findit_for_crash.FindItForCrash(Stacktrace(), {}, {}), |
| 252 []) | 253 []) |
| 253 | 254 |
| 254 def testFindItForCrashNoMatchFound(self): | 255 def testFindItForCrashNoMatchFound(self): |
| 255 | 256 |
| 256 def _MockFindMatchResults(*_): | 257 def _MockFindMatchResults(*_): |
| 257 return [] | 258 return [] |
| 258 | 259 |
| 259 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) | 260 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) |
| 260 | 261 |
| 261 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', | 262 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', |
| 262 '1', '2')} | 263 '1', '2')} |
| 263 self.assertEqual(findit_for_crash.FindItForCrash( | 264 self.assertEqual(findit_for_crash.FindItForCrash( |
| 264 Stacktrace(), regression_deps_rolls, {}), []) | 265 Stacktrace(), regression_deps_rolls, {}), []) |
| 265 | 266 |
| 266 def testFindItForCrash(self): | 267 def testFindItForCrash(self): |
| 267 | 268 |
| 268 def _MockFindMatchResults(*_): | 269 def _MockFindMatchResults(*_): |
| 269 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') | 270 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') |
| 271 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) |
| 272 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) |
| 270 match_result1.file_to_stack_infos = { | 273 match_result1.file_to_stack_infos = { |
| 271 'a.cc': [ | 274 'a.cc': [(frame1, 0), (frame2, 0)] |
| 272 (StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]), 0), | |
| 273 (StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]), 0), | |
| 274 ] | |
| 275 } | 275 } |
| 276 match_result1.min_distance = 0 | 276 match_result1.file_to_analysis_info = { |
| 277 'a.cc': {'min_distance': 0, 'min_distance_frame': frame1} |
| 278 } |
| 277 | 279 |
| 278 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') | 280 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') |
| 281 frame3 = StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) |
| 279 match_result2.file_to_stack_infos = { | 282 match_result2.file_to_stack_infos = { |
| 280 'f.cc': [ | 283 'f.cc': [(frame3, 0)] |
| 281 (StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1]), 0), | |
| 282 ] | |
| 283 } | 284 } |
| 284 match_result2.min_distance = 20 | 285 match_result2.file_to_analysis_info = { |
| 286 'a.cc': {'min_distance': 20, 'min_distance_frame': frame3} |
| 287 } |
| 285 | 288 |
| 286 return [match_result1, match_result2] | 289 return [match_result1, match_result2] |
| 287 | 290 |
| 288 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) | 291 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) |
| 289 | 292 |
| 290 expected_match_results = [ | 293 expected_match_results = [ |
| 291 { | 294 { |
| 292 'reason': ('(1) Modified top crashing frame is #0\n' | 295 'reasons': [('TopFrameIndex', 1.0, 'Top frame is #0'), |
| 293 '(2) Modification distance (LOC) is 0\n\n' | 296 ('MinDistance', 1, 'Minimum distance is 0')], |
| 294 'Changed file a.cc crashed in frame #0, frame #1'), | 297 'changed_files': [{'info': 'Minimum distance (LOC) 0, frame #0', |
| 295 'time': 'Thu Mar 31 21:24:43 2016', | 298 'blame_url': None, 'file': 'a.cc'}], |
| 296 'author': 'r@chromium.org', | 299 'time': 'Thu Mar 31 21:24:43 2016', |
| 297 'url': 'https://repo.test/+/1', | 300 'author': 'r@chromium.org', |
| 298 'project_path': 'src/', | 301 'url': 'https://repo.test/+/1', |
| 299 'review_url': 'https://codereview.chromium.org/3281', | 302 'project_path': 'src/', |
| 300 'confidence': 1.0, 'revision': '1' | 303 'review_url': 'https://codereview.chromium.org/3281', |
| 301 }, | 304 'confidence': 1.0, 'revision': '1' |
| 305 }, |
| 302 ] | 306 ] |
| 303 | 307 |
| 304 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', | 308 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', |
| 305 '1', '2')} | 309 '1', '2')} |
| 306 | 310 |
| 307 results = findit_for_crash.FindItForCrash(Stacktrace(), | 311 results = findit_for_crash.FindItForCrash(Stacktrace(), |
| 308 regression_deps_rolls, {}) | 312 regression_deps_rolls, {}) |
| 309 self.assertEqual([result.ToDict() for result in results], | 313 self.assertEqual([result.ToDict() for result in results], |
| 310 expected_match_results) | 314 expected_match_results) |
| 311 | 315 |
| 312 def testFinditForCrashFilterZeroConfidentResults(self): | 316 def testFinditForCrashFilterZeroConfidentResults(self): |
| 313 def _MockFindMatchResults(*_): | 317 def _MockFindMatchResults(*_): |
| 314 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') | 318 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') |
| 319 frame1 = StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]) |
| 320 frame2 = StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]) |
| 315 match_result1.file_to_stack_infos = { | 321 match_result1.file_to_stack_infos = { |
| 316 'a.cc': [ | 322 'a.cc': [(frame1, 0), (frame2, 0)] |
| 317 (StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]), 0), | |
| 318 (StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]), 0), | |
| 319 ] | |
| 320 } | 323 } |
| 321 match_result1.min_distance = 1 | 324 match_result1.file_to_analysis_info = { |
| 325 'a.cc': {'min_distance': 1, 'min_distance_frame': frame1} |
| 326 } |
| 322 | 327 |
| 323 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') | 328 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') |
| 329 frame3 = StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1]) |
| 324 match_result2.file_to_stack_infos = { | 330 match_result2.file_to_stack_infos = { |
| 325 'f.cc': [ | 331 'f.cc': [(frame3, 0)] |
| 326 (StackFrame(15, 'src/', 'func', 'f.cc', 'src/f.cc', [1]), 0), | |
| 327 ] | |
| 328 } | 332 } |
| 329 match_result2.min_distance = 20 | 333 match_result2.file_to_analysis_info = { |
| 334 'f.cc': {'min_distance': 20, 'min_distance_frame': frame3} |
| 335 } |
| 330 | 336 |
| 331 match_result3 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') | 337 match_result3 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') |
| 338 frame4 = StackFrame(3, 'src/', 'func', 'ff.cc', 'src/ff.cc', [1]) |
| 332 match_result3.file_to_stack_infos = { | 339 match_result3.file_to_stack_infos = { |
| 333 'f.cc': [ | 340 'f.cc': [(frame4, 0)] |
| 334 (StackFrame(3, 'src/', 'func', 'ff.cc', 'src/ff.cc', [1]), 0), | |
| 335 ] | |
| 336 } | 341 } |
| 337 match_result3.min_distance = 60 | 342 match_result3.file_to_analysis_info = { |
| 343 'f.cc': {'min_distance': 60, 'min_distance_frame': frame4} |
| 344 } |
| 338 | 345 |
| 339 return [match_result1, match_result2, match_result3] | 346 return [match_result1, match_result2, match_result3] |
| 340 | 347 |
| 341 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) | 348 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) |
| 342 | 349 |
| 343 expected_match_results = [ | 350 expected_match_results = [ |
| 344 { | 351 { |
| 345 'reason': ('(1) Modified top crashing frame is #0\n' | 352 'author': 'r@chromium.org', |
| 346 '(2) Modification distance (LOC) is 1\n\n' | 353 'changed_files': [ |
| 347 'Changed file a.cc crashed in frame #0, frame #1'), | 354 { |
| 355 'blame_url': None, |
| 356 'file': 'a.cc', |
| 357 'info': 'Minimum distance (LOC) 1, frame #0' |
| 358 } |
| 359 ], |
| 360 'confidence': 0.8, |
| 361 'project_path': 'src/', |
| 362 'reasons': [ |
| 363 ('TopFrameIndex', 1.0, 'Top frame is #0'), |
| 364 ('MinDistance', 0.8, 'Minimum distance is 1') |
| 365 ], |
| 366 'review_url': 'https://codereview.chromium.org/3281', |
| 367 'revision': '1', |
| 348 'time': 'Thu Mar 31 21:24:43 2016', | 368 'time': 'Thu Mar 31 21:24:43 2016', |
| 349 'author': 'r@chromium.org', | 369 'url': 'https://repo.test/+/1' |
| 350 'url': 'https://repo.test/+/1', | 370 } |
| 351 'project_path': 'src/', | |
| 352 'review_url': 'https://codereview.chromium.org/3281', | |
| 353 'confidence': 0.8, 'revision': '1' | |
| 354 }, | |
| 355 ] | 371 ] |
| 356 | 372 |
| 357 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', | 373 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', |
| 358 '1', '2')} | 374 '1', '2')} |
| 359 | 375 |
| 360 results = findit_for_crash.FindItForCrash(Stacktrace(), | 376 results = findit_for_crash.FindItForCrash(Stacktrace(), |
| 361 regression_deps_rolls, {}) | 377 regression_deps_rolls, {}) |
| 378 |
| 362 self.assertEqual([result.ToDict() for result in results], | 379 self.assertEqual([result.ToDict() for result in results], |
| 363 expected_match_results) | 380 expected_match_results) |
| 364 | 381 |
| 365 def testFinditForCrashAllMatchResultsWithZeroConfidences(self): | 382 def testFinditForCrashAllMatchResultsWithZeroConfidences(self): |
| 366 def _MockFindMatchResults(*_): | 383 def _MockFindMatchResults(*_): |
| 367 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') | 384 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') |
| 385 frame1 = StackFrame(20, 'src/', '', 'func', 'a.cc', [1]) |
| 386 frame2 = StackFrame(21, 'src/', '', 'func', 'a.cc', [7]) |
| 368 match_result1.file_to_stack_infos = { | 387 match_result1.file_to_stack_infos = { |
| 369 'a.cc': [ | 388 'a.cc': [(frame1, 0), (frame2, 0)] |
| 370 (StackFrame(20, 'src/', '', 'func', 'a.cc', [1]), 0), | |
| 371 (StackFrame(21, 'src/', '', 'func', 'a.cc', [7]), 0), | |
| 372 ] | |
| 373 } | 389 } |
| 374 match_result1.min_distance = 1 | 390 match_result1.file_to_analysis_info = { |
| 391 'a.cc': {'min_distance': 1, 'min_distance_frame': frame1} |
| 392 } |
| 375 | 393 |
| 376 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') | 394 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') |
| 395 frame3 = StackFrame(15, 'src/', '', 'func', 'f.cc', [1]) |
| 377 match_result2.file_to_stack_infos = { | 396 match_result2.file_to_stack_infos = { |
| 378 'f.cc': [ | 397 'f.cc': [(frame3, 0)] |
| 379 (StackFrame(15, 'src/', '', 'func', 'f.cc', [1]), 0), | |
| 380 ] | |
| 381 } | 398 } |
| 382 match_result2.min_distance = 20 | 399 match_result2.min_distance = 20 |
| 400 match_result2.file_to_analysis_info = { |
| 401 'f.cc': {'min_distance': 20, 'min_distance_frame': frame3} |
| 402 } |
| 383 | 403 |
| 384 return [match_result1, match_result2] | 404 return [match_result1, match_result2] |
| 385 | 405 |
| 386 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) | 406 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) |
| 387 | 407 |
| 388 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', | 408 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', |
| 389 '1', '2')} | 409 '1', '2')} |
| 390 | 410 |
| 391 self.assertEqual(findit_for_crash.FindItForCrash( | 411 self.assertEqual(findit_for_crash.FindItForCrash( |
| 392 Stacktrace(), regression_deps_rolls, {}), []) | 412 Stacktrace(), regression_deps_rolls, {}), []) |
| OLD | NEW |