| 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 common import chrome_dependency_fetcher | 5 from common import chrome_dependency_fetcher |
| 6 from common.dependency import DependencyRoll | 6 from common.dependency import DependencyRoll |
| 7 from common.http_client_appengine import HttpClientAppengine | 7 from common.http_client_appengine import HttpClientAppengine |
| 8 from crash import chromecrash_parser | 8 from crash import chromecrash_parser |
| 9 from crash import detect_regression_range | 9 from crash import detect_regression_range |
| 10 from crash import findit_for_chromecrash | 10 from crash import findit_for_chromecrash |
| 11 from crash.changelist_classifier import ChangelistClassifier | 11 from crash.changelist_classifier import ChangelistClassifier |
| 12 from crash.chromecrash_parser import ChromeCrashParser | 12 from crash.chromecrash_parser import ChromeCrashParser |
| 13 from crash.component_classifier import ComponentClassifier | 13 from crash.component_classifier import ComponentClassifier |
| 14 from crash.crash_report import CrashReport | 14 from crash.crash_report import CrashReport |
| 15 from crash.culprit import Culprit | 15 from crash.culprit import Culprit |
| 16 from crash.culprit import NullCulprit | |
| 17 from crash.findit_for_chromecrash import FinditForChromeCrash | 16 from crash.findit_for_chromecrash import FinditForChromeCrash |
| 18 from crash.findit_for_chromecrash import FinditForFracas | 17 from crash.findit_for_chromecrash import FinditForFracas |
| 19 from crash.findit import Findit | 18 from crash.findit import Findit |
| 20 from crash.project_classifier import ProjectClassifier | 19 from crash.project_classifier import ProjectClassifier |
| 21 from crash.results import MatchResult | 20 from crash.results import MatchResult |
| 22 from crash.stacktrace import CallStack | 21 from crash.stacktrace import CallStack |
| 23 from crash.stacktrace import Stacktrace | 22 from crash.stacktrace import Stacktrace |
| 24 from crash.test.crash_pipeline_test import DummyCrashData | 23 from crash.test.crash_pipeline_test import DummyCrashData |
| 25 from crash.test.crash_testcase import CrashTestCase | 24 from crash.test.crash_testcase import CrashTestCase |
| 26 from crash.type_enums import CrashClient | 25 from crash.type_enums import CrashClient |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 class FinditForChromeCrashTest(CrashTestCase): | 76 class FinditForChromeCrashTest(CrashTestCase): |
| 78 | 77 |
| 79 chrome_dep_fetcher = chrome_dependency_fetcher.ChromeDependencyFetcher( | 78 chrome_dep_fetcher = chrome_dependency_fetcher.ChromeDependencyFetcher( |
| 80 gitiles_repository.GitilesRepository(http_client=HttpClientAppengine())) | 79 gitiles_repository.GitilesRepository(http_client=HttpClientAppengine())) |
| 81 | 80 |
| 82 # TODO(wrengr): what was the purpose of this test? As written it's | 81 # TODO(wrengr): what was the purpose of this test? As written it's |
| 83 # just testing that mocking works. I'm guessing it was to check that | 82 # just testing that mocking works. I'm guessing it was to check that |
| 84 # we fail when the analysis is for the wrong client_id; but if so, | 83 # we fail when the analysis is for the wrong client_id; but if so, |
| 85 # then we shouldn't need to mock FindCulprit... | 84 # then we shouldn't need to mock FindCulprit... |
| 86 def testFindCulprit(self): | 85 def testFindCulprit(self): |
| 87 self.mock(FinditForChromeCrash, 'FindCulprit', | 86 self.mock(FinditForChromeCrash, 'FindCulprit', lambda self, *_: None) |
| 88 lambda self, *_: NullCulprit()) | |
| 89 | 87 |
| 90 # TODO(wrengr): would be less fragile to call | 88 # TODO(wrengr): would be less fragile to call |
| 91 # FinditForFracas.CreateAnalysis instead; though if I'm right about | 89 # FinditForFracas.CreateAnalysis instead; though if I'm right about |
| 92 # the original purpose of this test, then this is one of the few | 90 # the original purpose of this test, then this is one of the few |
| 93 # places where calling FracasCrashAnalysis directly would actually | 91 # places where calling FracasCrashAnalysis directly would actually |
| 94 # make sense. | 92 # make sense. |
| 95 analysis = FracasCrashAnalysis.Create({'signature': 'sig'}) | 93 analysis = FracasCrashAnalysis.Create({'signature': 'sig'}) |
| 96 # TODO(wrengr): shouldn't FracasCrashAnalysis.Create already have set | 94 # TODO(wrengr): shouldn't FracasCrashAnalysis.Create already have set |
| 97 # the client_id? | 95 # the client_id? |
| 98 analysis.client_id = CrashClient.FRACAS | 96 analysis.client_id = CrashClient.FRACAS |
| 99 | 97 |
| 100 findit_client = _FinditForChromeCrash( | 98 findit_client = _FinditForChromeCrash( |
| 101 gitiles_repository.GitilesRepository(http_client=HttpClientAppengine())) | 99 gitiles_repository.GitilesRepository(http_client=HttpClientAppengine())) |
| 102 result, tags = findit_client.FindCulprit(analysis).ToDicts() | 100 self.assertIsNone(findit_client.FindCulprit(analysis)) |
| 103 # TODO(wrengr): just test for the NullCulprit directly; instead of | |
| 104 # going through ``ToDicts``. | |
| 105 expected_result, expected_tags = NullCulprit().ToDicts() | |
| 106 self.assertDictEqual(result, expected_result) | |
| 107 self.assertDictEqual(tags, expected_tags) | |
| 108 | 101 |
| 109 | 102 |
| 110 class FinditForFracasTest(CrashTestCase): | 103 class FinditForFracasTest(CrashTestCase): |
| 111 | 104 |
| 112 def testPlatformRename(self): | 105 def testPlatformRename(self): |
| 113 self.assertEqual(_FinditForFracas().RenamePlatform('linux'), 'unix') | 106 self.assertEqual(_FinditForFracas().RenamePlatform('linux'), 'unix') |
| 114 | 107 |
| 115 def testCheckPolicyUnsupportedPlatform(self): | 108 def testCheckPolicyUnsupportedPlatform(self): |
| 116 self.assertIsNone(_FinditForFracas().CheckPolicy(DummyCrashData( | 109 self.assertIsNone(_FinditForFracas().CheckPolicy(DummyCrashData( |
| 117 platform = 'unsupported_platform'))) | 110 platform = 'unsupported_platform'))) |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 analysis = findit_client.CreateAnalysis(crash_identifiers) | 203 analysis = findit_client.CreateAnalysis(crash_identifiers) |
| 211 analysis.status = analysis_status.COMPLETED | 204 analysis.status = analysis_status.COMPLETED |
| 212 analysis.put() | 205 analysis.put() |
| 213 self.assertFalse(findit_client.ScheduleNewAnalysis(crash_data)) | 206 self.assertFalse(findit_client.ScheduleNewAnalysis(crash_data)) |
| 214 | 207 |
| 215 def testFindCulpritForChromeCrashEmptyStacktrace(self): | 208 def testFindCulpritForChromeCrashEmptyStacktrace(self): |
| 216 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 209 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
| 217 'GetDependency', lambda *_: {}) | 210 'GetDependency', lambda *_: {}) |
| 218 self.mock(ChromeCrashParser, 'Parse', lambda *_: Stacktrace()) | 211 self.mock(ChromeCrashParser, 'Parse', lambda *_: Stacktrace()) |
| 219 | 212 |
| 220 # TODO(wrengr): use NullCulprit instead | |
| 221 expected_results = {'found': False, | |
| 222 'regression_range': None, | |
| 223 'suspected_cls': [], | |
| 224 'suspected_components': [], | |
| 225 'suspected_project': ''} | |
| 226 expected_tag = {'found_suspects': False, | |
| 227 'found_components': False, | |
| 228 'found_project': False, | |
| 229 'has_regression_range': False, | |
| 230 'solution': None} | |
| 231 | |
| 232 analysis = CrashAnalysis() | 213 analysis = CrashAnalysis() |
| 233 analysis.signature = 'signature' | 214 analysis.signature = 'signature' |
| 234 analysis.platform = 'win' | 215 analysis.platform = 'win' |
| 235 analysis.stack_trace = 'frame1\nframe2' | 216 analysis.stack_trace = 'frame1\nframe2' |
| 236 analysis.crashed_version = '50.0.1234.0' | 217 analysis.crashed_version = '50.0.1234.0' |
| 237 analysis.historical_metadata = [ | 218 analysis.historical_metadata = [ |
| 238 {'chrome_version': '51.0.1234.0', 'cpm': 0.6}] | 219 {'chrome_version': '51.0.1234.0', 'cpm': 0.6}] |
| 239 results, tag = _FinditForChromeCrash().FindCulprit(analysis).ToDicts() | 220 self.assertIsNone(_FinditForChromeCrash().FindCulprit(analysis)) |
| 240 | |
| 241 self.assertDictEqual(expected_results, results) | |
| 242 self.assertDictEqual(expected_tag, tag) | |
| 243 | 221 |
| 244 # TODO(http://crbug.com/659346): why do these mocks give coverage | 222 # TODO(http://crbug.com/659346): why do these mocks give coverage |
| 245 # failures? That's almost surely hiding a bug in the tests themselves. | 223 # failures? That's almost surely hiding a bug in the tests themselves. |
| 246 def testFindCulpritForChromeCrash(self): # pragma: no cover | 224 def testFindCulpritForChromeCrash(self): # pragma: no cover |
| 247 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 225 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
| 248 'GetDependency', lambda *_: {}) | 226 'GetDependency', lambda *_: {}) |
| 249 self.mock(ChromeCrashParser, 'Parse', lambda *_: Stacktrace([CallStack(0)])) | 227 self.mock(ChromeCrashParser, 'Parse', lambda *_: Stacktrace([CallStack(0)])) |
| 250 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 228 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
| 251 'GetDependencyRollsDict', | 229 'GetDependencyRollsDict', |
| 252 lambda *_: { | 230 lambda *_: { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 271 self._testFindCulpritForChromeCrashFails() | 249 self._testFindCulpritForChromeCrashFails() |
| 272 | 250 |
| 273 def _testFindCulpritForChromeCrashSucceeds(self, dummy_match_result): | 251 def _testFindCulpritForChromeCrashSucceeds(self, dummy_match_result): |
| 274 analysis = CrashAnalysis() | 252 analysis = CrashAnalysis() |
| 275 analysis.signature = 'signature' | 253 analysis.signature = 'signature' |
| 276 analysis.platform = 'win' | 254 analysis.platform = 'win' |
| 277 analysis.stack_trace = 'frame1\nframe2' | 255 analysis.stack_trace = 'frame1\nframe2' |
| 278 analysis.crashed_version = '50.0.1234.0' | 256 analysis.crashed_version = '50.0.1234.0' |
| 279 dummy_regression_range = ['50.0.1233.0', '50.0.1234.0'] | 257 dummy_regression_range = ['50.0.1233.0', '50.0.1234.0'] |
| 280 analysis.regression_range = dummy_regression_range | 258 analysis.regression_range = dummy_regression_range |
| 281 results, tag = _FinditForChromeCrash().FindCulprit(analysis).ToDicts() | 259 culprit = _FinditForChromeCrash().FindCulprit(analysis) |
| 260 self.assertIsNotNone(culprit, 'FindCulprit failed unexpectedly') |
| 261 results, tag = culprit.ToDicts() |
| 282 | 262 |
| 283 expected_results = { | 263 expected_results = { |
| 284 'found': True, | 264 'found': True, |
| 285 'suspected_project': '', | 265 'suspected_project': '', |
| 286 'suspected_components': [], | 266 'suspected_components': [], |
| 287 'suspected_cls': [dummy_match_result.ToDict()], | 267 'suspected_cls': [dummy_match_result.ToDict()], |
| 288 'regression_range': dummy_regression_range | 268 'regression_range': dummy_regression_range |
| 289 } | 269 } |
| 290 expected_tag = { | 270 expected_tag = { |
| 291 'found_suspects': True, | 271 'found_suspects': True, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 304 analysis.platform = 'win' | 284 analysis.platform = 'win' |
| 305 analysis.stack_trace = 'frame1\nframe2' | 285 analysis.stack_trace = 'frame1\nframe2' |
| 306 analysis.crashed_version = '50.0.1234.0' | 286 analysis.crashed_version = '50.0.1234.0' |
| 307 results, tag = _FinditForChromeCrash().FindCulprit(analysis).ToDicts() | 287 results, tag = _FinditForChromeCrash().FindCulprit(analysis).ToDicts() |
| 308 | 288 |
| 309 expected_results = { | 289 expected_results = { |
| 310 'found': False, | 290 'found': False, |
| 311 'suspected_project': '', | 291 'suspected_project': '', |
| 312 'suspected_components': [], | 292 'suspected_components': [], |
| 313 'suspected_cls': [], | 293 'suspected_cls': [], |
| 314 'regression_range': None | |
| 315 } | 294 } |
| 316 expected_tag = { | 295 expected_tag = { |
| 317 'found_suspects': False, | 296 'found_suspects': False, |
| 318 'found_project': False, | 297 'found_project': False, |
| 319 'found_components': False, | 298 'found_components': False, |
| 320 'has_regression_range': False, | 299 'has_regression_range': False, |
| 321 'solution': 'core_algorithm', | 300 'solution': 'core_algorithm', |
| 322 } | 301 } |
| 323 | 302 |
| 324 self.assertDictEqual(expected_results, results) | 303 self.assertDictEqual(expected_results, results) |
| 325 self.assertDictEqual(expected_tag, tag) | 304 self.assertDictEqual(expected_tag, tag) |
| OLD | NEW |