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