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.
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(), {})
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
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:',
45 sys
.path
= old_sys_path
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
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.')
70 for policy
in missing
:
71 results
.append(output_api
.PresubmitError(error_missing
% policy
))
73 results
.append(output_api
.PresubmitError(error_extra
% policy
))
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.')
95 for policy
in policies
:
96 if policy
['id'] not in policy_ids
:
97 results
.append(output_api
.PresubmitError(error_missing
% policy
['name']))
101 def _CommonChecks(input_api
, output_api
):
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
):
111 policies
= _GetPolicyTemplates(template_path
)
113 results
.append(output_api
.PresubmitError('Invalid Python/JSON syntax.'))
115 results
.extend(_CheckPolicyTestCases(input_api
, output_api
, policies
))
116 results
.extend(_CheckPolicyHistograms(input_api
, output_api
, policies
))
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
)