diff --git a/charms_openstack/charm/core.py b/charms_openstack/charm/core.py index c12b911..74237e4 100644 --- a/charms_openstack/charm/core.py +++ b/charms_openstack/charm/core.py @@ -16,6 +16,7 @@ import charmhelpers.core.templating import charmhelpers.core.unitdata as unitdata import charmhelpers.fetch as fetch import charms.reactive as reactive +import charms.reactive.flags as flags import charms.reactive.relations as relations import charms_openstack.adapters as os_adapters @@ -735,15 +736,6 @@ class BaseOpenStackCharmActions(object): """Render the configuration files identified in the list passed as configs. - If adapters_instance is None then the self.adapters_instance is used - that was setup in the __init__() method. Note, if no interfaces were - passed (the default) then there will be no interfaces. - - TODO: need to work out how to make this function more useful - at the - moment, with a default setup, this function is only useful to - render_with_interfaces() which constructs a new adapters_instance - anyway. - Configs may not only be loaded via OpenStack loaders but also via string templates passed via config options or from relation data. This must be explicitly declared via string_templates dict of a given @@ -755,7 +747,16 @@ class BaseOpenStackCharmActions(object): :param adapters_instance: [optional] the adapters_instance to use. """ if adapters_instance is None: - adapters_instance = self.adapters_instance + interfaces = [] + for f in flags.get_flags(): + ep_from_f = relations.endpoint_from_flag(f) + if ep_from_f: + interfaces.append(ep_from_f) + try: + adapters_instance = self.adapters_class(interfaces, + charm_instance=self) + except TypeError: + adapters_instance = self.adapters_class(interfaces) with self.restart_on_change(): for conf in configs: diff --git a/unit_tests/charms_openstack/charm/test_core.py b/unit_tests/charms_openstack/charm/test_core.py index 4d61134..43c22d3 100644 --- a/unit_tests/charms_openstack/charm/test_core.py +++ b/unit_tests/charms_openstack/charm/test_core.py @@ -465,8 +465,49 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): self.patch_object(chm_core.os_templating, 'get_loader', return_value='my-loader') - # self.patch_target('adapter_instance', new='my-adapter') - self.target.render_configs(['path1']) + self.target.render_configs( + ['path1'], + adapters_instance=self.target.adapters_instance) + self.assertEqual(d[0], 1) + self.render.assert_called_once_with( + source='path1', + template_loader='my-loader', + target='path1', + context=mock.ANY, + config_template=None, + group='root', + perms=0o640, + ) + # assert the context was an MyAdapter instance. + context = self.render.call_args_list[0][1]['context'] + assert isinstance(context, MyAdapter) + self.assertEqual(context.interfaces, ['interface1', 'interface2']) + + def test_render_configs_construct_adapters_instance(self): + # give us a way to check that the context manager was called. + from contextlib import contextmanager + d = [0] + + @contextmanager + def fake_restart_on_change(): + d[0] += 1 + yield + + self.patch_target('restart_on_change', new=fake_restart_on_change) + self.patch_object(chm_core.charmhelpers.core.templating, 'render') + self.patch_object(chm_core.os_templating, + 'get_loader', + return_value='my-loader') + self.patch_object( + chm_core.flags, + 'get_flags', + return_value=['interface1.available', 'interface2.ready']) + self.patch_object( + chm_core.relations, + 'endpoint_from_flag', + side_effect=lambda x: x.split('.')[0]) + self.target.render_configs( + ['path1']) self.assertEqual(d[0], 1) self.render.assert_called_once_with( source='path1', @@ -505,7 +546,9 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): adapters_instance.options = mock.MagicMock() adapters_instance.options.t_prop = config_template - self.target.render_configs(['path1']) + self.target.render_configs( + ['path1'], + adapters_instance=self.target.adapters_instance) self.assertEqual(d[0], 1) self.render.assert_called_once_with( source='path1', @@ -534,7 +577,10 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): os_adapters.ConfigurationAdapter ) - self.assertRaises(RuntimeError, self.target.render_configs, ['path1']) + self.assertRaises( + RuntimeError, + self.target.render_configs, ['path1'], + adapters_instance=self.target.adapters_instance) def test_render_config_from_string_no_relation(self): """ @@ -554,7 +600,9 @@ class TestMyOpenStackCharm(BaseOpenStackCharmTest): adapters_instance = self.target.adapters_instance - self.target.render_configs(['path1']) + self.target.render_configs( + ['path1'], + adapters_instance=adapters_instance) m.assert_called_once_with('path1', adapters_instance) self.render.assert_not_called()