Merge "Hooks around mutate_config_files"

This commit is contained in:
Jenkins
2016-02-19 22:28:40 +00:00
committed by Gerrit Code Review
2 changed files with 48 additions and 0 deletions

View File

@@ -2042,6 +2042,7 @@ class ConfigOpts(collections.Mapping):
self._oparser = None
self._namespace = None
self._mutable_ns = None
self._mutate_hooks = set([])
self.__cache = {}
self._config_opts = []
self._cli_opts = collections.deque()
@@ -2214,6 +2215,7 @@ class ConfigOpts(collections.Mapping):
self._oparser = None
self._namespace = None
self._mutable_ns = None
# Keep _mutate_hooks
self._validate_default_values = False
self.unregister_opts(self._config_opts)
for group in self._groups.values():
@@ -2819,12 +2821,25 @@ class ConfigOpts(collections.Mapping):
self._namespace = namespace
return True
def register_mutate_hook(self, hook):
"""Registers a hook to be called by mutate_config_files.
:param hook: a function accepting this ConfigOpts object and a dict of
config mutations, as returned by mutate_config_files.
:return None
"""
self._mutate_hooks.add(hook)
@__clear_cache
def mutate_config_files(self):
"""Reload configure files and parse all options.
Only options marked as 'mutable' will appear to change.
Hooks are called in a NON-DETERMINISTIC ORDER. Do not expect hooks to
be called in the same order as they were added.
:return {(None or 'group', 'optname'): (old_value, new_value), ... }
:raises Error if reloading fails
"""
@@ -2843,6 +2858,8 @@ class ConfigOpts(collections.Mapping):
groupname = groupname if groupname else 'DEFAULT'
LOG.info("Option %s.%s changed from [%s] to [%s]",
groupname, optname, old, new)
for hook in self._mutate_hooks:
hook(self, fresh)
return fresh
def _warn_immutability(self):

View File

@@ -1727,6 +1727,37 @@ class ConfigFileMutateTestCase(BaseTestCase):
"Option group.boo changed from [old_boo] to [new_boo]\n")
self.assertEqual(expected, self.log_fixture.output)
def test_hooks(self):
fresh = {}
result = [0]
def foo(conf, foo_fresh):
self.assertEqual(self.conf, conf)
self.assertEqual(fresh, foo_fresh)
result[0] += 1
self.conf.register_mutate_hook(foo)
self.conf.register_mutate_hook(foo)
self._test_conf_files_mutate()
self.assertEqual(1, result[0])
def test_clear(self):
"""Show that #clear doesn't undeclare opts.
This justifies not clearing mutate_hooks either. ResetAndClearTestCase
shows that values are cleared.
"""
self.conf.register_cli_opt(cfg.StrOpt('cli'))
self.conf.register_opt(cfg.StrOpt('foo'))
dests = [info['opt'].dest for info, _ in self.conf._all_opt_infos()]
self.assertIn('cli', dests)
self.assertIn('foo', dests)
self.conf.clear()
dests = [info['opt'].dest for info, _ in self.conf._all_opt_infos()]
self.assertIn('cli', dests)
self.assertIn('foo', dests)
class OptGroupsTestCase(BaseTestCase):