Browse Source

unit tests and corresponding tweaks

git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@964 e5f2f494-b856-4b98-b285-d166d9295462
Jelte Jansen 15 years ago
parent
commit
ed617e0845

+ 2 - 6
src/lib/cc/python/isc/cc/data.py

@@ -78,12 +78,8 @@ def set(element, identifier, value):
         if id in cur_el.keys():
             cur_el = cur_el[id]
         else:
-            if value:
-                cur_el[id] = {}
-                cur_el = cur_el[id]
-            else:
-                # set to none, and parent el not found, return
-                return element
+            cur_el[id] = {}
+            cur_el = cur_el[id]
     # value can be an empty list or dict, so check for None eplicitely
     if value != None:
         cur_el[id_parts[-1]] = value

+ 20 - 17
src/lib/config/python/isc/config/config_data.py

@@ -30,10 +30,10 @@ def check_type(spec_part, value):
        specification part relevant for the value. Raises an
        isc.cc.data.DataTypeError exception if not. spec_part can be
        retrieved with find_spec_part()"""
-    if type(spec_part) == list:
-        data_type = "list"
-    else:
+    if type(spec_part) == dict and 'item_type' in spec_part:
         data_type = spec_part['item_type']
+    else:
+        raise isc.cc.data.DataTypeError(str("Incorrect specification part for type checking"))
 
     if data_type == "integer" and type(value) != int:
         raise isc.cc.data.DataTypeError(str(value) + " is not an integer")
@@ -62,11 +62,7 @@ def find_spec_part(element, identifier):
     id_parts[:] = (value for value in id_parts if value != "")
     cur_el = element
     for id in id_parts:
-        if type(cur_el) == dict and id in cur_el.keys():
-            cur_el = cur_el[id]
-        elif type(cur_el) == dict and 'item_name' in cur_el.keys() and cur_el['item_name'] == id:
-            pass
-        elif type(cur_el) == dict and 'map_item_spec' in cur_el.keys():
+        if type(cur_el) == dict and 'map_item_spec' in cur_el.keys():
             found = False
             for cur_el_item in cur_el['map_item_spec']:
                 if cur_el_item['item_name'] == id:
@@ -83,12 +79,13 @@ def find_spec_part(element, identifier):
             if not found:
                 raise isc.cc.data.DataNotFoundError(id + " in " + str(cur_el))
         else:
-            raise isc.cc.data.DataNotFoundError(id + " in " + str(cur_el))
+            raise isc.cc.data.DataNotFoundError("Not a correct config specification")
     return cur_el
 
 def spec_name_list(spec, prefix="", recurse=False):
     """Returns a full list of all possible item identifiers in the
-       specification (part)"""
+       specification (part). Raises a ConfigDataError if spec is not
+       a correct spec (as returned by ModuleSpec.get_config_spec()"""
     result = []
     if prefix != "" and not prefix.endswith("/"):
         prefix += "/"
@@ -98,7 +95,10 @@ def spec_name_list(spec, prefix="", recurse=False):
                 name = map_el['item_name']
                 if map_el['item_type'] == 'map':
                     name += "/"
-                result.append(prefix + name)
+                if recurse and 'map_item_spec' in map_el:
+                    result.extend(spec_name_list(map_el['map_item_spec'], prefix + map_el['item_name'], recurse))
+                else:
+                    result.append(prefix + name)
         else:
             for name in spec:
                 result.append(prefix + name + "/")
@@ -114,6 +114,10 @@ def spec_name_list(spec, prefix="", recurse=False):
                     if list_el['item_type'] in ["list", "map"]:
                         name += "/"
                     result.append(prefix + name)
+            else:
+                raise ConfigDataError("Bad specication")
+    else:
+        raise ConfigDataError("Bad specication")
     return result
 
 class ConfigData:
@@ -192,9 +196,9 @@ class MultiConfigData:
         self._local_changes = {}
 
     def set_specification(self, spec):
-        """Add or update a ModuleSpec"""
+        """Add or update a ModuleSpec. Raises a ConfigDataError is spec is not a ModuleSpec"""
         if type(spec) != isc.config.ModuleSpec:
-            raise Exception("not a datadef: " + str(type(spec)))
+            raise ConfigDataError("not a datadef: " + str(type(spec)))
         self._specifications[spec.get_module_name()] = spec
 
     def get_module_spec(self, module):
@@ -324,7 +328,6 @@ class MultiConfigData:
             spec = self.get_module_spec(module)
             if spec:
                 spec_part = find_spec_part(spec.get_config_spec(), id)
-                print(spec_part)
                 if type(spec_part) == list:
                     for item in spec_part:
                         entry = {}
@@ -389,14 +392,14 @@ class MultiConfigData:
            specified, returns a list of module names. The first part of
            the identifier (up to the first /) is interpreted as the
            module name"""
-        if identifier:
+        if identifier and identifier != "/":
             spec = self.find_spec_part(identifier)
             return spec_name_list(spec, identifier + "/", recurse)
         else:
             if recurse:
                 id_list = []
-                for module in self._specifications:
-                    id_list.extend(spec_name_list(self._specifications[module], module, recurse))
+                for module in self._specifications.keys():
+                    id_list.extend(spec_name_list(self.find_spec_part(module), module, recurse))
                 return id_list
             else:
                 return list(self._specifications.keys())

+ 81 - 10
src/lib/config/python/isc/config/config_data_test.py

@@ -39,8 +39,8 @@ class TestConfigData(unittest.TestCase):
     #    self.assertRaises(ConfigDataError, ConfigData, 1)
 
     def test_check_type(self):
-        config_spec = self.cd.get_module_spec().get_config_spec()
-        spec_part = find_spec_part(config_spec, "item1")
+        config_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec22.spec").get_config_spec()
+        spec_part = find_spec_part(config_spec, "value1")
         check_type(spec_part, 1)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, True)
@@ -48,7 +48,7 @@ class TestConfigData(unittest.TestCase):
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
         
-        spec_part = find_spec_part(config_spec, "item2")
+        spec_part = find_spec_part(config_spec, "value2")
         check_type(spec_part, 1.1)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, True)
@@ -56,7 +56,7 @@ class TestConfigData(unittest.TestCase):
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
         
-        spec_part = find_spec_part(config_spec, "item3")
+        spec_part = find_spec_part(config_spec, "value3")
         check_type(spec_part, True)
         check_type(spec_part, False)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
@@ -65,7 +65,7 @@ class TestConfigData(unittest.TestCase):
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
         
-        spec_part = find_spec_part(config_spec, "item4")
+        spec_part = find_spec_part(config_spec, "value4")
         check_type(spec_part, "asdf")
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
@@ -73,16 +73,16 @@ class TestConfigData(unittest.TestCase):
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
         
-        spec_part = find_spec_part(config_spec, "item5")
-        check_type(spec_part, ["a", "b"])
+        spec_part = find_spec_part(config_spec, "value5")
+        check_type(spec_part, [1, 2])
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, True)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, "a")
-        self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
+        self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ "a", "b" ])
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "a": 1 })
         
-        spec_part = find_spec_part(config_spec, "item6")
+        spec_part = find_spec_part(config_spec, "value6")
         check_type(spec_part, { "value1": "aaa", "value2": 2 })
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1)
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, 1.1)
@@ -91,14 +91,19 @@ class TestConfigData(unittest.TestCase):
         self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, [ 1, 2 ])
         #self.assertRaises(isc.cc.data.DataTypeError, check_type, spec_part, { "value1": 1 })
 
+        self.assertRaises(isc.cc.data.DataTypeError, check_type, config_spec, 1)
+
     def test_find_spec_part(self):
         config_spec = self.cd.get_module_spec().get_config_spec()
         spec_part = find_spec_part(config_spec, "item1")
         self.assertEqual({'item_name': 'item1', 'item_type': 'integer', 'item_optional': False, 'item_default': 1, }, spec_part)
+        spec_part = find_spec_part(config_spec, "/item1")
+        self.assertEqual({'item_name': 'item1', 'item_type': 'integer', 'item_optional': False, 'item_default': 1, }, spec_part)
         self.assertRaises(isc.cc.data.DataNotFoundError, find_spec_part, config_spec, "no_such_item")
         self.assertRaises(isc.cc.data.DataNotFoundError, find_spec_part, config_spec, "no_such_item/multilevel")
+        self.assertRaises(isc.cc.data.DataNotFoundError, find_spec_part, config_spec, "item6/multilevel")
+        self.assertRaises(isc.cc.data.DataNotFoundError, find_spec_part, 1, "item6/multilevel")
         spec_part = find_spec_part(config_spec, "item6/value1")
-        #print(spec_part)
         self.assertEqual({'item_name': 'value1', 'item_type': 'string', 'item_optional': True, 'item_default': 'default'}, spec_part)
 
     def test_spec_name_list(self):
@@ -106,7 +111,29 @@ class TestConfigData(unittest.TestCase):
         self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5/', 'item6/'], name_list)
         name_list = spec_name_list(self.cd.get_module_spec().get_config_spec(), "", True)
         self.assertEqual(['item1', 'item2', 'item3', 'item4', 'item5/', 'item6/value1', 'item6/value2'], name_list)
+        spec_part = find_spec_part(self.cd.get_module_spec().get_config_spec(), "item6")
+        name_list = spec_name_list(spec_part, "item6", True)
+        self.assertEqual(['item6/value1', 'item6/value2'], name_list)
+        spec_part = find_spec_part(self.cd.get_module_spec().get_config_spec(), "item6")
+        name_list = spec_name_list(spec_part, "item6", True)
+        self.assertEqual(['item6/value1', 'item6/value2'], name_list)
+
+        config_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec22.spec").get_config_spec()
+        spec_part = find_spec_part(config_spec, "value9")
+        name_list = spec_name_list(spec_part, "value9", True)
+        self.assertEqual(['value9/v91', 'value9/v92/v92a', 'value9/v92/v92b'], name_list)
+
+        name_list = spec_name_list({ "myModule": config_spec }, "", False)
+        self.assertEqual(['myModule/'], name_list)
+        name_list = spec_name_list({ "myModule": config_spec }, "", True)
+        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)
+
+        self.assertRaises(ConfigDataError, spec_name_list, 1)
+        self.assertRaises(ConfigDataError, spec_name_list, [ 'a' ])
 
+    def test_init(self):
+        self.assertRaises(ConfigDataError, ConfigData, "asdf")
+        
     def test_get_value(self):
         value, default = self.cd.get_value("item1")
         self.assertEqual(1, value)
@@ -178,6 +205,7 @@ class TestMultiConfigData(unittest.TestCase):
         self.mcd.set_specification(module_spec)
         self.assert_(module_spec.get_module_name() in self.mcd._specifications)
         self.assertEquals(module_spec, self.mcd._specifications[module_spec.get_module_name()])
+        self.assertRaises(ConfigDataError, self.mcd.set_specification, "asdf")
 
     def test_get_module_spec(self):
         module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec1.spec")
@@ -190,11 +218,18 @@ class TestMultiConfigData(unittest.TestCase):
     def test_find_spec_part(self):
         spec_part = self.mcd.find_spec_part("Spec2/item1")
         self.assertEqual(None, spec_part)
+        spec_part = self.mcd.find_spec_part("/Spec2/item1")
+        self.assertEqual(None, spec_part)
         module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
         self.mcd.set_specification(module_spec)
         spec_part = self.mcd.find_spec_part("Spec2/item1")
         self.assertEqual({'item_name': 'item1', 'item_type': 'integer', 'item_optional': False, 'item_default': 1, }, spec_part)
 
+    def test_get_current_config(self):
+        cf = { 'module1': { 'item1': 2, 'item2': True } }
+        self.mcd._set_current_config(cf);
+        self.assertEqual(cf, self.mcd.get_current_config())
+
     def test_get_local_changes(self):
         module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
         self.mcd.set_specification(module_spec)
@@ -234,6 +269,8 @@ class TestMultiConfigData(unittest.TestCase):
         self.mcd.set_specification(module_spec)
         value = self.mcd.get_default_value("Spec2/item1")
         self.assertEqual(1, value)
+        value = self.mcd.get_default_value("/Spec2/item1")
+        self.assertEqual(1, value)
         value = self.mcd.get_default_value("Spec2/item6/value1")
         self.assertEqual('default', value)
         value = self.mcd.get_default_value("Spec2/item6/value2")
@@ -264,6 +301,34 @@ class TestMultiConfigData(unittest.TestCase):
         self.mcd.set_specification(module_spec)
         maps = self.mcd.get_value_maps()
         self.assertEqual([{'default': False, 'type': 'module', 'name': 'Spec2', 'value': None, 'modified': False}], maps)
+        self.mcd._set_current_config({ "Spec2": { "item1": 2 } })
+        self.mcd.set_value("Spec2/item3", False)
+        maps = self.mcd.get_value_maps("/Spec2")
+        self.assertEqual([{'default': False, 'type': 'integer', 'name': 'item1', 'value': 2, 'modified': False},
+                          {'default': False, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False},
+                          {'default': False, 'type': 'boolean', 'name': 'item3', 'value': False, 'modified': True},
+                          {'default': False, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False},
+                          {'default': False, 'type': 'list', 'name': 'item5', 'value': ['a', 'b'], 'modified': False},
+                          {'default': False, 'type': 'map', 'name': 'item6', 'value': {}, 'modified': False}], maps)
+        maps = self.mcd.get_value_maps("Spec2")
+        self.assertEqual([{'default': False, 'type': 'integer', 'name': 'item1', 'value': 2, 'modified': False},
+                          {'default': False, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False},
+                          {'default': False, 'type': 'boolean', 'name': 'item3', 'value': False, 'modified': True},
+                          {'default': False, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False},
+                          {'default': False, 'type': 'list', 'name': 'item5', 'value': ['a', 'b'], 'modified': False},
+                          {'default': False, 'type': 'map', 'name': 'item6', 'value': {}, 'modified': False}], maps)
+        maps = self.mcd.get_value_maps("/Spec2/item5")
+        self.assertEqual([{'default': False, 'type': 'string', 'name': 'list_element', 'value': 'a', 'modified': False},
+                          {'default': False, 'type': 'string', 'name': 'list_element', 'value': 'b', 'modified': False}], maps)
+        maps = self.mcd.get_value_maps("/Spec2/item1")
+        self.assertEqual([{'default': False, 'type': 'integer', 'name': 'item1', 'value': 2, 'modified': False}], maps)
+        maps = self.mcd.get_value_maps("/Spec2/item2")
+        self.assertEqual([{'default': False, 'type': 'real', 'name': 'item2', 'value': 1.1, 'modified': False}], maps)
+        maps = self.mcd.get_value_maps("/Spec2/item3")
+        self.assertEqual([{'default': False, 'type': 'boolean', 'name': 'item3', 'value': False, 'modified': True}], maps)
+        maps = self.mcd.get_value_maps("/Spec2/item4")
+        self.assertEqual([{'default': False, 'type': 'string', 'name': 'item4', 'value': 'test', 'modified': False}], maps)
+
 
     def test_set_value(self):
         module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec2.spec")
@@ -279,6 +344,12 @@ class TestMultiConfigData(unittest.TestCase):
         self.mcd.set_specification(module_spec)
         config_items = self.mcd.get_config_item_list()
         self.assertEqual(['Spec2'], config_items)
+        config_items = self.mcd.get_config_item_list(None, False)
+        self.assertEqual(['Spec2'], config_items)
+        config_items = self.mcd.get_config_item_list(None, True)
+        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5/', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
+        config_items = self.mcd.get_config_item_list("Spec2", True)
+        self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5/', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items)
         config_items = self.mcd.get_config_item_list("Spec2")
         self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5/', 'Spec2/item6/'], config_items)
         config_items = self.mcd.get_config_item_list("Spec2", True)

+ 2 - 1
src/lib/config/testdata/data22_1.data

@@ -4,5 +4,6 @@
     "value3": True,
     "value4": "foo",
     "value5": [ 1, 2, 3 ],
-    "value6": { "v61": "bar", "v62": True }
+    "value6": { "v61": "bar", "v62": True },
+    "value9": { "v91": "hi", "v92": { "v92a": "Hi", "v92b": 3 } }
 }

+ 2 - 1
src/lib/config/testdata/data22_6.data

@@ -5,5 +5,6 @@
     "value4": "foo",
     "value5": [ 1, 2, 3 ],
     "value6": { "v61": "bar", "v62": True },
-    "value7": [ 1, 2.2, "str", True ]
+    "value7": [ 1, 2.2, "str", True ],
+    "value9": { "v91": "hi", "v92": { "v92a": "Hi", "v92b": 3 } }
 }

+ 2 - 1
src/lib/config/testdata/data22_7.data

@@ -5,5 +5,6 @@
     "value4": "foo",
     "value5": [ 1, 2, 3 ],
     "value6": { "v61": "bar", "v62": True },
-    "value8": [ { "a": "d" }, { "a": "e" } ]
+    "value8": [ { "a": "d" }, { "a": "e" } ],
+    "value9": { "v91": "hi", "v92": { "v92a": "Hi", "v92b": 3 } }
 }

+ 30 - 0
src/lib/config/testdata/spec22.spec

@@ -78,6 +78,36 @@
           ]
         }
       },
+      { "item_name": "value9",
+        "item_type": "map",
+        "item_optional": False,
+        "item_default": {},
+        "map_item_spec": [
+          { "item_name": "v91",
+            "item_type": "string",
+            "item_optional": False,
+            "item_default": "def"
+          },
+          { "item_name": "v92",
+            "item_type": "map",
+            "item_optional": False,
+            "item_default": {},
+            "map_item_spec": [
+              { "item_name": "v92a",
+                "item_type": "string",
+                "item_optional": False,
+                "item_default": "Hello"
+              } ,
+              {
+                "item_name": "v92b",
+                "item_type": "integer",
+                "item_optional": False,
+                "item_default": 47806
+              }
+            ]
+          }
+        ]
+      }
     ]
   }
 }