Add functional tests for verifying clean-up

- Verify that quick cleanup is ran in between tests, during
which test-created resources are removed and resources generated
by charm and discover-tempest-config remain in the cloud.
- Verify that extensive cleanup is triggered when keystone
relation breaks, which deletes all resources created during
tempest init phase.
- Verify that resources created by the charm itself (through
keystone relation) are removed and re-generated upon keystone
relation re-join.

Change-Id: I0c9c3e16e581b236f978cd4a816f59956ef563e9
This commit is contained in:
Tianqi Xiao 2024-03-06 01:49:35 +00:00 committed by Samuel Allan
parent 895320264c
commit 8ea5199cc6
No known key found for this signature in database
GPG Key ID: 622F8E99C893BD61

View File

@ -13,8 +13,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from zaza import model
from zaza.openstack.charm_tests import test_utils
from zaza.openstack.utilities import openstack as openstack_utils
logger = logging.getLogger(__name__)
def wait_for_application_state(
@ -41,6 +47,63 @@ class TempestK8sTest(test_utils.BaseCharmTest):
"""Run class setup for running tests."""
super(TempestK8sTest, cls).setUpClass(application_name="tempest")
# Connect to the OpenStack cloud
keystone_session = openstack_utils.get_overcloud_keystone_session()
cls.keystone_client = openstack_utils.get_keystone_session_client(keystone_session)
cls.glance_client = openstack_utils.get_glance_session_client(keystone_session)
cls.neutron_client = openstack_utils.get_neutron_session_client(keystone_session)
def get_tempest_init_resources(self, domain_id):
"""Get the test accounts and associated resources generated by tempest.
Return a dict of resources containing users, projects, and networks created
at tempest init stage.
"""
test_accounts_resources = dict()
test_accounts_resources["projects"] = [
project.name
for project in self.keystone_client.projects.list(domain=domain_id)
if project.name.startswith('tempest-')
]
test_accounts_resources["users"] = [
user.name
for user in self.keystone_client.users.list(domain=domain_id)
if user.name.startswith('tempest-')
]
test_accounts_resources["networks"] = [
network["name"]
for network in self.neutron_client.list_networks()['networks']
if network["name"].startswith('tempest-')
]
return test_accounts_resources
def get_domain_id(self):
"""Get tempest domain id."""
return openstack_utils.get_domain_id(
self.keystone_client,
domain_name="CloudValidation-b82746a08d"
)
def check_charm_created_resources(self, domain_id):
"""Check charm created resources exists."""
self.assertTrue(domain_id)
projects = [
project.name
for project in self.keystone_client.projects.list(domain=domain_id)
if project.name == "CloudValidation-test-project"
]
users = [
user.name
for user in self.keystone_client.users.list(domain=domain_id)
if user.name == "CloudValidation-test-user"
]
self.assertTrue(projects)
self.assertTrue(users)
def test_get_lists(self):
"""Verify that the get-lists action returns list names as expected."""
action = model.run_action_on_leader(self.application_name, "get-lists")
@ -48,9 +111,25 @@ class TempestK8sTest(test_utils.BaseCharmTest):
self.assertIn("readonly-quick", lists)
self.assertIn("refstack-2022.11", lists)
def test_bounce_keystone_relation(self):
"""Test removing and re-adding the keystone relation."""
# verify that the application is blocked when keystone is missing
def test_bounce_keystone_relation_with_extensive_cleanup(self):
"""Test removing and re-adding the keystone relation.
Extensive cleanup should be triggered upon keystone relation break to
remove all resources created by tempest init. Charm-created
resources gets removed and re-created upon keystone relation rejoin.
"""
# Verify the existance of charm-created resources
domain_id = self.get_domain_id()
self.check_charm_created_resources(domain_id)
# Verify the existance of resources created by tempest init
# when keystone relation is joined
test_accounts_resources = self.get_tempest_init_resources(domain_id)
self.assertTrue(test_accounts_resources["projects"])
self.assertTrue(test_accounts_resources["users"])
self.assertTrue(test_accounts_resources["networks"])
# Verify that the application is blocked when keystone is missing
model.remove_relation("tempest", "identity-ops", "keystone")
wait_for_application_state(
model,
@ -65,6 +144,17 @@ class TempestK8sTest(test_utils.BaseCharmTest):
r"^$",
)
# Verify that charm-created resources remain in the cloud
self.assertEqual(domain_id, self.get_domain_id())
self.check_charm_created_resources(domain_id)
# Verify that there are no more resources created by tempest init
# when keystone relation is removed
test_accounts_resources = self.get_tempest_init_resources(domain_id)
self.assertFalse(test_accounts_resources["projects"])
self.assertFalse(test_accounts_resources["users"])
self.assertFalse(test_accounts_resources["networks"])
# And then verify that adding it back
# results in reaching active/idle state again.
# ie. successful tempest init again.
@ -76,3 +166,60 @@ class TempestK8sTest(test_utils.BaseCharmTest):
"active",
r"^$",
)
# Verify that a new domain (with project and user) is created which
# replaces the old one
new_domain_id = self.get_domain_id()
self.assertNotEqual(new_domain_id, domain_id)
self.check_charm_created_resources(new_domain_id)
# Verify that tempest init re-created projects, users and networks when
# keystone relation is re-joined
test_accounts_resources = self.get_tempest_init_resources(new_domain_id)
self.assertTrue(test_accounts_resources["projects"])
self.assertTrue(test_accounts_resources["users"])
self.assertTrue(test_accounts_resources["networks"])
def test_quick_cleanup_in_between_tests(self):
"""Verify that quick cleanup in between tests are behaving correctly.
Test-created resources should be removed. Resources generated by charm and
tempest init remain in the cloud.
"""
# Get the list of images before test is run. Note that until an upstream
# fix [1] lands and releases, we cannot use `tempest-` prefix as the filter.
# Instead, we compare the list of all images before and after a test run.
# [1]: https://review.opendev.org/c/openstack/tempest/+/908358
before_images = [i.name for i in self.glance_client.images.list()]
# Get the resources (domain, projects, users, and networks) generated by
# the charm and tempest init
domain_id = self.get_domain_id()
self.check_charm_created_resources(domain_id)
before_test_accounts_resources = self.get_tempest_init_resources(domain_id)
# Run a test that will create an image in the cloud
action = model.run_action_on_leader(
self.application_name, "validate",
action_params={
"regex": "test_image_web_download_import_with_bad_url",
}
)
logger.info("action.data = %s", action.data)
summary = action.data["results"]["summary"]
# Verify that the test is successfully ran and passed.
# Successul test run means the image resource has been created.
self.assertIn("Ran: 1 tests", summary)
self.assertIn("Passed: 1", summary)
# Verify that the image createby test is removed
after_images = [i.name for i in self.glance_client.images.list()]
self.assertEqual(after_images, before_images)
# Verify that the resources created by charm and tempest init
# (domain, projects, users, and networks) remain intact.
self.assertEqual(domain_id, self.get_domain_id())
self.check_charm_created_resources(domain_id)
after_test_accounts_resources = self.get_tempest_init_resources(domain_id)
self.assertEqual(after_test_accounts_resources, before_test_accounts_resources)