[svn] commit: r999 - in /trunk/src: bin/auth/ bin/bind10/ lib/config/cpp/ lib/config/python/isc/config/

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Feb 26 11:21:42 UTC 2010


Author: jelte
Date: Fri Feb 26 11:21:41 2010
New Revision: 999

Log:
working on ccsession tests
updated command callback fingerprint; the function a module provides should now
take 2 arguments; the first is a string with the name of the command, the second
an ElementPtr containing argument(s)

Added:
    trunk/src/lib/config/python/isc/config/ccsession_test.py
    trunk/src/lib/config/python/isc/config/unittest_fakesession.py
Modified:
    trunk/src/bin/auth/main.cc
    trunk/src/bin/bind10/bind10.py.in
    trunk/src/lib/config/cpp/ccsession.cc
    trunk/src/lib/config/cpp/ccsession.h
    trunk/src/lib/config/python/isc/config/ccsession.py
    trunk/src/lib/config/python/isc/config/cfgmgr.py
    trunk/src/lib/config/python/isc/config/cfgmgr_test.py
    trunk/src/lib/config/python/isc/config/config_test.in

Modified: trunk/src/bin/auth/main.cc
==============================================================================
--- trunk/src/bin/auth/main.cc (original)
+++ trunk/src/bin/auth/main.cc Fri Feb 26 11:21:41 2010
@@ -63,15 +63,15 @@
 }
 
 isc::data::ElementPtr
-my_command_handler(isc::data::ElementPtr command) {
+my_command_handler(const std::string& command, const isc::data::ElementPtr args) {
     isc::data::ElementPtr answer = isc::config::createAnswer(0);
 
-    cout << "[XX] Handle command: " << endl << command->str() << endl;
-    if (command->get(0)->stringValue() == "print_message") 
+    cout << "[XX] Handle command: " << endl << command << endl;
+    if (command == "print_message") 
     {
-        cout << command->get(1)->get("message") << endl;
+        cout << args << endl;
         /* let's add that message to our answer as well */
-        answer->get("result")->add(command->get(1));
+        answer->get("result")->add(args);
     }
     return answer;
 }

Modified: trunk/src/bin/bind10/bind10.py.in
==============================================================================
--- trunk/src/bin/bind10/bind10.py.in (original)
+++ trunk/src/bin/bind10/bind10.py.in Fri Feb 26 11:21:41 2010
@@ -119,24 +119,23 @@
         return answer
         # TODO
 
-    def command_handler(self, command):
-        # a command is of the form [ "command", { "arg1": arg1, "arg2": arg2 } ]
+    def command_handler(self, command, args):
         if self.verbose:
             print("[XX] Boss got command:")
             print(command)
         answer = [ 1, "Command not implemented" ]
-        if type(command) != list or len(command) == 0:
+        if type(command) != str:
             answer = isc.config.ccsession.create_answer(1, "bad command")
         else:
-            cmd = command[0]
+            cmd = command
             if cmd == "shutdown":
                 print("[XX] got shutdown command")
                 self.runnable = False
                 answer = isc.config.ccsession.create_answer(0)
             elif cmd == "print_message":
-                if len(command) > 1 and type(command[1]) == dict and "message" in command[1]:
-                    print(command[1]["message"])
-                answer = isc.config.ccsession.create_answer(0)
+                if args:
+                    print(args)
+                answer = isc.config.ccsession.create_answer(0, args)
             elif cmd == "print_settings":
                 print("Full Config:")
                 full_config = self.ccs.get_full_config()

Modified: trunk/src/lib/config/cpp/ccsession.cc
==============================================================================
--- trunk/src/lib/config/cpp/ccsession.cc (original)
+++ trunk/src/lib/config/cpp/ccsession.cc Fri Feb 26 11:21:41 2010
@@ -164,7 +164,7 @@
 
 ModuleCCSession::ModuleCCSession(std::string spec_file_name,
                                isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config),
-                               isc::data::ElementPtr(*command_handler)(isc::data::ElementPtr command)
+                               isc::data::ElementPtr(*command_handler)(const std::string& command, const isc::data::ElementPtr args)
                               ) throw (isc::cc::SessionError):
     session_(isc::cc::Session())
 {
@@ -249,16 +249,16 @@
         if (!data->getType() == Element::map || data->contains("result")) {
             return 0;
         }
+        ElementPtr arg;
+        std::string cmd_str = parseCommand(arg, data);
         ElementPtr answer;
-        if (data->contains("config_update")) {
-            ElementPtr new_config = data->get("config_update");
-            answer = handleConfigUpdate(new_config);
-        }
-        if (data->contains("command")) {
+        if (cmd_str == "config_update") {
+            answer = handleConfigUpdate(arg);
+        } else {
             if (command_handler_) {
-                answer = command_handler_(data->get("command"));
+                answer = command_handler_(cmd_str, arg);
             } else {
-                answer = Element::createFromString("{ \"result\": [0] }");
+                answer = createAnswer(1, "Command given but no command handler for module");
             }
         }
         session_.reply(routing, answer);

Modified: trunk/src/lib/config/cpp/ccsession.h
==============================================================================
--- trunk/src/lib/config/cpp/ccsession.h (original)
+++ trunk/src/lib/config/cpp/ccsession.h Fri Feb 26 11:21:41 2010
@@ -54,7 +54,7 @@
      */
     ModuleCCSession(std::string spec_file_name,
                     isc::data::ElementPtr(*config_handler)(isc::data::ElementPtr new_config) = NULL,
-                    isc::data::ElementPtr(*command_handler)(isc::data::ElementPtr command) = NULL
+                    isc::data::ElementPtr(*command_handler)(const std::string& command, const isc::data::ElementPtr args) = NULL
                     ) throw (isc::cc::SessionError);
     int getSocket();
 
@@ -87,7 +87,7 @@
      *
      * This protocol is very likely to change.
      */
-    void set_command_handler(isc::data::ElementPtr(*command_handler)(isc::data::ElementPtr command)) { command_handler_ = command_handler; };
+    void set_command_handler(isc::data::ElementPtr(*command_handler)(const std::string& command, const isc::data::ElementPtr args)) { command_handler_ = command_handler; };
 
     const ElementPtr getConfig() { return config_; }
 private:
@@ -100,7 +100,7 @@
     ElementPtr handleConfigUpdate(ElementPtr new_config);
 
     isc::data::ElementPtr(*config_handler_)(isc::data::ElementPtr new_config);
-    isc::data::ElementPtr(*command_handler_)(isc::data::ElementPtr command);
+    isc::data::ElementPtr(*command_handler_)(const std::string& command, const isc::data::ElementPtr args);
 };
 
 ElementPtr createAnswer(const int rcode);

Modified: trunk/src/lib/config/python/isc/config/ccsession.py
==============================================================================
--- trunk/src/lib/config/python/isc/config/ccsession.py (original)
+++ trunk/src/lib/config/python/isc/config/ccsession.py Fri Feb 26 11:21:41 2010
@@ -58,6 +58,8 @@
         raise ModuleCCSessionError("wrong rcode type in answer message")
     else:
         if len(msg['result']) > 1:
+            if (msg['result'][0] != 0 and type(msg['result'][1]) != str):
+                raise ModuleCCSessionError("rcode in answer message is non-zero, value is not a string")
             return msg['result'][0], msg['result'][1]
         else:
             return msg['result'][0], None
@@ -78,6 +80,7 @@
 
 # 'fixed' commands
 """Fixed names for command and configuration messages"""
+COMMAND_CONFIG_UPDATE = "config_update"
 COMMAND_COMMANDS_UPDATE = "commands_update"
 COMMAND_SPECIFICATION_UPDATE = "specification_update"
 
@@ -94,9 +97,9 @@
     if type(msg) == dict and len(msg.items()) == 1:
         cmd, value = msg.popitem()
         if cmd == "command" and type(value) == list:
-            if len(value) == 1:
+            if len(value) == 1 and type(value[0]) == str:
                 return value[0], None
-            elif len(value) > 1:
+            elif len(value) > 1 and type(value[0]) == str:
                 return value[0], value[1]
     return None, None
 
@@ -105,6 +108,8 @@
        specified in the module's specification, and an optional params
        object"""
     # TODO: validate_command with spec
+    if type(command_name) != str:
+        raise ModuleCCSessionError("command in create_command() not a string")
     cmd = [ command_name ]
     if params:
         cmd.append(params)
@@ -121,7 +126,7 @@
        callbacks are called when 'check_command' is called on the
        ModuleCCSession"""
        
-    def __init__(self, spec_file_name, config_handler, command_handler):
+    def __init__(self, spec_file_name, config_handler, command_handler, cc_session = None):
         """Initialize a ModuleCCSession. This does *NOT* send the
            specification and request the configuration yet. Use start()
            for that once the ModuleCCSession has been initialized.
@@ -137,7 +142,10 @@
         self.set_config_handler(config_handler)
         self.set_command_handler(command_handler)
 
-        self._session = Session()
+        if not cc_session:
+            self._session = Session()
+        else:
+            self._session = cc_session
         self._session.group_subscribe(self._module_name, "*")
 
     def start(self):
@@ -172,17 +180,18 @@
         if msg:
             answer = None
             try:
-                if "config_update" in msg:
-                    new_config = msg["config_update"]
+                cmd, arg = isc.config.ccsession.parse_command(msg)
+                if cmd == COMMAND_CONFIG_UPDATE:
+                    new_config = arg
                     errors = []
                     if not self._config_handler:
                         answer = create_answer(2, self._module_name + " has no config handler")
                     elif not self.get_module_spec().validate_config(False, new_config, errors):
                         answer = create_answer(1, " ".join(errors))
                     else:
-                        answer = self._config_handler(msg["config_update"])
-                if "command" in msg and self._command_handler:
-                    answer = self._command_handler(msg["command"])
+                        answer = self._config_handler(new_config)
+                else:
+                    answer = self._command_handler(cmd, arg)
             except Exception as exc:
                 answer = create_answer(1, str(exc))
             if answer:
@@ -208,18 +217,22 @@
         answer, env = self._session.group_recvmsg(False)
         
     def __request_config(self):
-        """Asks the configuration manager for the current configuration, and call the config handler if set"""
+        """Asks the configuration manager for the current configuration, and call the config handler if set.
+           Raises a ModuleCCSessionError if there is no answer from the configuration manager"""
         self._session.group_sendmsg({ "command": [ "get_config", { "module_name": self._module_name } ] }, "ConfigManager")
         answer, env = self._session.group_recvmsg(False)
-        rcode, value = parse_answer(answer)
-        if rcode == 0:
-            if value != None and self.get_module_spec().validate_config(False, value):
-                self.set_local_config(value);
-                if self._config_handler:
-                    self._config_handler(value)
+        if answer:
+            rcode, value = parse_answer(answer)
+            if rcode == 0:
+                if value != None and self.get_module_spec().validate_config(False, value):
+                    self.set_local_config(value);
+                    if self._config_handler:
+                        self._config_handler(value)
+            else:
+                # log error
+                print("Error requesting configuration: " + value)
         else:
-            # log error
-            print("Error requesting configuration: " + value)
+            raise ModuleCCSessionError("No answer from configuration manager")
 
 class UIModuleCCSession(MultiConfigData):
     """This class is used in a configuration user interface. It contains

Modified: trunk/src/lib/config/python/isc/config/cfgmgr.py
==============================================================================
--- trunk/src/lib/config/python/isc/config/cfgmgr.py (original)
+++ trunk/src/lib/config/python/isc/config/cfgmgr.py Fri Feb 26 11:21:41 2010
@@ -241,13 +241,15 @@
             conf_part = data.find_no_exc(self.config.data, module_name)
             if conf_part:
                 data.merge(conf_part, cmd[1])
-                self.cc.group_sendmsg({ "config_update": conf_part }, module_name)
+                update_cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, conf_part)
+                self.cc.group_sendmsg(update_cmd, module_name)
                 answer, env = self.cc.group_recvmsg(False)
             else:
                 conf_part = data.set(self.config.data, module_name, {})
                 data.merge(conf_part[module_name], cmd[1])
                 # send out changed info
-                self.cc.group_sendmsg({ "config_update": conf_part[module_name] }, module_name)
+                update_cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, conf_part[module_name])
+                self.cc.group_sendmsg(update_cmd, module_name)
                 # replace 'our' answer with that of the module
                 answer, env = self.cc.group_recvmsg(False)
             if answer:
@@ -263,7 +265,8 @@
             err_list = []
             for module in self.config.data:
                 if module != "version":
-                    self.cc.group_sendmsg({ "config_update": self.config.data[module] }, module)
+                    update_cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, self.config.data[module])
+                    self.cc.group_sendmsg(update_cmd, module)
                     answer, env = self.cc.group_recvmsg(False)
                     if answer == None:
                         got_error = True

Modified: trunk/src/lib/config/python/isc/config/cfgmgr_test.py
==============================================================================
--- trunk/src/lib/config/python/isc/config/cfgmgr_test.py (original)
+++ trunk/src/lib/config/python/isc/config/cfgmgr_test.py Fri Feb 26 11:21:41 2010
@@ -20,6 +20,7 @@
 import unittest
 import os
 from isc.config.cfgmgr import *
+from unittest_fakesession import FakeModuleCCSession
 
 class TestConfigManagerData(unittest.TestCase):
     def setUp(self):
@@ -70,51 +71,6 @@
         self.assertEqual(cfd1, cfd2)
         cfd2.data['test'] = { 'a': [ 1, 2, 3]}
         self.assertNotEqual(cfd1, cfd2)
-        
-#
-# We can probably use a more general version of this
-#
-class FakeModuleCCSession:
-    def __init__(self):
-        self.subscriptions = {}
-        # each entry is of the form [ channel, instance, message ]
-        self.message_queue = []
-
-    def group_subscribe(self, group_name, instance_name = None):
-        if not group_name in self.subscriptions:
-            self.subscriptions[group_name] = []
-        if instance_name:
-            self.subscriptions[group_name].append(instance_name)
-            
-
-    def has_subscription(self, group_name, instance_name = None):
-        if group_name in self.subscriptions:
-            if instance_name:
-                return instance_name in self.subscriptions[group_name]
-            else:
-                return True
-        else:
-            return False
-
-    def group_sendmsg(self, msg, channel, target = None):
-        self.message_queue.append([ channel, target, msg ])
-
-    def group_reply(self, env, msg):
-        pass
-
-    def group_recvmsg(self, blocking):
-        for qm in self.message_queue:
-            if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in self.subscriptions[qm[0]]):
-                self.message_queue.remove(qm)
-                return qm[2], {}
-        return None, None
-
-    def get_message(self, channel, target = None):
-        for qm in self.message_queue:
-            if qm[0] == channel and qm[1] == target:
-                self.message_queue.remove(qm)
-                return qm[2]
-        return None
         
 
 class TestConfigManager(unittest.TestCase):
@@ -257,7 +213,7 @@
                                 my_ok_answer)
         # The cfgmgr should have eaten the ok message, and sent out an update again
         self.assertEqual(len(self.fake_session.message_queue), 1)
-        self.assertEqual({'config_update': {'test': 123}},
+        self.assertEqual({'command': [ 'config_update', {'test': 123}]},
                          self.fake_session.get_message(self.name, None))
         # and the queue should now be empty again
         self.assertEqual(len(self.fake_session.message_queue), 0)
@@ -267,7 +223,7 @@
         self._handle_msg_helper({ "command": [ "set_config", [self.name, { "test": 124 }] ] },
                                 my_ok_answer)
         self.assertEqual(len(self.fake_session.message_queue), 1)
-        self.assertEqual({'config_update': {'test': 124}},
+        self.assertEqual({'command': [ 'config_update', {'test': 124}]},
                          self.fake_session.get_message(self.name, None))
         self.assertEqual(len(self.fake_session.message_queue), 0)
 
@@ -277,7 +233,7 @@
         self._handle_msg_helper({ "command": [ "set_config", [ { self.name: { "test": 125 } }] ] },
                                 my_ok_answer )
         self.assertEqual(len(self.fake_session.message_queue), 1)
-        self.assertEqual({'config_update': {'test': 125}},
+        self.assertEqual({'command': [ 'config_update', {'test': 125}]},
                          self.fake_session.get_message(self.name, None))
         self.assertEqual(len(self.fake_session.message_queue), 0)
 
@@ -286,7 +242,7 @@
                           self.cm.handle_msg,
                           { "command": [ "set_config", [ { self.name: { "test": 125 } }] ] } )
         self.assertEqual(len(self.fake_session.message_queue), 1)
-        self.assertEqual({'config_update': {'test': 125}},
+        self.assertEqual({'command': [ 'config_update', {'test': 125}]},
                          self.fake_session.get_message(self.name, None))
         self.assertEqual(len(self.fake_session.message_queue), 0)
 
@@ -295,7 +251,7 @@
         self._handle_msg_helper({ "command": [ "set_config", [ { self.name: { "test": 125 } }] ] },
                                 my_bad_answer )
         self.assertEqual(len(self.fake_session.message_queue), 1)
-        self.assertEqual({'config_update': {'test': 125}},
+        self.assertEqual({'command': [ 'config_update', {'test': 125}]},
                          self.fake_session.get_message(self.name, None))
         self.assertEqual(len(self.fake_session.message_queue), 0)
 
@@ -304,7 +260,7 @@
         self._handle_msg_helper({ "command": [ "set_config", [ self.name, { "test": 125 }] ] },
                                 my_bad_answer )
         self.assertEqual(len(self.fake_session.message_queue), 1)
-        self.assertEqual({'config_update': {'test': 125}},
+        self.assertEqual({'command': [ 'config_update', {'test': 125}]},
                          self.fake_session.get_message(self.name, None))
         self.assertEqual(len(self.fake_session.message_queue), 0)
 

Modified: trunk/src/lib/config/python/isc/config/config_test.in
==============================================================================
--- trunk/src/lib/config/python/isc/config/config_test.in (original)
+++ trunk/src/lib/config/python/isc/config/config_test.in Fri Feb 26 11:21:41 2010
@@ -16,4 +16,6 @@
 
 ${PYTHON_EXEC} -O ${CONFIG_PATH}/module_spec_test.py $*
 
+${PYTHON_EXEC} -O ${CONFIG_PATH}/ccsession_test.py $*
+
 ${PYTHON_EXEC} -O ${CONFIG_PATH}/cfgmgr_test.py $*




More information about the bind10-changes mailing list