BIND 10 trac810, updated. 111334856c3beb8cfad23ff60264604746dd1492 [trac810] Call checkers with virtual modules
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Apr 8 13:36:48 UTC 2011
The branch, trac810 has been updated
via 111334856c3beb8cfad23ff60264604746dd1492 (commit)
via 2e11f6cdbae2c29e12bbce2c9d14f1851439155f (commit)
from e7d0dbd6ba745bab334aef6e747056c33f5edaa8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 111334856c3beb8cfad23ff60264604746dd1492
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Fri Apr 8 15:35:00 2011 +0200
[trac810] Call checkers with virtual modules
commit 2e11f6cdbae2c29e12bbce2c9d14f1851439155f
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Fri Apr 8 13:41:39 2011 +0200
[trac810] Functions to add virtual modules
-----------------------------------------------------------------------
Summary of changes:
src/lib/python/isc/config/cfgmgr.py | 45 ++++++++++++++----
src/lib/python/isc/config/tests/cfgmgr_test.py | 61 ++++++++++++++++++++++++
2 files changed, 96 insertions(+), 10 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/python/isc/config/cfgmgr.py b/src/lib/python/isc/config/cfgmgr.py
index 8561378..3b6d278 100644
--- a/src/lib/python/isc/config/cfgmgr.py
+++ b/src/lib/python/isc/config/cfgmgr.py
@@ -170,6 +170,10 @@ class ConfigManager:
self.data_path = data_path
self.database_filename = database_filename
self.module_specs = {}
+ # Virtual modules are the ones which have no process running. The
+ # checking of validity is done by functions presented here instead
+ # of some other process
+ self.virtual_modules = {}
self.config = ConfigManagerData(data_path, database_filename)
if session:
self.cc = session
@@ -187,11 +191,20 @@ class ConfigManager:
"""Adds a ModuleSpec"""
self.module_specs[spec.get_module_name()] = spec
+ def set_virtual_module(self, spec, check_func):
+ """Adds a virtual module with its spec and checking function."""
+ self.module_specs[spec.get_module_name()] = spec
+ self.virtual_modules[spec.get_module_name()] = check_func
+
def remove_module_spec(self, module_name):
"""Removes the full ModuleSpec for the given module_name.
+ Also removes the virtual module check function if it
+ was present.
Does nothing if the module was not present."""
if module_name in self.module_specs:
del self.module_specs[module_name]
+ if module_name in self.virtual_modules:
+ del self.virtual_modules[module_name]
def get_module_spec(self, module_name = None):
"""Returns the full ModuleSpec for the module with the given
@@ -299,24 +312,36 @@ class ConfigManager:
# todo: use api (and check the data against the definition?)
old_data = copy.deepcopy(self.config.data)
conf_part = data.find_no_exc(self.config.data, module_name)
+ update_cmd = None
+ use_part = None
if conf_part:
data.merge(conf_part, cmd)
- update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE,
- conf_part)
- seq = self.cc.group_sendmsg(update_cmd, module_name)
- try:
- answer, env = self.cc.group_recvmsg(False, seq)
- except isc.cc.SessionTimeout:
- answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name)
+ use_part = conf_part
else:
conf_part = data.set(self.config.data, module_name, {})
data.merge(conf_part[module_name], cmd)
+ use_part = conf_part[module_name]
+
+ if module_name in self.virtual_modules:
+ # The module is virtual, so call it to get the answer
+ try:
+ error = self.virtual_modules[module_name](use_part)
+ if error is None:
+ answer = ccsession.create_answer(0)
+ else:
+ answer = ccsession.create_answer(1, error)
+ # Make sure just a validating plugin don't kill the whole manager
+ except Exception as excp:
+ # Provide answer
+ answer = ccsession.create_answer(1, "Exception: " + str(excp))
+ else:
+ # Real module, send it over the wire to it
# send out changed info
- update_cmd = ccsession.create_command(ccsession.COMMAND_CONFIG_UPDATE,
- conf_part[module_name])
+ update_cmd = ccsession.create_command(
+ ccsession.COMMAND_CONFIG_UPDATE, use_part)
seq = self.cc.group_sendmsg(update_cmd, module_name)
- # replace 'our' answer with that of the module
try:
+ # replace 'our' answer with that of the module
answer, env = self.cc.group_recvmsg(False, seq)
except isc.cc.SessionTimeout:
answer = ccsession.create_answer(1, "Timeout waiting for answer from " + module_name)
diff --git a/src/lib/python/isc/config/tests/cfgmgr_test.py b/src/lib/python/isc/config/tests/cfgmgr_test.py
index 9534e14..6d8f3a5 100644
--- a/src/lib/python/isc/config/tests/cfgmgr_test.py
+++ b/src/lib/python/isc/config/tests/cfgmgr_test.py
@@ -135,6 +135,8 @@ class TestConfigManager(unittest.TestCase):
self.assert_(module_spec.get_module_name() not in self.cm.module_specs)
self.cm.set_module_spec(module_spec)
self.assert_(module_spec.get_module_name() in self.cm.module_specs)
+ self.assert_(module_spec.get_module_name() not in
+ self.cm.virtual_modules)
def test_remove_module_spec(self):
module_spec = isc.config.module_spec.module_spec_from_file(self.data_path + os.sep + "spec1.spec")
@@ -143,6 +145,30 @@ class TestConfigManager(unittest.TestCase):
self.assert_(module_spec.get_module_name() in self.cm.module_specs)
self.cm.remove_module_spec(module_spec.get_module_name())
self.assert_(module_spec.get_module_name() not in self.cm.module_specs)
+ self.assert_(module_spec.get_module_name() not in
+ self.cm.virtual_modules)
+
+ def test_add_remove_virtual_module(self):
+ module_spec = isc.config.module_spec.module_spec_from_file(
+ self.data_path + os.sep + "spec1.spec")
+ check_func = lambda: True
+ # Make sure it's not in there before
+ self.assert_(module_spec.get_module_name() not in self.cm.module_specs)
+ self.assert_(module_spec.get_module_name() not in
+ self.cm.virtual_modules)
+ # Add it there
+ self.cm.set_virtual_module(module_spec, check_func)
+ # Check it's in there
+ self.assert_(module_spec.get_module_name() in self.cm.module_specs)
+ self.assertEqual(self.cm.module_specs[module_spec.get_module_name()],
+ module_spec)
+ self.assertEqual(self.cm.virtual_modules[module_spec.get_module_name()],
+ check_func)
+ # Remove it again
+ self.cm.remove_module_spec(module_spec.get_module_name())
+ self.assert_(module_spec.get_module_name() not in self.cm.module_specs)
+ self.assert_(module_spec.get_module_name() not in
+ self.cm.virtual_modules)
def test_get_module_spec(self):
module_spec = isc.config.module_spec.module_spec_from_file(self.data_path + os.sep + "spec1.spec")
@@ -312,6 +338,41 @@ class TestConfigManager(unittest.TestCase):
},
{'result': [0]})
+ def test_set_config_virtual(self):
+ """Test that if the module is virtual, we don't send it over the
+ message bus, but call the checking function.
+ """
+ # We run the same three times, with different return values
+ def single_test(value, returnFunc, expectedResult):
+ # Because closures can't assign to closed-in variables, we pass
+ # it trough self
+ self.called_with = None
+ def check_test(new_data):
+ self.called_with = new_data
+ return returnFunc()
+
+ # Register our virtual module
+ self.cm.set_virtual_module(self.spec, check_test)
+ # The fake session will throw now if it is touched, as there's no
+ # message or answer ready. Handy, we don't need any code about it
+ # to check explicitly.
+ result = self.cm._handle_set_config_module(self.spec.
+ get_module_name(),
+ {'item1': value})
+ # Check the correct result is passed and our function was called
+ # With correct data
+ self.assertEqual(self.called_with['item1'], value)
+ self.assertEqual(result, {'result': expectedResult})
+
+ # Success
+ single_test(5, lambda: None, [0])
+ # Graceful error
+ single_test(6, lambda: "Just error", [1, "Just error"])
+ # Exception from the checker
+ def raiser():
+ raise Exception("Just exception")
+ single_test(7, raiser, [1, "Exception: Just exception"])
+
def test_set_config_all(self):
my_ok_answer = { 'result': [ 0 ] }
More information about the bind10-changes
mailing list