Bug 1917491 - Part 3: Introduce call-like syntax for resource disposal in DisposableS...
[gecko.git] / testing / mozharness / scripts / configtest.py
blob269ddb201133dd3538cbb54f52316c18adcc0cd3
1 #!/usr/bin/env python
2 # This Source Code Form is subject to the terms of the Mozilla Public
3 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 # You can obtain one at http://mozilla.org/MPL/2.0/.
5 """configtest.py
7 Verify the .json and .py files in the configs/ directory are well-formed.
8 Further tests to verify validity would be desirable.
10 This is also a good example script to look at to understand mozharness.
11 """
13 import os
14 import pprint
15 import sys
17 try:
18 import simplejson as json
19 except ImportError:
20 import json
22 sys.path.insert(1, os.path.dirname(sys.path[0]))
24 from mozharness.base.script import BaseScript
27 # ConfigTest {{{1
28 class ConfigTest(BaseScript):
29 config_options = [
32 "--test-file",
35 "action": "extend",
36 "dest": "test_files",
37 "help": "Specify which config files to test",
42 def __init__(self, require_config_file=False):
43 self.config_files = []
44 BaseScript.__init__(
45 self,
46 config_options=self.config_options,
47 all_actions=[
48 "list-config-files",
49 "test-json-configs",
50 "test-python-configs",
51 "summary",
53 default_actions=[
54 "test-json-configs",
55 "test-python-configs",
56 "summary",
58 require_config_file=require_config_file,
61 def query_config_files(self):
62 """This query method, much like others, caches its runtime
63 settings in self.VAR so we don't have to figure out config_files
64 multiple times.
65 """
66 if self.config_files:
67 return self.config_files
68 c = self.config
69 if "test_files" in c:
70 self.config_files = c["test_files"]
71 return self.config_files
72 self.debug(
73 "No --test-file(s) specified; defaulting to crawling the configs/ directory."
75 config_files = []
76 for root, dirs, files in os.walk(os.path.join(sys.path[0], "..", "configs")):
77 for name in files:
78 # Hardcode =P
79 if name.endswith(".json") or name.endswith(".py"):
80 if not name.startswith("test_malformed"):
81 config_files.append(os.path.join(root, name))
82 self.config_files = config_files
83 return self.config_files
85 def list_config_files(self):
86 """Non-default action that is mainly here to demonstrate how
87 non-default actions work in a mozharness script.
88 """
89 config_files = self.query_config_files()
90 for config_file in config_files:
91 self.info(config_file)
93 def test_json_configs(self):
94 """Currently only "is this well-formed json?" """
95 config_files = self.query_config_files()
96 filecount = [0, 0]
97 for config_file in config_files:
98 if config_file.endswith(".json"):
99 filecount[0] += 1
100 self.info("Testing %s." % config_file)
101 contents = self.read_from_file(config_file, verbose=False)
102 try:
103 json.loads(contents)
104 except ValueError:
105 self.add_summary("%s is invalid json." % config_file, level="error")
106 self.error(pprint.pformat(sys.exc_info()[1]))
107 else:
108 self.info("Good.")
109 filecount[1] += 1
110 if filecount[0]:
111 self.add_summary(
112 "%d of %d json config files were good." % (filecount[1], filecount[0])
114 else:
115 self.add_summary("No json config files to test.")
117 def test_python_configs(self):
118 """Currently only "will this give me a config dictionary?" """
119 config_files = self.query_config_files()
120 filecount = [0, 0]
121 for config_file in config_files:
122 if config_file.endswith(".py"):
123 filecount[0] += 1
124 self.info("Testing %s." % config_file)
125 global_dict = {}
126 local_dict = {}
127 try:
128 with open(config_file, "r") as f:
129 exec(f.read(), global_dict, local_dict)
130 except Exception:
131 self.add_summary(
132 "%s is invalid python." % config_file, level="error"
134 self.error(pprint.pformat(sys.exc_info()[1]))
135 else:
136 if "config" in local_dict and isinstance(
137 local_dict["config"], dict
139 self.info("Good.")
140 filecount[1] += 1
141 else:
142 self.add_summary(
143 "%s is valid python, "
144 "but doesn't create a config dictionary." % config_file,
145 level="error",
147 if filecount[0]:
148 self.add_summary(
149 "%d of %d python config files were good." % (filecount[1], filecount[0])
151 else:
152 self.add_summary("No python config files to test.")
155 # __main__ {{{1
156 if __name__ == "__main__":
157 config_test = ConfigTest()
158 config_test.run_and_exit()