[svn] commit: r773 - in /branches/jelte-configuration/src/lib: cc/python/isc/cc/data.py cc/python/isc/cc/data_test.py config/python/isc/config/cfgmgr.py config/python/isc/config/cfgmgr_test.py

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Feb 9 16:12:41 UTC 2010


Author: jelte
Date: Tue Feb  9 16:12:41 2010
New Revision: 773

Log:
cfgmgr handle non-existent db file
update copyright statements
added tests for data element helper functions
improved and cleaned up data element helper functions

Added:
    branches/jelte-configuration/src/lib/cc/python/isc/cc/data_test.py
Modified:
    branches/jelte-configuration/src/lib/cc/python/isc/cc/data.py
    branches/jelte-configuration/src/lib/config/python/isc/config/cfgmgr.py
    branches/jelte-configuration/src/lib/config/python/isc/config/cfgmgr_test.py

Modified: branches/jelte-configuration/src/lib/cc/python/isc/cc/data.py
==============================================================================
--- branches/jelte-configuration/src/lib/cc/python/isc/cc/data.py (original)
+++ branches/jelte-configuration/src/lib/cc/python/isc/cc/data.py Tue Feb  9 16:12:41 2010
@@ -1,5 +1,25 @@
-# data, data_definition, config_data, module_config_data and ui_config_data classes
-# we might want to split these up :)
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#
+# Helper functions for data elements as used in cc-channel and
+# configuration. There is no python equivalent for the cpp Element
+# class, since data elements are represented by native python types
+# (int, real, bool, string, list and dict respectively)
+#
+
 import ast
 
 class DataNotFoundError(Exception): pass
@@ -9,6 +29,8 @@
     """Merges the contents of new into orig, think recursive update()
        orig and new must both be dicts. If an element value is None in
        new it will be removed in orig."""
+    if type(orig) != dict or type(new) != dict:
+        raise DataTypeError("Not a dict in merge()")
     for kn in new.keys():
         if kn in orig:
             if new[kn]:
@@ -23,6 +45,10 @@
 
 def find(element, identifier):
     """Returns the subelement in the given data element, raises DataNotFoundError if not found"""
+    if type(identifier) != str or (type(element) != dict and identifier != ""):
+        raise DataTypeError("identifier in merge() is not a string")
+    if type(identifier) != str or (type(element) != dict and identifier != ""):
+        raise DataTypeError("element in merge() is not a dict")
     id_parts = identifier.split("/")
     id_parts[:] = (value for value in id_parts if value != "")
     cur_el = element
@@ -34,6 +60,17 @@
     return cur_el
 
 def set(element, identifier, value):
+    """Sets the value at the element specified by identifier to value.
+       If the value is None, it is removed from the dict. If element
+       is not a dict, or if the identifier points to something that is
+       not, a DataTypeError is raised. The element is updated inline,
+       so if the original needs to be kept, you must make a copy before
+       calling set(). The updated base element is returned (so that
+       el.set().set().set() is possible)"""
+    if type(element) != dict:
+        raise DataTypeError("element in set() is not a dict")
+    if type(identifier) != str:
+        raise DataTypeError("identifier in set() is not a string")
     id_parts = identifier.split("/")
     id_parts[:] = (value for value in id_parts if value != "")
     cur_el = element
@@ -41,36 +78,46 @@
         if id in cur_el.keys():
             cur_el = cur_el[id]
         else:
-            cur_el[id] = {}
-            cur_el = cur_el[id]
-    cur_el[id_parts[-1]] = value
+            if value:
+                cur_el[id] = {}
+                cur_el = cur_el[id]
+            else:
+                # set to none, and parent el not found, return
+                return element
+    if value:
+        cur_el[id_parts[-1]] = value
+    else:
+        del cur_el[id_parts[-1]]
     return element
 
 def unset(element, identifier):
-    id_parts = identifier.split("/")
-    id_parts[:] = (value for value in id_parts if value != "")
-    cur_el = element
-    for id in id_parts[:-1]:
-        if id in cur_el.keys():
-            cur_el = cur_el[id]
-        else:
-            cur_el[id] = {}
-            cur_el = cur_el[id]
-    cur_el[id_parts[-1]] = None
-    return element
+    """Removes the element at the given identifier if it exists. Raises
+       a DataTypeError if element is not a dict or if identifier is not
+       a string. Returns the base element."""
+    # perhaps we can simply do with set none, and remove this whole
+    # function
+    return set(element, identifier, None)
 
 def find_no_exc(element, identifier):
-    """Returns the subelement in the given data element, returns None if not found"""
+    """Returns the subelement in the given data element, returns None
+       if not found, or if an error occurred (i.e. this function should
+       never raise an exception)"""
+    if type(identifier) != str:
+        return None
     id_parts = identifier.split("/")
     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():
+        if (type(cur_el) == dict and id in cur_el.keys()) or id=="":
             cur_el = cur_el[id]
         else:
             return None
     return cur_el
 
+#
+# hmm, these are more relevant for datadefition
+# should we (re)move them?
+#
 def find_spec(element, identifier):
     """find the data definition for the given identifier
        returns either a map with 'item_name' etc, or a list of those"""
@@ -147,6 +194,11 @@
     return result
 
 def parse_value_str(value_str):
+    """Parses the given string to a native python object. If the
+       string cannot be parsed, it is returned. If it is not a string,
+       None is returned"""
+    if type(value_str) != str:
+        return None
     try:
         return ast.literal_eval(value_str)
     except ValueError as ve:

Modified: branches/jelte-configuration/src/lib/config/python/isc/config/cfgmgr.py
==============================================================================
--- branches/jelte-configuration/src/lib/config/python/isc/config/cfgmgr.py (original)
+++ branches/jelte-configuration/src/lib/config/python/isc/config/cfgmgr.py Tue Feb  9 16:12:41 2010
@@ -1,3 +1,22 @@
+# Copyright (C) 2010  Internet Systems Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#
+# This is the main class for the b10-cfgmgr daemon
+#
+
 import isc
 import signal
 import ast
@@ -122,7 +141,11 @@
     def read_config(self):
         """Read the current configuration from the b10-config.db file
            at the path specificied at init()"""
-        self.config = ConfigManagerData.read_from_file(self.data_path)
+        try:
+            self.config = ConfigManagerData.read_from_file(self.data_path)
+        except ConfigManagerDataEmpty:
+            # ok, just start with an empty config
+            self.config = ConfigManagerData(self.data_path)
         
     def write_config(self):
         """Write the current configuration to the b10-config.db file

Modified: branches/jelte-configuration/src/lib/config/python/isc/config/cfgmgr_test.py
==============================================================================
--- branches/jelte-configuration/src/lib/config/python/isc/config/cfgmgr_test.py (original)
+++ branches/jelte-configuration/src/lib/config/python/isc/config/cfgmgr_test.py Tue Feb  9 16:12:41 2010
@@ -1,4 +1,4 @@
-# Copyright (C) 2009  Internet Systems Consortium.
+# Copyright (C) 2010  Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above




More information about the bind10-changes mailing list