Browse Source

fix for getting default values within lists where the whole list (also) has a default (not just individual elements)

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac384@4129 e5f2f494-b856-4b98-b285-d166d9295462
Jelte Jansen 14 years ago
parent
commit
25530c6ca2

+ 34 - 24
src/lib/python/isc/config/config_data.py

@@ -364,34 +364,44 @@ class MultiConfigData:
            See get_value() for a general way to find a configuration
            value
         """
-        if identifier[0] == '/':
-            identifier = identifier[1:]
-        module, sep, id = identifier.partition("/")
         try:
-            spec = find_spec_part(self._specifications[module].get_config_spec(), id)
-            if type(spec) == dict and 'item_default' in spec:
-                id, list_indices = isc.cc.data.split_identifier_list_indices(id)
-                if list_indices is not None and \
-                   type(spec['item_default']) == list:
-                    if len(list_indices) == 1:
-                        default_list = spec['item_default']
-                        index = list_indices[0]
-                        if index < len(default_list):
-                            return default_list[index]
+            if identifier[0] == '/':
+                identifier = identifier[1:]
+            module, sep, id = identifier.partition("/")
+            # if there is a 'higher-level' list index specified, we need
+            # to check if that list specification has a default that
+            # overrides the more specific default in the final spec item
+            # (ie. list_default = [1, 2, 3], list_item_spec=int, default=0)
+            # def default list[1] should return 2, not 0
+            id_parts = isc.cc.data.split_identifier(id)
+            id_prefix = ""
+            while len(id_parts) > 0:
+                id_part = id_parts.pop(0)
+                item_id, list_indices = isc.cc.data.split_identifier_list_indices(id_part)
+                id_prefix += "/" + id_part
+                if list_indices is not None:
+                    spec = find_spec_part(self._specifications[module].get_config_spec(), id_prefix)
+                    if 'item_default' in spec:
+                        list_value = spec['item_default']
+                        for i in list_indices:
+                            if i < len(list_value):
+                                list_value = list_value[i]
+                            else:
+                                # out of range, return None
+                                return None
+                            
+                        if len(id_parts) > 0:
+                            rest_of_id = "/".join(id_parts)
+                            return isc.cc.data.find(list_value, rest_of_id)
                         else:
-                            return None
-                else:
-                    return spec['item_default']
-            elif type(spec) == list:
-                result = {}
-                for i in spec:
-                    if type(i) == dict and 'item_default' in i:
-                        result[i['item_name']] = i['item_default']
-                    else:
-                        result[i['item_name']] = None
-                return result
+                            return list_value
+    
+            spec = find_spec_part(self._specifications[module].get_config_spec(), id)
+            if 'item_default' in spec:
+                return spec['item_default']
             else:
                 return None
+
         except isc.cc.data.DataNotFoundError as dnfe:
             return None
 

+ 24 - 7
src/lib/python/isc/config/tests/config_data_test.py

@@ -360,6 +360,8 @@ class TestMultiConfigData(unittest.TestCase):
         self.assertEqual(1, value)
         value = self.mcd.get_default_value("Spec2/item5[0]")
         self.assertEqual('a', value)
+        value = self.mcd.get_default_value("Spec2/item5[1]")
+        self.assertEqual('b', value)
         value = self.mcd.get_default_value("Spec2/item5[5]")
         self.assertEqual(None, value)
         value = self.mcd.get_default_value("Spec2/item5[0][1]")
@@ -394,6 +396,10 @@ class TestMultiConfigData(unittest.TestCase):
         self.assertEqual(None, value)
         self.assertEqual(MultiConfigData.NONE, status)
 
+        value, status = self.mcd.get_value("Spec2/item5")
+        self.assertEqual(['a', 'b'], value)
+        self.assertEqual(MultiConfigData.DEFAULT, status)
+
         value, status = self.mcd.get_value("Spec2/item5[0]")
         self.assertEqual("a", value)
         self.assertEqual(MultiConfigData.DEFAULT, status)
@@ -402,6 +408,11 @@ class TestMultiConfigData(unittest.TestCase):
         self.assertEqual(None, value)
         self.assertEqual(MultiConfigData.NONE, status)
 
+        value, status = self.mcd.get_value("Spec2/item5[1]")
+        self.assertEqual("b", value)
+        self.assertEqual(MultiConfigData.DEFAULT, status)
+
+
 
     def test_get_value_maps(self):
         maps = self.mcd.get_value_maps()
@@ -425,21 +436,21 @@ class TestMultiConfigData(unittest.TestCase):
         self.mcd._set_current_config({ "Spec2": { "item1": 2 } })
         self.mcd.set_value("Spec2/item3", False)
         maps = self.mcd.get_value_maps("/Spec2")
-        print("[XX] MAPS:")
-        print(maps)
         self.assertEqual([{'default': False, 'type': 'integer', 'name': 'Spec2/item1', 'value': 2, 'modified': False},
                           {'default': True, 'type': 'real', 'name': 'Spec2/item2', 'value': 1.1, 'modified': False},
                           {'default': False, 'type': 'boolean', 'name': 'Spec2/item3', 'value': False, 'modified': True},
                           {'default': True, 'type': 'string', 'name': 'Spec2/item4', 'value': 'test', 'modified': False},
                           {'default': True, 'type': 'list', 'name': 'Spec2/item5', 'value': ['a', 'b'], 'modified': False},
-                          {'default': True, 'type': 'map', 'name': 'Spec2/item6', 'value': {}, 'modified': False}], maps)
+                          {'default': True, 'type': 'string', 'name': 'Spec2/item6/value1', 'value': 'default', 'modified': False},
+                          {'default': False, 'type': 'integer', 'name': 'Spec2/item6/value2', 'value': None, 'modified': False}], maps)
         maps = self.mcd.get_value_maps("Spec2")
         self.assertEqual([{'default': False, 'type': 'integer', 'name': 'Spec2/item1', 'value': 2, 'modified': False},
                           {'default': True, 'type': 'real', 'name': 'Spec2/item2', 'value': 1.1, 'modified': False},
                           {'default': False, 'type': 'boolean', 'name': 'Spec2/item3', 'value': False, 'modified': True},
                           {'default': True, 'type': 'string', 'name': 'Spec2/item4', 'value': 'test', 'modified': False},
                           {'default': True, 'type': 'list', 'name': 'Spec2/item5', 'value': ['a', 'b'], 'modified': False},
-                          {'default': True, 'type': 'map', 'name': 'Spec2/item6', 'value': {}, 'modified': False}], maps)
+                          {'default': True, 'type': 'string', 'name': 'Spec2/item6/value1', 'value': 'default', 'modified': False},
+                          {'default': False, 'type': 'integer', 'name': 'Spec2/item6/value2', 'value': None, 'modified': False}], maps)
         maps = self.mcd.get_value_maps("/Spec2/item5")
         self.assertEqual([{'default': True, 'type': 'string', 'name': 'Spec2/item5[0]', 'value': 'a', 'modified': False},
                           {'default': True, 'type': 'string', 'name': 'Spec2/item5[1]', 'value': 'b', 'modified': False}], maps)
@@ -471,9 +482,15 @@ class TestMultiConfigData(unittest.TestCase):
                      'value': 'def'},
                     {'default': True,
                      'modified': False,
-                     'name': 'Spec22/value9/v92',
-                     'type': 'map',
-                     'value': {}
+                     'name': 'Spec22/value9/v92/v92a',
+                     'type': 'string',
+                     'value': 'Hello'
+                    },
+                    {'default': True,
+                     'modified': False,
+                     'name': 'Spec22/value9/v92/v92b',
+                     'type': 'integer',
+                     'value': 47806
                     }
                    ]
         maps = self.mcd.get_value_maps("/Spec22/value9")