Bug 1383996 - Make most calls to `mach artifact toolchain` output a manifest. r=gps
[gecko.git] / testing / mozharness / scripts / configtest.py
blob5db684f0a7f8b5e4be505431350c45ac788c7cf2
1 #!/usr/bin/env python
2 # ***** BEGIN LICENSE BLOCK *****
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 # You can obtain one at http://mozilla.org/MPL/2.0/.
6 # ***** END LICENSE BLOCK *****
7 """configtest.py
9 Verify the .json and .py files in the configs/ directory are well-formed.
10 Further tests to verify validity would be desirable.
12 This is also a good example script to look at to understand mozharness.
13 """
15 import os
16 import pprint
17 import sys
18 try:
19 import simplejson as json
20 except ImportError:
21 import json
23 sys.path.insert(1, os.path.dirname(sys.path[0]))
25 from mozharness.base.script import BaseScript
27 # ConfigTest {{{1
28 class ConfigTest(BaseScript):
29 config_options = [[
30 ["--test-file",],
31 {"action": "extend",
32 "dest": "test_files",
33 "help": "Specify which config files to test"
37 def __init__(self, require_config_file=False):
38 self.config_files = []
39 BaseScript.__init__(self, config_options=self.config_options,
40 all_actions=['list-config-files',
41 'test-json-configs',
42 'test-python-configs',
43 'summary',
45 default_actions=['test-json-configs',
46 'test-python-configs',
47 'summary',
49 require_config_file=require_config_file)
51 def query_config_files(self):
52 """This query method, much like others, caches its runtime
53 settings in self.VAR so we don't have to figure out config_files
54 multiple times.
55 """
56 if self.config_files:
57 return self.config_files
58 c = self.config
59 if 'test_files' in c:
60 self.config_files = c['test_files']
61 return self.config_files
62 self.debug("No --test-file(s) specified; defaulting to crawling the configs/ directory.")
63 config_files = []
64 for root, dirs, files in os.walk(os.path.join(sys.path[0], "..",
65 "configs")):
66 for name in files:
67 # Hardcode =P
68 if name.endswith(".json") or name.endswith(".py"):
69 if not name.startswith("test_malformed"):
70 config_files.append(os.path.join(root, name))
71 self.config_files = config_files
72 return self.config_files
74 def list_config_files(self):
75 """ Non-default action that is mainly here to demonstrate how
76 non-default actions work in a mozharness script.
77 """
78 config_files = self.query_config_files()
79 for config_file in config_files:
80 self.info(config_file)
82 def test_json_configs(self):
83 """ Currently only "is this well-formed json?"
85 """
86 config_files = self.query_config_files()
87 filecount = [0, 0]
88 for config_file in config_files:
89 if config_file.endswith(".json"):
90 filecount[0] += 1
91 self.info("Testing %s." % config_file)
92 contents = self.read_from_file(config_file, verbose=False)
93 try:
94 json.loads(contents)
95 except ValueError:
96 self.add_summary("%s is invalid json." % config_file,
97 level="error")
98 self.error(pprint.pformat(sys.exc_info()[1]))
99 else:
100 self.info("Good.")
101 filecount[1] += 1
102 if filecount[0]:
103 self.add_summary("%d of %d json config files were good." %
104 (filecount[1], filecount[0]))
105 else:
106 self.add_summary("No json config files to test.")
108 def test_python_configs(self):
109 """Currently only "will this give me a config dictionary?"
112 config_files = self.query_config_files()
113 filecount = [0, 0]
114 for config_file in config_files:
115 if config_file.endswith(".py"):
116 filecount[0] += 1
117 self.info("Testing %s." % config_file)
118 global_dict = {}
119 local_dict = {}
120 try:
121 execfile(config_file, global_dict, local_dict)
122 except:
123 self.add_summary("%s is invalid python." % config_file,
124 level="error")
125 self.error(pprint.pformat(sys.exc_info()[1]))
126 else:
127 if 'config' in local_dict and isinstance(local_dict['config'], dict):
128 self.info("Good.")
129 filecount[1] += 1
130 else:
131 self.add_summary("%s is valid python, but doesn't create a config dictionary." %
132 config_file, level="error")
133 if filecount[0]:
134 self.add_summary("%d of %d python config files were good." %
135 (filecount[1], filecount[0]))
136 else:
137 self.add_summary("No python config files to test.")
139 # __main__ {{{1
140 if __name__ == '__main__':
141 config_test = ConfigTest()
142 config_test.run_and_exit()