# Copyright 2016 AT&T Corp # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import time import uuid from oslo_log import log as logging from ranger_tempest_plugin.tests.api import base from tempest import config from tempest.common.utils import data_utils from tempest.lib import exceptions CONF = config.CONF LOG = logging.getLogger(__name__) class ImsBaseOrmTest(base.BaseOrmTest): credentials = ['admin', 'primary', 'alt'] @classmethod def setup_clients(cls): super(ImsBaseOrmTest, cls).setup_clients() # service clients cls.client = cls.os_primary.ims_client cls.rms_client = cls.os_primary.rms_client cls.cms_client = cls.os_primary.cms_client # setup variables cls.region_id = CONF.identity.region cls.tenant_id = cls._get_project_id( cls.os_primary.credentials.project_name) cls.alt_tenant_id = cls._get_project_id( cls.os_alt.credentials.project_name) @classmethod def _get_image_params(cls, set_region=True, single_tenant=True, set_shared=True, set_enabled=True): region, post_body = {}, {} post_body["id"] = uuid.uuid4().hex post_body["name"] = data_utils.rand_name( "orm-plugin-TestTempestIms-image") post_body["url"] = CONF.ranger.image_url post_body["disk-format"] = "qcow2" post_body["container-format"] = "bare" region["name"] = CONF.identity.region region["type"] = "single" # set enabled status to True or False based on set_enabled value post_body["enabled"] = bool(set_enabled) # add region for the image as needed post_body["regions"] = [region] if set_region else [] # create image with visibililty = "public" or "shared" post_body["visibility"] = "shared" if set_shared else "public" # set image tags post_body["tags"] = ["tag1", "tag2"] # add tenant for the image only if set_shared if set_shared: if single_tenant: post_body["customers"] = [cls.tenant_id] else: post_body["customers"] = [cls.tenant_id, cls.alt_tenant_id] else: post_body["customers"] = [] return post_body @classmethod def _get_project_id(cls, project_name): body = cls.project_client.list_projects() for project in body["projects"]: if(project["name"] == project_name): return project["id"] message = ('project %s not found on project list' % project_name) raise exceptions.TempestException(message) @classmethod def _create_img_and_validate_creation_on_dcp_and_lcp(cls, **kwargs): _, body = cls.client.create_image(**kwargs) image = body["image"] image_id = image["id"] _, body = cls.client.get_image(image_id) image_detail = body["image"] if image_detail["name"] != kwargs["name"]: message = ('Image %s not created successfully' % kwargs["name"]) raise exceptions.TempestException(message) if image_detail["regions"] != []: cls._wait_for_image_status_on_dcp(image_id, 'Success') return image @classmethod def _wait_for_image_status_on_dcp(cls, image_id, status): _, body = cls.client.get_image(image_id) image_status = body["image"]["status"] start = int(time.time()) while True: time.sleep(cls.build_interval) _, body = cls.client.get_image(image_id) image_status = body["image"]["status"] if image_status == status: break if image_status == 'Error': # Some test cases have multiple regions message = "" for region in body["image"]["regions"]: if "error_message" in region: message += "Region %s Error: %s. " % ( region["name"], region["error_message"]) if not message: message = ('Image %s failed to reach %s status' ' and is in ERROR status' % (image_id, status)) raise exceptions.ServerFault(message) if int(time.time()) - start >= cls.image_build_timeout: message = ('Image %s failed to reach %s' ' status within the required time (%s s)' ' and is in %s status.' % (image_id, status, cls.image_build_timeout, image_status)) raise exceptions.TimeoutException(message) @classmethod def _validate_image_status_on_lcp(cls, image_id, status): _, body = cls.client.list_images()["images"] image_ids = [image["id"] for image in body] if image_id not in image_ids: message = ('Image %s not in image list on LCP' % image_id) raise exceptions.TempestException(message) image_status = cls.client.show_image()["image"]["status"] if image_status != status: message = ('Image %s is in %s status instead of %s on LCP.' % (image_id, image_status, status)) raise exceptions.TempestException(message) @classmethod def _update_img_validate_status_on_dcp_and_lcp(cls, image_id, para=None, **kwargs): if para: cls.client.update_image(image_id, para, **kwargs) else: cls.client.update_image(image_id, **kwargs) cls._wait_for_image_status_on_dcp(image_id, "Success") cls._validate_image_status_on_lcp(image_id, "active") @classmethod def _del_img_validate_deletion_on_dcp_and_lcp(cls, image_id): _, body = cls.client.get_image(image_id) image = body["image"] regions_on_image = [region["name"] for region in image["regions"]] for region in regions_on_image: cls._delete_region_from_image_and_validate_deletion( image_id, region) cls._wait_for_image_status_on_dcp(image_id, "no regions") cls.client.delete_image(image_id) cls._validate_image_deletion_on_lcp(image_id) @classmethod def _delete_region_from_image_and_validate_deletion(cls, image_id, region_id): cls.client.delete_region_from_image(image_id, region_id) start = int(time.time()) while True: time.sleep(cls.build_interval) if int(time.time()) - start >= cls.image_build_timeout: message = ('Image %s failed to be deleted' ' within the required time (%s s)' % (image_id, cls.image_build_timeout)) raise exceptions.TimeoutException(message) not_found = True _, body = cls.client.get_image(image_id) for regions_on_image in body['image']['regions']: if regions_on_image['name'] == region_id: not_found = False if not_found: break @classmethod def _wait_for_image_deletion_on_dcp(cls, image_id): _, body = cls.client.list_images() image_ids = [image["id"] for image in body["images"]] if image_id in image_ids: start = int(time.time()) while image_id in image_ids: time.sleep(cls.build_interval) _, image_list = cls.client.list_images()["images"] image_ids = [image["id"] for image in image_list if image["id"] == image_id] if image_ids: image_status = image_list[0]["status"] _, body = cls.client.list_images()["images"] image_ids = [image["id"] for image in body] if image_id in image_ids: image_status = image_ids[0]["status"] if image_status == 'Error': message = \ ('Image %s failed to get deleted ' 'and is in error status') % image_id raise exceptions.TempestException(message) if int(time.time()) - start >= cls.image_build_timeout: message = ('Image %s failed to get deleted within ' 'the required time (%s s) on orm ' 'and is in %s status.' % (image_id, cls.image_build_timeout, image_status)) raise exceptions.TimeoutException(message) @classmethod def _validate_image_deletion_on_lcp(cls, image_id): _, body = cls.client.list_images() image_ids = [image["id"] for image in body["images"] if image["id"] == image_id] if image_id in image_ids: image_status = body["status"] message = "image %s failed to get deleted and is in %s status" \ % (image_id, image_status) raise exceptions.TempestException(message) @classmethod def _validate_custs_on_img_on_dcp_and_lcp(cls, image_id, expected_customers): expected_customers = sorted(expected_customers) _, actual_customers_orm = sorted( cls.client.get_image(image_id)["customers"]) members = cls.client.member_list(image_id)["members"] actual_customers_lcp =\ sorted([member["member_id"] for member in members]) if actual_customers_orm != expected_customers: message = ( 'Incorrect customers on image on orm.' 'expected customers = %s, actual customers = %s' % (expected_customers, actual_customers_orm)) raise exceptions.TempestException(message) if actual_customers_lcp != expected_customers: message = ( 'Incorrect customers on image on orm.' 'expected customers = %s, actual customers = %s' % (expected_customers, actual_customers_lcp)) raise exceptions.TempestException(message)