Bug 1856942: part 5) Factor async loading of a sheet out of `Loader::LoadSheet`....
[gecko.git] / testing / mozharness / scripts / configtest.py
blobf846cba0d4dfe9eb1dc74c910917d7b4dd2b5ca9
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
19 try:
20 import simplejson as json
21 except ImportError:
22 import json
24 sys.path.insert(1, os.path.dirname(sys.path[0]))
26 from mozharness.base.script import BaseScript
29 # ConfigTest {{{1
30 class ConfigTest(BaseScript):
31 config_options = [
34 "--test-file",
37 "action": "extend",
38 "dest": "test_files",
39 "help": "Specify which config files to test",
44 def __init__(self, require_config_file=False):
45 self.config_files = []
46 BaseScript.__init__(
47 self,
48 config_options=self.config_options,
49 all_actions=[
50 "list-config-files",
51 "test-json-configs",
52 "test-python-configs",
53 "summary",
55 default_actions=[
56 "test-json-configs",
57 "test-python-configs",
58 "summary",
60 require_config_file=require_config_file,
63 def query_config_files(self):
64 """This query method, much like others, caches its runtime
65 settings in self.VAR so we don't have to figure out config_files
66 multiple times.
67 """
68 if self.config_files:
69 return self.config_files
70 c = self.config
71 if "test_files" in c:
72 self.config_files = c["test_files"]
73 return self.config_files
74 self.debug(
75 "No --test-file(s) specified; defaulting to crawling the configs/ directory."
77 config_files = []
78 for root, dirs, files in os.walk(os.path.join(sys.path[0], "..", "configs")):
79 for name in files:
80 # Hardcode =P
81 if name.endswith(".json") or name.endswith(".py"):
82 if not name.startswith("test_malformed"):
83 config_files.append(os.path.join(root, name))
84 self.config_files = config_files
85 return self.config_files
87 def list_config_files(self):
88 """Non-default action that is mainly here to demonstrate how
89 non-default actions work in a mozharness script.
90 """
91 config_files = self.query_config_files()
92 for config_file in config_files:
93 self.info(config_file)
95 def test_json_configs(self):
96 """Currently only "is this well-formed json?" """
97 config_files = self.query_config_files()
98 filecount = [0, 0]
99 for config_file in config_files:
100 if config_file.endswith(".json"):
101 filecount[0] += 1
102 self.info("Testing %s." % config_file)
103 contents = self.read_from_file(config_file, verbose=False)
104 try:
105 json.loads(contents)
106 except ValueError:
107 self.add_summary("%s is invalid json." % config_file, level="error")
108 self.error(pprint.pformat(sys.exc_info()[1]))
109 else:
110 self.info("Good.")
111 filecount[1] += 1
112 if filecount[0]:
113 self.add_summary(
114 "%d of %d json config files were good." % (filecount[1], filecount[0])
116 else:
117 self.add_summary("No json config files to test.")
119 def test_python_configs(self):
120 """Currently only "will this give me a config dictionary?" """
121 config_files = self.query_config_files()
122 filecount = [0, 0]
123 for config_file in config_files:
124 if config_file.endswith(".py"):
125 filecount[0] += 1
126 self.info("Testing %s." % config_file)
127 global_dict = {}
128 local_dict = {}
129 try:
130 with open(config_file, "r") as f:
131 exec(f.read(), global_dict, local_dict)
132 except Exception:
133 self.add_summary(
134 "%s is invalid python." % config_file, level="error"
136 self.error(pprint.pformat(sys.exc_info()[1]))
137 else:
138 if "config" in local_dict and isinstance(
139 local_dict["config"], dict
141 self.info("Good.")
142 filecount[1] += 1
143 else:
144 self.add_summary(
145 "%s is valid python, "
146 "but doesn't create a config dictionary." % config_file,
147 level="error",
149 if filecount[0]:
150 self.add_summary(
151 "%d of %d python config files were good." % (filecount[1], filecount[0])
153 else:
154 self.add_summary("No python config files to test.")
157 # __main__ {{{1
158 if __name__ == "__main__":
159 config_test = ConfigTest()
160 config_test.run_and_exit()