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