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.
         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():
         if module_name not in self.command_spec.keys():
             return 1, {'error' : 'unknown module'}
             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"""
            manager through b10-cmdctl, and stores those as CURRENT"""
         config = self._conn.send_GET('/config_data')
         config = self._conn.send_GET('/config_data')
         if 'version' not in config or config['version'] != 1:
         if 'version' not in config or config['version'] != 1:
-            raise Exception("Bad config version")
+            raise ModuleCCSessionError("Bad config version")
         self._set_current_config(config)
         self._set_current_config(config)
 
 
     def add_value(self, identifier, value_str):
     def add_value(self, identifier, value_str):
@@ -279,7 +279,7 @@ class UIModuleCCSession(MultiConfigData):
            of the module config data specification"""
            of the module config data specification"""
         module_spec = self.find_spec_part(identifier)
         module_spec = self.find_spec_part(identifier)
         if (type(module_spec) != dict or "list_item_spec" not in module_spec):
         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)
         value = isc.cc.data.parse_value_str(value_str)
         cur_list, status = self.get_value(identifier)
         cur_list, status = self.get_value(identifier)
         if not cur_list:
         if not cur_list:
@@ -296,7 +296,7 @@ class UIModuleCCSession(MultiConfigData):
            """
            """
         module_spec = self.find_spec_part(identifier)
         module_spec = self.find_spec_part(identifier)
         if (type(module_spec) != dict or "list_item_spec" not in module_spec):
         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)
         value = isc.cc.data.parse_value_str(value_str)
         isc.config.config_data.check_type(module_spec, [value])
         isc.config.config_data.check_type(module_spec, [value])
         cur_list, status = self.get_value(identifier)
         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)
         self.assertEqual(len(fake_session.message_queue), 1)
         mccs.check_command()
         mccs.check_command()
         self.assertEqual(len(fake_session.message_queue), 0)
         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__':
 if __name__ == '__main__':
     unittest.main()
     unittest.main()
 
 

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

@@ -313,6 +313,7 @@ class ConfigManager:
     def handle_msg(self, msg):
     def handle_msg(self, msg):
         """Handle a command from the cc channel to the configuration manager"""
         """Handle a command from the cc channel to the configuration manager"""
         answer = {}
         answer = {}
+        print("[XX] got msg: " + str(msg))
         cmd, arg = isc.config.ccsession.parse_command(msg)
         cmd, arg = isc.config.ccsession.parse_command(msg)
         if cmd:
         if cmd:
             if cmd == isc.config.ccsession.COMMAND_GET_COMMANDS_SPEC:
             if cmd == isc.config.ccsession.COMMAND_GET_COMMANDS_SPEC:
@@ -322,6 +323,7 @@ class ConfigManager:
             elif cmd == isc.config.ccsession.COMMAND_GET_CONFIG:
             elif cmd == isc.config.ccsession.COMMAND_GET_CONFIG:
                 answer = self._handle_get_config(arg)
                 answer = self._handle_get_config(arg)
             elif cmd == isc.config.ccsession.COMMAND_SET_CONFIG:
             elif cmd == isc.config.ccsession.COMMAND_SET_CONFIG:
+                print("[b10-cfgmgr] got set_config command")
                 answer = self._handle_set_config(arg)
                 answer = self._handle_set_config(arg)
             elif cmd == "shutdown":
             elif cmd == "shutdown":
                 # TODO: logging
                 # 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
         """Returns the specification for the item at the given
            identifier, or None if not found. The first part of the
            identifier, or None if not found. The first part of the
            identifier (up to the first /) is interpreted as the module
            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] == '/':
         if identifier[0] == '/':
             identifier = identifier[1:]
             identifier = identifier[1:]
         module, sep, id = identifier.partition("/")
         module, sep, id = identifier.partition("/")