Browse Source

Merged trac292

git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@3358 e5f2f494-b856-4b98-b285-d166d9295462
Kazunori Fujiwara 14 years ago
parent
commit
56a0159357

+ 14 - 8
src/lib/python/isc/config/ccsession.py

@@ -176,13 +176,12 @@ class ModuleCCSession(ConfigData):
         self._session.close()
         self._session.close()
 
 
     def check_command(self, nonblock=True):
     def check_command(self, nonblock=True):
-        """Check whether there is a command or configuration update
-           on the channel. Call the corresponding callback function if
-           there is. This function does a read on the cc session, and
-           returns nothing. It will respond to any command by either
-           an error or the answer message returned by the callback,
-           unless the latter is None.
-
+        """Check whether there is a command or configuration update on
+           the channel. This function does a read on the cc session, and
+           returns nothing.
+           It calls check_command_without_recvmsg()
+           to parse the received message.
+           
            If nonblock is True, it just checks if there's a command
            If nonblock is True, it just checks if there's a command
            and does nothing if there isn't. If nonblock is False, it
            and does nothing if there isn't. If nonblock is False, it
            waits until it arrives. It temporarily sets timeout to infinity,
            waits until it arrives. It temporarily sets timeout to infinity,
@@ -193,7 +192,13 @@ class ModuleCCSession(ConfigData):
             msg, env = self._session.group_recvmsg(nonblock)
             msg, env = self._session.group_recvmsg(nonblock)
         finally:
         finally:
             self._session.set_timeout(timeout_orig)
             self._session.set_timeout(timeout_orig)
+        self.check_command_without_recvmsg(msg, env)
 
 
+    def check_command_without_recvmsg(self, msg, env):
+        """Parse the given message to see if there is a command or a
+           configuration update. Calls the corresponding handler
+           functions if present. Responds on the channel if the
+           handler returns a message.""" 
         # should we default to an answer? success-by-default? unhandled error?
         # should we default to an answer? success-by-default? unhandled error?
         if msg is not None and not 'result' in msg:
         if msg is not None and not 'result' in msg:
             answer = None
             answer = None
@@ -211,7 +216,8 @@ class ModuleCCSession(ConfigData):
                             newc = self._remote_module_configs[module_name].get_local_config()
                             newc = self._remote_module_configs[module_name].get_local_config()
                             isc.cc.data.merge(newc, new_config)
                             isc.cc.data.merge(newc, new_config)
                             self._remote_module_configs[module_name].set_local_config(newc)
                             self._remote_module_configs[module_name].set_local_config(newc)
-                            return
+                        # For other modules, we're not supposed to answer
+                        return
 
 
                     # ok, so apparently this update is for us.
                     # ok, so apparently this update is for us.
                     errors = []
                     errors = []

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

@@ -397,6 +397,112 @@ class TestModuleCCSession(unittest.TestCase):
         mccs.set_command_handler(self.my_command_handler_ok)
         mccs.set_command_handler(self.my_command_handler_ok)
         self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
         self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
 
 
+    def test_check_command_without_recvmsg1(self):
+        "copied from test_check_command2"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec1.spec", None, None, fake_session)
+        mccs.set_config_handler(self.my_config_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+        cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec1': 'abcd' })
+        env = { 'group': 'Spec1', 'from':None };
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [1, 'No config_data specification']},
+                         fake_session.get_message('Spec1', None))
+ 
+    def test_check_command_without_recvmsg2(self):
+        "copied from test_check_command3"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_config_handler(self.my_config_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+        cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 2 }})
+        self.assertEqual(len(fake_session.message_queue), 0)
+        env = { 'group':'Spec2', 'from':None }
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [0]},
+                          fake_session.get_message('Spec2', None))
+ 
+    def test_check_command_without_recvmsg3(self):
+        "copied from test_check_command7"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(self.my_command_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+        cmd = isc.config.ccsession.create_command("print_message", "just a message")
+        env = { 'group':'Spec2', 'from':None }
+        self.assertEqual(len(fake_session.message_queue), 0)
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual({'result': [0]},
+                         fake_session.get_message('Spec2', None))
+ 
+    def test_check_command_without_recvmsg_remote_module(self):
+        "copied from test_check_command3"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec1.spec", None, None, fake_session)
+        mccs.set_config_handler(self.my_config_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+        fake_session.group_sendmsg(None, 'Spec2')
+        rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+        print(fake_session.message_queue)
+        self.assertEqual({'command': ['get_config', {'module_name': 'Spec2'}]},
+                         fake_session.get_message('ConfigManager', None))
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+        cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec2': { 'item1': 2 }})
+        env = { 'group':'Spec2', 'from':None }
+        self.assertEqual(len(fake_session.message_queue), 0)
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual(len(fake_session.message_queue), 0)
+ 
+    def test_check_command_without_recvmsg_remote_module2(self):
+        "copied from test_check_command3"
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec1.spec", None, None, fake_session)
+        mccs.set_config_handler(self.my_config_handler_ok)
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+        fake_session.group_sendmsg(None, 'Spec2')
+        rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
+        self.assertEqual({'command': ['get_config', {'module_name': 'Spec2'}]},
+                         fake_session.get_message('ConfigManager', None))
+        self.assertEqual(len(fake_session.message_queue), 0)
+
+        cmd = isc.config.ccsession.create_command(isc.config.ccsession.COMMAND_CONFIG_UPDATE, { 'Spec3': { 'item1': 2 }})
+        env = { 'group':'Spec3', 'from':None }
+        self.assertEqual(len(fake_session.message_queue), 0)
+        mccs.check_command_without_recvmsg(cmd, env)
+        self.assertEqual(len(fake_session.message_queue), 0)
+ 
+    def test_check_command_block_timeout(self):
+        """Check it works if session has timeout and it sets it back."""
+        def cmd_check(mccs, session):
+            session.set_timeout(1)
+            mccs.check_command(False)
+        fake_session = self.common_check_command_check(
+            self.my_command_handler_ok, cmd_check)
+        self.assertEqual(len(fake_session.message_queue), 1)
+        self.assertEqual({'result': [0]},
+                         fake_session.get_message('Spec2', None))
+        self.assertEqual(fake_session.get_timeout(), 1)
+
+    def test_check_command_blocks_forever(self):
+        """Check it would wait forever checking a command."""
+        fake_session = FakeModuleCCSession()
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(self.my_command_handler_ok)
+        self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
+
+    def test_check_command_blocks_forever_timeout(self):
+        """Like above, but it should wait forever even with timeout here."""
+        fake_session = FakeModuleCCSession()
+        fake_session.set_timeout(1)
+        mccs = self.create_session("spec2.spec", None, None, fake_session)
+        mccs.set_command_handler(self.my_command_handler_ok)
+        self.assertRaises(WouldBlockForever, lambda: mccs.check_command(False))
+
     def test_remote_module(self):
     def test_remote_module(self):
         fake_session = FakeModuleCCSession()
         fake_session = FakeModuleCCSession()
         mccs = self.create_session("spec1.spec", None, None, fake_session)
         mccs = self.create_session("spec1.spec", None, None, fake_session)