From 8ee154ae611fd35f5cc9446c2c243188be4ced43 Mon Sep 17 00:00:00 2001 From: Caner Derici Date: Thu, 9 Sep 2021 14:24:39 -0600 Subject: [PATCH 1/2] Allow ApplicationFacade set_config with non-string values Fixes #388 --- juju/application.py | 7 ++++++- tests/integration/test_application.py | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/juju/application.py b/juju/application.py index 98ec20202..f1c792c00 100644 --- a/juju/application.py +++ b/juju/application.py @@ -517,7 +517,12 @@ async def set_config(self, config): log.debug( 'Setting config for %s: %s', self.name, config) - return await app_facade.Set(application=self.name, options=config) + str_config = {} + for k, v in config.items(): + if v.get('value') is not None: + str_config[k] = str(v.get('value')) + + await app_facade.Set(application=self.name, options=str_config) async def reset_config(self, to_default): """ diff --git a/tests/integration/test_application.py b/tests/integration/test_application.py index a3a2c1653..2e47b5c23 100644 --- a/tests/integration/test_application.py +++ b/tests/integration/test_application.py @@ -46,6 +46,31 @@ async def test_action(event_loop): assert 'backup' in actions.keys() +@base.bootstrapped +@pytest.mark.asyncio +async def test_get_set_config(event_loop): + async with base.CleanModel() as model: + ubuntu_app = await model.deploy( + 'percona-cluster', + application_name='mysql', + series='xenial', + channel='stable', + config={ + 'tuning-level': 'safest', + }, + constraints={ + 'arch': 'amd64', + 'mem': 256 * MB, + }, + ) + + config = await ubuntu_app.get_config() + await ubuntu_app.set_config(config) + + config2 = await ubuntu_app.get_config() + assert config == config2 + + @base.bootstrapped @pytest.mark.asyncio async def test_status_is_not_unset(event_loop): From 2dc598adbfb93d23279952f17a23a26cf3478459 Mon Sep 17 00:00:00 2001 From: Caner Derici Date: Wed, 15 Sep 2021 16:17:54 -0400 Subject: [PATCH 2/2] manually perform assert_has_calls for some reason assert_has_calls is failing in Python 3.5 when it shouldn't fail, so we manually check if the coroutine actually had those calls, it may be sensible to refactor this back into having assert_has_calls after Python3.5 support is dropped --- tests/unit/test_bundle.py | 64 ++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/tests/unit/test_bundle.py b/tests/unit/test_bundle.py index deb441a08..acaa51c9b 100644 --- a/tests/unit/test_bundle.py +++ b/tests/unit/test_bundle.py @@ -1001,29 +1001,45 @@ async def __call__(self, *args, **kwargs): bundle = await handler._handle_local_charms(bundle, bundle_dir) - model.add_local_resources.assert_has_calls([ - mock.call( - "oci-image-charm", - "charm_uri", - yaml.load(Path("tests/integration/oci-image-charm/metadata.yaml").read_text(), Loader=yaml.FullLoader), - resources={"oci-image": "ubuntu:latest"}, - ), - mock.call( - "oci-image-charm-2", - "charm_uri", - yaml.load(Path("tests/integration/oci-image-charm-no-series/metadata.yaml").read_text(), Loader=yaml.FullLoader), - resources={"oci-image": "ubuntu:latest"}, - ), - mock.call( - "oci-image-charm-3", - "charm_uri", - yaml.load(Path("tests/integration/oci-image-charm-no-series/metadata.yaml").read_text(), Loader=yaml.FullLoader), - resources={"oci-image": "ubuntu:latest"}, - )] + # TODO: for some reason 'assert_has_calls' is failing in + # Python3.5, refactor this with 'assert_has_calls' when + # Python3.5 support is dropped + + m1 = mock.call( + "oci-image-charm", + "charm_uri", + yaml.load(Path("tests/integration/oci-image-charm/metadata.yaml").read_text(), Loader=yaml.FullLoader), + resources={"oci-image": "ubuntu:latest"}, ) - model.add_local_charm_dir.assert_has_calls([ - mock.call(charm_path_1, "focal"), - mock.call(charm_path_2, "focal"), - mock.call(charm_path_2, "focal") - ]) + + m2 = mock.call( + "oci-image-charm-2", + "charm_uri", + yaml.load(Path("tests/integration/oci-image-charm-no-series/metadata.yaml").read_text(), Loader=yaml.FullLoader), + resources={"oci-image": "ubuntu:latest"}, + ) + + m3 = mock.call( + "oci-image-charm-3", + "charm_uri", + yaml.load(Path("tests/integration/oci-image-charm-no-series/metadata.yaml").read_text(), Loader=yaml.FullLoader), + resources={"oci-image": "ubuntu:latest"}, + ) + + m_add_local_resources_calls = model.add_local_resources.mock_calls + assert len(m_add_local_resources_calls) == 3 + assert m1 in m_add_local_resources_calls and \ + m2 in m_add_local_resources_calls and \ + m3 in m_add_local_resources_calls + + mc_1 = mock.call(charm_path_1, "focal") + mc_2 = mock.call(charm_path_2, "focal") + mc_3 = mock.call(charm_path_2, "focal") + + m_add_local_charm_dir_calls = model.add_local_charm_dir.mock_calls + assert len(m_add_local_charm_dir_calls) == 3 + assert mc_1 in m_add_local_charm_dir_calls and \ + mc_2 in m_add_local_charm_dir_calls and \ + mc_3 in m_add_local_charm_dir_calls + assert bundle["applications"]["oci-image-charm"]["resources"]["oci-image"] == "id"