Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / components / policy / resources / PRESUBMIT.py
blobb59e8d3504f25bd5b355e988053a69bee0ebc045
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
5 # If this presubmit check fails or misbehaves, please complain to
6 # mnissler@chromium.org, bartfab@chromium.org or atwilson@chromium.org.
8 import itertools
9 import sys
10 import xml.dom.minidom
12 def _GetPolicyTemplates(template_path):
13 # Read list of policies in the template. eval() is used instead of a JSON
14 # parser because policy_templates.json is not quite JSON, and uses some
15 # python features such as #-comments and '''strings'''. policy_templates.json
16 # is actually maintained as a python dictionary.
17 with open(template_path) as f:
18 template_data = eval(f.read(), {})
19 policies = ( policy
20 for policy in template_data['policy_definitions']
21 if policy['type'] != 'group' )
22 groups = ( policy['policies']
23 for policy in template_data['policy_definitions']
24 if policy['type'] == 'group' )
25 subpolicies = ( policy for group in groups for policy in group )
26 return list(itertools.chain(policies, subpolicies))
28 def _CheckPolicyTemplatesSyntax(input_api, output_api):
29 local_path = input_api.PresubmitLocalPath()
30 filepath = input_api.os_path.join(local_path, 'policy_templates.json')
31 if any(f.AbsoluteLocalPath() == filepath
32 for f in input_api.AffectedFiles()):
33 old_sys_path = sys.path
34 try:
35 tools_path = input_api.os_path.normpath(
36 input_api.os_path.join(local_path, input_api.os_path.pardir, 'tools'))
37 sys.path = [ tools_path ] + sys.path
38 # Optimization: only load this when it's needed.
39 import syntax_check_policy_template_json
40 checker = syntax_check_policy_template_json.PolicyTemplateChecker()
41 if checker.Run([], filepath) > 0:
42 return [output_api.PresubmitError('Syntax error(s) in file:',
43 [filepath])]
44 finally:
45 sys.path = old_sys_path
46 return []
49 def _CheckPolicyTestCases(input_api, output_api, policies):
50 # Read list of policies in chrome/test/data/policy/policy_test_cases.json.
51 root = input_api.change.RepositoryRoot()
52 policy_test_cases_file = input_api.os_path.join(
53 root, 'chrome', 'test', 'data', 'policy', 'policy_test_cases.json')
54 test_names = input_api.json.load(open(policy_test_cases_file)).keys()
55 tested_policies = frozenset(name.partition('.')[0]
56 for name in test_names
57 if name[:2] != '--')
58 policy_names = frozenset(policy['name'] for policy in policies)
60 # Finally check if any policies are missing.
61 missing = policy_names - tested_policies
62 extra = tested_policies - policy_names
63 error_missing = ('Policy \'%s\' was added to policy_templates.json but not '
64 'to src/chrome/test/data/policy/policy_test_cases.json. '
65 'Please update both files.')
66 error_extra = ('Policy \'%s\' is tested by '
67 'src/chrome/test/data/policy/policy_test_cases.json but is not'
68 ' defined in policy_templates.json. Please update both files.')
69 results = []
70 for policy in missing:
71 results.append(output_api.PresubmitError(error_missing % policy))
72 for policy in extra:
73 results.append(output_api.PresubmitError(error_extra % policy))
74 return results
77 def _CheckPolicyHistograms(input_api, output_api, policies):
78 root = input_api.change.RepositoryRoot()
79 histograms = input_api.os_path.join(
80 root, 'tools', 'metrics', 'histograms', 'histograms.xml')
81 with open(histograms) as f:
82 tree = xml.dom.minidom.parseString(f.read())
83 enums = (tree.getElementsByTagName('histogram-configuration')[0]
84 .getElementsByTagName('enums')[0]
85 .getElementsByTagName('enum'))
86 policy_enum = [e for e in enums
87 if e.getAttribute('name') == 'EnterprisePolicies'][0]
88 policy_ids = frozenset([int(e.getAttribute('value'))
89 for e in policy_enum.getElementsByTagName('int')])
91 error_missing = ('Policy \'%s\' was added to policy_templates.json but not '
92 'to src/tools/metrics/histograms/histograms.xml. '
93 'Please update both files.')
94 results = []
95 for policy in policies:
96 if policy['id'] not in policy_ids:
97 results.append(output_api.PresubmitError(error_missing % policy['name']))
98 return results
101 def _CommonChecks(input_api, output_api):
102 results = []
103 results.extend(_CheckPolicyTemplatesSyntax(input_api, output_api))
105 os_path = input_api.os_path
106 local_path = input_api.PresubmitLocalPath()
107 template_path = os_path.join(local_path, 'policy_templates.json')
108 affected_files = input_api.AffectedFiles()
109 if any(f.AbsoluteLocalPath() == template_path for f in affected_files):
110 try:
111 policies = _GetPolicyTemplates(template_path)
112 except:
113 results.append(output_api.PresubmitError('Invalid Python/JSON syntax.'))
114 return results
115 results.extend(_CheckPolicyTestCases(input_api, output_api, policies))
116 results.extend(_CheckPolicyHistograms(input_api, output_api, policies))
118 return results
121 def CheckChangeOnUpload(input_api, output_api):
122 return _CommonChecks(input_api, output_api)
125 def CheckChangeOnCommit(input_api, output_api):
126 return _CommonChecks(input_api, output_api)