config_data_test.py 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. # Copyright (C) 2010 Internet Systems Consortium.
  2. #
  3. # Permission to use, copy, modify, and distribute this software for any
  4. # purpose with or without fee is hereby granted, provided that the above
  5. # copyright notice and this permission notice appear in all copies.
  6. #
  7. # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
  8. # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
  9. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  10. # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
  12. # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  13. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  14. # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. #
  16. # Tests for the ConfigData and MultiConfigData classes
  17. #
  18. import unittest
  19. import os
  20. from isc.config.config_data import *
  21. from isc.config.module_spec import *
  22. class TestConfigData(unittest.TestCase):
  23. def setUp(self):
  24. if 'CONFIG_TESTDATA_PATH' in os.environ:
  25. self.data_path = os.environ['CONFIG_TESTDATA_PATH']
  26. else:
  27. self.data_path = "../../../testdata"
  28. spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  29. self.cd = ConfigData(spec)
  30. #def test_module_spec_from_file(self):
  31. # spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec1.spec")
  32. # cd = ConfigData(spec)
  33. # self.assertEqual(cd.specification, spec)
  34. # self.assertEqual(cd.data, {})
  35. # self.assertRaises(ConfigDataError, ConfigData, 1)
  36. def test_check_type(self):
  37. config_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec22.spec").get_config_spec()
  38. spec_part = find_spec_part(config_spec, "value1")
  39. check_type(spec_part, 1)
  40. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
  41. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, True)
  42. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, "a")
  43. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
  44. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
  45. spec_part = find_spec_part(config_spec, "value2")
  46. check_type(spec_part, 1.1)
  47. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
  48. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, True)
  49. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, "a")
  50. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
  51. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
  52. spec_part = find_spec_part(config_spec, "value3")
  53. check_type(spec_part, True)
  54. check_type(spec_part, False)
  55. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
  56. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
  57. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, "a")
  58. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
  59. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
  60. spec_part = find_spec_part(config_spec, "value4")
  61. check_type(spec_part, "asdf")
  62. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
  63. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
  64. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, True)
  65. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
  66. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
  67. spec_part = find_spec_part(config_spec, "value5")
  68. check_type(spec_part, [1, 2])
  69. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
  70. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
  71. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, True)
  72. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, "a")
  73. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ "a", "b" ])
  74. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
  75. spec_part = find_spec_part(config_spec, "value6")
  76. check_type(spec_part, { "value1": "aaa", "value2": 2 })
  77. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
  78. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
  79. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, True)
  80. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, "a")
  81. self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
  82. #self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "value1": 1 })
  83. self.assertRaises(isc.cc.data.DataTypeError, check_type, config_spec, 1)
  84. def test_convert_type(self):
  85. config_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec22.spec").get_config_spec()
  86. spec_part = find_spec_part(config_spec, "value1")
  87. self.assertEqual(1, convert_type(spec_part, '1'))
  88. self.assertEqual(2, convert_type(spec_part, 2.1))
  89. self.assertEqual(2, convert_type(spec_part, '2'))
  90. self.assertEqual(3, convert_type(spec_part, '3'))
  91. self.assertEqual(1, convert_type(spec_part, True))
  92. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "a")
  93. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ 1, 2 ])
  94. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, { "a": 1 })
  95. self.assertRaises(isc.cc.data.DataTypeError, convert_type, 1, "a")
  96. self.assertRaises(isc.cc.data.DataTypeError, convert_type, { 'somedict': 'somevalue' }, "a")
  97. spec_part = find_spec_part(config_spec, "value2")
  98. self.assertEqual(1.1, convert_type(spec_part, '1.1'))
  99. self.assertEqual(123.0, convert_type(spec_part, '123'))
  100. self.assertEqual(1.0, convert_type(spec_part, True))
  101. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "a")
  102. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ 1, 2 ])
  103. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, { "a": 1 })
  104. spec_part = find_spec_part(config_spec, "value3")
  105. self.assertEqual(True, convert_type(spec_part, 'True'))
  106. self.assertEqual(False, convert_type(spec_part, 'False'))
  107. self.assertEqual(True, convert_type(spec_part, 1))
  108. self.assertEqual(True, convert_type(spec_part, 1.1))
  109. self.assertEqual(True, convert_type(spec_part, 'a'))
  110. self.assertEqual(True, convert_type(spec_part, [1, 2]))
  111. self.assertEqual(True, convert_type(spec_part, {'a' : 1}))
  112. spec_part = find_spec_part(config_spec, "value4")
  113. self.assertEqual('asdf', convert_type(spec_part, "asdf"))
  114. self.assertEqual('1', convert_type(spec_part, 1))
  115. self.assertEqual('1.1', convert_type(spec_part, 1.1))
  116. self.assertEqual('True', convert_type(spec_part, True))
  117. spec_part = find_spec_part(config_spec, "value5")
  118. self.assertEqual([1, 2], convert_type(spec_part, '1, 2'))
  119. self.assertEqual([1, 2, 3], convert_type(spec_part, '1 2 3'))
  120. self.assertEqual([1, 2, 3,4], convert_type(spec_part, '1 2 3, 4'))
  121. self.assertEqual([1], convert_type(spec_part, [1,]))
  122. self.assertEqual([1,2], convert_type(spec_part, [1,2]))
  123. self.assertEqual([1,2], convert_type(spec_part, ['1', '2']))
  124. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, 1.1)
  125. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, True)
  126. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "a")
  127. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ "a", "b" ])
  128. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ "1", "b" ])
  129. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, { "a": 1 })
  130. spec_part = find_spec_part(config_spec, "value6")
  131. self.assertEqual({}, convert_type(spec_part, '{}'))
  132. self.assertEqual({ 'v61': 'a' }, convert_type(spec_part, '{ \'v61\': \'a\' }'))
  133. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, 1.1)
  134. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, True)
  135. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "a")
  136. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "1")
  137. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ "a", "b" ])
  138. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, [ "1", "b" ])
  139. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, { "a": 1 })
  140. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, "\"{ \"a\": 1 }\"")
  141. spec_part = find_spec_part(config_spec, "value7")
  142. self.assertEqual(['1', '2'], convert_type(spec_part, '1, 2'))
  143. self.assertEqual(['1', '2', '3'], convert_type(spec_part, '1 2 3'))
  144. self.assertEqual(['1', '2', '3','4'], convert_type(spec_part, '1 2 3, 4'))
  145. self.assertEqual([1], convert_type(spec_part, [1,]))
  146. self.assertEqual([1,2], convert_type(spec_part, [1,2]))
  147. self.assertEqual(['1','2'], convert_type(spec_part, ['1', '2']))
  148. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, 1.1)
  149. self.assertRaises(isc.cc.data.DataTypeError, convert_type, spec_part, True)
  150. self.assertEqual(['a'], convert_type(spec_part, "a"))
  151. self.assertEqual(['a', 'b'], convert_type(spec_part, ["a", "b" ]))
  152. self.assertEqual([1, 'b'], convert_type(spec_part, [1, "b" ]))
  153. def test_find_spec_part(self):
  154. config_spec = self.cd.get_module_spec().get_config_spec()
  155. spec_part = find_spec_part(config_spec, "item1")
  156. self.assertEqual({'item_name': 'item1', 'item_type': 'integer', 'item_optional': False, 'item_default': 1, }, spec_part)
  157. spec_part = find_spec_part(config_spec, "/item1")
  158. self.assertEqual({'item_name': 'item1', 'item_type': 'integer', 'item_optional': False, 'item_default': 1, }, spec_part)
  159. self.assertRaises(isc.cc.data.DataNotFoundError, find_spec_part, config_spec, "no_such_item")
  160. self.assertRaises(isc.cc.data.DataNotFoundError, find_spec_part, config_spec, "no_such_item/multilevel")
  161. self.assertRaises(isc.cc.data.DataNotFoundError, find_spec_part, config_spec, "item6/multilevel")
  162. self.assertRaises(isc.cc.data.DataNotFoundError, find_spec_part, 1, "item6/multilevel")
  163. spec_part = find_spec_part(config_spec, "item6/value1")
  164. self.assertEqual({'item_name': 'value1', 'item_type': 'string', 'item_optional': True, 'item_default': 'default'}, spec_part)
  165. def test_find_spec_part_lists(self):
  166. # A few specific tests for list data
  167. module_spec = isc.config.module_spec_from_file(self.data_path +
  168. os.sep +
  169. "spec31.spec")
  170. config_spec = module_spec.get_config_spec()
  171. expected_spec_part = {'item_name': 'number',
  172. 'item_type': 'integer',
  173. 'item_default': 1,
  174. 'item_optional': False}
  175. # First a check for a correct fetch
  176. spec_part = find_spec_part(config_spec,
  177. "/first_list_items[0]/second_list_items[1]/"
  178. "map_element/list1[1]/list2[1]")
  179. self.assertEqual(expected_spec_part, spec_part)
  180. # Leaving out an index should fail by default
  181. self.assertRaises(isc.cc.data.DataNotFoundError,
  182. find_spec_part, config_spec,
  183. "/first_list_items[0]/second_list_items/"
  184. "map_element/list1[1]/list2[1]")
  185. # But not for the last element
  186. spec_part = find_spec_part(config_spec,
  187. "/first_list_items[0]/second_list_items[1]/"
  188. "map_element/list1[1]/list2")
  189. self.assertEqual(expected_spec_part, spec_part)
  190. # And also not if strict_identifier is false (third argument)
  191. spec_part = find_spec_part(config_spec,
  192. "/first_list_items[0]/second_list_items/"
  193. "map_element/list1[1]/list2[1]", False)
  194. self.assertEqual(expected_spec_part, spec_part)
  195. def test_spec_name_list(self):
  196. name_list = spec_name_list(self.cd.get_module_spec().get_config_spec())
  197. self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5', 'item6'], name_list)
  198. name_list = spec_name_list(self.cd.get_module_spec().get_config_spec(), "", True)
  199. self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5', 'item6/value1', 'item6/value2'], name_list)
  200. spec_part = find_spec_part(self.cd.get_module_spec().get_config_spec(), "item6")
  201. name_list = spec_name_list(spec_part, "item6", True)
  202. self.assertEqual(['item6/value1', 'item6/value2'], name_list)
  203. spec_part = find_spec_part(self.cd.get_module_spec().get_config_spec(), "item6")
  204. name_list = spec_name_list(spec_part, "item6", True)
  205. self.assertEqual(['item6/value1', 'item6/value2'], name_list)
  206. config_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec22.spec").get_config_spec()
  207. spec_part = find_spec_part(config_spec, "value9")
  208. name_list = spec_name_list(spec_part, "value9", True)
  209. self.assertEqual(['value9/v91', 'value9/v92/v92a', 'value9/v92/v92b'], name_list)
  210. name_list = spec_name_list({ "myModule": config_spec }, "", False)
  211. self.assertEqual(['myModule/'], name_list)
  212. name_list = spec_name_list({ "myModule": config_spec }, "", True)
  213. self.assertEqual(['myModule/', 'myModule/value1', 'myModule/value2', 'myModule/value3', 'myModule/value4', 'myModule/value5', 'myModule/value6/v61', 'myModule/value6/v62', 'myModule/value7', 'myModule/value8', 'myModule/value9/v91', 'myModule/value9/v92/v92a', 'myModule/value9/v92/v92b'], name_list)
  214. self.assertRaises(ConfigDataError, spec_name_list, 1)
  215. self.assertRaises(ConfigDataError, spec_name_list, [ 'a' ])
  216. def test_init(self):
  217. self.assertRaises(ConfigDataError, ConfigData, "asdf")
  218. def test_get_value(self):
  219. value, default = self.cd.get_value("item1")
  220. self.assertEqual(1, value)
  221. self.assertEqual(True, default)
  222. value, default = self.cd.get_value("item2")
  223. self.assertEqual(1.1, value)
  224. self.assertEqual(True, default)
  225. value, default = self.cd.get_value("item3")
  226. self.assertEqual(True, value)
  227. self.assertEqual(True, default)
  228. value, default = self.cd.get_value("item4")
  229. self.assertEqual("test", value)
  230. self.assertEqual(True, default)
  231. value, default = self.cd.get_value("item5")
  232. self.assertEqual(["a", "b"], value)
  233. self.assertEqual(True, default)
  234. value, default = self.cd.get_value("item6")
  235. self.assertEqual({}, value)
  236. self.assertEqual(True, default)
  237. self.assertRaises(isc.cc.data.DataNotFoundError, self.cd.get_value, "no_such_item")
  238. value, default = self.cd.get_value("item6/value2")
  239. self.assertEqual(None, value)
  240. self.assertEqual(False, default)
  241. self.assertRaises(isc.cc.data.DataNotFoundError, self.cd.get_value, "item6/no_such_item")
  242. def test_get_default_value(self):
  243. self.assertEqual(1, self.cd.get_default_value("item1"))
  244. self.assertEqual('default', self.cd.get_default_value("item6/value1"))
  245. self.assertEqual(None, self.cd.get_default_value("item6/value2"))
  246. # set some local values to something else, and see if we
  247. # still get the default
  248. self.cd.set_local_config({"item1": 2, "item6": { "value1": "asdf" } })
  249. self.assertEqual((2, False), self.cd.get_value("item1"))
  250. self.assertEqual(1, self.cd.get_default_value("item1"))
  251. self.assertEqual(('asdf', False), self.cd.get_value("item6/value1"))
  252. self.assertEqual('default', self.cd.get_default_value("item6/value1"))
  253. self.assertRaises(isc.cc.data.DataNotFoundError,
  254. self.cd.get_default_value,
  255. "does_not_exist/value1")
  256. self.assertRaises(isc.cc.data.DataNotFoundError,
  257. self.cd.get_default_value,
  258. "item6/doesnotexist")
  259. def test_set_local_config(self):
  260. self.cd.set_local_config({"item1": 2})
  261. value, default = self.cd.get_value("item1")
  262. self.assertEqual(2, value)
  263. self.assertEqual(False, default)
  264. def test_get_local_config(self):
  265. local_config = self.cd.get_local_config()
  266. self.assertEqual({}, local_config)
  267. my_config = { "item1": 2, "item2": 2.2, "item3": False, "item4": "asdf", "item5": [ "c", "d" ] }
  268. self.cd.set_local_config(my_config)
  269. self.assertEqual(my_config, self.cd.get_local_config())
  270. def test_get_item_list(self):
  271. name_list = self.cd.get_item_list()
  272. self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5', 'item6'], name_list)
  273. name_list = self.cd.get_item_list("", True)
  274. self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5', 'item6/value1', 'item6/value2'], name_list)
  275. name_list = self.cd.get_item_list("item6", False)
  276. self.assertEqual(['item6/value1', 'item6/value2'], name_list)
  277. def test_get_full_config(self):
  278. full_config = self.cd.get_full_config()
  279. self.assertEqual({ "item1": 1, "item2": 1.1, "item3": True, "item4": "test", "item5": ['a', 'b'], "item6/value1": 'default', 'item6/value2': None}, full_config)
  280. my_config = { "item1": 2, "item2": 2.2, "item3": False, "item4": "asdf", "item5": [ "c", "d" ] }
  281. self.cd.set_local_config(my_config)
  282. full_config = self.cd.get_full_config()
  283. self.assertEqual({ "item1": 2, "item2": 2.2, "item3": False, "item4": "asdf", "item5": [ "c", "d" ], "item6/value1": 'default', 'item6/value2': None}, full_config)
  284. class TestMultiConfigData(unittest.TestCase):
  285. def setUp(self):
  286. if 'CONFIG_TESTDATA_PATH' in os.environ:
  287. self.data_path = os.environ['CONFIG_TESTDATA_PATH']
  288. else:
  289. self.data_path = "../../../testdata"
  290. self.mcd = MultiConfigData()
  291. def test_init(self):
  292. self.assertEqual({}, self.mcd._specifications)
  293. self.assertEqual({}, self.mcd._current_config)
  294. self.assertEqual({}, self.mcd._local_changes)
  295. def test_set_remove_specification(self):
  296. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec1.spec")
  297. self.assertFalse(self.mcd.have_specification(module_spec.get_module_name()))
  298. self.mcd.set_specification(module_spec)
  299. self.assertTrue(self.mcd.have_specification(module_spec.get_module_name()))
  300. self.assert_(module_spec.get_module_name() in self.mcd._specifications)
  301. self.assertEquals(module_spec, self.mcd._specifications[module_spec.get_module_name()])
  302. self.assertRaises(ConfigDataError, self.mcd.set_specification, "asdf")
  303. self.mcd.remove_specification(module_spec.get_module_name())
  304. self.assertFalse(self.mcd.have_specification(module_spec.get_module_name()))
  305. def test_clear_specifications(self):
  306. self.assertEqual(0, len(self.mcd._specifications))
  307. module_spec = isc.config.module_spec_from_file(self.data_path +
  308. os.sep +
  309. "spec1.spec")
  310. self.mcd.set_specification(module_spec)
  311. self.assertEqual(1, len(self.mcd._specifications))
  312. self.mcd.clear_specifications()
  313. self.assertEqual(0, len(self.mcd._specifications))
  314. def test_get_module_spec(self):
  315. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec1.spec")
  316. self.mcd.set_specification(module_spec)
  317. module_spec2 = self.mcd.get_module_spec(module_spec.get_module_name())
  318. self.assertEqual(module_spec, module_spec2)
  319. module_spec3 = self.mcd.get_module_spec("no_such_module")
  320. self.assertEqual(None, module_spec3)
  321. def test_find_spec_part(self):
  322. spec_part = self.mcd.find_spec_part("Spec2/item1")
  323. self.assertEqual(None, spec_part)
  324. spec_part = self.mcd.find_spec_part("/Spec2/item1")
  325. self.assertEqual(None, spec_part)
  326. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  327. self.mcd.set_specification(module_spec)
  328. spec_part = self.mcd.find_spec_part("Spec2/item1")
  329. self.assertEqual({'item_name': 'item1', 'item_type': 'integer', 'item_optional': False, 'item_default': 1, }, spec_part)
  330. def test_find_spec_part_nested(self):
  331. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec30.spec")
  332. self.mcd.set_specification(module_spec)
  333. spec_part = self.mcd.find_spec_part("/lists/first_list_items[0]/second_list_items[1]/final_element")
  334. self.assertEqual({'item_name': 'final_element', 'item_type': 'string', 'item_default': 'hello', 'item_optional': False}, spec_part)
  335. spec_part = self.mcd.find_spec_part("/BAD_NAME/first_list_items[0]/second_list_items[1]/final_element")
  336. self.assertEqual(None, spec_part)
  337. def test_find_spec_part_nested2(self):
  338. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec31.spec")
  339. self.mcd.set_specification(module_spec)
  340. spec_part = self.mcd.find_spec_part("/lists/first_list_items[0]/second_list_items[1]/map_element/list1[1]/list2[2]")
  341. self.assertEqual({"item_name": "number", "item_type": "integer", "item_optional": False, "item_default": 1}, spec_part)
  342. spec_part = self.mcd.find_spec_part("/DOESNOTEXIST")
  343. self.assertEqual(None, spec_part)
  344. spec_part = self.mcd.find_spec_part("/lists/DOESNOTEXIST")
  345. self.assertEqual(None, spec_part)
  346. spec_part = self.mcd.find_spec_part("/lists/first_list_items[0]/DOESNOTEXIST")
  347. self.assertEqual(None, spec_part)
  348. spec_part = self.mcd.find_spec_part("/lists/first_list_items[0]/second_list_items[1]/DOESNOTEXIST")
  349. self.assertEqual(None, spec_part)
  350. spec_part = self.mcd.find_spec_part("/lists/first_list_items[0]/second_list_items[1]/map_element/DOESNOTEXIST")
  351. self.assertEqual(None, spec_part)
  352. spec_part = self.mcd.find_spec_part("/lists/first_list_items[0]/second_list_items[1]/map_element/list1[1]/DOESNOTEXIST")
  353. self.assertEqual(None, spec_part)
  354. spec_part = self.mcd.find_spec_part("/lists/first_list_items[0]/second_list_items[1]/map_element/list1[1]/list2[1]/DOESNOTEXIST")
  355. self.assertEqual(None, spec_part)
  356. def test_get_current_config(self):
  357. cf = { 'module1': { 'item1': 2, 'item2': True } }
  358. self.mcd._set_current_config(cf)
  359. self.assertEqual(cf, self.mcd.get_current_config())
  360. def test_get_local_changes(self):
  361. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  362. self.mcd.set_specification(module_spec)
  363. local_changes = self.mcd.get_local_changes()
  364. self.assertEqual({}, local_changes)
  365. self.mcd.set_value("Spec2/item1", 2)
  366. local_changes = self.mcd.get_local_changes()
  367. self.assertEqual({"Spec2": { "item1": 2}}, local_changes)
  368. def test_clear_local_changes(self):
  369. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  370. self.mcd.set_specification(module_spec)
  371. self.mcd.set_value("Spec2/item1", 2)
  372. self.mcd.clear_local_changes()
  373. local_changes = self.mcd.get_local_changes()
  374. self.assertEqual({}, local_changes)
  375. pass
  376. def test_get_local_value(self):
  377. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  378. self.mcd.set_specification(module_spec)
  379. value = self.mcd.get_local_value("Spec2/item1")
  380. self.assertEqual(None, value)
  381. self.mcd.set_value("Spec2/item1", 2)
  382. value = self.mcd.get_local_value("Spec2/item1")
  383. self.assertEqual(2, value)
  384. def test_get_current_value(self):
  385. value = self.mcd.get_current_value("Spec2/item1")
  386. self.assertEqual(None, value)
  387. self.mcd._current_config = { "Spec2": { "item1": 3 } }
  388. value = self.mcd.get_current_value("Spec2/item1")
  389. self.assertEqual(3, value)
  390. pass
  391. def test_get_default_value(self):
  392. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  393. self.mcd.set_specification(module_spec)
  394. value = self.mcd.get_default_value("Spec2/item1")
  395. self.assertEqual(1, value)
  396. value = self.mcd.get_default_value("/Spec2/item1")
  397. self.assertEqual(1, value)
  398. value = self.mcd.get_default_value("Spec2/item5[0]")
  399. self.assertEqual('a', value)
  400. value = self.mcd.get_default_value("Spec2/item5[1]")
  401. self.assertEqual('b', value)
  402. value = self.mcd.get_default_value("Spec2/item5[5]")
  403. self.assertEqual(None, value)
  404. value = self.mcd.get_default_value("Spec2/item5[0][1]")
  405. self.assertEqual(None, value)
  406. value = self.mcd.get_default_value("Spec2/item6/value1")
  407. self.assertEqual('default', value)
  408. value = self.mcd.get_default_value("Spec2/item6/value2")
  409. self.assertEqual(None, value)
  410. value = self.mcd.get_default_value("Spec2/no_such_item/asdf")
  411. self.assertEqual(None, value)
  412. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec32.spec")
  413. self.mcd.set_specification(module_spec)
  414. value = self.mcd.get_default_value("Spec32/named_set_item")
  415. self.assertEqual({ 'a': 1, 'b': 2}, value)
  416. value = self.mcd.get_default_value("Spec32/named_set_item/a")
  417. self.assertEqual(1, value)
  418. value = self.mcd.get_default_value("Spec32/named_set_item/b")
  419. self.assertEqual(2, value)
  420. value = self.mcd.get_default_value("Spec32/named_set_item/no_such_item")
  421. self.assertEqual(None, value)
  422. def test_get_value(self):
  423. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  424. self.mcd.set_specification(module_spec)
  425. self.mcd.set_value("Spec2/item1", 2)
  426. value, status = self.mcd.get_value("Spec2/item1")
  427. self.assertEqual(2, value)
  428. self.assertEqual(MultiConfigData.LOCAL, status)
  429. value, status = self.mcd.get_value("Spec2/item2")
  430. self.assertEqual(1.1, value)
  431. self.assertEqual(MultiConfigData.DEFAULT, status)
  432. self.mcd._current_config = { "Spec2": { "item3": False } }
  433. value, status = self.mcd.get_value("Spec2/item3")
  434. self.assertEqual(False, value)
  435. self.assertEqual(MultiConfigData.CURRENT, status)
  436. value, status = self.mcd.get_value("Spec2/no_such_item")
  437. self.assertEqual(None, value)
  438. self.assertEqual(MultiConfigData.NONE, status)
  439. value, status = self.mcd.get_value("Spec2/item5")
  440. self.assertEqual(['a', 'b'], value)
  441. self.assertEqual(MultiConfigData.DEFAULT, status)
  442. value, status = self.mcd.get_value("Spec2/item5[0]")
  443. self.assertEqual("a", value)
  444. self.assertEqual(MultiConfigData.DEFAULT, status)
  445. value, status = self.mcd.get_value("Spec2/item5[0]", False)
  446. self.assertEqual(None, value)
  447. self.assertEqual(MultiConfigData.NONE, status)
  448. value, status = self.mcd.get_value("Spec2/item5[1]")
  449. self.assertEqual("b", value)
  450. self.assertEqual(MultiConfigData.DEFAULT, status)
  451. def test_get_value_maps(self):
  452. maps = self.mcd.get_value_maps()
  453. self.assertEqual([], maps)
  454. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec1.spec")
  455. self.mcd.set_specification(module_spec)
  456. expected = [{'default': False,
  457. 'type': 'module',
  458. 'name': 'Spec1',
  459. 'value': None,
  460. 'modified': False}]
  461. maps = self.mcd.get_value_maps()
  462. self.assertEqual(expected, maps)
  463. maps = self.mcd.get_value_maps("/")
  464. self.assertEqual(expected, maps)
  465. maps = self.mcd.get_value_maps('Spec2')
  466. self.assertEqual([], maps)
  467. maps = self.mcd.get_value_maps('Spec1')
  468. self.assertEqual([], maps)
  469. self.mcd.remove_specification("Spec1")
  470. self.mcd.remove_specification("foo")
  471. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  472. self.mcd.set_specification(module_spec)
  473. maps = self.mcd.get_value_maps()
  474. self.assertEqual([{'default': False, 'type': 'module', 'name': 'Spec2', 'value': None, 'modified': False}], maps)
  475. self.mcd._set_current_config({ "Spec2": { "item1": 2 } })
  476. self.mcd.set_value("Spec2/item3", False)
  477. maps = self.mcd.get_value_maps("/Spec2")
  478. self.assertEqual([{'default': False, 'type': 'integer', 'name': 'Spec2/item1', 'value': 2, 'modified': False},
  479. {'default': True, 'type': 'real', 'name': 'Spec2/item2', 'value': 1.1, 'modified': False},
  480. {'default': False, 'type': 'boolean', 'name': 'Spec2/item3', 'value': False, 'modified': True},
  481. {'default': True, 'type': 'string', 'name': 'Spec2/item4', 'value': 'test', 'modified': False},
  482. {'default': True, 'type': 'list', 'name': 'Spec2/item5', 'value': ['a', 'b'], 'modified': False},
  483. {'default': True, 'type': 'string', 'name': 'Spec2/item6/value1', 'value': 'default', 'modified': False},
  484. {'default': False, 'type': 'integer', 'name': 'Spec2/item6/value2', 'value': None, 'modified': False}], maps)
  485. maps = self.mcd.get_value_maps("Spec2")
  486. self.assertEqual([{'default': False, 'type': 'integer', 'name': 'Spec2/item1', 'value': 2, 'modified': False},
  487. {'default': True, 'type': 'real', 'name': 'Spec2/item2', 'value': 1.1, 'modified': False},
  488. {'default': False, 'type': 'boolean', 'name': 'Spec2/item3', 'value': False, 'modified': True},
  489. {'default': True, 'type': 'string', 'name': 'Spec2/item4', 'value': 'test', 'modified': False},
  490. {'default': True, 'type': 'list', 'name': 'Spec2/item5', 'value': ['a', 'b'], 'modified': False},
  491. {'default': True, 'type': 'string', 'name': 'Spec2/item6/value1', 'value': 'default', 'modified': False},
  492. {'default': False, 'type': 'integer', 'name': 'Spec2/item6/value2', 'value': None, 'modified': False}], maps)
  493. maps = self.mcd.get_value_maps("/Spec2/item5")
  494. self.assertEqual([{'default': True, 'type': 'string', 'name': 'Spec2/item5[0]', 'value': 'a', 'modified': False},
  495. {'default': True, 'type': 'string', 'name': 'Spec2/item5[1]', 'value': 'b', 'modified': False}], maps)
  496. maps = self.mcd.get_value_maps("/Spec2/item5[0]")
  497. self.assertEqual([{'default': True, 'modified': False, 'name': 'Spec2/item5[0]', 'type': 'string', 'value': 'a'}], maps)
  498. maps = self.mcd.get_value_maps("/Spec2/item1")
  499. self.assertEqual([{'default': False, 'type': 'integer', 'name': 'Spec2/item1', 'value': 2, 'modified': False}], maps)
  500. maps = self.mcd.get_value_maps("/Spec2/item2")
  501. self.assertEqual([{'default': True, 'type': 'real', 'name': 'Spec2/item2', 'value': 1.1, 'modified': False}], maps)
  502. maps = self.mcd.get_value_maps("/Spec2/item3")
  503. self.assertEqual([{'default': False, 'type': 'boolean', 'name': 'Spec2/item3', 'value': False, 'modified': True}], maps)
  504. maps = self.mcd.get_value_maps("/Spec2/item4")
  505. self.assertEqual([{'default': True, 'type': 'string', 'name': 'Spec2/item4', 'value': 'test', 'modified': False}], maps)
  506. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec24.spec")
  507. self.mcd.set_specification(module_spec)
  508. self.assertRaises(isc.cc.data.DataNotFoundError,
  509. self.mcd.get_value_maps, "/Spec24/item", 4)
  510. self.mcd._set_current_config({ "Spec24": { "item": [] } })
  511. maps = self.mcd.get_value_maps("/Spec24/item")
  512. self.assertEqual([{'default': False, 'modified': False, 'name': 'Spec24/item', 'type': 'list', 'value': []}], maps)
  513. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec22.spec")
  514. self.mcd.set_specification(module_spec)
  515. expected = [{'default': True,
  516. 'modified': False,
  517. 'name': 'Spec22/value9/v91',
  518. 'type': 'string',
  519. 'value': 'def'},
  520. {'default': True,
  521. 'modified': False,
  522. 'name': 'Spec22/value9/v92/v92a',
  523. 'type': 'string',
  524. 'value': 'Hello'
  525. },
  526. {'default': True,
  527. 'modified': False,
  528. 'name': 'Spec22/value9/v92/v92b',
  529. 'type': 'integer',
  530. 'value': 47806
  531. }
  532. ]
  533. maps = self.mcd.get_value_maps("/Spec22/value9")
  534. self.assertEqual(expected, maps)
  535. # A slash at the end should not produce different output
  536. maps = self.mcd.get_value_maps("/Spec22/value9/")
  537. self.assertEqual(expected, maps)
  538. # A slash at the end should not produce different output with
  539. # indices too
  540. expected2 = [{'default': True,
  541. 'type': 'integer',
  542. 'name': 'Spec22/value5[1]',
  543. 'value': 'b',
  544. 'modified': False}]
  545. maps = self.mcd.get_value_maps("/Spec22/value5[1]/")
  546. self.assertEqual(expected2, maps)
  547. def test_get_value_maps_named_set(self):
  548. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec32.spec")
  549. self.mcd.set_specification(module_spec)
  550. maps = self.mcd.get_value_maps()
  551. self.assertEqual([{'default': False, 'type': 'module',
  552. 'name': 'Spec32', 'value': None,
  553. 'modified': False}], maps)
  554. maps = self.mcd.get_value_maps("/Spec32/named_set_item")
  555. self.assertEqual([{'default': True, 'type': 'integer',
  556. 'name': 'Spec32/named_set_item/a',
  557. 'value': 1, 'modified': False},
  558. {'default': True, 'type': 'integer',
  559. 'name': 'Spec32/named_set_item/b',
  560. 'value': 2, 'modified': False}], maps)
  561. maps = self.mcd.get_value_maps("/Spec32/named_set_item/a")
  562. self.assertEqual([{'default': True, 'type': 'integer',
  563. 'name': 'Spec32/named_set_item/a',
  564. 'value': 1, 'modified': False}], maps)
  565. maps = self.mcd.get_value_maps("/Spec32/named_set_item/b")
  566. self.assertEqual([{'default': True, 'type': 'integer',
  567. 'name': 'Spec32/named_set_item/b',
  568. 'value': 2, 'modified': False}], maps)
  569. def test_set_value(self):
  570. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  571. self.mcd.set_specification(module_spec)
  572. self.mcd.set_value("Spec2/item1", 2)
  573. self.assertRaises(isc.cc.data.DataTypeError,
  574. self.mcd.set_value, "Spec2/item1", "asdf")
  575. self.assertRaises(isc.cc.data.DataNotFoundError,
  576. self.mcd.set_value, "Spec2/no_such_item", 4)
  577. self.mcd.set_value("Spec2/item5[0]", "c")
  578. value, status = self.mcd.get_value("Spec2/item5[0]")
  579. self.assertEqual(value, "c")
  580. self.assertEqual(MultiConfigData.LOCAL, status)
  581. self.assertRaises(isc.cc.data.DataTypeError, self.mcd.set_value, "Spec2/item5[a]", "asdf")
  582. def test_unset(self):
  583. """
  584. Test the unset command works.
  585. """
  586. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  587. self.mcd.set_specification(module_spec)
  588. self.mcd.set_specification(module_spec)
  589. value, status = self.mcd.get_value("Spec2/item1")
  590. # This is the default first
  591. self.assertEqual(1, value)
  592. self.assertEqual(MultiConfigData.DEFAULT, status)
  593. # Unseting a default item does nothing.
  594. self.mcd.unset("Spec2/item1")
  595. value, status = self.mcd.get_value("Spec2/item1")
  596. # This should be the default
  597. self.assertEqual(1, value)
  598. self.assertEqual(MultiConfigData.DEFAULT, status)
  599. # Set it to something else
  600. self.mcd.set_value("Spec2/item1", 42)
  601. value, status = self.mcd.get_value("Spec2/item1")
  602. self.assertEqual(42, value)
  603. self.assertEqual(MultiConfigData.LOCAL, status)
  604. # Try to unset it
  605. self.mcd.unset("Spec2/item1")
  606. value, status = self.mcd.get_value("Spec2/item1")
  607. # This should be the default
  608. self.assertEqual(1, value)
  609. self.assertEqual(MultiConfigData.DEFAULT, status)
  610. # Unset a nonexisting item. Should raise.
  611. self.assertRaises(isc.cc.data.DataNotFoundError, self.mcd.unset, "Spec2/doesnotexist")
  612. def test_get_config_item_list(self):
  613. config_items = self.mcd.get_config_item_list()
  614. self.assertEqual([], config_items)
  615. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
  616. self.mcd.set_specification(module_spec)
  617. config_items = self.mcd.get_config_item_list()
  618. self.assertEqual(['Spec2'], config_items)
  619. config_items = self.mcd.get_config_item_list(None, False)
  620. self.assertEqual(['Spec2'], config_items)
  621. config_items = self.mcd.get_config_item_list(None, True)
  622. self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
  623. config_items = self.mcd.get_config_item_list("Spec2", True)
  624. self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
  625. config_items = self.mcd.get_config_item_list("Spec2")
  626. self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6'], config_items)
  627. config_items = self.mcd.get_config_item_list("/Spec2")
  628. self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6'], config_items)
  629. config_items = self.mcd.get_config_item_list("Spec2", True)
  630. self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
  631. def test_is_named_set(self):
  632. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec32.spec")
  633. self.mcd.set_specification(module_spec)
  634. spec_part = self.mcd.find_spec_part("Spec32/named_set_item")
  635. self.assertTrue(spec_part_is_named_set(spec_part))
  636. def test_get_config_item_list_named_set(self):
  637. config_items = self.mcd.get_config_item_list()
  638. self.assertEqual([], config_items)
  639. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec32.spec")
  640. self.mcd.set_specification(module_spec)
  641. config_items = self.mcd.get_config_item_list()
  642. self.assertEqual(['Spec32'], config_items)
  643. config_items = self.mcd.get_config_item_list(None, False)
  644. self.assertEqual(['Spec32'], config_items)
  645. config_items = self.mcd.get_config_item_list(None, True)
  646. self.assertEqual(['Spec32/named_set_item', 'Spec32/named_set_item2'], config_items)
  647. self.mcd.set_value('Spec32/named_set_item', { "aaaa": 4, "aabb": 5, "bbbb": 6})
  648. config_items = self.mcd.get_config_item_list("/Spec32/named_set_item", True)
  649. self.assertEqual(['Spec32/named_set_item/aaaa',
  650. 'Spec32/named_set_item/aabb',
  651. 'Spec32/named_set_item/bbbb',
  652. ], config_items)
  653. def test_set_named_set_nonlocal(self):
  654. # Test whether a default named set is copied to local if a subitem
  655. # is changed, and that other items in the set do not get lost
  656. module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + 'spec32.spec')
  657. self.mcd.set_specification(module_spec)
  658. value, status = self.mcd.get_value('Spec32/named_set_item')
  659. self.assertEqual({'a': 1, 'b': 2}, value)
  660. self.assertEqual(MultiConfigData.DEFAULT, status)
  661. self.mcd.set_value('Spec32/named_set_item/b', 3)
  662. value, status = self.mcd.get_value('Spec32/named_set_item')
  663. self.assertEqual({'a': 1, 'b': 3}, value)
  664. self.assertEqual(MultiConfigData.LOCAL, status)
  665. if __name__ == '__main__':
  666. unittest.main()