module_spec_test.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. # Copyright (C) 2009 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. # $Id$
  16. #
  17. # Tests for the module_spec module
  18. #
  19. import unittest
  20. import os
  21. from isc.config import ModuleSpec, ModuleSpecError
  22. import isc.cc.data
  23. class TestModuleSpec(unittest.TestCase):
  24. def setUp(self):
  25. if 'CONFIG_TESTDATA_PATH' in os.environ:
  26. self.data_path = os.environ['CONFIG_TESTDATA_PATH']
  27. else:
  28. self.data_path = "../../../testdata"
  29. def spec_file(self, filename):
  30. return(self.data_path + os.sep + filename)
  31. def read_spec_file(self, filename):
  32. return isc.config.module_spec_from_file(self.spec_file(filename))
  33. def spec1(self, dd):
  34. module_spec = dd.get_full_spec()
  35. self.assert_('module_name' in module_spec)
  36. self.assertEqual(module_spec['module_name'], "Spec1")
  37. def test_open_file_name(self):
  38. dd = self.read_spec_file("spec1.spec")
  39. self.spec1(dd)
  40. def test_open_file_obj(self):
  41. file1 = open(self.spec_file("spec1.spec"))
  42. dd = isc.config.module_spec_from_file(file1)
  43. self.spec1(dd)
  44. def test_open_bad_file_obj(self):
  45. self.assertRaises(ModuleSpecError, isc.config.module_spec_from_file, 1)
  46. # contains single quotes which json parser does not accept
  47. self.assertRaises(ModuleSpecError, isc.config.module_spec_from_file, self.spec_file("spec28.spec"), False)
  48. my_spec_file = open(self.spec_file("spec28.spec"))
  49. self.assertRaises(ModuleSpecError, isc.config.module_spec_from_file, my_spec_file, False)
  50. self.assertRaises(ModuleSpecError, isc.config.module_spec_from_file, self.spec_file("does_not_exist"), False)
  51. def test_bad_specfiles(self):
  52. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec3.spec")
  53. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec4.spec")
  54. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec5.spec")
  55. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec6.spec")
  56. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec7.spec")
  57. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec8.spec")
  58. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec9.spec")
  59. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec10.spec")
  60. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec11.spec")
  61. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec12.spec")
  62. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec13.spec")
  63. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec14.spec")
  64. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec15.spec")
  65. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec16.spec")
  66. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec17.spec")
  67. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec18.spec")
  68. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec19.spec")
  69. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec20.spec")
  70. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec21.spec")
  71. self.assertRaises(ModuleSpecError, self.read_spec_file, "spec26.spec")
  72. def validate_data(self, specfile_name, datafile_name):
  73. dd = self.read_spec_file(specfile_name);
  74. data_file = open(self.spec_file(datafile_name))
  75. data_str = data_file.read()
  76. data = isc.cc.data.parse_value_str(data_str)
  77. return dd.validate_config(True, data)
  78. def test_data_validation(self):
  79. self.assertEqual(True, self.validate_data("spec22.spec", "data22_1.data"))
  80. self.assertEqual(False, self.validate_data("spec22.spec", "data22_2.data"))
  81. self.assertEqual(False, self.validate_data("spec22.spec", "data22_3.data"))
  82. self.assertEqual(False, self.validate_data("spec22.spec", "data22_4.data"))
  83. self.assertEqual(False, self.validate_data("spec22.spec", "data22_5.data"))
  84. self.assertEqual(True, self.validate_data("spec22.spec", "data22_6.data"))
  85. self.assertEqual(True, self.validate_data("spec22.spec", "data22_7.data"))
  86. self.assertEqual(False, self.validate_data("spec22.spec", "data22_8.data"))
  87. def validate_command_params(self, specfile_name, datafile_name, cmd_name):
  88. dd = self.read_spec_file(specfile_name);
  89. data_file = open(self.spec_file(datafile_name))
  90. data_str = data_file.read()
  91. params = isc.cc.data.parse_value_str(data_str)
  92. return dd.validate_command(cmd_name, params)
  93. def test_command_validation(self):
  94. self.assertEqual(True, self.validate_command_params("spec27.spec", "data22_1.data", 'cmd1'))
  95. self.assertEqual(False, self.validate_command_params("spec27.spec", "data22_2.data",'cmd1'))
  96. self.assertEqual(False, self.validate_command_params("spec27.spec", "data22_3.data", 'cmd1'))
  97. self.assertEqual(False, self.validate_command_params("spec27.spec", "data22_4.data", 'cmd1'))
  98. self.assertEqual(False, self.validate_command_params("spec27.spec", "data22_5.data", 'cmd1'))
  99. self.assertEqual(True, self.validate_command_params("spec27.spec", "data22_6.data", 'cmd1'))
  100. self.assertEqual(True, self.validate_command_params("spec27.spec", "data22_7.data", 'cmd1'))
  101. self.assertEqual(False, self.validate_command_params("spec27.spec", "data22_8.data", 'cmd1'))
  102. self.assertEqual(False, self.validate_command_params("spec27.spec", "data22_8.data", 'cmd2'))
  103. def test_init(self):
  104. self.assertRaises(ModuleSpecError, ModuleSpec, 1)
  105. module_spec = isc.config.module_spec_from_file(self.spec_file("spec1.spec"), False)
  106. self.spec1(module_spec)
  107. module_spec = isc.config.module_spec_from_file(self.spec_file("spec25.spec"), True)
  108. self.assertEqual("Spec25", module_spec.get_module_name())
  109. self.assertEqual("Just an empty module", module_spec.get_module_description())
  110. def test_str(self):
  111. module_spec = isc.config.module_spec_from_file(self.spec_file("spec1.spec"), False)
  112. self.assertEqual(module_spec.__str__(), "{'module_name': 'Spec1'}")
  113. def test_check_module_spec(self):
  114. self.assertRaises(ModuleSpecError, isc.config.module_spec._check, 1)
  115. def test_check_command_spec(self):
  116. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_command_spec, 1 )
  117. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_command_spec, [ 1 ] )
  118. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_command_spec,
  119. [ { 'command_name': 1,
  120. 'command_description': 'just for testing',
  121. 'command_args': [
  122. { 'item_name': 'arg1',
  123. 'item_type': 'string',
  124. 'item_optional': True
  125. }
  126. ]
  127. }
  128. ]
  129. )
  130. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_command_spec,
  131. [ { 'command_name': 'test_command',
  132. 'command_description': 1,
  133. 'command_args': [
  134. { 'item_name': 'arg1',
  135. 'item_type': 'string',
  136. 'item_optional': True
  137. }
  138. ]
  139. }
  140. ]
  141. )
  142. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_command_spec,
  143. [ { 'command_name': 'test_command',
  144. 'command_args': [ 1 ]
  145. }
  146. ]
  147. )
  148. def test_check_item_spec(self):
  149. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec, 1 )
  150. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  151. { 'item_name': 1,
  152. 'item_type': "string",
  153. 'item_optional': False,
  154. 'item_default': "asdf"
  155. }
  156. )
  157. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  158. { 'item_name': "an_item",
  159. 'item_type': "bad_type",
  160. 'item_optional': False,
  161. 'item_default': "asdf"
  162. }
  163. )
  164. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  165. { 'item_name': "an_item",
  166. 'item_type': 1,
  167. 'item_optional': False,
  168. 'item_default': "asdf"
  169. }
  170. )
  171. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  172. { 'item_name': "an_item",
  173. 'item_type': "string",
  174. 'item_optional': False,
  175. }
  176. )
  177. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  178. { 'item_name': "an_item",
  179. 'item_type': "string",
  180. 'item_optional': 1,
  181. }
  182. )
  183. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  184. { 'item_name': "an_item",
  185. 'item_type': "string",
  186. 'item_optional': False,
  187. 'item_default': 1
  188. }
  189. )
  190. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  191. { 'item_name': "an_item",
  192. 'item_type': "list",
  193. 'item_optional': False,
  194. 'item_default': []
  195. }
  196. )
  197. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  198. { 'item_name': "an_item",
  199. 'item_type': "list",
  200. 'item_optional': False,
  201. 'item_default': [],
  202. 'list_item_spec': 1
  203. }
  204. )
  205. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  206. { 'item_name': "an_item",
  207. 'item_type': "map",
  208. 'item_optional': False,
  209. 'item_default': {}
  210. }
  211. )
  212. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  213. { 'item_name': "an_item",
  214. 'item_type': "map",
  215. 'item_optional': False,
  216. 'item_default': {},
  217. 'map_item_spec': 1
  218. }
  219. )
  220. self.assertRaises(ModuleSpecError, isc.config.module_spec._check_item_spec,
  221. { 'item_name': "an_item",
  222. 'item_type': "map",
  223. 'item_optional': False,
  224. 'item_default': {},
  225. 'map_item_spec': [ 1 ]
  226. }
  227. )
  228. def test_validate_type(self):
  229. errors = []
  230. self.assertEqual(True, isc.config.module_spec._validate_type({ 'item_type': 'integer' }, 1, errors))
  231. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'integer' }, "a", None))
  232. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'integer' }, "a", errors))
  233. self.assertEqual(['a should be an integer'], errors)
  234. errors = []
  235. self.assertEqual(True, isc.config.module_spec._validate_type({ 'item_type': 'real' }, 1.1, errors))
  236. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'real' }, "a", None))
  237. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'real' }, "a", errors))
  238. self.assertEqual(['a should be a real'], errors)
  239. errors = []
  240. self.assertEqual(True, isc.config.module_spec._validate_type({ 'item_type': 'boolean' }, True, errors))
  241. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'boolean' }, "a", None))
  242. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'boolean' }, "a", errors))
  243. self.assertEqual(['a should be a boolean'], errors)
  244. errors = []
  245. self.assertEqual(True, isc.config.module_spec._validate_type({ 'item_type': 'string' }, "a", errors))
  246. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'string' }, 1, None))
  247. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'string' }, 1, errors))
  248. self.assertEqual(['1 should be a string'], errors)
  249. errors = []
  250. self.assertEqual(True, isc.config.module_spec._validate_type({ 'item_type': 'list' }, [ 1, 1], errors))
  251. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'list' }, 1, None))
  252. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'list' }, 1, errors))
  253. self.assertEqual(['1 should be a list'], errors)
  254. errors = []
  255. self.assertEqual(True, isc.config.module_spec._validate_type({ 'item_type': 'map' }, {"a": 1}, errors))
  256. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'map' }, 1, None))
  257. self.assertEqual(False, isc.config.module_spec._validate_type({ 'item_type': 'map' }, 1, errors))
  258. self.assertEqual(['1 should be a map'], errors)
  259. def test_validate_spec(self):
  260. spec = { 'item_name': "an_item",
  261. 'item_type': "string",
  262. 'item_optional': False,
  263. 'item_default': "asdf"
  264. }
  265. errors = []
  266. self.assertEqual(False, isc.config.module_spec._validate_spec(spec, True, {}, None))
  267. self.assertEqual(False, isc.config.module_spec._validate_spec(spec, True, {}, errors))
  268. self.assertEqual(['non-optional item an_item missing'], errors)
  269. def test_validate_unknown_items(self):
  270. spec = [{ 'item_name': "an_item",
  271. 'item_type': "string",
  272. 'item_optional': True,
  273. 'item_default': "asdf"
  274. }]
  275. errors = []
  276. self.assertEqual(False, isc.config.module_spec._validate_spec_list(spec, True, { 'does_not_exist': 1 }, None))
  277. self.assertEqual(False, isc.config.module_spec._validate_spec_list(spec, True, { 'does_not_exist': 1 }, errors))
  278. self.assertEqual(['unknown item does_not_exist'], errors)
  279. if __name__ == '__main__':
  280. unittest.main()