| 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 import mock | 5 import mock |
| 6 | 6 |
| 7 from common import chrome_dependency_fetcher | 7 from common import chrome_dependency_fetcher |
| 8 from common.dependency import DependencyRoll | 8 from common.dependency import DependencyRoll |
| 9 from crash import chromecrash_parser | 9 from crash import chromecrash_parser |
| 10 from crash import detect_regression_range | 10 from crash import detect_regression_range |
| 11 from crash import findit | 11 from crash import findit |
| 12 from crash import findit_for_chromecrash | 12 from crash import findit_for_chromecrash |
| 13 from crash.loglinear.changelist_classifier import LogLinearChangelistClassifier | 13 from crash.loglinear.changelist_classifier import LogLinearChangelistClassifier |
| 14 from crash.chromecrash_parser import ChromeCrashParser | 14 from crash.chromecrash_parser import ChromeCrashParser |
| 15 from crash.component_classifier import ComponentClassifier | 15 from crash.component_classifier import ComponentClassifier |
| 16 from crash.crash_report import CrashReport | 16 from crash.crash_report import CrashReport |
| 17 from crash.culprit import Culprit | 17 from crash.culprit import Culprit |
| 18 from crash.findit_for_chromecrash import FinditForChromeCrash | 18 from crash.findit_for_chromecrash import FinditForChromeCrash |
| 19 from crash.findit_for_chromecrash import FinditForFracas | 19 from crash.findit_for_chromecrash import FinditForFracas |
| 20 from crash.project_classifier import ProjectClassifier | 20 from crash.project_classifier import ProjectClassifier |
| 21 from crash.suspect import Suspect | 21 from crash.suspect import Suspect |
| 22 from crash.stacktrace import CallStack | 22 from crash.stacktrace import CallStack |
| 23 from crash.stacktrace import Stacktrace | 23 from crash.stacktrace import Stacktrace |
| 24 from crash.test.predator_testcase import PredatorTestCase | 24 from crash.test.predator_testcase import PredatorTestCase |
| 25 from crash.type_enums import CrashClient | 25 from crash.type_enums import CrashClient |
| 26 from gae_libs.http.http_client_appengine import HttpClientAppengine | 26 from gae_libs.http.http_client_appengine import HttpClientAppengine |
| 27 from libs.gitiles.gitiles_repository import GitilesRepository | 27 from libs.gitiles.gitiles_repository import GitilesRepository |
| 28 from model import analysis_status | 28 from model import analysis_status |
| 29 from model.crash.crash_analysis import CrashAnalysis | 29 from model.crash.crash_analysis import CrashAnalysis |
| 30 from model.crash.crash_config import CrashConfig |
| 30 from model.crash.fracas_crash_analysis import FracasCrashAnalysis | 31 from model.crash.fracas_crash_analysis import FracasCrashAnalysis |
| 31 | 32 |
| 32 MOCK_GET_REPOSITORY = lambda _: None # pragma: no cover | 33 MOCK_GET_REPOSITORY = lambda _: None # pragma: no cover |
| 33 | 34 |
| 35 |
| 34 class _FinditForChromeCrash(FinditForChromeCrash): # pylint: disable = W | 36 class _FinditForChromeCrash(FinditForChromeCrash): # pylint: disable = W |
| 35 # We allow overriding the default ``get_repository`` because one unittest | 37 # We allow overriding the default ``get_repository`` because one unittest |
| 36 # needs to. | 38 # needs to. |
| 37 def __init__(self, get_repository=MOCK_GET_REPOSITORY): | 39 def __init__(self, get_repository=MOCK_GET_REPOSITORY, config=None): |
| 38 super(_FinditForChromeCrash, self).__init__(get_repository) | 40 super(_FinditForChromeCrash, self).__init__(get_repository, config) |
| 39 | 41 |
| 40 @classmethod | 42 @classmethod |
| 41 def _ClientID(cls): # pragma: no cover | 43 def _ClientID(cls): # pragma: no cover |
| 42 """Avoid throwing a NotImplementedError. | 44 """Avoid throwing a NotImplementedError. |
| 43 | 45 |
| 44 Since this method is called from ``FinditForChromeCrash.__init__`` | 46 Since this method is called from ``FinditForChromeCrash.__init__`` |
| 45 in order to construct the Azalea object, we need to not throw | 47 in order to construct the Azalea object, we need to not throw |
| 46 exceptions since we want to be able to test the FinditForChromeCrash | 48 exceptions since we want to be able to test the FinditForChromeCrash |
| 47 class itself. | 49 class itself. |
| 48 """ | 50 """ |
| 49 return '' | 51 return 'fracas' |
| 50 | 52 |
| 51 @property | 53 @property |
| 52 def config(self): | 54 def client_config(self): |
| 53 """Avoid returning None. | 55 """Avoid returning None. |
| 54 | 56 |
| 55 The default ``Findit.config`` will return None if the client | 57 The default ``Findit.client_config`` will return None if the client |
| 56 id is not found in the CrashConfig. This in turn will cause | 58 id is not found in the CrashConfig. This in turn will cause |
| 57 ``FinditForChromeCrash.__init__`` to crash, since NoneType doesn't | 59 ``FinditForChromeCrash.__init__`` to crash, since NoneType doesn't |
| 58 have a ``get`` method. In general it's fine for things to crash, since | 60 have a ``get`` method. In general it's fine for things to crash, since |
| 59 noone should make instances of Findit subclasses which don't define | 61 noone should make instances of Findit subclasses which don't define |
| 60 ``_clientID``; but for this test suite, we want to permit instances | 62 ``_clientID``; but for this test suite, we want to permit instances |
| 61 of FinditForChromeCrash, so that we can test that class directly. | 63 of FinditForChromeCrash, so that we can test that class directly. |
| 62 """ | 64 """ |
| 63 return {} | 65 return {} |
| 64 | 66 |
| 65 | 67 |
| 66 def _FinditForFracas(): | 68 def _FinditForFracas(config=None): |
| 67 """A helper to pass in the standard pipeline class.""" | 69 """A helper to pass in the standard pipeline class.""" |
| 68 return FinditForFracas(MOCK_GET_REPOSITORY) | 70 return FinditForFracas(MOCK_GET_REPOSITORY, config or {}) |
| 69 | 71 |
| 70 | 72 |
| 71 class FinditForChromeCrashTest(PredatorTestCase): | 73 class FinditForChromeCrashTest(PredatorTestCase): |
| 72 | 74 |
| 73 # TODO(wrengr): what was the purpose of this test? As written it's | 75 # TODO(wrengr): what was the purpose of this test? As written it's |
| 74 # just testing that mocking works. I'm guessing it was to check that | 76 # just testing that mocking works. I'm guessing it was to check that |
| 75 # we fail when the analysis is for the wrong client_id; but if so, | 77 # we fail when the analysis is for the wrong client_id; but if so, |
| 76 # then we shouldn't need to mock FindCulprit... | 78 # then we shouldn't need to mock FindCulprit... |
| 77 def testFindCulprit(self): | 79 def testFindCulprit(self): |
| 78 self.mock(FinditForChromeCrash, 'FindCulprit', lambda self, *_: None) | 80 self.mock(FinditForChromeCrash, 'FindCulprit', lambda self, *_: None) |
| 79 | 81 |
| 80 # TODO(wrengr): would be less fragile to call | 82 # TODO(wrengr): would be less fragile to call |
| 81 # FinditForFracas.CreateAnalysis instead; though if I'm right about | 83 # FinditForFracas.CreateAnalysis instead; though if I'm right about |
| 82 # the original purpose of this test, then this is one of the few | 84 # the original purpose of this test, then this is one of the few |
| 83 # places where calling FracasCrashAnalysis directly would actually | 85 # places where calling FracasCrashAnalysis directly would actually |
| 84 # make sense. | 86 # make sense. |
| 85 analysis = FracasCrashAnalysis.Create({'signature': 'sig'}) | 87 analysis = FracasCrashAnalysis.Create({'signature': 'sig'}) |
| 86 # TODO(wrengr): shouldn't FracasCrashAnalysis.Create already have set | 88 # TODO(wrengr): shouldn't FracasCrashAnalysis.Create already have set |
| 87 # the client_id? | 89 # the client_id? |
| 88 analysis.client_id = CrashClient.FRACAS | 90 analysis.client_id = CrashClient.FRACAS |
| 89 | 91 |
| 90 findit_client = ( | 92 findit_client = _FinditForChromeCrash( |
| 91 _FinditForChromeCrash(GitilesRepository.Factory(HttpClientAppengine()))) | 93 GitilesRepository.Factory(HttpClientAppengine()), |
| 94 config=CrashConfig.Get()) |
| 92 self.assertIsNone(findit_client.FindCulprit(analysis)) | 95 self.assertIsNone(findit_client.FindCulprit(analysis)) |
| 93 | 96 |
| 94 | 97 |
| 95 class FinditForFracasTest(PredatorTestCase): | 98 class FinditForFracasTest(PredatorTestCase): |
| 96 | 99 |
| 100 def setUp(self): |
| 101 super(FinditForFracasTest, self).setUp() |
| 102 self.findit = _FinditForFracas(config=CrashConfig.Get()) |
| 103 |
| 97 def testPlatformRename(self): | 104 def testPlatformRename(self): |
| 98 self.assertEqual(_FinditForFracas().RenamePlatform('linux'), 'unix') | 105 self.assertEqual(self.findit.RenamePlatform('linux'), 'unix') |
| 99 | 106 |
| 100 def testCheckPolicyUnsupportedPlatform(self): | 107 def testCheckPolicyUnsupportedPlatform(self): |
| 101 self.assertIsNone(_FinditForFracas().CheckPolicy(self.GetDummyCrashData( | 108 self.assertIsNone(self.findit.CheckPolicy(self.GetDummyCrashData( |
| 102 platform = 'unsupported_platform'))) | 109 platform = 'unsupported_platform'))) |
| 103 | 110 |
| 104 def testCheckPolicyBlacklistedSignature(self): | 111 def testCheckPolicyBlacklistedSignature(self): |
| 105 self.assertIsNone(_FinditForFracas().CheckPolicy(self.GetDummyCrashData( | 112 self.assertIsNone(self.findit.CheckPolicy(self.GetDummyCrashData( |
| 106 signature = 'Blacklist marker signature'))) | 113 signature = 'Blacklist marker signature'))) |
| 107 | 114 |
| 108 def testCheckPolicyPlatformRename(self): | 115 def testCheckPolicyPlatformRename(self): |
| 109 new_crash_data = _FinditForFracas().CheckPolicy(self.GetDummyCrashData( | 116 new_crash_data = self.findit.CheckPolicy(self.GetDummyCrashData( |
| 110 platform = 'linux')) | 117 platform = 'linux')) |
| 111 self.assertIsNotNone(new_crash_data, | 118 self.assertIsNotNone(new_crash_data, |
| 112 'FinditForFracas.CheckPolicy unexpectedly returned None') | 119 'FinditForFracas.CheckPolicy unexpectedly returned None') |
| 113 self.assertEqual(new_crash_data['platform'], 'unix') | 120 self.assertEqual(new_crash_data['platform'], 'unix') |
| 114 | 121 |
| 115 def testCreateAnalysis(self): | 122 def testCreateAnalysis(self): |
| 116 self.assertIsNotNone(_FinditForFracas().CreateAnalysis( | 123 self.assertIsNotNone(self.findit.CreateAnalysis( |
| 117 {'signature': 'sig'})) | 124 {'signature': 'sig'})) |
| 118 | 125 |
| 119 def testGetAnalysis(self): | 126 def testGetAnalysis(self): |
| 120 crash_identifiers = {'signature': 'sig'} | 127 crash_identifiers = {'signature': 'sig'} |
| 121 # TODO(wrengr): would be less fragile to call | 128 # TODO(wrengr): would be less fragile to call |
| 122 # FinditForFracas.CreateAnalysis instead. | 129 # FinditForFracas.CreateAnalysis instead. |
| 123 analysis = FracasCrashAnalysis.Create(crash_identifiers) | 130 analysis = FracasCrashAnalysis.Create(crash_identifiers) |
| 124 analysis.put() | 131 analysis.put() |
| 125 self.assertEqual(_FinditForFracas().GetAnalysis(crash_identifiers), | 132 self.assertEqual(self.findit.GetAnalysis(crash_identifiers), |
| 126 analysis) | 133 analysis) |
| 127 | 134 |
| 128 def testInitializeAnalysisForFracas(self): | 135 def testInitializeAnalysisForFracas(self): |
| 129 crash_data = self.GetDummyCrashData(platform = 'linux') | 136 crash_data = self.GetDummyCrashData(platform = 'linux') |
| 130 crash_identifiers = crash_data['crash_identifiers'] | 137 crash_identifiers = crash_data['crash_identifiers'] |
| 131 | 138 |
| 132 findit_client = _FinditForFracas() | 139 self.findit = self.findit |
| 133 analysis = findit_client.CreateAnalysis(crash_identifiers) | 140 analysis = self.findit.CreateAnalysis(crash_identifiers) |
| 134 findit_client._InitializeAnalysis(analysis, crash_data) | 141 self.findit._InitializeAnalysis(analysis, crash_data) |
| 135 analysis.put() | 142 analysis.put() |
| 136 analysis = findit_client.GetAnalysis(crash_identifiers) | 143 analysis = self.findit.GetAnalysis(crash_identifiers) |
| 137 self.assertIsNotNone(analysis, | 144 self.assertIsNotNone(analysis, |
| 138 'FinditForFracas.GetAnalysis unexpectedly returned None') | 145 'FinditForFracas.GetAnalysis unexpectedly returned None') |
| 139 | 146 |
| 140 self.assertEqual(analysis.crashed_version, crash_data['chrome_version']) | 147 self.assertEqual(analysis.crashed_version, crash_data['chrome_version']) |
| 141 self.assertEqual(analysis.signature, crash_data['signature']) | 148 self.assertEqual(analysis.signature, crash_data['signature']) |
| 142 self.assertEqual(analysis.platform, crash_data['platform']) | 149 self.assertEqual(analysis.platform, crash_data['platform']) |
| 143 self.assertEqual(analysis.stack_trace, crash_data['stack_trace']) | 150 self.assertEqual(analysis.stack_trace, crash_data['stack_trace']) |
| 144 channel = crash_data['customized_data'].get('channel', None) | 151 channel = crash_data['customized_data'].get('channel', None) |
| 145 self.assertIsNotNone(channel, | 152 self.assertIsNotNone(channel, |
| 146 'channel is unexpectedly not defined in crash_data') | 153 'channel is unexpectedly not defined in crash_data') |
| 147 self.assertEqual(analysis.channel, channel) | 154 self.assertEqual(analysis.channel, channel) |
| 148 | 155 |
| 149 def testNeedsNewAnalysisIsTrueIfNoAnalysisYet(self): | 156 def testNeedsNewAnalysisIsTrueIfNoAnalysisYet(self): |
| 150 self.assertTrue(_FinditForFracas()._NeedsNewAnalysis( | 157 self.assertTrue(self.findit._NeedsNewAnalysis( |
| 151 self.GetDummyCrashData())) | 158 self.GetDummyCrashData())) |
| 152 | 159 |
| 153 def testNeedsNewAnalysisIsTrueIfLastOneFailed(self): | 160 def testNeedsNewAnalysisIsTrueIfLastOneFailed(self): |
| 154 findit_client = _FinditForFracas() | |
| 155 crash_data = self.GetDummyCrashData() | 161 crash_data = self.GetDummyCrashData() |
| 156 analysis = findit_client.CreateAnalysis(crash_data['crash_identifiers']) | 162 analysis = self.findit.CreateAnalysis(crash_data['crash_identifiers']) |
| 157 analysis.status = analysis_status.ERROR | 163 analysis.status = analysis_status.ERROR |
| 158 analysis.put() | 164 analysis.put() |
| 159 self.assertTrue(findit_client._NeedsNewAnalysis(crash_data)) | 165 self.assertTrue(self.findit._NeedsNewAnalysis(crash_data)) |
| 160 | 166 |
| 161 def testNeedsNewAnalysisIsFalseIfLastOneIsNotFailed(self): | 167 def testNeedsNewAnalysisIsFalseIfLastOneIsNotFailed(self): |
| 162 findit_client = _FinditForFracas() | |
| 163 crash_data = self.GetDummyCrashData() | 168 crash_data = self.GetDummyCrashData() |
| 164 crash_identifiers = crash_data['crash_identifiers'] | 169 crash_identifiers = crash_data['crash_identifiers'] |
| 165 for status in (analysis_status.PENDING, analysis_status.RUNNING, | 170 for status in (analysis_status.PENDING, analysis_status.RUNNING, |
| 166 analysis_status.COMPLETED, analysis_status.SKIPPED): | 171 analysis_status.COMPLETED, analysis_status.SKIPPED): |
| 167 analysis = findit_client.CreateAnalysis(crash_identifiers) | 172 analysis = self.findit.CreateAnalysis(crash_identifiers) |
| 168 analysis.status = status | 173 analysis.status = status |
| 169 analysis.put() | 174 analysis.put() |
| 170 self.assertFalse(findit_client._NeedsNewAnalysis(crash_data)) | 175 self.assertFalse(self.findit._NeedsNewAnalysis(crash_data)) |
| 171 | 176 |
| 172 def testFindCulpritForChromeCrashEmptyStacktrace(self): | 177 def testFindCulpritForChromeCrashEmptyStacktrace(self): |
| 173 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 178 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
| 174 'GetDependency', lambda *_: {}) | 179 'GetDependency', lambda *_: {}) |
| 175 self.mock(ChromeCrashParser, 'Parse', lambda *_: None) | 180 self.mock(ChromeCrashParser, 'Parse', lambda *_: None) |
| 176 | 181 |
| 177 analysis = CrashAnalysis() | 182 analysis = CrashAnalysis() |
| 178 analysis.signature = 'signature' | 183 analysis.signature = 'signature' |
| 179 analysis.platform = 'win' | 184 analysis.platform = 'win' |
| 180 analysis.stack_trace = 'frame1\nframe2' | 185 analysis.stack_trace = 'frame1\nframe2' |
| 181 analysis.crashed_version = '50.0.1234.0' | 186 analysis.crashed_version = '50.0.1234.0' |
| 182 analysis.historical_metadata = [ | 187 analysis.historical_metadata = [ |
| 183 {'chrome_version': '51.0.1234.0', 'cpm': 0.6}] | 188 {'chrome_version': '51.0.1234.0', 'cpm': 0.6}] |
| 184 self.assertIsNone(_FinditForChromeCrash().FindCulprit(analysis)) | 189 self.assertIsNone(_FinditForChromeCrash( |
| 190 config=CrashConfig.Get()).FindCulprit(analysis)) |
| 185 | 191 |
| 186 # TODO(http://crbug.com/659346): why do these mocks give coverage | 192 # TODO(http://crbug.com/659346): why do these mocks give coverage |
| 187 # failures? That's almost surely hiding a bug in the tests themselves. | 193 # failures? That's almost surely hiding a bug in the tests themselves. |
| 188 def testFindCulpritForChromeCrash(self): # pragma: no cover | 194 def testFindCulpritForChromeCrash(self): # pragma: no cover |
| 189 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 195 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
| 190 'GetDependency', lambda *_: {}) | 196 'GetDependency', lambda *_: {}) |
| 191 stack = CallStack(0) | 197 stack = CallStack(0) |
| 192 self.mock(ChromeCrashParser, 'Parse', | 198 self.mock(ChromeCrashParser, 'Parse', |
| 193 lambda *_: Stacktrace([stack], stack)) | 199 lambda *_: Stacktrace([stack], stack)) |
| 194 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, | 200 self.mock(chrome_dependency_fetcher.ChromeDependencyFetcher, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 217 self._testFindCulpritForChromeCrashFails() | 223 self._testFindCulpritForChromeCrashFails() |
| 218 | 224 |
| 219 def _testFindCulpritForChromeCrashSucceeds(self, dummy_suspect): | 225 def _testFindCulpritForChromeCrashSucceeds(self, dummy_suspect): |
| 220 analysis = CrashAnalysis() | 226 analysis = CrashAnalysis() |
| 221 analysis.signature = 'signature' | 227 analysis.signature = 'signature' |
| 222 analysis.platform = 'win' | 228 analysis.platform = 'win' |
| 223 analysis.stack_trace = 'frame1\nframe2' | 229 analysis.stack_trace = 'frame1\nframe2' |
| 224 analysis.crashed_version = '50.0.1234.0' | 230 analysis.crashed_version = '50.0.1234.0' |
| 225 dummy_regression_range = ('50.0.1233.0', '50.0.1234.0') | 231 dummy_regression_range = ('50.0.1233.0', '50.0.1234.0') |
| 226 analysis.regression_range = dummy_regression_range | 232 analysis.regression_range = dummy_regression_range |
| 227 culprit = _FinditForChromeCrash().FindCulprit(analysis) | 233 culprit = _FinditForChromeCrash(config=CrashConfig.Get()).FindCulprit( |
| 234 analysis) |
| 228 self.assertIsNotNone(culprit, 'FindCulprit failed unexpectedly') | 235 self.assertIsNotNone(culprit, 'FindCulprit failed unexpectedly') |
| 229 suspects, tag = culprit.ToDicts() | 236 suspects, tag = culprit.ToDicts() |
| 230 | 237 |
| 231 expected_suspects = { | 238 expected_suspects = { |
| 232 'found': True, | 239 'found': True, |
| 233 'suspected_cls': [dummy_suspect.ToDict()], | 240 'suspected_cls': [dummy_suspect.ToDict()], |
| 234 'regression_range': dummy_regression_range | 241 'regression_range': dummy_regression_range |
| 235 } | 242 } |
| 236 expected_tag = { | 243 expected_tag = { |
| 237 'found_suspects': True, | 244 'found_suspects': True, |
| 238 'found_project': False, | 245 'found_project': False, |
| 239 'found_components': False, | 246 'found_components': False, |
| 240 'has_regression_range': True, | 247 'has_regression_range': True, |
| 241 'solution': 'core_algorithm', | 248 'solution': 'core_algorithm', |
| 242 } | 249 } |
| 243 | 250 |
| 244 self.assertDictEqual(expected_suspects, suspects) | 251 self.assertDictEqual(expected_suspects, suspects) |
| 245 self.assertDictEqual(expected_tag, tag) | 252 self.assertDictEqual(expected_tag, tag) |
| 246 | 253 |
| 247 def _testFindCulpritForChromeCrashFails(self): | 254 def _testFindCulpritForChromeCrashFails(self): |
| 248 analysis = CrashAnalysis() | 255 analysis = CrashAnalysis() |
| 249 analysis.signature = 'signature' | 256 analysis.signature = 'signature' |
| 250 analysis.platform = 'win' | 257 analysis.platform = 'win' |
| 251 analysis.stack_trace = 'frame1\nframe2' | 258 analysis.stack_trace = 'frame1\nframe2' |
| 252 analysis.crashed_version = '50.0.1234.0' | 259 analysis.crashed_version = '50.0.1234.0' |
| 253 # N.B., analysis.regression_range is None | 260 # N.B., analysis.regression_range is None |
| 254 suspects, tag = _FinditForChromeCrash().FindCulprit(analysis).ToDicts() | 261 suspects, tag = _FinditForChromeCrash(config=CrashConfig.Get()).FindCulprit( |
| 262 analysis).ToDicts() |
| 255 | 263 |
| 256 expected_suspects = {'found': False} | 264 expected_suspects = {'found': False} |
| 257 expected_tag = { | 265 expected_tag = { |
| 258 'found_suspects': False, | 266 'found_suspects': False, |
| 259 'found_project': False, | 267 'found_project': False, |
| 260 'found_components': False, | 268 'found_components': False, |
| 261 'has_regression_range': False, | 269 'has_regression_range': False, |
| 262 'solution': 'core_algorithm', | 270 'solution': 'core_algorithm', |
| 263 } | 271 } |
| 264 | 272 |
| 265 self.assertDictEqual(expected_suspects, suspects) | 273 self.assertDictEqual(expected_suspects, suspects) |
| 266 self.assertDictEqual(expected_tag, tag) | 274 self.assertDictEqual(expected_tag, tag) |
| 267 | 275 |
| 268 @mock.patch('google.appengine.ext.ndb.Key.urlsafe') | 276 @mock.patch('google.appengine.ext.ndb.Key.urlsafe') |
| 269 @mock.patch('common.appengine_util.GetDefaultVersionHostname') | 277 @mock.patch('common.appengine_util.GetDefaultVersionHostname') |
| 270 def testProcessResultForPublishing(self, mocked_get_default_host, | 278 def testProcessResultForPublishing(self, mocked_get_default_host, |
| 271 mocked_urlsafe): | 279 mocked_urlsafe): |
| 272 mocked_host = 'http://host' | 280 mocked_host = 'http://host' |
| 273 mocked_get_default_host.return_value = mocked_host | 281 mocked_get_default_host.return_value = mocked_host |
| 274 urlsafe_key = 'abcde' | 282 urlsafe_key = 'abcde' |
| 275 mocked_urlsafe.return_value = urlsafe_key | 283 mocked_urlsafe.return_value = urlsafe_key |
| 276 | 284 |
| 277 crash_identifiers = {'signature': 'sig'} | 285 crash_identifiers = {'signature': 'sig'} |
| 278 analysis = FracasCrashAnalysis.Create(crash_identifiers) | 286 analysis = FracasCrashAnalysis.Create(crash_identifiers) |
| 279 analysis.result = {'other': 'data'} | 287 analysis.result = {'other': 'data'} |
| 280 findit_object = FinditForFracas(MOCK_GET_REPOSITORY) | 288 findit_object = _FinditForFracas(config=CrashConfig.Get()) |
| 281 expected_processed_suspect = { | 289 expected_processed_suspect = { |
| 282 'client_id': findit_object.client_id, | 290 'client_id': findit_object.client_id, |
| 283 'crash_identifiers': {'signature': 'sig'}, | 291 'crash_identifiers': {'signature': 'sig'}, |
| 284 'result': { | 292 'result': { |
| 285 'feedback_url': ( | 293 'feedback_url': ( |
| 286 findit_for_chromecrash._FRACAS_FEEDBACK_URL_TEMPLATE % ( | 294 findit_for_chromecrash._FRACAS_FEEDBACK_URL_TEMPLATE % ( |
| 287 mocked_host, urlsafe_key)), | 295 mocked_host, urlsafe_key)), |
| 288 'other': 'data' | 296 'other': 'data' |
| 289 } | 297 } |
| 290 } | 298 } |
| 291 | 299 |
| 292 self.assertDictEqual(findit_object.GetPublishableResult(crash_identifiers, | 300 self.assertDictEqual(findit_object.GetPublishableResult(crash_identifiers, |
| 293 analysis), | 301 analysis), |
| 294 expected_processed_suspect) | 302 expected_processed_suspect) |
| OLD | NEW |