test_base_config.py (11981B)
1 import os 2 import unittest 3 from copy import deepcopy 4 5 import mozunit 6 7 JSON_TYPE = None 8 try: 9 import simplejson as json 10 11 assert json 12 except ImportError: 13 import json 14 15 JSON_TYPE = "json" 16 else: 17 JSON_TYPE = "simplejson" 18 19 from mozharness.base import config 20 21 MH_DIR = os.path.dirname(os.path.dirname(__file__)) 22 23 24 class TestParseConfigFile(unittest.TestCase): 25 def _get_json_config( 26 self, 27 filename=os.path.join(MH_DIR, "configs", "test", "test.json"), 28 output="dict", 29 ): 30 fh = open(filename) 31 contents = json.load(fh) 32 fh.close() 33 if output == "dict": 34 return dict(contents) 35 else: 36 return contents 37 38 def _get_python_config( 39 self, filename=os.path.join(MH_DIR, "configs", "test", "test.py"), output="dict" 40 ): 41 global_dict = {} 42 local_dict = {} 43 # exec(open(filename).read(), global_dict, local_dict) 44 exec( 45 compile(open(filename, "rb").read(), filename, "exec"), 46 global_dict, 47 local_dict, 48 ) 49 return local_dict["config"] 50 51 def test_json_config(self): 52 c = config.BaseConfig(initial_config_file="test/test.json") 53 content_dict = self._get_json_config() 54 for key in content_dict.keys(): 55 self.assertEqual(content_dict[key], c._config[key]) 56 57 def test_python_config(self): 58 c = config.BaseConfig(initial_config_file="test/test.py") 59 config_dict = self._get_python_config() 60 for key in config_dict.keys(): 61 self.assertEqual(config_dict[key], c._config[key]) 62 63 def test_illegal_config(self): 64 self.assertRaises( 65 IOError, 66 config.parse_config_file, 67 "this_file_does_not_exist.py", 68 search_path="yadda", 69 ) 70 71 def test_illegal_suffix(self): 72 self.assertRaises( 73 RuntimeError, config.parse_config_file, "test/test.illegal_suffix" 74 ) 75 76 def test_malformed_json(self): 77 if JSON_TYPE == "simplejson": 78 self.assertRaises( 79 json.decoder.JSONDecodeError, 80 config.parse_config_file, 81 "test/test_malformed.json", 82 ) 83 else: 84 self.assertRaises( 85 ValueError, config.parse_config_file, "test/test_malformed.json" 86 ) 87 88 def test_malformed_python(self): 89 self.assertRaises( 90 SyntaxError, config.parse_config_file, "test/test_malformed.py" 91 ) 92 93 def test_multiple_config_files_override_string(self): 94 c = config.BaseConfig(initial_config_file="test/test.py") 95 c.parse_args(["--cfg", "test/test_override.py,test/test_override2.py"]) 96 self.assertEqual(c._config["override_string"], "yay") 97 98 def test_multiple_config_files_override_list(self): 99 c = config.BaseConfig(initial_config_file="test/test.py") 100 c.parse_args(["--cfg", "test/test_override.py,test/test_override2.py"]) 101 self.assertEqual(c._config["override_list"], ["yay", "worked"]) 102 103 def test_multiple_config_files_override_dict(self): 104 c = config.BaseConfig(initial_config_file="test/test.py") 105 c.parse_args(["--cfg", "test/test_override.py,test/test_override2.py"]) 106 self.assertEqual(c._config["override_dict"], {"yay": "worked"}) 107 108 def test_multiple_config_files_keep_string(self): 109 c = config.BaseConfig(initial_config_file="test/test.py") 110 c.parse_args(["--cfg", "test/test_override.py,test/test_override2.py"]) 111 self.assertEqual(c._config["keep_string"], "don't change me") 112 113 def test_optional_config_files_override_value(self): 114 c = config.BaseConfig(initial_config_file="test/test.py") 115 c.parse_args([ 116 "--cfg", 117 "test/test_override.py,test/test_override2.py", 118 "--opt-cfg", 119 "test/test_optional.py", 120 ]) 121 self.assertEqual(c._config["opt_override"], "new stuff") 122 123 def test_optional_config_files_missing_config(self): 124 c = config.BaseConfig(initial_config_file="test/test.py") 125 c.parse_args([ 126 "--cfg", 127 "test/test_override.py,test/test_override2.py", 128 "--opt-cfg", 129 "test/test_optional.py,does_not_exist.py", 130 ]) 131 self.assertEqual(c._config["opt_override"], "new stuff") 132 133 def test_optional_config_files_keep_string(self): 134 c = config.BaseConfig(initial_config_file="test/test.py") 135 c.parse_args([ 136 "--cfg", 137 "test/test_override.py,test/test_override2.py", 138 "--opt-cfg", 139 "test/test_optional.py", 140 ]) 141 self.assertEqual(c._config["keep_string"], "don't change me") 142 143 144 class TestReadOnlyDict(unittest.TestCase): 145 control_dict = { 146 "b": "2", 147 "c": {"d": "4"}, 148 "h": ["f", "g"], 149 "e": ["f", "g", {"turtles": ["turtle1"]}], 150 "d": {"turtles": ["turtle1"]}, 151 } 152 153 def get_unlocked_ROD(self): 154 r = config.ReadOnlyDict(self.control_dict) 155 return r 156 157 def get_locked_ROD(self): 158 r = config.ReadOnlyDict(self.control_dict) 159 r.lock() 160 return r 161 162 def test_create_ROD(self): 163 r = self.get_unlocked_ROD() 164 self.assertEqual( 165 r, self.control_dict, msg="can't transfer dict to ReadOnlyDict" 166 ) 167 168 def test_pop_item(self): 169 r = self.get_unlocked_ROD() 170 r.popitem() 171 self.assertEqual( 172 len(r), 173 len(self.control_dict) - 1, 174 msg="can't popitem() ReadOnlyDict when unlocked", 175 ) 176 177 def test_pop(self): 178 r = self.get_unlocked_ROD() 179 r.pop("e") 180 self.assertEqual( 181 len(r), 182 len(self.control_dict) - 1, 183 msg="can't pop() ReadOnlyDict when unlocked", 184 ) 185 186 def test_set(self): 187 r = self.get_unlocked_ROD() 188 r["e"] = "yarrr" 189 self.assertEqual( 190 r["e"], "yarrr", msg="can't set var in ReadOnlyDict when unlocked" 191 ) 192 193 def test_del(self): 194 r = self.get_unlocked_ROD() 195 del r["e"] 196 self.assertEqual( 197 len(r), 198 len(self.control_dict) - 1, 199 msg="can't del in ReadOnlyDict when unlocked", 200 ) 201 202 def test_clear(self): 203 r = self.get_unlocked_ROD() 204 r.clear() 205 self.assertEqual(r, {}, msg="can't clear() ReadOnlyDict when unlocked") 206 207 def test_set_default(self): 208 r = self.get_unlocked_ROD() 209 for key in self.control_dict.keys(): 210 r.setdefault(key, self.control_dict[key]) 211 self.assertEqual( 212 r, self.control_dict, msg="can't setdefault() ReadOnlyDict when unlocked" 213 ) 214 215 def test_locked_set(self): 216 r = self.get_locked_ROD() 217 # TODO use |with self.assertRaises(AssertionError):| if/when we're 218 # all on 2.7. 219 try: 220 r["e"] = 2 221 except AssertionError: 222 pass 223 else: 224 self.assertEqual(0, 1, msg="can set r['e'] when locked") 225 226 def test_locked_del(self): 227 r = self.get_locked_ROD() 228 try: 229 del r["e"] 230 except AssertionError: 231 pass 232 else: 233 self.assertEqual(0, 1, "can del r['e'] when locked") 234 235 def test_locked_popitem(self): 236 r = self.get_locked_ROD() 237 self.assertRaises(AssertionError, r.popitem) 238 239 def test_locked_update(self): 240 r = self.get_locked_ROD() 241 self.assertRaises(AssertionError, r.update, {}) 242 243 def test_locked_set_default(self): 244 r = self.get_locked_ROD() 245 self.assertRaises(AssertionError, r.setdefault, {}) 246 247 def test_locked_pop(self): 248 r = self.get_locked_ROD() 249 self.assertRaises(AssertionError, r.pop) 250 251 def test_locked_clear(self): 252 r = self.get_locked_ROD() 253 self.assertRaises(AssertionError, r.clear) 254 255 def test_locked_second_level_dict_pop(self): 256 r = self.get_locked_ROD() 257 self.assertRaises(AssertionError, r["c"].update, {}) 258 259 def test_locked_second_level_list_pop(self): 260 r = self.get_locked_ROD() 261 with self.assertRaises(AttributeError): 262 r["e"].pop() 263 264 def test_locked_third_level_mutate(self): 265 r = self.get_locked_ROD() 266 with self.assertRaises(AttributeError): 267 r["d"]["turtles"].append("turtle2") 268 269 def test_locked_object_in_tuple_mutate(self): 270 r = self.get_locked_ROD() 271 with self.assertRaises(AttributeError): 272 r["e"][2]["turtles"].append("turtle2") 273 274 def test_locked_second_level_dict_pop2(self): 275 r = self.get_locked_ROD() 276 self.assertRaises(AssertionError, r["c"].update, {}) 277 278 def test_locked_second_level_list_pop2(self): 279 r = self.get_locked_ROD() 280 with self.assertRaises(AttributeError): 281 r["e"].pop() 282 283 def test_locked_third_level_mutate2(self): 284 r = self.get_locked_ROD() 285 with self.assertRaises(AttributeError): 286 r["d"]["turtles"].append("turtle2") 287 288 def test_locked_object_in_tuple_mutate2(self): 289 r = self.get_locked_ROD() 290 with self.assertRaises(AttributeError): 291 r["e"][2]["turtles"].append("turtle2") 292 293 def test_locked_deepcopy_set(self): 294 r = self.get_locked_ROD() 295 c = deepcopy(r) 296 c["e"] = "hey" 297 self.assertEqual(c["e"], "hey", "can't set var in ROD after deepcopy") 298 299 300 class TestActions(unittest.TestCase): 301 all_actions = ["a", "b", "c", "d", "e"] 302 default_actions = ["b", "c", "d"] 303 304 def test_verify_actions(self): 305 c = config.BaseConfig(initial_config_file="test/test.json") 306 try: 307 c.verify_actions(["not_a_real_action"]) 308 except SystemExit: 309 pass 310 else: 311 self.assertEqual(0, 1, msg="verify_actions() didn't die on invalid action") 312 c = config.BaseConfig(initial_config_file="test/test.json") 313 returned_actions = c.verify_actions(c.all_actions) 314 self.assertEqual( 315 c.all_actions, 316 returned_actions, 317 msg="returned actions from verify_actions() changed", 318 ) 319 320 def test_default_actions(self): 321 c = config.BaseConfig( 322 default_actions=self.default_actions, 323 all_actions=self.all_actions, 324 initial_config_file="test/test.json", 325 ) 326 self.assertEqual( 327 self.default_actions, c.get_actions(), msg="default_actions broken" 328 ) 329 330 def test_no_action1(self): 331 c = config.BaseConfig( 332 default_actions=self.default_actions, 333 all_actions=self.all_actions, 334 initial_config_file="test/test.json", 335 ) 336 c.parse_args(args=["foo", "--no-action", "a"]) 337 self.assertEqual( 338 self.default_actions, c.get_actions(), msg="--no-ACTION broken" 339 ) 340 341 def test_no_action2(self): 342 c = config.BaseConfig( 343 default_actions=self.default_actions, 344 all_actions=self.all_actions, 345 initial_config_file="test/test.json", 346 ) 347 c.parse_args(args=["foo", "--no-c"]) 348 self.assertEqual(["b", "d"], c.get_actions(), msg="--no-ACTION broken") 349 350 def test_add_action(self): 351 c = config.BaseConfig( 352 default_actions=self.default_actions, 353 all_actions=self.all_actions, 354 initial_config_file="test/test.json", 355 ) 356 c.parse_args(args=["foo", "--add-action", "e"]) 357 self.assertEqual( 358 ["b", "c", "d", "e"], c.get_actions(), msg="--add-action ACTION broken" 359 ) 360 361 def test_only_action(self): 362 c = config.BaseConfig( 363 default_actions=self.default_actions, 364 all_actions=self.all_actions, 365 initial_config_file="test/test.json", 366 ) 367 c.parse_args(args=["foo", "--a", "--e"]) 368 self.assertEqual(["a", "e"], c.get_actions(), msg="--ACTION broken") 369 370 371 if __name__ == "__main__": 372 mozunit.main()