| 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 import copy | 4 import copy |
| 5 import json | 5 import json |
| 6 | 6 |
| 7 from google.appengine.api import app_identity | 7 from google.appengine.api import app_identity |
| 8 | 8 |
| 9 from common.pipeline_wrapper import pipeline_handlers | 9 from common.pipeline_wrapper import pipeline_handlers |
| 10 from crash import crash_pipeline | 10 from crash import crash_pipeline |
| 11 from crash import findit_for_fracas | 11 from crash import findit_for_chromecrash |
| 12 from crash.test.crash_testcase import CrashTestCase | 12 from crash.test.crash_testcase import CrashTestCase |
| 13 from model import analysis_status | 13 from model import analysis_status |
| 14 from model.crash.fracas_crash_analysis import FracasCrashAnalysis | 14 from model.crash.fracas_crash_analysis import FracasCrashAnalysis |
| 15 | 15 |
| 16 | 16 |
| 17 class CrashPipelineTest(CrashTestCase): | 17 class CrashPipelineTest(CrashTestCase): |
| 18 app_module = pipeline_handlers._APP | 18 app_module = pipeline_handlers._APP |
| 19 | 19 |
| 20 def testNoAnalysisIfLastOneIsNotFailed(self): | 20 def testNoAnalysisIfLastOneIsNotFailed(self): |
| 21 chrome_version = '1' | 21 chrome_version = '1' |
| 22 signature = 'signature' | 22 signature = 'signature' |
| 23 platform = 'win' | 23 platform = 'win' |
| 24 crash_identifiers = { | 24 crash_identifiers = { |
| 25 'chrome_version': chrome_version, | 25 'chrome_version': chrome_version, |
| 26 'signature': signature, | 26 'signature': signature, |
| 27 'channel': 'canary', | 27 'channel': 'canary', |
| 28 'platform': platform, | 28 'platform': platform, |
| 29 'process_type': 'browser', | 29 'process_type': 'browser', |
| 30 } | 30 } |
| 31 for status in (analysis_status.PENDING, analysis_status.RUNNING, | 31 for status in (analysis_status.PENDING, analysis_status.RUNNING, |
| 32 analysis_status.COMPLETED, analysis_status.SKIPPED): | 32 analysis_status.COMPLETED, analysis_status.SKIPPED): |
| 33 analysis = FracasCrashAnalysis.Create(crash_identifiers) | 33 analysis = FracasCrashAnalysis.Create(crash_identifiers) |
| 34 analysis.status = status | 34 analysis.status = status |
| 35 analysis.put() | 35 analysis.put() |
| 36 self.assertFalse(crash_pipeline._NeedsNewAnalysis( | 36 self.assertFalse(crash_pipeline._NeedsNewAnalysis( |
| 37 crash_identifiers, chrome_version, signature, 'fracas', | 37 crash_identifiers, chrome_version, signature, 'fracas', |
| 38 platform, None, None, None)) | 38 platform, None, {'channel': 'canary'})) |
| 39 | 39 |
| 40 def testAnalysisNeededIfLastOneFailed(self): | 40 def testAnalysisNeededIfLastOneFailed(self): |
| 41 chrome_version = '1' | 41 chrome_version = '1' |
| 42 signature = 'signature' | 42 signature = 'signature' |
| 43 platform = 'win' | 43 platform = 'win' |
| 44 crash_identifiers = { | 44 crash_identifiers = { |
| 45 'chrome_version': chrome_version, | 45 'chrome_version': chrome_version, |
| 46 'signature': signature, | 46 'signature': signature, |
| 47 'channel': 'canary', | 47 'channel': 'canary', |
| 48 'platform': platform, | 48 'platform': platform, |
| 49 'process_type': 'browser', | 49 'process_type': 'browser', |
| 50 } | 50 } |
| 51 analysis = FracasCrashAnalysis.Create(crash_identifiers) | 51 analysis = FracasCrashAnalysis.Create(crash_identifiers) |
| 52 analysis.status = analysis_status.ERROR | 52 analysis.status = analysis_status.ERROR |
| 53 analysis.put() | 53 analysis.put() |
| 54 self.assertTrue(crash_pipeline._NeedsNewAnalysis( | 54 self.assertTrue(crash_pipeline._NeedsNewAnalysis( |
| 55 crash_identifiers, chrome_version, signature, 'fracas', | 55 crash_identifiers, chrome_version, signature, 'fracas', |
| 56 platform, None, None, None)) | 56 platform, None, {'channel': 'canary'})) |
| 57 | 57 |
| 58 def testAnalysisNeededIfNoAnalysisYet(self): | 58 def testAnalysisNeededIfNoAnalysisYet(self): |
| 59 chrome_version = '1' | 59 chrome_version = '1' |
| 60 signature = 'signature' | 60 signature = 'signature' |
| 61 platform = 'win' | 61 platform = 'win' |
| 62 crash_identifiers = { | 62 crash_identifiers = { |
| 63 'chrome_version': chrome_version, | 63 'chrome_version': chrome_version, |
| 64 'signature': signature, | 64 'signature': signature, |
| 65 'channel': 'canary', | 65 'channel': 'canary', |
| 66 'platform': platform, | 66 'platform': platform, |
| 67 'process_type': 'browser', | 67 'process_type': 'browser', |
| 68 } | 68 } |
| 69 self.assertTrue(crash_pipeline._NeedsNewAnalysis( | 69 self.assertTrue(crash_pipeline._NeedsNewAnalysis( |
| 70 crash_identifiers, chrome_version, signature, 'fracas', | 70 crash_identifiers, chrome_version, signature, 'fracas', |
| 71 platform, None, None, None)) | 71 platform, None, {'channel': 'canary'})) |
| 72 | 72 |
| 73 def testUnsupportedChannelOrPlatformSkipped(self): | 73 def testUnsupportedChannelOrPlatformSkipped(self): |
| 74 self.assertFalse( | 74 self.assertFalse( |
| 75 crash_pipeline.ScheduleNewAnalysisForCrash( | 75 crash_pipeline.ScheduleNewAnalysisForCrash( |
| 76 {}, None, None, 'fracas', 'win', | 76 {}, None, None, 'fracas', 'win', |
| 77 None, 'unsupported_channel', None)) | 77 None, {'channel': 'unsupported_channel', |
| 78 'historical_metadata': None})) |
| 78 self.assertFalse( | 79 self.assertFalse( |
| 79 crash_pipeline.ScheduleNewAnalysisForCrash( | 80 crash_pipeline.ScheduleNewAnalysisForCrash( |
| 80 {}, None, None, 'fracas', 'unsupported_platform', | 81 {}, None, None, 'fracas', 'unsupported_platform', |
| 81 None, 'unsupported_channel', None)) | 82 None, {'channel': 'unsupported_channel', |
| 83 'historical_metadata': None})) |
| 82 | 84 |
| 83 def testBlackListSignatureSipped(self): | 85 def testBlackListSignatureSipped(self): |
| 84 self.assertFalse( | 86 self.assertFalse( |
| 85 crash_pipeline.ScheduleNewAnalysisForCrash( | 87 crash_pipeline.ScheduleNewAnalysisForCrash( |
| 86 {}, None, 'Blacklist marker signature', 'fracas', 'win', | 88 {}, None, 'Blacklist marker signature', 'fracas', 'win', |
| 87 None, 'canary', None)) | 89 None, {'channel': 'canary', |
| 90 'historical_metadata': None})) |
| 88 | 91 |
| 89 def testPlatformRename(self): | 92 def testPlatformRename(self): |
| 90 def _MockNeedsNewAnalysis(*args): | 93 def _MockNeedsNewAnalysis(*args): |
| 91 self.assertEqual(args, | 94 self.assertEqual(args, |
| 92 ({}, None, 'signature', 'fracas', 'unix', None, | 95 ({}, None, 'signature', 'fracas', 'unix', None, |
| 93 'canary', None)) | 96 {'channel': 'canary'})) |
| 94 return False | 97 return False |
| 95 | 98 |
| 96 self.mock(crash_pipeline, '_NeedsNewAnalysis', _MockNeedsNewAnalysis) | 99 self.mock(crash_pipeline, '_NeedsNewAnalysis', _MockNeedsNewAnalysis) |
| 97 | 100 |
| 98 crash_pipeline.ScheduleNewAnalysisForCrash( | 101 crash_pipeline.ScheduleNewAnalysisForCrash( |
| 99 {}, None, 'signature', 'fracas', 'linux', | 102 {}, None, 'signature', 'fracas', 'linux', |
| 100 None, 'canary', None) | 103 None, {'channel': 'canary'}) |
| 101 | 104 |
| 102 def testNoAnalysisNeeded(self): | 105 def testNoAnalysisNeeded(self): |
| 103 chrome_version = '1' | 106 chrome_version = '1' |
| 104 signature = 'signature' | 107 signature = 'signature' |
| 105 platform = 'win' | 108 platform = 'win' |
| 106 channel = 'canary' | 109 channel = 'canary' |
| 107 crash_identifiers = { | 110 crash_identifiers = { |
| 108 'chrome_version': chrome_version, | 111 'chrome_version': chrome_version, |
| 109 'signature': signature, | 112 'signature': signature, |
| 110 'channel': channel, | 113 'channel': channel, |
| 111 'platform': platform, | 114 'platform': platform, |
| 112 'process_type': 'browser', | 115 'process_type': 'browser', |
| 113 } | 116 } |
| 114 analysis = FracasCrashAnalysis.Create(crash_identifiers) | 117 analysis = FracasCrashAnalysis.Create(crash_identifiers) |
| 115 analysis.status = analysis_status.COMPLETED | 118 analysis.status = analysis_status.COMPLETED |
| 116 analysis.put() | 119 analysis.put() |
| 117 | 120 |
| 118 self.assertFalse( | 121 self.assertFalse( |
| 119 crash_pipeline.ScheduleNewAnalysisForCrash( | 122 crash_pipeline.ScheduleNewAnalysisForCrash( |
| 120 crash_identifiers, chrome_version, signature, 'fracas', | 123 crash_identifiers, chrome_version, signature, 'fracas', |
| 121 platform, None, channel, None)) | 124 platform, None, {'channel': channel, |
| 125 'historical_metadata': None})) |
| 122 | 126 |
| 123 def _TestRunningAnalysisForResult(self, analysis_result, analysis_tags): | 127 def _TestRunningAnalysisForResult(self, analysis_result, analysis_tags): |
| 124 pubsub_publish_requests = [] | 128 pubsub_publish_requests = [] |
| 125 def Mocked_PublishMessagesToTopic(messages_data, topic): | 129 def Mocked_PublishMessagesToTopic(messages_data, topic): |
| 126 pubsub_publish_requests.append((messages_data, topic)) | 130 pubsub_publish_requests.append((messages_data, topic)) |
| 127 self.mock(crash_pipeline.pubsub_util, 'PublishMessagesToTopic', | 131 self.mock(crash_pipeline.pubsub_util, 'PublishMessagesToTopic', |
| 128 Mocked_PublishMessagesToTopic) | 132 Mocked_PublishMessagesToTopic) |
| 129 | 133 |
| 130 analyzed_crashes = [] | 134 analyzed_crashes = [] |
| 131 def Mocked_FindCulpritForChromeCrash(*args): | 135 def Mocked_FindCulpritForChromeCrash(*args): |
| 132 analyzed_crashes.append(args) | 136 analyzed_crashes.append(args) |
| 133 return analysis_result, analysis_tags | 137 return analysis_result, analysis_tags |
| 134 self.mock(findit_for_fracas, 'FindCulpritForChromeCrash', | 138 self.mock(findit_for_chromecrash, 'FindCulpritForChromeCrash', |
| 135 Mocked_FindCulpritForChromeCrash) | 139 Mocked_FindCulpritForChromeCrash) |
| 136 chrome_version = '1' | 140 chrome_version = '1' |
| 137 signature = 'signature' | 141 signature = 'signature' |
| 138 platform = 'win' | 142 platform = 'win' |
| 139 channel = 'canary' | 143 channel = 'canary' |
| 140 crash_identifiers = { | 144 crash_identifiers = { |
| 141 'chrome_version': chrome_version, | 145 'chrome_version': chrome_version, |
| 142 'signature': signature, | 146 'signature': signature, |
| 143 'channel': channel, | 147 'channel': channel, |
| 144 'platform': platform, | 148 'platform': platform, |
| 145 'process_type': 'browser', | 149 'process_type': 'browser', |
| 146 } | 150 } |
| 147 stack_trace = 'frame1\nframe2\nframe3' | 151 stack_trace = 'frame1\nframe2\nframe3' |
| 148 chrome_version = '50.2500.0.0' | 152 chrome_version = '50.2500.0.0' |
| 149 historic_metadata = {'50.2500.0.0': 1.0} | 153 historical_metadata = {'50.2500.0.0': 1.0} |
| 150 | 154 |
| 151 mock_host = 'https://host.com' | 155 mock_host = 'https://host.com' |
| 152 self.mock(app_identity, 'get_default_version_hostname', lambda: mock_host) | 156 self.mock(app_identity, 'get_default_version_hostname', lambda: mock_host) |
| 153 | 157 |
| 154 self.assertTrue( | 158 self.assertTrue( |
| 155 crash_pipeline.ScheduleNewAnalysisForCrash( | 159 crash_pipeline.ScheduleNewAnalysisForCrash( |
| 156 crash_identifiers, chrome_version, signature, 'fracas', | 160 crash_identifiers, chrome_version, signature, 'fracas', |
| 157 platform, stack_trace, channel, historic_metadata)) | 161 platform, stack_trace, |
| 162 {'channel': channel, 'historical_metadata': historical_metadata})) |
| 158 | 163 |
| 159 self.execute_queued_tasks() | 164 self.execute_queued_tasks() |
| 160 | 165 |
| 161 self.assertEqual(1, len(pubsub_publish_requests)) | 166 self.assertEqual(1, len(pubsub_publish_requests)) |
| 162 | 167 |
| 163 processed_analysis_result = copy.deepcopy(analysis_result) | 168 processed_analysis_result = copy.deepcopy(analysis_result) |
| 164 processed_analysis_result['feedback_url'] = ( | 169 processed_analysis_result['feedback_url'] = ( |
| 165 mock_host + '/crash/fracas-result-feedback?' | 170 mock_host + '/crash/fracas-result-feedback?' |
| 166 'key=agx0ZXN0YmVkLXRlc3RyQQsSE0ZyYWNhc0NyYXNoQW5hbHlzaXMiKGU2ZWIyNj' | 171 'key=agx0ZXN0YmVkLXRlc3RyQQsSE0ZyYWNhc0NyYXNoQW5hbHlzaXMiKGU2ZWIyNj' |
| 167 'A2OTBlYTAyMjVjNWNjYTM3ZTNjYTlmYWExOGVmYjVlM2UM') | 172 'A2OTBlYTAyMjVjNWNjYTM3ZTNjYTlmYWExOGVmYjVlM2UM') |
| 168 | 173 |
| 169 if 'suspected_cls' in processed_analysis_result: | 174 if 'suspected_cls' in processed_analysis_result: |
| 170 for cl in processed_analysis_result['suspected_cls']: | 175 for cl in processed_analysis_result['suspected_cls']: |
| 171 cl['confidence'] = round(cl['confidence'], 2) | 176 cl['confidence'] = round(cl['confidence'], 2) |
| 172 cl.pop('reason', None) | 177 cl.pop('reason', None) |
| 173 | 178 |
| 174 expected_messages_data = [json.dumps({ | 179 expected_messages_data = [json.dumps({ |
| 175 'crash_identifiers': crash_identifiers, | 180 'crash_identifiers': crash_identifiers, |
| 176 'client_id': 'fracas', | 181 'client_id': 'fracas', |
| 177 'result': processed_analysis_result, | 182 'result': processed_analysis_result, |
| 178 }, sort_keys=True)] | 183 }, sort_keys=True)] |
| 179 self.assertEqual(expected_messages_data, pubsub_publish_requests[0][0]) | 184 self.assertEqual(expected_messages_data, pubsub_publish_requests[0][0]) |
| 180 | 185 |
| 181 self.assertEqual(1, len(analyzed_crashes)) | 186 self.assertEqual(1, len(analyzed_crashes)) |
| 182 self.assertEqual( | 187 self.assertEqual( |
| 183 (signature, platform, stack_trace, chrome_version, historic_metadata), | 188 (signature, platform, stack_trace, chrome_version, historical_metadata), |
| 184 analyzed_crashes[0]) | 189 analyzed_crashes[0]) |
| 185 | 190 |
| 186 analysis = FracasCrashAnalysis.Get(crash_identifiers) | 191 analysis = FracasCrashAnalysis.Get(crash_identifiers) |
| 187 self.assertEqual(analysis_result, analysis.result) | 192 self.assertEqual(analysis_result, analysis.result) |
| 188 return analysis | 193 return analysis |
| 189 | 194 |
| 190 | 195 |
| 191 def testRunningAnalysis(self): | 196 def testRunningAnalysis(self): |
| 192 analysis_result = { | 197 analysis_result = { |
| 193 'found': True, | 198 'found': True, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 'chrome_version': chrome_version, | 260 'chrome_version': chrome_version, |
| 256 'signature': signature, | 261 'signature': signature, |
| 257 'channel': 'canary', | 262 'channel': 'canary', |
| 258 'platform': platform, | 263 'platform': platform, |
| 259 'process_type': 'browser', | 264 'process_type': 'browser', |
| 260 } | 265 } |
| 261 analysis = FracasCrashAnalysis.Create(crash_identifiers) | 266 analysis = FracasCrashAnalysis.Create(crash_identifiers) |
| 262 analysis.status = analysis_status.RUNNING | 267 analysis.status = analysis_status.RUNNING |
| 263 analysis.put() | 268 analysis.put() |
| 264 | 269 |
| 265 pipeline = crash_pipeline.CrashAnalysisPipeline(crash_identifiers) | 270 pipeline = crash_pipeline.CrashAnalysisPipeline(crash_identifiers, 'fracas') |
| 266 pipeline._SetErrorIfAborted(True) | 271 pipeline._SetErrorIfAborted(True) |
| 267 analysis = FracasCrashAnalysis.Get(crash_identifiers) | 272 analysis = FracasCrashAnalysis.Get(crash_identifiers) |
| 268 self.assertEqual(analysis_status.ERROR, analysis.status) | 273 self.assertEqual(analysis_status.ERROR, analysis.status) |
| OLD | NEW |