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

Side by Side Diff: chrome/app/policy/syntax_check_policy_template_json.py

Issue 6409040: New policy protobuf protocol. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address feedback; fix gyp files Created 9 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 | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python2 1 #!/usr/bin/python2
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 ''' 6 '''
7 Checks a policy_templates.json file for conformity to its syntax specification. 7 Checks a policy_templates.json file for conformity to its syntax specification.
8 ''' 8 '''
9 9
10 import json 10 import json
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 (container_name.title(), value_type.__name__, key), 74 (container_name.title(), value_type.__name__, key),
75 container_name, identifier, offending) 75 container_name, identifier, offending)
76 return None 76 return None
77 value = container[key] 77 value = container[key]
78 if not isinstance(value, value_type): 78 if not isinstance(value, value_type):
79 self._Error('Value of "%s" must be a %s.' % 79 self._Error('Value of "%s" must be a %s.' %
80 (key, value_type.__name__), 80 (key, value_type.__name__),
81 container_name, identifier, value) 81 container_name, identifier, value)
82 return value 82 return value
83 83
84 def _CheckPolicy(self, policy, may_contain_groups): 84 def _AddPolicyID(self, id, policy_ids, policy):
85 '''
86 Adds |id| to |policy_ids|. Generates an error message if the
87 |id| exists already; |policy| is needed for this message.
88 '''
89 if id in policy_ids:
90 self._Error('Duplicate id', 'policy', policy.get('name'),
91 id)
92 else:
93 policy_ids.add(id)
94
95 def _CheckPolicyIDs(self, policy_ids, group=None):
96 '''
97 Checks a set of policy_ids to make sure it contains a continuous range
98 of entries (i.e. no holes).
Mattias Nissler (ping if slow) 2011/02/03 16:23:41 can you elaborate here please on why we don't want
Jakob Kummerow 2011/02/08 16:15:43 Done.
99 '''
100 for i in range(len(policy_ids)):
101 if (i + 1) not in policy_ids:
102 if group is not None:
103 self._Error('Missing id: %s' % (i + 1), 'policy group',
104 group.get('name'))
105 else:
106 self._Error('No policy with id: %s' % (i + 1))
107
108 def _CheckPolicy(self, policy, is_in_group, policy_ids):
85 if not isinstance(policy, dict): 109 if not isinstance(policy, dict):
86 self._Error('Each policy must be a dictionary.', 'policy', None, policy) 110 self._Error('Each policy must be a dictionary.', 'policy', None, policy)
87 return 111 return
88 112
89 # There should not be any unknown keys in |policy|. 113 # There should not be any unknown keys in |policy|.
90 for key in policy: 114 for key in policy:
91 if key not in ('name', 'type', 'caption', 'desc', 'supported_on', 115 if key not in ('name', 'type', 'caption', 'desc', 'supported_on',
92 'label', 'policies', 'items', 'example_value', 'features', 116 'label', 'policies', 'items', 'example_value', 'features',
93 'deprecated', 'future'): 117 'deprecated', 'future', 'id'):
94 self.warning_count += 1 118 self.warning_count += 1
95 print ('In policy %s: Warning: Unknown key: %s' % 119 print ('In policy %s: Warning: Unknown key: %s' %
96 (policy.get('name'), key)) 120 (policy.get('name'), key))
97 121
98 # Each policy must have a name. 122 # Each policy must have a name.
99 self._CheckContains(policy, 'name', str) 123 self._CheckContains(policy, 'name', str)
100 124
101 # Each policy must have a type. 125 # Each policy must have a type.
102 policy_type = self._CheckContains(policy, 'type', str) 126 policy_type = self._CheckContains(policy, 'type', str)
103 if policy_type not in ('group', 'main', 'string', 'int', 'list', 'int-enum', 127 if policy_type not in ('group', 'main', 'string', 'int', 'list', 'int-enum',
104 'string-enum'): 128 'string-enum'):
105 self._Error('Policy type must be either of: group, main, string, int, ' 129 self._Error('Policy type must be either of: group, main, string, int, '
106 'list, int-enum, string-enum', 'policy', policy, policy_type) 130 'list, int-enum, string-enum', 'policy', policy, policy_type)
107 return # Can't continue for unsupported type. 131 return # Can't continue for unsupported type.
108 132
109 # Each policy must have a caption message. 133 # Each policy must have a caption message.
110 self._CheckContains(policy, 'caption', str) 134 self._CheckContains(policy, 'caption', str)
111 135
112 # Each policy must have a description message. 136 # Each policy must have a description message.
113 self._CheckContains(policy, 'desc', str) 137 self._CheckContains(policy, 'desc', str)
114 138
115 # If 'label' is present, it must be a string. 139 # If 'label' is present, it must be a string.
116 self._CheckContains(policy, 'label', str, True) 140 self._CheckContains(policy, 'label', str, True)
117 141
142 # Each policy must have a protobuf ID.
143 id = self._CheckContains(policy, 'id', int)
144 self._AddPolicyID(id, policy_ids, policy)
145
118 # If 'deprecated' is present, it must be a bool. 146 # If 'deprecated' is present, it must be a bool.
119 self._CheckContains(policy, 'deprecated', bool, True) 147 self._CheckContains(policy, 'deprecated', bool, True)
120 148
121 # If 'future' is present, it must be a bool. 149 # If 'future' is present, it must be a bool.
122 self._CheckContains(policy, 'future', bool, True) 150 self._CheckContains(policy, 'future', bool, True)
123 151
124 if policy_type == 'group': 152 if policy_type == 'group':
125 153
126 # Groups must not be nested. 154 # Groups must not be nested.
127 if not may_contain_groups: 155 if is_in_group:
128 self._Error('Policy groups must not be nested.', 'policy', policy) 156 self._Error('Policy groups must not be nested.', 'policy', policy)
129 157
130 # Each policy group must have a list of policies. 158 # Each policy group must have a list of policies.
131 policies = self._CheckContains(policy, 'policies', list) 159 policies = self._CheckContains(policy, 'policies', list)
160
161 # Check sub-policies.
162 group_policy_ids = set()
132 if policies is not None: 163 if policies is not None:
133 for nested_policy in policies: 164 for nested_policy in policies:
134 self._CheckPolicy(nested_policy, False) 165 self._CheckPolicy(nested_policy, True, group_policy_ids)
166 self._CheckPolicyIDs(group_policy_ids, policy)
135 167
136 # Statistics. 168 # Statistics.
137 self.num_groups += 1 169 self.num_groups += 1
138 else: # policy_type != group 170 else: # policy_type != group
139 171
140 # Each policy must have a supported_on list. 172 # Each policy must have a supported_on list.
141 supported_on = self._CheckContains(policy, 'supported_on', list) 173 supported_on = self._CheckContains(policy, 'supported_on', list)
142 if supported_on is not None: 174 if supported_on is not None:
143 for s in supported_on: 175 for s in supported_on:
144 if not isinstance(s, str): 176 if not isinstance(s, str):
145 self._Error('Entries in "supported_on" must be strings.', 'policy', 177 self._Error('Entries in "supported_on" must be strings.', 'policy',
146 policy, supported_on) 178 policy, supported_on)
147 179
148 # Each policy must have a 'features' dict. 180 # Each policy must have a 'features' dict.
149 self._CheckContains(policy, 'features', dict) 181 self._CheckContains(policy, 'features', dict)
150 182
151 # Each policy must have an 'example_value' of appropriate type. 183 # Each policy must have an 'example_value' of appropriate type.
152 if policy_type == 'main': 184 if policy_type == 'main':
153 value_type = bool 185 value_type = bool
154 elif policy_type in ('string', 'string-enum'): 186 elif policy_type in ('string', 'string-enum'):
155 value_type = str 187 value_type = str
156 elif policy_type in ('int', 'int-enum'): 188 elif policy_type in ('int', 'int-enum'):
157 value_type = int 189 value_type = int
158 elif policy_type == 'list': 190 elif policy_type == 'list':
159 value_type = list 191 value_type = list
160 else: 192 else:
161 raise NotImplementedError('Unimplemented policy type: %s' % policy_type) 193 raise NotImplementedError('Unimplemented policy type: %s' % policy_type)
162 self._CheckContains(policy, 'example_value', value_type) 194 self._CheckContains(policy, 'example_value', value_type)
163 195
164 # Statistics. 196 # Statistics.
165 self.num_policies += 1 197 self.num_policies += 1
166 if not may_contain_groups: 198 if is_in_group:
167 self.num_policies_in_groups += 1 199 self.num_policies_in_groups += 1
168 200
169 if policy_type in ('int-enum', 'string-enum'): 201 if policy_type in ('int-enum', 'string-enum'):
170 202
171 # Enums must contain a list of items. 203 # Enums must contain a list of items.
172 items = self._CheckContains(policy, 'items', list) 204 items = self._CheckContains(policy, 'items', list)
173 if items is not None: 205 if items is not None:
174 if len(items) < 1: 206 if len(items) < 1:
175 self._Error('"items" must not be empty.', 'policy', policy, items) 207 self._Error('"items" must not be empty.', 'policy', policy, items)
176 for item in items: 208 for item in items:
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 self.options = options 361 self.options = options
330 362
331 # First part: check JSON structure. 363 # First part: check JSON structure.
332 364
333 # Check policy definitions. 365 # Check policy definitions.
334 policy_definitions = self._CheckContains(data, 'policy_definitions', list, 366 policy_definitions = self._CheckContains(data, 'policy_definitions', list,
335 parent_element=None, 367 parent_element=None,
336 container_name='The root element', 368 container_name='The root element',
337 offending=None) 369 offending=None)
338 if policy_definitions is not None: 370 if policy_definitions is not None:
371 policy_ids = set()
339 for policy in policy_definitions: 372 for policy in policy_definitions:
340 self._CheckPolicy(policy, True) 373 self._CheckPolicy(policy, False, policy_ids)
374 self._CheckPolicyIDs(policy_ids)
341 375
342 # Check (non-policy-specific) message definitions. 376 # Check (non-policy-specific) message definitions.
343 messages = self._CheckContains(data, 'messages', dict, 377 messages = self._CheckContains(data, 'messages', dict,
344 parent_element=None, 378 parent_element=None,
345 container_name='The root element', 379 container_name='The root element',
346 offending=None) 380 offending=None)
347 if messages is not None: 381 if messages is not None:
348 for message in messages: 382 for message in messages:
349 self._CheckMessage(message, messages[message]) 383 self._CheckMessage(message, messages[message])
350 384
351 # Check placeholders. 385 # Check placeholders.
352 placeholders = self._CheckContains(data, 'placeholders', list, 386 placeholders = self._CheckContains(data, 'placeholders', list,
353 parent_element=None, 387 parent_element=None,
354 container_name='The root element', 388 container_name='The root element',
355 offending=None) 389 offending=None)
356 if placeholders is not None: 390 if placeholders is not None:
357 for placeholder in placeholders: 391 for placeholder in placeholders:
358 self._CheckPlaceholder(placeholder) 392 self._CheckPlaceholder(placeholder)
359 393
360 # Second part: check formatting. 394 # Second part: check formatting.
361 self._CheckFormat(filename) 395 self._CheckFormat(filename)
362 396
363 # Third part: summary and exit. 397 # Third part: summary and exit.
364 print ('Finished. %d errors, %d warnings.' % 398 print ('Finished checking %s. %d errors, %d warnings.' %
365 (self.error_count, self.warning_count)) 399 (filename, self.error_count, self.warning_count))
366 if self.options.stats: 400 if self.options.stats:
367 if self.num_groups > 0: 401 if self.num_groups > 0:
368 print ('%d policies, %d of those in %d groups (containing on ' 402 print ('%d policies, %d of those in %d groups (containing on '
369 'average %.1f policies).' % 403 'average %.1f policies).' %
370 (self.num_policies, self.num_policies_in_groups, self.num_groups, 404 (self.num_policies, self.num_policies_in_groups, self.num_groups,
371 (1.0 * self.num_policies_in_groups / self.num_groups))) 405 (1.0 * self.num_policies_in_groups / self.num_groups)))
372 else: 406 else:
373 print self.num_policies, 'policies, 0 policy groups.' 407 print self.num_policies, 'policies, 0 policy groups.'
374 if self.error_count > 0: 408 if self.error_count > 0:
375 return 1 409 return 1
(...skipping 14 matching lines...) Expand all
390 if len(args) != 2: 424 if len(args) != 2:
391 parser.print_help() 425 parser.print_help()
392 sys.exit(1) 426 sys.exit(1)
393 filename = args[1] 427 filename = args[1]
394 return self.Main(filename, options) 428 return self.Main(filename, options)
395 429
396 430
397 if __name__ == '__main__': 431 if __name__ == '__main__':
398 checker = PolicyTemplateChecker() 432 checker = PolicyTemplateChecker()
399 sys.exit(checker.Run(sys.argv)) 433 sys.exit(checker.Run(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698