Browse Source

add a 'shortcut' in cmdctl.py; it now only checks for existing module/command if the module is not ConfigManager (that one doesn't pass around its commands, i am thinking that that is possible, but at the moment it is completely seen as core and builtin)
added unittests for UIModuleCCSession
fixed a few badly named exceptions


git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1001 e5f2f494-b856-4b98-b285-d166d9295462

Jelte Jansen 15 years ago
parent
commit
2d71c1c3ce

+ 4 - 0
src/bin/cmdctl/cmdctl.py.in

@@ -266,6 +266,10 @@ class CommandControl():
         TODO. add check for parameters.
         '''
 
+        # core module ConfigManager does not have a specification file
+        if module_name == 'ConfigManager':
+            return self.send_command(module_name, command_name, params)
+
         if module_name not in self.command_spec.keys():
             return 1, {'error' : 'unknown module'}
 

+ 3 - 3
src/lib/config/python/isc/config/ccsession.py

@@ -270,7 +270,7 @@ class UIModuleCCSession(MultiConfigData):
            manager through b10-cmdctl, and stores those as CURRENT"""
         config = self._conn.send_GET('/config_data')
         if 'version' not in config or config['version'] != 1:
-            raise Exception("Bad config version")
+            raise ModuleCCSessionError("Bad config version")
         self._set_current_config(config)
 
     def add_value(self, identifier, value_str):
@@ -279,7 +279,7 @@ class UIModuleCCSession(MultiConfigData):
            of the module config data specification"""
         module_spec = self.find_spec_part(identifier)
         if (type(module_spec) != dict or "list_item_spec" not in module_spec):
-            raise DataTypeError(identifier + " is not a list")
+            raise isc.cc.data.DataNotFoundError(str(identifier) + " is not a list")
         value = isc.cc.data.parse_value_str(value_str)
         cur_list, status = self.get_value(identifier)
         if not cur_list:
@@ -296,7 +296,7 @@ class UIModuleCCSession(MultiConfigData):
            """
         module_spec = self.find_spec_part(identifier)
         if (type(module_spec) != dict or "list_item_spec" not in module_spec):
-            raise DataTypeError(identifier + " is not a list")
+            raise isc.cc.data.DataNotFoundError(str(identifier) + " is not a list")
         value = isc.cc.data.parse_value_str(value_str)
         isc.config.config_data.check_type(module_spec, [value])
         cur_list, status = self.get_value(identifier)

+ 88 - 0
src/lib/config/python/isc/config/ccsession_test.py

@@ -342,7 +342,95 @@ class TestModuleCCSession(unittest.TestCase):
         self.assertEqual(len(fake_session.message_queue), 1)
         mccs.check_command()
         self.assertEqual(len(fake_session.message_queue), 0)
+
+class fakeUIConn():
+    def __init__(self):
+        self.get_answers = {}
+        self.post_answers = {}
+
+    def set_get_answer(self, name, answer):
+        self.get_answers[name] = answer
+    
+    def set_post_answer(self, name, answer):
+        self.post_answers[name] = answer
+    
+    def send_GET(self, name, arg = None):
+        if name in self.get_answers:
+            return self.get_answers[name]
+        else:
+            return None
+    
+    def send_POST(self, name, arg = None):
+        if name in self.post_answers:
+            return self.post_answers[name]
+        else:
+            return None
+    
+
+class TestUIModuleCCSession(unittest.TestCase):
+    def setUp(self):
+        if 'CONFIG_TESTDATA_PATH' in os.environ:
+            self.data_path = os.environ['CONFIG_TESTDATA_PATH']
+        else:
+            self.data_path = "../../../testdata"
+
+    def spec_file(self, file):
+        return self.data_path + os.sep + file
         
+    def create_uccs2(self, fake_conn):
+        module_spec = isc.config.module_spec_from_file(self.spec_file("spec2.spec"))
+        fake_conn.set_get_answer('/config_spec', { module_spec.get_module_name(): module_spec.get_config_spec()})
+        fake_conn.set_get_answer('/commands', { module_spec.get_module_name(): module_spec.get_commands_spec()})
+        fake_conn.set_get_answer('/config_data', { 'version': 1 })
+        return UIModuleCCSession(fake_conn)
+
+    def test_init(self):
+        fake_conn = fakeUIConn()
+        fake_conn.set_get_answer('/config_spec', {})
+        fake_conn.set_get_answer('/commands', {})
+        fake_conn.set_get_answer('/config_data', { 'version': 1 })
+        uccs = UIModuleCCSession(fake_conn)
+        self.assertEqual({}, uccs._specifications)
+        self.assertEqual({ 'version': 1}, uccs._current_config)
+
+        module_spec = isc.config.module_spec_from_file(self.spec_file("spec2.spec"))
+        fake_conn.set_get_answer('/config_spec', { module_spec.get_module_name(): module_spec.get_config_spec()})
+        fake_conn.set_get_answer('/commands', { module_spec.get_module_name(): module_spec.get_commands_spec()})
+        fake_conn.set_get_answer('/config_data', { 'version': 1 })
+        uccs = UIModuleCCSession(fake_conn)
+        self.assertEqual(module_spec._module_spec, uccs._specifications['Spec2']._module_spec)
+
+        fake_conn.set_get_answer('/config_data', { 'version': 123123 })
+        self.assertRaises(ModuleCCSessionError, UIModuleCCSession, fake_conn)
+
+    def test_add_remove_value(self):
+        fake_conn = fakeUIConn()
+        uccs = self.create_uccs2(fake_conn)
+        self.assertRaises(isc.cc.data.DataNotFoundError, uccs.add_value, 1, "a")
+        self.assertRaises(isc.cc.data.DataNotFoundError, uccs.add_value, "no_such_item", "a")
+        self.assertRaises(isc.cc.data.DataNotFoundError, uccs.add_value, "Spec2/item1", "a")
+        self.assertRaises(isc.cc.data.DataNotFoundError, uccs.remove_value, 1, "a")
+        self.assertRaises(isc.cc.data.DataNotFoundError, uccs.remove_value, "no_such_item", "a")
+        self.assertRaises(isc.cc.data.DataNotFoundError, uccs.remove_value, "Spec2/item1", "a")
+        self.assertEqual({}, uccs._local_changes)
+        uccs.add_value("Spec2/item5", "foo")
+        self.assertEqual({'Spec2': {'item5': ['a', 'b', 'foo']}}, uccs._local_changes)
+        uccs.remove_value("Spec2/item5", "foo")
+        self.assertEqual({'Spec2': {'item5': ['a', 'b']}}, uccs._local_changes)
+        uccs._local_changes = {'Spec2': {'item5': []}}
+        uccs.remove_value("Spec2/item5", "foo")
+        uccs.add_value("Spec2/item5", "foo")
+        self.assertEqual({'Spec2': {'item5': ['foo']}}, uccs._local_changes)
+        uccs.add_value("Spec2/item5", "foo")
+        self.assertEqual({'Spec2': {'item5': ['foo']}}, uccs._local_changes)
+
+    def test_commit(self):
+        fake_conn = fakeUIConn()
+        uccs = self.create_uccs2(fake_conn)
+        uccs.commit()
+        uccs._local_changes = {'Spec2': {'item5': [ 'a' ]}}
+        uccs.commit()
+
 if __name__ == '__main__':
     unittest.main()
 

+ 2 - 0
src/lib/config/python/isc/config/cfgmgr.py

@@ -313,6 +313,7 @@ class ConfigManager:
     def handle_msg(self, msg):
         """Handle a command from the cc channel to the configuration manager"""
         answer = {}
+        print("[XX] got msg: " + str(msg))
         cmd, arg = isc.config.ccsession.parse_command(msg)
         if cmd:
             if cmd == isc.config.ccsession.COMMAND_GET_COMMANDS_SPEC:
@@ -322,6 +323,7 @@ class ConfigManager:
             elif cmd == isc.config.ccsession.COMMAND_GET_CONFIG:
                 answer = self._handle_get_config(arg)
             elif cmd == isc.config.ccsession.COMMAND_SET_CONFIG:
+                print("[b10-cfgmgr] got set_config command")
                 answer = self._handle_set_config(arg)
             elif cmd == "shutdown":
                 # TODO: logging

+ 4 - 1
src/lib/config/python/isc/config/config_data.py

@@ -218,7 +218,10 @@ class MultiConfigData:
         """Returns the specification for the item at the given
            identifier, or None if not found. The first part of the
            identifier (up to the first /) is interpreted as the module
-           name. Returns None if not found."""
+           name. Returns None if not found, or if identifier is not a
+           string."""
+        if type(identifier) != str:
+            return None
         if identifier[0] == '/':
             identifier = identifier[1:]
         module, sep, id = identifier.partition("/")