| 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 logging | 5 import logging |
| 6 | 6 |
| 7 from google.appengine.ext import ndb | 7 from google.appengine.ext import ndb |
| 8 | 8 |
| 9 from common import appengine_util | 9 from common import appengine_util |
| 10 from crash import detect_regression_range | 10 from crash import detect_regression_range |
| 11 from crash.chromecrash_parser import ChromeCrashParser | 11 from crash.chromecrash_parser import ChromeCrashParser |
| 12 from crash.component import Component | |
| 13 from crash.component_classifier import ComponentClassifier | |
| 14 from crash.findit import Findit | 12 from crash.findit import Findit |
| 15 from crash.loglinear.changelist_classifier import LogLinearChangelistClassifier | 13 from crash.loglinear.changelist_classifier import LogLinearChangelistClassifier |
| 16 from crash.loglinear.changelist_features.touch_crashed_file_meta import ( | 14 from crash.loglinear.changelist_features.touch_crashed_file_meta import ( |
| 17 TouchCrashedFileMetaFeature) | 15 TouchCrashedFileMetaFeature) |
| 18 from crash.loglinear.feature import WrapperMetaFeature | 16 from crash.loglinear.feature import WrapperMetaFeature |
| 19 from crash.loglinear.weight import MetaWeight | 17 from crash.loglinear.weight import MetaWeight |
| 20 from crash.loglinear.weight import Weight | 18 from crash.loglinear.weight import Weight |
| 21 from crash.predator import Predator | 19 from crash.predator import Predator |
| 22 from crash.project import Project | |
| 23 from crash.project_classifier import ProjectClassifier | |
| 24 from crash.type_enums import CrashClient | 20 from crash.type_enums import CrashClient |
| 25 from model.crash.cracas_crash_analysis import CracasCrashAnalysis | 21 from model.crash.cracas_crash_analysis import CracasCrashAnalysis |
| 26 from model.crash.crash_config import CrashConfig | 22 from model.crash.crash_config import CrashConfig |
| 27 from model.crash.fracas_crash_analysis import FracasCrashAnalysis | 23 from model.crash.fracas_crash_analysis import FracasCrashAnalysis |
| 28 | 24 |
| 29 # TODO(katesonia): Remove the default value after adding validity check to | 25 # TODO(katesonia): Remove the default value after adding validity check to |
| 30 # config. | 26 # config. |
| 31 _FRACAS_FEEDBACK_URL_TEMPLATE = 'https://%s/crash/fracas-result-feedback?key=%s' | 27 _FRACAS_FEEDBACK_URL_TEMPLATE = 'https://%s/crash/fracas-result-feedback?key=%s' |
| 32 | 28 |
| 33 # TODO(wrengr): [Note#1] in many places below we have to do some ugly | 29 # TODO(wrengr): [Note#1] in many places below we have to do some ugly |
| (...skipping 13 matching lines...) Expand all Loading... |
| 47 def _ClientID(cls): # pragma: no cover | 43 def _ClientID(cls): # pragma: no cover |
| 48 if cls is FinditForChromeCrash: | 44 if cls is FinditForChromeCrash: |
| 49 logging.warning('FinditForChromeCrash is abstract, ' | 45 logging.warning('FinditForChromeCrash is abstract, ' |
| 50 'but someone constructed an instance and called _ClientID') | 46 'but someone constructed an instance and called _ClientID') |
| 51 else: | 47 else: |
| 52 logging.warning( | 48 logging.warning( |
| 53 'FinditForChromeCrash subclass %s forgot to implement _ClientID', | 49 'FinditForChromeCrash subclass %s forgot to implement _ClientID', |
| 54 cls.__name__) | 50 cls.__name__) |
| 55 raise NotImplementedError() | 51 raise NotImplementedError() |
| 56 | 52 |
| 57 # TODO(http://crbug.com/659354): remove the dependency on CrashConfig | 53 def __init__(self, get_repository, config): |
| 58 # entirely, by passing the relevant data as arguments to this constructor. | 54 super(FinditForChromeCrash, self).__init__(get_repository, config) |
| 59 def __init__(self, get_repository): | |
| 60 super(FinditForChromeCrash, self).__init__(get_repository) | |
| 61 | 55 |
| 62 # TODO(http://crbug.com/687670): Move meta weight initial value to config. | 56 # TODO(http://crbug.com/687670): Move meta weight initial value to config. |
| 63 meta_weight = MetaWeight({ | 57 meta_weight = MetaWeight({ |
| 64 'TouchCrashedFileMeta': MetaWeight({ | 58 'TouchCrashedFileMeta': MetaWeight({ |
| 65 'MinDistance': Weight(1.), | 59 'MinDistance': Weight(1.), |
| 66 'TopFrameIndex': Weight(1.), | 60 'TopFrameIndex': Weight(1.), |
| 67 'TouchCrashedFile': Weight(1.), | 61 'TouchCrashedFile': Weight(1.), |
| 68 }) | 62 }) |
| 69 }) | 63 }) |
| 70 meta_feature = WrapperMetaFeature( | 64 meta_feature = WrapperMetaFeature( |
| 71 [TouchCrashedFileMetaFeature(get_repository)]) | 65 [TouchCrashedFileMetaFeature(get_repository)]) |
| 72 | 66 |
| 73 project_classifier_config = CrashConfig.Get().project_classifier | |
| 74 projects = [Project(name, path_regexs, function_regexs, host_directories) | |
| 75 for name, path_regexs, function_regexs, host_directories | |
| 76 in project_classifier_config['project_path_function_hosts']] | |
| 77 component_classifier_config = CrashConfig.Get().component_classifier | |
| 78 components = [Component(component_name, path_regex, function_regex) | |
| 79 for path_regex, function_regex, component_name | |
| 80 in component_classifier_config['path_function_component']] | |
| 81 | |
| 82 # The top_n is the number of frames we want to check to get component or | 67 # The top_n is the number of frames we want to check to get component or |
| 83 # project classifications. | 68 # project classifications. |
| 84 self._predator = Predator( | 69 self._predator = Predator( |
| 85 cl_classifier = LogLinearChangelistClassifier(get_repository, | 70 cl_classifier = LogLinearChangelistClassifier(get_repository, |
| 86 meta_feature, | 71 meta_feature, |
| 87 meta_weight), | 72 meta_weight), |
| 88 component_classifier = ComponentClassifier( | 73 project_classifier = self._project_classifier, |
| 89 components, component_classifier_config['top_n']), | 74 component_classifier = self._component_classifier) |
| 90 project_classifier = ProjectClassifier( | |
| 91 projects, project_classifier_config['top_n'], | |
| 92 project_classifier_config['non_chromium_project_rank_priority'])) | |
| 93 | 75 |
| 94 self._stacktrace_parser = ChromeCrashParser() | 76 self._stacktrace_parser = ChromeCrashParser() |
| 95 | 77 |
| 96 def _InitializeAnalysis(self, model, crash_data): | 78 def _InitializeAnalysis(self, model, crash_data): |
| 97 super(FinditForChromeCrash, self)._InitializeAnalysis(model, crash_data) | 79 super(FinditForChromeCrash, self)._InitializeAnalysis(model, crash_data) |
| 98 # TODO(wrengr): see Note#1 | 80 # TODO(wrengr): see Note#1 |
| 99 customized_data = crash_data.get('customized_data', {}) | 81 customized_data = crash_data.get('customized_data', {}) |
| 100 model.channel = customized_data.get('channel', None) | 82 model.channel = customized_data.get('channel', None) |
| 101 model.historical_metadata = customized_data.get('historical_metadata', []) | 83 model.historical_metadata = customized_data.get('historical_metadata', []) |
| 102 | 84 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 125 model.put() | 107 model.put() |
| 126 return True | 108 return True |
| 127 | 109 |
| 128 def CheckPolicy(self, crash_data): | 110 def CheckPolicy(self, crash_data): |
| 129 crash_identifiers = crash_data['crash_identifiers'] | 111 crash_identifiers = crash_data['crash_identifiers'] |
| 130 platform = crash_data['platform'] | 112 platform = crash_data['platform'] |
| 131 # TODO(wrengr): see Note#1 | 113 # TODO(wrengr): see Note#1 |
| 132 channel = crash_data.get('customized_data', {}).get('channel', None) | 114 channel = crash_data.get('customized_data', {}).get('channel', None) |
| 133 # TODO(katesonia): Remove the default value after adding validity check to | 115 # TODO(katesonia): Remove the default value after adding validity check to |
| 134 # config. | 116 # config. |
| 135 if platform not in self.config.get( | 117 if platform not in self.client_config.get( |
| 136 'supported_platform_list_by_channel', {}).get(channel, []): | 118 'supported_platform_list_by_channel', {}).get(channel, []): |
| 137 # Bail out if either the channel or platform is not supported yet. | 119 # Bail out if either the channel or platform is not supported yet. |
| 138 logging.info('Analysis of channel %s, platform %s is not supported. ' | 120 logging.info('Analysis of channel %s, platform %s is not supported. ' |
| 139 'No analysis is scheduled for %s', | 121 'No analysis is scheduled for %s', |
| 140 channel, platform, repr(crash_identifiers)) | 122 channel, platform, repr(crash_identifiers)) |
| 141 return None | 123 return None |
| 142 | 124 |
| 143 signature = crash_data['signature'] | 125 signature = crash_data['signature'] |
| 144 # TODO(wrengr): can this blacklist stuff be lifted to the base class? | 126 # TODO(wrengr): can this blacklist stuff be lifted to the base class? |
| 145 # TODO(katesonia): Remove the default value after adding validity check to | 127 # TODO(katesonia): Remove the default value after adding validity check to |
| 146 # config. | 128 # config. |
| 147 for blacklist_marker in self.config.get('signature_blacklist_markers', []): | 129 for blacklist_marker in self.client_config.get( |
| 130 'signature_blacklist_markers', []): |
| 148 if blacklist_marker in signature: | 131 if blacklist_marker in signature: |
| 149 logging.info('%s signature is not supported. ' | 132 logging.info('%s signature is not supported. ' |
| 150 'No analysis is scheduled for %s', blacklist_marker, | 133 'No analysis is scheduled for %s', blacklist_marker, |
| 151 repr(crash_identifiers)) | 134 repr(crash_identifiers)) |
| 152 return None | 135 return None |
| 153 | 136 |
| 154 # TODO(wrengr): should we clone ``crash_data`` rather than mutating it? | 137 # TODO(wrengr): should we clone ``crash_data`` rather than mutating it? |
| 155 crash_data['platform'] = self.RenamePlatform(platform) | 138 crash_data['platform'] = self.RenamePlatform(platform) |
| 156 return crash_data | 139 return crash_data |
| 157 | 140 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 177 |
| 195 def GetAnalysis(self, crash_identifiers): | 178 def GetAnalysis(self, crash_identifiers): |
| 196 # TODO: inline FracasCrashAnalysis.Get stuff here. | 179 # TODO: inline FracasCrashAnalysis.Get stuff here. |
| 197 return FracasCrashAnalysis.Get(crash_identifiers) | 180 return FracasCrashAnalysis.Get(crash_identifiers) |
| 198 | 181 |
| 199 def ProcessResultForPublishing(self, result, key): | 182 def ProcessResultForPublishing(self, result, key): |
| 200 """Fracas specific processing of result data for publishing.""" | 183 """Fracas specific processing of result data for publishing.""" |
| 201 result['feedback_url'] = _FRACAS_FEEDBACK_URL_TEMPLATE % ( | 184 result['feedback_url'] = _FRACAS_FEEDBACK_URL_TEMPLATE % ( |
| 202 appengine_util.GetDefaultVersionHostname(), key) | 185 appengine_util.GetDefaultVersionHostname(), key) |
| 203 return result | 186 return result |
| OLD | NEW |