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._oparser = None
self._namespace = None self._namespace = None
self._mutable_ns = None self._mutable_ns = None
self._mutate_hooks = set([])
self.__cache = {} self.__cache = {}
self._config_opts = [] self._config_opts = []
self._cli_opts = collections.deque() self._cli_opts = collections.deque()
@@ -2214,6 +2215,7 @@ class ConfigOpts(collections.Mapping):
self._oparser = None self._oparser = None
self._namespace = None self._namespace = None
self._mutable_ns = None self._mutable_ns = None
# Keep _mutate_hooks
self._validate_default_values = False self._validate_default_values = False
self.unregister_opts(self._config_opts) self.unregister_opts(self._config_opts)
for group in self._groups.values(): for group in self._groups.values():
@@ -2819,12 +2821,25 @@ class ConfigOpts(collections.Mapping):
self._namespace = namespace self._namespace = namespace
return True 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 @__clear_cache
def mutate_config_files(self): def mutate_config_files(self):
"""Reload configure files and parse all options. """Reload configure files and parse all options.
Only options marked as 'mutable' will appear to change. 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 :raises Error if reloading fails
""" """
@@ -2843,6 +2858,8 @@ class ConfigOpts(collections.Mapping):
groupname = groupname if groupname else 'DEFAULT' groupname = groupname if groupname else 'DEFAULT'
LOG.info("Option %s.%s changed from [%s] to [%s]", LOG.info("Option %s.%s changed from [%s] to [%s]",
groupname, optname, old, new) groupname, optname, old, new)
for hook in self._mutate_hooks:
hook(self, fresh)
return fresh return fresh
def _warn_immutability(self): def _warn_immutability(self):

View File

@@ -1727,6 +1727,37 @@ class ConfigFileMutateTestCase(BaseTestCase):
"Option group.boo changed from [old_boo] to [new_boo]\n") "Option group.boo changed from [old_boo] to [new_boo]\n")
self.assertEqual(expected, self.log_fixture.output) 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): class OptGroupsTestCase(BaseTestCase):