| 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 'revision': '3', | 88 'revision': '3', |
| 89 'reverted_revision': None | 89 'reverted_revision': None |
| 90 }) | 90 }) |
| 91 | 91 |
| 92 | 92 |
| 93 class FinditForCrashTest(CrashTestSuite): | 93 class FinditForCrashTest(CrashTestSuite): |
| 94 | 94 |
| 95 def testGetDepsInCrashStack(self): | 95 def testGetDepsInCrashStack(self): |
| 96 crash_stack = CallStack(0) | 96 crash_stack = CallStack(0) |
| 97 crash_stack.extend([ | 97 crash_stack.extend([ |
| 98 StackFrame(0, 'src/', '', 'func0', 'f0.cc', [1]), | 98 StackFrame(0, 'src/', 'func0', 'f0.cc', 'src/f0.cc', [1]), |
| 99 StackFrame(1, 'src/', '', 'func1', 'f1.cc', [2, 3]), | 99 StackFrame(1, 'src/', 'func1', 'f1.cc', 'src/f1.cc', [2, 3]), |
| 100 ]) | 100 ]) |
| 101 crash_deps = {'src/': Dependency('src/', 'https://chromium_repo', '1'), | 101 crash_deps = {'src/': Dependency('src/', 'https://chromium_repo', '1'), |
| 102 'src/v8/': Dependency('src/v8/', 'https://v8_repo', '2')} | 102 'src/v8/': Dependency('src/v8/', 'https://v8_repo', '2')} |
| 103 | 103 |
| 104 expected_stack_deps = {'src/': crash_deps['src/']} | 104 expected_stack_deps = {'src/': crash_deps['src/']} |
| 105 | 105 |
| 106 self.assertEqual( | 106 self.assertEqual( |
| 107 findit_for_crash.GetDepsInCrashStack(crash_stack, crash_deps), | 107 findit_for_crash.GetDepsInCrashStack(crash_stack, crash_deps), |
| 108 expected_stack_deps) | 108 expected_stack_deps) |
| 109 | 109 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 } | 155 } |
| 156 } | 156 } |
| 157 self.assertEqual(dep_file_to_changelogs_json, | 157 self.assertEqual(dep_file_to_changelogs_json, |
| 158 expected_dep_file_to_changelogs_json) | 158 expected_dep_file_to_changelogs_json) |
| 159 self.assertEqual(ignore_cls, set(['1'])) | 159 self.assertEqual(ignore_cls, set(['1'])) |
| 160 | 160 |
| 161 def testGetStackInfosForFilesGroupedByDeps(self): | 161 def testGetStackInfosForFilesGroupedByDeps(self): |
| 162 | 162 |
| 163 main_stack = CallStack(0) | 163 main_stack = CallStack(0) |
| 164 main_stack.extend( | 164 main_stack.extend( |
| 165 [StackFrame(0, 'src/', '', 'c(p* &d)', 'a.cc', [177]), | 165 [StackFrame(0, 'src/', 'c(p* &d)', 'a.cc', 'src/a.cc', [177]), |
| 166 StackFrame(1, 'src/', '', 'd(a* c)', 'a.cc', [227, 228, 229]), | 166 StackFrame(1, 'src/', 'd(a* c)', 'a.cc', 'src/a.cc', [227, 228, 229]), |
| 167 StackFrame(2, 'src/v8/', '', 'e(int)', 'b.cc', [87, 88, 89, 90])]) | 167 StackFrame(2, 'src/v8/', 'e(int)', 'b.cc', 'src/v8/b.cc', [89, 90])]) |
| 168 | 168 |
| 169 low_priority_stack = CallStack(1) | 169 low_priority_stack = CallStack(1) |
| 170 low_priority_stack.append( | 170 low_priority_stack.append( |
| 171 StackFrame(0, 'src/dummy/', '', 'c(p* &d)', 'd.cc', [17])) | 171 StackFrame(0, 'src/dummy/', 'c(p* &d)', 'd.cc', 'src/dummy/d.cc', [17])) |
| 172 | 172 |
| 173 stacktrace = Stacktrace() | 173 stacktrace = Stacktrace() |
| 174 stacktrace.extend([main_stack, low_priority_stack]) | 174 stacktrace.extend([main_stack, low_priority_stack]) |
| 175 | 175 |
| 176 crashed_deps = {'src/': Dependency('src/', 'https//repo', '2'), | 176 crashed_deps = {'src/': Dependency('src/', 'https//repo', '2'), |
| 177 'src/v8/': Dependency('src/v8', 'https//repo', '1')} | 177 'src/v8/': Dependency('src/v8', 'https//repo', '1')} |
| 178 | 178 |
| 179 expected_dep_file_to_stack_infos = { | 179 expected_dep_file_to_stack_infos = { |
| 180 'src/': { | 180 'src/': { |
| 181 'a.cc': [ | 181 'a.cc': [ |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 dummy_blame.AddRegion( | 215 dummy_blame.AddRegion( |
| 216 Region(6, 10, '1', 'b', 'b@email.com', 'Thu Mar 31 21:24:43 2016')) | 216 Region(6, 10, '1', 'b', 'b@email.com', 'Thu Mar 31 21:24:43 2016')) |
| 217 | 217 |
| 218 def _MockGetBlame(*_): | 218 def _MockGetBlame(*_): |
| 219 return dummy_blame | 219 return dummy_blame |
| 220 | 220 |
| 221 self.mock(GitRepository, 'GetBlame', _MockGetBlame) | 221 self.mock(GitRepository, 'GetBlame', _MockGetBlame) |
| 222 | 222 |
| 223 main_stack = CallStack(0) | 223 main_stack = CallStack(0) |
| 224 main_stack.extend( | 224 main_stack.extend( |
| 225 [StackFrame(0, 'src/', '', 'c(p* &d)', 'a.cc', [177]), | 225 [StackFrame(0, 'src/', 'c(p* &d)', 'a.cc', 'src/a.cc', [177]), |
| 226 StackFrame(1, 'src/', '', 'd(a* c)', 'a.cc', [227, 228, 229])]) | 226 StackFrame(1, 'src/', 'd(a* c)', 'a.cc', 'src/a.cc', [227, 228, 229])]) |
| 227 | 227 |
| 228 low_priority_stack = CallStack(1) | 228 low_priority_stack = CallStack(1) |
| 229 low_priority_stack.append( | 229 low_priority_stack.append( |
| 230 StackFrame(0, 'dummy_dep/', '', 'k(p* &d)', 'h.cc', [17])) | 230 StackFrame(0, 'dummy_dep/', 'k(p* &d)', 'h.cc', 'dummy_dep/h.cc', [17])) |
| 231 | 231 |
| 232 stacktrace = Stacktrace() | 232 stacktrace = Stacktrace() |
| 233 stacktrace.extend([main_stack, low_priority_stack]) | 233 stacktrace.extend([main_stack, low_priority_stack]) |
| 234 | 234 |
| 235 crash_deps = {'src/': Dependency('src/', 'https://chromium_repo', '1')} | 235 crash_deps = {'src/': Dependency('src/', 'https://chromium_repo', '1')} |
| 236 | 236 |
| 237 dep_file_to_blame = findit_for_crash.GetBlameForFilesGroupedByDeps( | 237 dep_file_to_blame = findit_for_crash.GetBlameForFilesGroupedByDeps( |
| 238 stacktrace, | 238 stacktrace, |
| 239 findit_for_crash.GetDepsInCrashStack(main_stack, crash_deps)) | 239 findit_for_crash.GetDepsInCrashStack(main_stack, crash_deps)) |
| 240 | 240 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 260 'src/': { | 260 'src/': { |
| 261 'a.cc': [ | 261 'a.cc': [ |
| 262 DUMMY_CHANGELOG1, | 262 DUMMY_CHANGELOG1, |
| 263 ] | 263 ] |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 | 266 |
| 267 dep_file_to_stack_infos = { | 267 dep_file_to_stack_infos = { |
| 268 'src/': { | 268 'src/': { |
| 269 'a.cc': [ | 269 'a.cc': [ |
| 270 (StackFrame(0, 'src/', '', 'func', 'a.cc', [1]), 0), | 270 (StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]), 0), |
| 271 (StackFrame(1, 'src/', '', 'func', 'a.cc', [7]), 0), | 271 (StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]), 0), |
| 272 ], | 272 ], |
| 273 'b.cc': [ | 273 'b.cc': [ |
| 274 (StackFrame(2, 'src/', '', 'func', 'b.cc', [36]), 0), | 274 (StackFrame(2, 'src/', 'func', 'b.cc', 'src/b.cc', [36]), 0), |
| 275 ] | 275 ] |
| 276 } | 276 } |
| 277 } | 277 } |
| 278 | 278 |
| 279 dummy_blame = Blame('9', 'a.cc') | 279 dummy_blame = Blame('9', 'a.cc') |
| 280 dummy_blame.AddRegion( | 280 dummy_blame.AddRegion( |
| 281 Region(1, 5, '6', 'a', 'a@chromium.org', 'Thu Mar 31 21:24:43 2016')) | 281 Region(1, 5, '6', 'a', 'a@chromium.org', 'Thu Mar 31 21:24:43 2016')) |
| 282 dummy_blame.AddRegion( | 282 dummy_blame.AddRegion( |
| 283 Region(6, 10, '1', 'b', 'b@chromium.org', 'Thu Jun 19 12:11:40 2015')) | 283 Region(6, 10, '1', 'b', 'b@chromium.org', 'Thu Jun 19 12:11:40 2015')) |
| 284 | 284 |
| 285 dep_file_to_blame = { | 285 dep_file_to_blame = { |
| 286 'src/': { | 286 'src/': { |
| 287 'a.cc': dummy_blame | 287 'a.cc': dummy_blame |
| 288 } | 288 } |
| 289 } | 289 } |
| 290 | 290 |
| 291 expected_match_results = [{ | 291 expected_match_results = [{ |
| 292 'url': 'https://repo.test/+/1', | 292 'url': 'https://repo.test/+/1', |
| 293 'revision': '1', | 293 'revision': '1', |
| 294 'dep_path': 'src/', | 294 'dep_path': 'src/', |
| 295 'component': '', | |
| 296 'author': 'r@chromium.org', | 295 'author': 'r@chromium.org', |
| 297 'time': 'Thu Mar 31 21:24:43 2016', | 296 'time': 'Thu Mar 31 21:24:43 2016', |
| 298 'reason': None, | 297 'reason': None, |
| 299 'confidence': None, | 298 'confidence': None, |
| 300 }] | 299 }] |
| 301 | 300 |
| 302 match_results = findit_for_crash.FindMatchResults(dep_file_to_changelogs, | 301 match_results = findit_for_crash.FindMatchResults(dep_file_to_changelogs, |
| 303 dep_file_to_stack_infos, | 302 dep_file_to_stack_infos, |
| 304 dep_file_to_blame) | 303 dep_file_to_blame) |
| 305 self.assertEqual([result.ToDict() for result in match_results], | 304 self.assertEqual([result.ToDict() for result in match_results], |
| (...skipping 15 matching lines...) Expand all Loading... |
| 321 '1', '2')} | 320 '1', '2')} |
| 322 self.assertEqual(findit_for_crash.FindItForCrash( | 321 self.assertEqual(findit_for_crash.FindItForCrash( |
| 323 Stacktrace(), regression_deps_rolls, {}), []) | 322 Stacktrace(), regression_deps_rolls, {}), []) |
| 324 | 323 |
| 325 def testFindItForCrash(self): | 324 def testFindItForCrash(self): |
| 326 | 325 |
| 327 def _MockFindMatchResults(*_): | 326 def _MockFindMatchResults(*_): |
| 328 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') | 327 match_result1 = MatchResult(DUMMY_CHANGELOG1, 'src/', '') |
| 329 match_result1.file_to_stack_infos = { | 328 match_result1.file_to_stack_infos = { |
| 330 'a.cc': [ | 329 'a.cc': [ |
| 331 (StackFrame(0, 'src/', '', 'func', 'a.cc', [1]), 0), | 330 (StackFrame(0, 'src/', 'func', 'a.cc', 'src/a.cc', [1]), 0), |
| 332 (StackFrame(1, 'src/', '', 'func', 'a.cc', [7]), 0), | 331 (StackFrame(1, 'src/', 'func', 'a.cc', 'src/a.cc', [7]), 0), |
| 333 ] | 332 ] |
| 334 } | 333 } |
| 335 match_result1.min_distance = 0 | 334 match_result1.min_distance = 0 |
| 336 | 335 |
| 337 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') | 336 match_result2 = MatchResult(DUMMY_CHANGELOG3, 'src/', '') |
| 338 match_result2.file_to_stack_infos = { | 337 match_result2.file_to_stack_infos = { |
| 339 'f.cc': [ | 338 'f.cc': [ |
| 340 (StackFrame(5, 'src/', '', 'func', 'f.cc', [1]), 0), | 339 (StackFrame(5, 'src/', 'func', 'f.cc', 'src/f.cc', [1]), 0), |
| 341 ] | 340 ] |
| 342 } | 341 } |
| 343 match_result2.min_distance = 20 | 342 match_result2.min_distance = 20 |
| 344 | 343 |
| 345 return [match_result1, match_result2] | 344 return [match_result1, match_result2] |
| 346 | 345 |
| 347 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) | 346 self.mock(findit_for_crash, 'FindMatchResults', _MockFindMatchResults) |
| 348 | 347 |
| 349 expected_match_results = [ | 348 expected_match_results = [ |
| 350 { | 349 { |
| 351 'url': 'https://repo.test/+/1', | 350 'url': 'https://repo.test/+/1', |
| 352 'revision': '1', | 351 'revision': '1', |
| 353 'dep_path': 'src/', | 352 'dep_path': 'src/', |
| 354 'component': '', | |
| 355 'author': 'r@chromium.org', | 353 'author': 'r@chromium.org', |
| 356 'time': 'Thu Mar 31 21:24:43 2016', | 354 'time': 'Thu Mar 31 21:24:43 2016', |
| 357 'reason': ('1. Top frame changed is frame #0 (score: 1)\n' | 355 'reason': ('1. Top frame changed is frame #0 (score: 1)\n' |
| 358 '2. Minimum distance to crashed line is 0 (score: 1)\n' | 356 '2. Minimum distance to crashed line is 0 (score: 1)\n' |
| 359 '\nChanged file a.cc crashed in func (#0)' | 357 '\nChanged file a.cc crashed in func (#0)' |
| 360 ', func (#1)'), | 358 ', func (#1)'), |
| 361 'confidence': 1, | 359 'confidence': 1, |
| 362 }, | 360 }, |
| 363 { | 361 { |
| 364 'url': 'https://repo.test/+/3', | 362 'url': 'https://repo.test/+/3', |
| 365 'revision': '3', | 363 'revision': '3', |
| 366 'dep_path': 'src/', | 364 'dep_path': 'src/', |
| 367 'component': '', | |
| 368 'author': 'e@chromium.org', | 365 'author': 'e@chromium.org', |
| 369 'time': 'Thu Apr 1 21:24:43 2016', | 366 'time': 'Thu Apr 1 21:24:43 2016', |
| 370 'reason': ('1. Top frame changed is frame #5 (score: 0)\n' | 367 'reason': ('1. Top frame changed is frame #5 (score: 0)\n' |
| 371 '2. Minimum distance to crashed line is 20 (score: 0)\n' | 368 '2. Minimum distance to crashed line is 20 (score: 0)\n' |
| 372 '\nChanged file f.cc crashed in func (#5)'), | 369 '\nChanged file f.cc crashed in func (#5)'), |
| 373 'confidence': 0.22857142857142856, | 370 'confidence': 0.22857142857142856, |
| 374 }, | 371 }, |
| 375 ] | 372 ] |
| 376 | 373 |
| 377 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', | 374 regression_deps_rolls = {'src/': DependencyRoll('src/', 'https://repo', |
| 378 '1', '2')} | 375 '1', '2')} |
| 379 | 376 |
| 380 self.assertEqual(findit_for_crash.FindItForCrash( | 377 self.assertEqual(findit_for_crash.FindItForCrash( |
| 381 Stacktrace(), regression_deps_rolls, {}), expected_match_results) | 378 Stacktrace(), regression_deps_rolls, {}), expected_match_results) |
| OLD | NEW |