Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(659)

Side by Side Diff: appengine/findit/handlers/crash/crash_config.py

Issue 2657913002: [Predator] Add ``Project`` class and ``ClassifySuspect`` method to project and component classifier (Closed)
Patch Set: Fix nits. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 """Handles requests to the crash config page.""" 5 """Handles requests to the crash config page."""
6 6
7 import json 7 import json
8 8
9 from google.appengine.api import users 9 from google.appengine.api import users
10 10
11 from common.base_handler import BaseHandler, Permission 11 from common.base_handler import BaseHandler, Permission
12 from model.crash.crash_config import CrashConfig as CrashConfigModel 12 from model.crash.crash_config import CrashConfig as CrashConfigModel
13 13
14 14
15 def _SortConfig(config):
16 """Sorts ``host_direcotries`` list in config dict.
17
18 N.B This method can only be called after validation function, namely the
19 config should be properly formatted.
20 """
21 project_config = config.get('project_classifier')
22 for project_pattern in project_config['project_path_function_hosts']:
23 # Validation assures that the host_directories in the 3rd index of
24 # project_pattern.
25 hosts = project_pattern[3]
26 for index, host in enumerate(hosts or []):
27 if not host.endswith('/'):
28 hosts[index] = host + '/'
29
30 if hosts:
31 hosts.sort(key=lambda host: -len(host.split('/')))
32
33
34 def _ValidateComponentClassifierConfig(component_classifier_config):
35 """Checks that a component_classifier_config dict is properly formatted.
36
37 Args:
38 commponent_classifier_config (dict): A dictionary that provides component to
39 its function and path patterns, and some other settings.
40 For example:
41 {
42 'path_function_component': [
43 [
44 'src/chrome/common/extensions/api/gcm.json',
45 '',
46 'Services>CloudMessaging'
47 ],
48 ...
49 [
50 'src/chrome/browser/accessibility',
51 '',
52 'UI>Accessibility'
53 ],
54 ],
55 'top_n': 4
56 }
57
58 Returns:
59 True if ``component_classifier_config`` is properly formatted, False
60 otherwise.
61 """
62 if not isinstance(component_classifier_config, dict):
63 return False
64
65 path_function_component = component_classifier_config.get(
66 'path_function_component')
67 if not isinstance(path_function_component, list):
68 return False
69
70 top_n = component_classifier_config.get('top_n')
71 if not isinstance(top_n, int):
72 return False
73
74 return True
75
76
77 def _ValidateProjectClassifierConfig(project_classifier_config):
78 """Checks that a project_classifier_config dict is properly formatted.
79
80 Args:
81 project_classifier_config (dict): A dictionary that provides mapping from
82 project to its function patterns, path patterns and its host_directories,
83 and some other settings.
84 For example:
85 {
86 'project_path_function_hosts': [
87 ['android_os', ['googleplex-android/'], ['android.'], None],
88 ['chromium', None, ['org.chromium'],
89 ['src/chrome/browser/resources/',
90 'src/chrome/test/data/layout_tests/',
91 'src/media/']]
92 ],
93 'non_chromium_project_rank_priority': {
94 'android_os': '-1',
95 'others': '-2',
96 },
97 'top_n': 4
98 }
99
100 Returns:
101 True if ``project_classifier_config`` is properly formatted, False
102 otherwise.
103 """
104 if not isinstance(project_classifier_config, dict):
105 return False
106
107 project_path_function_hosts = project_classifier_config.get(
108 'project_path_function_hosts')
109 if not isinstance(project_path_function_hosts, list):
110 return False
111
112 non_chromium_project_rank_priority = project_classifier_config.get(
113 'non_chromium_project_rank_priority')
114 if not isinstance(non_chromium_project_rank_priority, dict):
115 return False
116
117 top_n = project_classifier_config.get('top_n')
118 if not isinstance(top_n, int):
119 return False
120
121 return True
122
123
124 # TODO(katesonia): Add validation function for ``cracas`` and ``fracas``.
125 # Maps config properties to their validation functions.
126 _CONFIG_VALIDATION_FUNCTIONS = {
127 'fracas': None,
128 'cracas': None,
129 'component_classifier': _ValidateComponentClassifierConfig,
130 'project_classifier': _ValidateProjectClassifierConfig
131 }
132
133
134 def _ConfigurationDictIsValid(configuration_dict):
135 """Checks that each configuration setting is properly formatted.
136
137 Args:
138 configuration_dict: A dictionary expected to map configuration properties
139 by name to their intended settings. For example,
140
141 configuration_dict = {
142 'some_config_property': (some dictionary),
143 'some_other_config_property': (some list),
144 'another_config_property': (some value),
145 ...
146 }
147
148 Returns:
149 True if all configuration properties are properly formatted, False
150 otherwise.
151 """
152 if not isinstance(configuration_dict, dict):
153 return False
154
155 for configurable_property, validation_function in (
156 _CONFIG_VALIDATION_FUNCTIONS.iteritems()):
157 if configurable_property not in configuration_dict:
158 return False
159
160 # No validation rules specified for this property.
161 if validation_function is None:
162 continue
163
164 configuration = configuration_dict[configurable_property]
165 if not validation_function(configuration):
166 return False
167
168 return True
169
170
15 class CrashConfig(BaseHandler): 171 class CrashConfig(BaseHandler):
16 PERMISSION_LEVEL = Permission.ADMIN 172 PERMISSION_LEVEL = Permission.ADMIN
17 173
18 def HandleGet(self): 174 def HandleGet(self):
19 settings = CrashConfigModel.Get() 175 settings = CrashConfigModel.Get()
20 176
21 data = { 177 data = {
22 'fracas': settings.fracas, 178 'fracas': settings.fracas,
23 'cracas': settings.cracas, 179 'cracas': settings.cracas,
24 'component_classifier': settings.component_classifier, 180 'component_classifier': settings.component_classifier,
25 'project_classifier': settings.project_classifier, 181 'project_classifier': settings.project_classifier,
26 } 182 }
27 183
28 return {'template': 'crash/crash_config.html', 'data': data} 184 return {'template': 'crash/crash_config.html', 'data': data}
29 185
30 def HandlePost(self): 186 def HandlePost(self):
31 data = self.request.params.get('data') 187 data = self.request.params.get('data')
32 new_config_dict = json.loads(data) 188 new_config_dict = json.loads(data)
189 if not _ConfigurationDictIsValid(new_config_dict):
190 return self.CreateError(
191 'New configuration settings are not properly formatted.', 400)
192
193 # Sort config dict in place.
194 _SortConfig(new_config_dict)
33 195
34 crash_config = CrashConfigModel.Get() 196 crash_config = CrashConfigModel.Get()
35
36 crash_config.ClearCache() 197 crash_config.ClearCache()
37 crash_config.Update( 198 crash_config.Update(
38 users.get_current_user(), users.IsCurrentUserAdmin(), **new_config_dict) 199 users.get_current_user(), users.IsCurrentUserAdmin(), **new_config_dict)
39 return self.HandleGet() 200 return self.HandleGet()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698