From f61ccd44f8bb3aba15fdc388d9781d8dd08947d2 Mon Sep 17 00:00:00 2001 From: Luciano Lo Giudice Date: Tue, 2 Jan 2024 19:26:28 -0300 Subject: [PATCH] Make Ceph tests self-contained. This PR implements the needed changes so that the Ceph charms can be run without a full Openstack environment. In particular, the RBD mirror charm needed tweaking so as to not depend on Cinder, using pools of its own creating. --- .../charm_tests/ceph/rbd_mirror/tests.py | 43 ++++++++++++++++--- zaza/openstack/charm_tests/ceph/tests.py | 4 ++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/zaza/openstack/charm_tests/ceph/rbd_mirror/tests.py b/zaza/openstack/charm_tests/ceph/rbd_mirror/tests.py index 7cf1b5b..132d976 100644 --- a/zaza/openstack/charm_tests/ceph/rbd_mirror/tests.py +++ b/zaza/openstack/charm_tests/ceph/rbd_mirror/tests.py @@ -17,6 +17,7 @@ import json import logging import re import time +import unittest import cinderclient.exceptions as cinder_exceptions @@ -154,7 +155,23 @@ def create_cinder_volume(cinder, name='zaza', image_id=None, type_id=None): return create_volume(cinder, volume_params) -class CephRBDMirrorBase(test_utils.OpenStackBaseTest): +def setup_rbd_mirror(): + """Setup an RBD pool in case Cinder isn't present.""" + zaza.model.run_action_on_leader( + 'ceph-mon', + 'create-pool', + action_params={ + 'name': 'zaza-boot', + 'app-name': 'rbd', + }) + zaza.model.run_action_on_leader( + 'ceph-rbd-mirror', + 'refresh-pools', + action_params={} + ) + + +class CephRBDMirrorBase(test_utils.BaseCharmTest): """Base class for ``ceph-rbd-mirror`` tests.""" @classmethod @@ -166,6 +183,17 @@ class CephRBDMirrorBase(test_utils.OpenStackBaseTest): # get ready for multi-model Zaza cls.site_a_model = cls.site_b_model = zaza.model.get_juju_model() cls.site_b_app_suffix = '-b' + # Test if we have the needed Openstack applications. + try: + zaza.model.get_application(cls.cinder_ceph_app_name) + cls.with_cinder = True + except Exception: + cls.with_cinder = False + + def check_cinder_present(self, caller): + if not self.with_cinder: + raise unittest.SkipTest('Skipping %s due to lack of Cinder' + % caller) def run_status_action(self, application_name=None, model_name=None, pools=[]): @@ -215,7 +243,8 @@ class CephRBDMirrorBase(test_utils.OpenStackBaseTest): :rtype: Tuple[List[str], List[str]] """ site_a_pools, site_b_pools = self.get_pools() - if get_cinder_rbd_mirroring_mode(self.cinder_ceph_app_name) == 'image': + if (self.with_cinder and + get_cinder_rbd_mirroring_mode(self.cinder_ceph_app_name) == 'image'): site_a_pools.remove(self.cinder_ceph_app_name) site_b_pools.remove(self.cinder_ceph_app_name) @@ -393,6 +422,7 @@ class CephRBDMirrorTest(CephRBDMirrorBase): site B and subsequently comparing the contents we get a full end to end test. """ + self.check_cinder_present('test_cinder_volume_mirrored') volume = self.setup_test_cinder_volume() site_a_hash = zaza.openstack.utilities.ceph.get_rbd_hash( zaza.model.get_lead_unit_name('ceph-mon', @@ -534,6 +564,7 @@ class CephRBDMirrorControlledFailoverTest(CephRBDMirrorBase): This test only makes sense if Cinder RBD mirroring mode is 'image'. It will return early, if this is not the case. """ + self.check_cinder_present('test_100_cinder_failover') cinder_rbd_mirroring_mode = get_cinder_rbd_mirroring_mode( self.cinder_ceph_app_name) if cinder_rbd_mirroring_mode != 'image': @@ -583,6 +614,7 @@ class CephRBDMirrorControlledFailoverTest(CephRBDMirrorBase): The test needs to be executed when the Cinder volume host is already failed-over with the test volume on it. """ + self.check_cinder_present('test_101_cinder_failback') cinder_rbd_mirroring_mode = get_cinder_rbd_mirroring_mode( self.cinder_ceph_app_name) if cinder_rbd_mirroring_mode != 'image': @@ -766,9 +798,9 @@ class CephRBDMirrorDisasterFailoverTest(CephRBDMirrorBase): }) self.assertEqual(int(result.results['Code']), 0) - # The site-b 'promote' Juju action is expected to fail, because the - # primary site is down. - self.assertEqual(result.status, 'failed') + # The action may not show up as 'failed' if there are no pools that needed + # to be promoted. + # self.assertEqual(result.status, 'failed') # Retry to promote site-b using the 'force' Juju action parameter. result = zaza.model.run_action_on_leader( @@ -792,6 +824,7 @@ class CephRBDMirrorDisasterFailoverTest(CephRBDMirrorBase): This assumes that the primary site is already killed. """ + self.check_cinder_present('test_200_forced_cinder_failover') cinder_rbd_mirroring_mode = get_cinder_rbd_mirroring_mode( self.cinder_ceph_app_name) if cinder_rbd_mirroring_mode != 'image': diff --git a/zaza/openstack/charm_tests/ceph/tests.py b/zaza/openstack/charm_tests/ceph/tests.py index fa8e898..aa4b7a4 100644 --- a/zaza/openstack/charm_tests/ceph/tests.py +++ b/zaza/openstack/charm_tests/ceph/tests.py @@ -1221,6 +1221,10 @@ class CephProxyTest(unittest.TestCase): def test_cinder_ceph_restrict_pool_setup(self): """Make sure cinder-ceph restrict pool was created successfully.""" + try: + zaza_model.get_application('cinder-ceph') + except KeyError: + raise unittest.SkipTest("Skipping OpenStack dependent test") logging.info('Wait for idle/ready status...') zaza_model.wait_for_application_states( states=self.target_deploy_status)