Chi Lo 446168b7bd Display Ranger error response messasge in tempest exception
When resource creation failed, the region's error message is
retrieved and included as part of the tempest exception
message.

Change-Id: I6309b29ad516651b9a89ffe54763d11fb56949a4
2020-11-10 07:14:33 -08:00

268 lines
11 KiB
Python
Executable File

# 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)