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

363 lines
14 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 random
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 CmsBaseOrmTest(base.BaseOrmTest):
credentials = ['admin', 'primary', 'alt']
@classmethod
def resource_setup(cls):
super(CmsBaseOrmTest, cls).resource_setup()
cls.setup_customer = cls._get_customer_params()
cls.setup_customer['uuid'] = uuid.uuid4().hex
cls.setup_customer_id = \
cls._create_cust_validate_creation_on_dcp_and_lcp(
cleanup=True, **cls.setup_customer)
cls.bare_customer = cls._get_bare_customer_params()
cls.bare_customer['uuid'] = uuid.uuid4().hex
cls.bare_customer_id = \
cls._create_cust_validate_creation_on_dcp_and_lcp(
cleanup=True, **cls.bare_customer)
@classmethod
def setup_clients(cls):
super(CmsBaseOrmTest, cls).setup_clients()
cls.client = cls.os_primary.cms_client
cls.rms_client = cls.os_primary.rms_client
@classmethod
def _get_quota(cls):
compute, storage, network, quota = {}, {}, {}, {}
compute["instances"] = "10"
compute["key-pairs"] = "10"
compute["ram"] = "10"
compute["vcpus"] = "36"
compute["metadata-items"] = "34"
storage["gigabytes"] = "10"
storage["snapshots"] = "10"
storage["volumes"] = "10"
network["floating-ips"] = "10"
network["networks"] = "10"
network["ports"] = "10"
network["routers"] = "10"
network["subnets"] = "10"
network["security-group-rules"] = "51"
network["security-groups"] = "50"
quota['compute'] = [compute]
quota['storage'] = [storage]
quota['network'] = [network]
return quota
@classmethod
def _get_additional_quota_for_cust(cls):
quota = cls._get_quota()
quota["compute"][0]["floating-ips"] = "10"
quota["compute"][0]["fixed-ips"] = "10"
quota["compute"][0]["server-groups"] = "10"
quota["compute"][0]["server-group-members"] = "34"
quota["network"][0]["health-monitor"] = "10"
quota["network"][0]["member"] = "10"
quota["network"][0]["nat-instance"] = "10"
quota["network"][0]["pool"] = "10"
quota["network"][0]["route-table"] = "10"
quota["network"][0]["vip"] = "10"
return quota
@classmethod
def _get_customer_params(cls, quota=None, enabled=True, region_users=True,
default_users=True):
region, user, metadata, customer = {}, {}, {}, {}
cust_name = data_utils.rand_name('ormTempestCms')
if not quota:
quota = cls._get_quota()
region['name'] = CONF.identity.region
region['type'] = 'single'
region['quotas'] = [quota]
user['id'] = cls.os_primary.credentials.username
user['role'] = ["admin"]
region["users"] = [user] if region_users else []
regions = [region]
metadata['my_server_name'] = cust_name
metadata['ocx_cust'] = str(random.randint(0, 999999999))
customer["description"] = cust_name
customer["enabled"] = bool(enabled)
customer["name"] = cust_name
customer['metadata'] = metadata
customer["regions"] = regions
customer["defaultQuotas"] = [quota]
customer['users'] = [user] if default_users else []
customer["customerDomain"] = CONF.auth.admin_domain_name
return customer
@classmethod
def _get_bare_customer_params(cls):
customer = {}
customer['description'] = ''
customer['enabled'] = True
customer['name'] = data_utils.rand_name('ormTempestCms')
customer['regions'] = []
customer['defaultQuotas'] = []
customer['users'] = []
customer["customerDomain"] = CONF.auth.admin_domain_name
return customer
@classmethod
def _get_user_params(cls, alt=False):
users = []
if not alt:
users.append({'id': cls.os_primary.credentials.username,
'role': ['admin']})
else:
users.append({'id': cls.os_alt.credentials.username,
'role': ['admin_viewer', 'admin_support']})
return users
@classmethod
def _get_region_params(cls):
quota = cls._get_quota()
region = {}
region['name'] = CONF.identity.region
region['type'] = 'single'
region['quotas'] = [quota]
return [region]
@classmethod
def _create_cust_validate_creation_on_dcp_and_lcp(cls, cleanup, **kwargs):
"""Creates a customer record
kwargs contains field data needed for customer POST body:
- name
- description
- enabled
- metadata
- regions
- defaultQuotas
- ephemeral
- regions
- visibility
- tenants
"""
_, body = cls.client.create_customer(**kwargs)
customer_id = body["customer"]["id"]
if cleanup:
cls.addClassResourceCleanup(
cls._del_cust_validate_deletion_on_dcp_and_lcp,
customer_id)
_, customer = cls.client.get_customer(customer_id)
if customer["name"] != kwargs["name"]:
message = "Customer %s creation FAILED" % kwargs["name"]
exceptions.TempestException(message)
if customer["regions"] != []:
cls._wait_for_status(customer_id, "Success")
return customer_id
@classmethod
def _wait_for_status(cls, customer_id, status):
_, customer = cls.client.get_customer(customer_id)
customer_status = customer["status"]
start = int(time.time())
while customer_status != status:
time.sleep(cls.build_interval)
_, customer = cls.client.get_customer(customer_id)
customer_status = customer["status"]
if customer_status == 'Error':
# Some test cases have multiple regions
message = ""
for region in customer["regions"]:
if "error_message" in region:
message += "Region %s Error: %s. " % (
region["name"], region["error_message"])
if not message:
message = ('Customer %s failed to reach %s status and is'
' in ERROR status' % (customer_id, status))
raise exceptions.ServerFault(message)
if int(time.time()) - start >= cls.build_timeout:
message = ('Customer %s failed to reach %s'
'status within the required time (%s s)'
'and is in %s status.'
% (customer_id, status,
cls.build_timeout,
customer_status))
raise exceptions.TimeoutException(message)
@classmethod
def _validate_cust_quota_on_lcp(cls, quota, cust_id):
expected_quota_count = len(quota["compute"][0]) +\
len(quota["storage"][0]) +\
len(quota["network"][0])
actual_quota_count = 0
body = cls.nova_quotas_client.show_quota_set(cust_id)
for param in quota["compute"][0]:
if param in body["quota_set"]:
if (quota["compute"][0][param]
== str(body["quota_set"][param])):
actual_quota_count += 1
body = cls.volume_quotas_client.show_quota_set(cust_id)
for param in quota["storage"][0]:
if param in body["quota_set"]:
if str(body["quota_set"][param]) == quota["compute"][0][param]:
actual_quota_count += 1
body = cls.networks_quotas_client.show_quotas(cust_id)
for param in quota["network"][0]:
if param in body["quota_set"]:
if (quota["compute"][0][param]
== str(body["quota_set"][param])):
actual_quota_count += 1
return bool(expected_quota_count == actual_quota_count)
@classmethod
def _validate_users_on_cust_on_dcp_and_lcp(cls, post_body, cust_id):
default_users_req, region_users_req, \
default_users_dcp, region_users_dcp, \
users_lcp = [], [], [], [], []
for user in post_body["regions"][0]["users"]:
region_users_req.append(user["id"])
for user in post_body["users"]:
default_users_req.append(user["id"])
expected_users_count = len(region_users_req) + len(default_users_req)
actual_users_count = 0
lcp_body = cls.project_client.list_tenant_users(cust_id)
for user in lcp_body["users"]:
users_lcp.append(user["id"])
dcp_body = cls.client.get_customer(cust_id)
for user in dcp_body["regions"][0]["users"]:
region_users_dcp.append(user["id"])
for user in dcp_body["users"]:
default_users_dcp.append(user["id"])
for user in default_users_req:
if (user in users_lcp) and (user in default_users_dcp):
actual_users_count += 1
for user in region_users_req:
if (user in users_lcp) and (user in region_users_dcp):
actual_users_count += 1
return bool(expected_users_count == actual_users_count)
@classmethod
def _del_cust_validate_deletion_on_dcp_and_lcp(cls, customer_id):
_, customer = cls.client.get_customer(customer_id)
regions_on_customer = \
[region['name'] for region in customer["regions"]]
for region in regions_on_customer:
cls._delete_region_from_customer_and_validate_deletion(
customer_id, region)
cls.client.delete_customer(customer_id)
cls._wait_for_customer_deletion_on_dcp(customer_id)
cls._validate_customer_deletion_on_lcp(customer_id)
@classmethod
def _delete_region_from_customer_and_validate_deletion(
cls, customer_id, rname):
_, region = cls.os_admin.rms_client.get_region(rname)
region_id = region["id"]
cls.client.delete_region_from_customer(customer_id, region_id)
time.sleep(cls.build_interval)
_, body = cls.client.get_customer(customer_id)
loopcount = 0
while loopcount < 10:
for regions_on_customer in body['regions']:
if regions_on_customer['name'] == rname:
time.sleep(cls.build_interval)
_, body = cls.client.get_customer(customer_id)
break
loopcount += 1
for regions_on_customer in body['regions']:
if regions_on_customer['name'] == rname:
message = \
"Region %s failed to get deleted from customer %s " % (
rname, customer_id)
raise exceptions.TempestException(message)
@classmethod
def _wait_for_customer_deletion_on_dcp(cls, customer_id):
_, body = cls.client.list_customers()
customer_list = body["customers"]
customer_ids = [customer["id"]
for customer in customer_list
if customer["id"] == customer_id]
start = int(time.time())
while customer_ids:
time.sleep(cls.build_interval)
_, body = cls.client.list_customers()["customers"]
customer_list = body["customers"]
customer_ids = [customer["id"]
for customer in customer_list
if customer["id"] == customer_id]
if customer_ids:
customer_status = customer_ids[0]["status"]
if customer_status == 'Error':
message = "customer %s failed to get deleted and is in\
error status" % customer_id
raise exceptions.TempestException(message)
if int(time.time()) - start >= cls.build_timeout:
message = (
'customer %s failed to get deleted within '
'the required time (%s s) and is in %s status.'
% (customer_id, cls.build_timeout,
customer_status))
raise exceptions.TimeoutException(message)
@classmethod
def _validate_customer_deletion_on_lcp(cls, customer_id):
body = cls.project_client.list_projects()["projects"]
customer_ids = [customer["id"]
for customer in body
if customer["id"] == customer_id]
if customer_ids:
message = "customer %s failed to get deleted on lcp" \
% customer_id
raise exceptions.TempestException(message)
@classmethod
def _update_cust_and_validate_status_on_dcp_and_lcp(
cls, customer_id, para, **kwargs):
body = cls.client.update_customer(customer_id, para, **kwargs)
if body["id"] == customer_id:
cls._wait_for_cust_status_on_dcp(customer_id, "Success")
cls._validate_cust_creation_on_lcp(customer_id)
else:
message = "customer %s not updated successfully" % customer_id
raise exceptions.TempestException(message)
return body