diff --git a/zaza/openstack/charm_tests/rabbitmq_server/tests.py b/zaza/openstack/charm_tests/rabbitmq_server/tests.py index 027ef95..9185cb7 100644 --- a/zaza/openstack/charm_tests/rabbitmq_server/tests.py +++ b/zaza/openstack/charm_tests/rabbitmq_server/tests.py @@ -39,7 +39,7 @@ class RmqTests(test_utils.OpenStackBaseTest): @classmethod def setUpClass(cls): """Run class setup for running tests.""" - super(RmqTests, cls).setUpClass() + super().setUpClass(application_name='rabbitmq-server') def _get_uuid_epoch_stamp(self): """Return a string based on uuid4 and epoch time. @@ -462,6 +462,63 @@ class RmqTests(test_utils.OpenStackBaseTest): logging.info('OK') + def test_policies(self): + """Test config policies.""" + app_config = zaza.model.get_application_config(self.application_name) + policies_config = json.loads( + app_config.get('policies') + .get('default') + .replace("\n", "") + .replace(" ", "") + ) + + # check policies implemented in the clusterer match with config + self._check_policies(policies_config) + + # add a new policy + new_policy = { + 'vhost': '/', + 'name': 'test', + 'pattern': 'foo', + 'type': 'ttl' + } + policies_config_changed = policies_config + [new_policy] + zaza.model.set_application_config( + 'rabbitmq-server', + {'policies': json.dumps(policies_config_changed)} + ) + zaza.model.block_until_all_units_idle() + + # check again after adding a new policy + self._check_policies(policies_config_changed) + + # NOTE(gabrielcocenza) Policies may take a little time + # to show up in RabbitMQ cluster + @tenacity.retry( + wait=tenacity.wait_exponential(max=60), + stop=tenacity.stop_after_attempt(8) + ) + def _check_policies(self, policies_config): + """Compare cluster policies with the juju config. + + :param policies_config: Policies from juju config + :type policies_config: List[Dict[str, str]] + """ + units = zaza.model.get_units(self.application_name) + policies_cluster = rmq_utils.list_policies(units[0]) + vhosts = set() + for policy in policies_cluster: + vhosts.add(policy['vhost']) + + n_policies = 0 + for policy in policies_config: + if policy['vhost'] == '*': + n_policies += len(vhosts) + else: + n_policies += 1 + + self.assertEqual(len(policies_cluster), n_policies) + class RabbitMQDeferredRestartTest(test_utils.BaseDeferredRestartTest): """Deferred restart tests.""" diff --git a/zaza/openstack/charm_tests/rabbitmq_server/utils.py b/zaza/openstack/charm_tests/rabbitmq_server/utils.py index a0ced05..3a01c26 100644 --- a/zaza/openstack/charm_tests/rabbitmq_server/utils.py +++ b/zaza/openstack/charm_tests/rabbitmq_server/utils.py @@ -24,6 +24,8 @@ import zaza.model import ssl as libssl import zaza.openstack.utilities.generic as generic_utils +from collections import OrderedDict + class RmqNoMessageException(Exception): """Message retrieval from Rmq resulted in no message.""" @@ -55,6 +57,59 @@ def wait_for_cluster(model_name=None, timeout=1200): timeout=timeout) +def list_vhosts(unit): + """Return a list of all the available vhosts. + + :returns: List of vhosts + :rtype: List[str] + """ + if is_rabbitmq_version_ge_382(unit): + cmd = 'rabbitmqctl list_vhosts --formatter=json' + cmd_result = zaza.model.run_on_unit(unit.entity_id, cmd) + output = json.loads(cmd_result['Stdout'].strip()) + return [ll['name'] for ll in output] + + else: + cmd = 'rabbitmqctl list_vhosts' + cmd_result = zaza.model.run_on_unit(unit.entity_id, cmd) + output = cmd_result['Stdout'].strip() + if '...done' in output: + return output.split('\n')[1:-2] + + return output.split('\n')[1:-1] + + +def list_policies(unit): + """Return a list of all the available policies. + + :returns: List of policies + :rtype: List[Dict[str, str]] or List[OrderedDict[str, str]] + """ + policies = [] + vhosts = list_vhosts(unit) + if is_rabbitmq_version_ge_382(unit): + for vhost in vhosts: + cmd = 'rabbitmqctl list_policies -p {} --formatter=json'.format( + vhost + ) + cmd_result = zaza.model.run_on_unit(unit.entity_id, cmd) + output = json.loads(cmd_result['Stdout'].strip()) + for policy in output: + policy["apply_to"] = policy.pop("apply-to") + policies = policies + [policy] + else: + for vhost in vhosts: + cmd = 'rabbitmqctl list_policies -p {}'.format(vhost) + cmd_result = zaza.model.run_on_unit(unit.entity_id, cmd) + output = cmd_result['Stdout'].strip() + keys = "vhost name apply_to pattern definition priority".split() + policies = policies + [ + OrderedDict(zip(keys, line.split("\t"))) + for line in output.splitlines()[1:] + ] + return policies + + def add_user(units, username="testuser1", password="changeme"): """Add a user to a RabbitMQ cluster.