[svn] commit: r3153 - in /trunk: ./ src/bin/cmdctl/ src/bin/xfrin/ src/bin/xfrout/ src/bin/zonemgr/ src/lib/python/isc/config/ src/lib/python/isc/config/tests/
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat Oct 9 11:09:44 UTC 2010
Author: vorner
Date: Sat Oct 9 11:09:43 2010
New Revision: 3153
Log:
Merged trac 349
Modified:
trunk/ (props changed)
trunk/src/bin/cmdctl/cmdctl.py.in
trunk/src/bin/xfrin/xfrin.py.in
trunk/src/bin/xfrout/xfrout.py.in
trunk/src/bin/zonemgr/zonemgr.py.in
trunk/src/lib/python/isc/config/ccsession.py
trunk/src/lib/python/isc/config/tests/ccsession_test.py
trunk/src/lib/python/isc/config/tests/cfgmgr_test.py
trunk/src/lib/python/isc/config/tests/unittest_fakesession.py
Modified: trunk/src/bin/cmdctl/cmdctl.py.in
==============================================================================
--- trunk/src/bin/cmdctl/cmdctl.py.in (original)
+++ trunk/src/bin/cmdctl/cmdctl.py.in Sat Oct 9 11:09:43 2010
@@ -1,6 +1,7 @@
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -323,8 +324,8 @@
def _handle_msg_from_msgq(self):
'''Process all the received commands with module session. '''
while self._serving:
- self._module_cc.check_command()
-
+ self._module_cc.check_command(False)
+
def _parse_command_result(self, rcode, reply):
'''Ignore the error reason when command rcode isn't 0, '''
if rcode != 0:
Modified: trunk/src/bin/xfrin/xfrin.py.in
==============================================================================
--- trunk/src/bin/xfrin/xfrin.py.in (original)
+++ trunk/src/bin/xfrin/xfrin.py.in Sat Oct 9 11:09:43 2010
@@ -1,6 +1,7 @@
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -396,7 +397,7 @@
'''This is a straightforward wrapper for cc.check_command,
but provided as a separate method for the convenience
of unit tests.'''
- self._module_cc.check_command()
+ self._module_cc.check_command(False)
def config_handler(self, new_config):
self._max_transfers_in = new_config.get("transfers_in") or self._max_transfers_in
Modified: trunk/src/bin/xfrout/xfrout.py.in
==============================================================================
--- trunk/src/bin/xfrout/xfrout.py.in (original)
+++ trunk/src/bin/xfrout/xfrout.py.in Sat Oct 9 11:09:43 2010
@@ -1,6 +1,7 @@
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -494,7 +495,7 @@
def run(self):
'''Get and process all commands sent from cfgmgr or other modules. '''
while not self._shutdown_event.is_set():
- self._cc.check_command()
+ self._cc.check_command(False)
xfrout_server = None
Modified: trunk/src/bin/zonemgr/zonemgr.py.in
==============================================================================
--- trunk/src/bin/zonemgr/zonemgr.py.in (original)
+++ trunk/src/bin/zonemgr/zonemgr.py.in Sat Oct 9 11:09:43 2010
@@ -1,6 +1,7 @@
#!@PYTHON@
# Copyright (C) 2010 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -481,7 +482,7 @@
def run(self):
while not self._shutdown_event.is_set():
- self._module_cc.check_command()
+ self._module_cc.check_command(False)
zonemgrd = None
Modified: trunk/src/lib/python/isc/config/ccsession.py
==============================================================================
--- trunk/src/lib/python/isc/config/ccsession.py (original)
+++ trunk/src/lib/python/isc/config/ccsession.py Sat Oct 9 11:09:43 2010
@@ -1,4 +1,5 @@
# Copyright (C) 2009 Internet Systems Consortium.
+# Copyright (C) 2010 CZ NIC
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -169,20 +170,30 @@
time-critical, it is strongly recommended to only use
check_command(), and not look at the socket at all."""
return self._session._socket
-
+
def close(self):
"""Close the session to the command channel"""
self._session.close()
- def check_command(self):
+ 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 non-blocking 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."""
- msg, env = self._session.group_recvmsg(True)
-
+ 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.
+
+ If nonblock is True, it just checks if there's a command
+ and does nothing if there isn't. If nonblock is False, it
+ waits until it arrives. It temporarily sets timeout to infinity,
+ because commands may not come in arbitrary long time."""
+ timeout_orig = self._session.get_timeout()
+ self._session.set_timeout(0)
+ try:
+ msg, env = self._session.group_recvmsg(nonblock)
+ finally:
+ self._session.set_timeout(timeout_orig)
+
# should we default to an answer? success-by-default? unhandled error?
if msg is not None and not 'result' in msg:
answer = None
Modified: trunk/src/lib/python/isc/config/tests/ccsession_test.py
==============================================================================
--- trunk/src/lib/python/isc/config/tests/ccsession_test.py (original)
+++ trunk/src/lib/python/isc/config/tests/ccsession_test.py Sat Oct 9 11:09:43 2010
@@ -23,7 +23,7 @@
import os
from isc.config.ccsession import *
from isc.config.config_data import BIND10_CONFIG_DATA_VERSION
-from unittest_fakesession import FakeModuleCCSession
+from unittest_fakesession import FakeModuleCCSession, WouldBlockForever
class TestHelperFunctions(unittest.TestCase):
def test_parse_answer(self):
@@ -125,6 +125,8 @@
self.assertTrue("Spec1" in fake_session.subscriptions)
self.assertEqual(len(fake_session.message_queue), 0)
+ fake_session.group_sendmsg(None, 'Spec1')
+ fake_session.group_sendmsg(None, 'Spec1')
self.assertRaises(ModuleCCSessionError, mccs.start)
self.assertEqual(len(fake_session.message_queue), 2)
self.assertEqual({'command': ['module_spec', {'module_name': 'Spec1'}]},
@@ -150,6 +152,8 @@
fake_session = FakeModuleCCSession()
mccs = self.create_session("spec2.spec", None, None, fake_session)
self.assertEqual(len(fake_session.message_queue), 0)
+ fake_session.group_sendmsg(None, 'Spec2')
+ fake_session.group_sendmsg(None, 'Spec2')
self.assertRaises(ModuleCCSessionError, mccs.start)
self.assertEqual(len(fake_session.message_queue), 2)
self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -173,6 +177,8 @@
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)
+ fake_session.group_sendmsg(None, 'Spec2')
+ fake_session.group_sendmsg(None, 'Spec2')
self.assertRaises(ModuleCCSessionError, mccs.start)
self.assertEqual(len(fake_session.message_queue), 2)
self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -196,6 +202,8 @@
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)
+ fake_session.group_sendmsg(None, 'Spec2')
+ fake_session.group_sendmsg(None, 'Spec2')
self.assertRaises(ModuleCCSessionError, mccs.start)
self.assertEqual(len(fake_session.message_queue), 2)
self.assertEqual({'command': ['module_spec', mccs.specification._module_spec]},
@@ -327,30 +335,67 @@
self.assertEqual(len(fake_session.message_queue), 1)
self.assertEqual({'result': [2, 'Spec2 has no command handler']},
fake_session.get_message('Spec2', None))
-
- def test_check_command7(self):
- fake_session = FakeModuleCCSession()
- mccs = self.create_session("spec2.spec", None, None, fake_session)
- mccs.set_command_handler(self.my_command_handler_ok)
+
+ """Many check_command tests look too similar, this is common body."""
+ def common_check_command_check(self, cmd_handler,
+ cmd_check=lambda mccs, _: mccs.check_command()):
+ fake_session = FakeModuleCCSession()
+ mccs = self.create_session("spec2.spec", None, None, fake_session)
+ mccs.set_command_handler(cmd_handler)
self.assertEqual(len(fake_session.message_queue), 0)
cmd = isc.config.ccsession.create_command("print_message", "just a message")
fake_session.group_sendmsg(cmd, 'Spec2')
self.assertEqual(len(fake_session.message_queue), 1)
- mccs.check_command()
+ cmd_check(mccs, fake_session)
+ return fake_session
+
+ def test_check_command7(self):
+ fake_session = self.common_check_command_check(
+ self.my_command_handler_ok)
self.assertEqual(len(fake_session.message_queue), 1)
self.assertEqual({'result': [0]},
fake_session.get_message('Spec2', None))
-
+
def test_check_command8(self):
- fake_session = FakeModuleCCSession()
- mccs = self.create_session("spec2.spec", None, None, fake_session)
- mccs.set_command_handler(self.my_command_handler_no_answer)
- self.assertEqual(len(fake_session.message_queue), 0)
- cmd = isc.config.ccsession.create_command("print_message", "just a message")
- fake_session.group_sendmsg(cmd, 'Spec2')
- self.assertEqual(len(fake_session.message_queue), 1)
- mccs.check_command()
- self.assertEqual(len(fake_session.message_queue), 0)
+ fake_session = self.common_check_command_check(
+ self.my_command_handler_no_answer)
+ self.assertEqual(len(fake_session.message_queue), 0)
+
+ def test_check_command_block(self):
+ """See if the message gets there even in blocking mode."""
+ fake_session = self.common_check_command_check(
+ self.my_command_handler_ok,
+ lambda mccs, _: mccs.check_command(False))
+ self.assertEqual(len(fake_session.message_queue), 1)
+ self.assertEqual({'result': [0]},
+ fake_session.get_message('Spec2', None))
+
+ 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):
fake_session = FakeModuleCCSession()
@@ -360,6 +405,7 @@
self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
self.assertFalse("Spec2" in fake_session.subscriptions)
+ fake_session.group_sendmsg(None, 'Spec2')
rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
self.assertTrue("Spec2" in fake_session.subscriptions)
self.assertEqual("Spec2", rmodname)
@@ -373,6 +419,7 @@
self.assertRaises(ModuleCCSessionError, mccs.get_remote_config_value, "Spec2", "item1")
# test if unsubscription is alse sent when object is deleted
+ fake_session.group_sendmsg({'result' : [0]}, 'Spec2')
rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
self.assertTrue("Spec2" in fake_session.subscriptions)
mccs = None
@@ -383,6 +430,7 @@
fake_session = FakeModuleCCSession()
mccs = self.create_session("spec1.spec", None, None, fake_session)
mccs.set_command_handler(self.my_command_handler_ok)
+ fake_session.group_sendmsg(None, 'Spec2')
rmodname = mccs.add_remote_config(self.spec_file("spec2.spec"))
# remove the 'get config' from the queue
Modified: trunk/src/lib/python/isc/config/tests/cfgmgr_test.py
==============================================================================
--- trunk/src/lib/python/isc/config/tests/cfgmgr_test.py (original)
+++ trunk/src/lib/python/isc/config/tests/cfgmgr_test.py Sat Oct 9 11:09:43 2010
@@ -255,6 +255,7 @@
self.fake_session.get_message(self.name, None))
self.assertEqual(len(self.fake_session.message_queue), 0)
+ self.fake_session.group_sendmsg(None, 'ConfigManager')
self._handle_msg_helper({ "command": [ "set_config", [ ] ] },
{'result': [1, 'Wrong number of arguments']} )
self._handle_msg_helper({ "command": [ "set_config", [ self.name, { "test": 125 }] ] },
Modified: trunk/src/lib/python/isc/config/tests/unittest_fakesession.py
==============================================================================
--- trunk/src/lib/python/isc/config/tests/unittest_fakesession.py (original)
+++ trunk/src/lib/python/isc/config/tests/unittest_fakesession.py Sat Oct 9 11:09:43 2010
@@ -16,6 +16,13 @@
# $Id$
import isc
+
+class WouldBlockForever(Exception):
+ """
+ This is thrown by the FakeModuleCCSession if it would need
+ to block forever for incoming message.
+ """
+ pass
#
# We can probably use a more general version of this
@@ -64,13 +71,18 @@
if 'group' in env:
self.message_queue.append([ env['group'], None, msg])
- def group_recvmsg(self, blocking, seq = None):
+ def group_recvmsg(self, nonblock=True, seq = None):
for qm in self.message_queue:
- if qm[0] in self.subscriptions and (qm[1] == None or qm[1] in self.subscriptions[qm[0]]):
+ 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], {'group': qm[0], 'from': qm[1]}
if self._timeout == 0:
- return None, None
+ if nonblock:
+ return None, None
+ else:
+ raise WouldBlockForever(
+ "Blocking read without timeout and no message ready")
else:
raise isc.cc.SessionTimeout("Timeout set but no data to "
"return to group_recvmsg()")
@@ -88,3 +100,6 @@
def set_timeout(self, timeout):
self._timeout = timeout
+
+ def get_timeout(self):
+ return self._timeout
More information about the bind10-changes
mailing list