jh629g 3ad54cf082 Adjusted FMS tests for fringe failures
Adjusted delete tag test to ensure tags
are correct before test begins. Updated
test build flavor with two regions to
account for an unordered list in results.
Adjusted build interval to a longer period
to allow for slow networks.

Change-Id: I188953a0aab18e0cbd797907bc8d98ee6759e142
2020-06-30 18:37:11 +00:00

262 lines
10 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.lib import exceptions
CONF = config.CONF
LOG = logging.getLogger(__name__)
class FmsBaseOrmTest(base.BaseOrmTest):
credentials = ['admin', 'primary', 'alt']
# added setup_clients function by stewie925
@classmethod
def setup_clients(cls):
super(FmsBaseOrmTest, cls).setup_clients()
cls.client = cls.os_primary.fms_client
cls.flavors_client = cls.os_admin.flavors_client
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_flavor_params(cls, set_region=True, single_tenant=True,
public=False):
post_body, region = {}, {}
region["name"] = CONF.identity.region
ram = random.randint(1, 4) * 1024
swap = random.randint(1, 40) * 1024
vcpus = random.randint(2, 36)
disk = random.randint(2, 102)
post_body['id'] = uuid.uuid4().hex
post_body["description"] = \
"orm-plugin-BaseORMTest-flavor"
post_body["series"] = random.choice(CONF.ranger.flavor_series)
post_body["alias"] = "flavor_alias"
post_body["ram"] = str(ram)
post_body["vcpus"] = str(vcpus)
post_body["disk"] = str(disk)
post_body["swap"] = str(swap)
post_body["ephemeral"] = "1024"
post_body["regions"] = [region] if set_region else []
post_body["visibility"] = "private" if not public else "public"
post_body['tag'] = {'a': 'b', 'c': 'd'}
if single_tenant:
post_body["tenants"] = [cls.tenant_id]
else:
post_body["tenants"] = [cls.tenant_id, cls.alt_tenant_id]
if public:
post_body["tenants"] = []
return post_body
@classmethod
def _create_flv_and_validate_creation_on_dcp_and_lcp(cls, **kwargs):
"""kwargs contain all field data needed in a flavor POST body:
- name
- description
- alias
- ram
- vcpus
- disk
- swap
- ephemeral
- regions
- visibility
- tenants
"""
_, body = cls.client.create_flavor(**kwargs)
flavor = body["flavor"]
flavor_id = flavor["id"]
_, body = cls.client.get_flavor(flavor_id)
flavor_detail = body["flavor"]
if flavor_detail["vcpus"] == kwargs["vcpus"]:
if flavor_detail["regions"] == []:
flavor_status = "no regions"
else:
flavor_status = "Success"
flavor_id = flavor_detail["id"]
cls._wait_for_flavor_status_on_dcp(flavor_id, flavor_status)
cls._validate_flavor_creation_on_lcp(flavor_id)
return flavor
else:
message = "flavor %s not created successfully" % flavor_id
raise exceptions.TempestException(message)
@classmethod
def _wait_for_flavor_status_on_dcp(cls, flavor_id, status):
_, body = cls.client.get_flavor(flavor_id)
flavor = body["flavor"]
flavor_status = flavor["status"]
start = int(time.time())
while flavor_status != status:
time.sleep(cls.build_interval)
_, body = cls.client.get_flavor(flavor_id)
flavor = body["flavor"]
flavor_status = flavor["status"]
if flavor_status == 'Error':
message = ('flavor %s failed to reach %s status'
' and is in ERROR status' %
(flavor_id, status))
raise exceptions.TempestException(message)
if int(time.time()) - start >= cls.build_timeout:
message = ('flavor %s failed to reach %s status within'
' the required time (%s s) and is in'
' %s status.') % (flavor_id, status,
cls.build_timeout,
flavor_status)
raise exceptions.TimeoutException(message)
@classmethod
def _validate_flavor_creation_on_lcp(cls, flavor_id):
_, body = cls.client.list_flavors()
flavor = [flavor["id"] for flavor in body["flavors"]
if flavor["id"] == flavor_id]
if not flavor:
message = "flavor %s not in nova flavor list" % flavor_id
raise exceptions.TempestException(message)
@classmethod
def _validate_flv_extraspecs_on_dcp_and_lcp(cls, flavor_id,
expected_specs):
expected_specs_count = len(expected_specs)
_, body = cls.client.get_flavor(flavor_id)
flavor_orm = body["flavor"]
flavor_lcp = cls.flavors_client.show_flavor(flavor_id)["flavor"]
def _validate_extra_specs(flv):
actual_specs_count = 0
actual_specs = {}
for spec in flv["extra-specs"]:
actual_specs[spec] = flv["extra-specs"][spec]
for spec in expected_specs:
if spec in actual_specs:
if expected_specs[spec] == actual_specs[spec]:
actual_specs_count += 1
return bool(expected_specs_count == actual_specs_count)
return bool(_validate_extra_specs(flavor_orm) and
_validate_extra_specs(flavor_lcp))
@classmethod
def _del_flv_and_validate_deletion_on_dcp_and_lcp(cls, flavor_id):
_, body = cls.client.get_flavor(flavor_id)
regions_on_flavor = \
[region['name'] for region in body["flavor"]["regions"]]
for regs in regions_on_flavor:
cls._delete_region_from_flavor_and_validate_deletion(
flavor_id, regs)
cls.client.delete_flavor(flavor_id)
cls._wait_for_flavor_deletion_on_dcp(flavor_id)
cls._validate_flavor_deletion_on_lcp(flavor_id)
@classmethod
def _delete_region_from_flavor_and_validate_deletion(
cls, flavor_id, rname):
cls.client.delete_region_from_flavor(flavor_id, rname)
delete_loop_counter = 0
_, body = cls.client.get_flavor(flavor_id)
while delete_loop_counter <= 5:
delete_loop_counter += 1
for regions_on_flavor in body['flavor']['regions']:
if regions_on_flavor['name'] == rname:
time.sleep(cls.build_interval)
_, body = cls.client.get_flavor(flavor_id)
if delete_loop_counter >= 5:
message = \
'Region {} failed to get deleted from flavor {}' \
.format(rname, flavor_id)
raise exceptions.TempestException(message)
@classmethod
def _wait_for_flavor_deletion_on_dcp(cls, flavor_id):
_, body = cls.client.list_flavors()
flavor_ids = [flavor["id"] for flavor in body["flavors"]
if flavor["id"] == flavor_id]
start = int(time.time())
while flavor_ids:
time.sleep(cls.build_interval)
_, body = cls.client.list_flavors()
flavor_ids = [flavor["id"] for flavor in body["flavors"]
if flavor["id"] == flavor_id]
if flavor_ids:
flavor_status = flavor_ids[0]["status"]
if flavor_status == 'Error':
message = \
('Flavor %s failed to get deleted'
'and is in error status') % flavor_id
raise exceptions.TempestException(message)
if int(time.time()) - start >= cls.build_timeout:
message = (
'flavor %s failed to get deleted within '
'the required time (%s s) and is in %s status.'
% (flavor_id, cls.build_timeout, flavor_status))
raise exceptions.TimeoutException(message)
@classmethod
def _validate_flavor_deletion_on_lcp(cls, flavor_id):
body = cls.flavors_client.list_flavors()["flavors"]
flavor_ids = [flavor["id"] for flavor in body]
if flavor_id in flavor_ids:
flavor_status = cls.flavors_client.show_flavor(
flavor_id)["flavor"]["status"]
message = "flavor %s failed to get deleted and is in %s status" \
% (flavor_id, flavor_status)
raise exceptions.TempestException(message)
@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 projects list' % project_name)
raise exceptions.TempestException(message)
@classmethod
def _get_expected_flavor_name(cls, post_body):
name = post_body["series"] + "." + "c" + \
post_body["vcpus"] + "r" + \
str(int(post_body["ram"]) // 1024) \
+ "d" + post_body["disk"] + "s" + \
str(int(post_body["swap"]) // 1024) \
+ "e" + str(int(post_body["ephemeral"]) // 1024)
return name
@classmethod
def _validate_flv_geometry_on_lcp(cls, flavor_id, post_body):
flv = cls.flavors_client.show_flavor(flavor_id)["flavor"]
return bool(flv["vcpus"] == int(post_body["vcpus"]) and
flv["ram"] == post_body["ram"] and
flv["swap"] == int(post_body["swap"]) and
flv["disk"] == int(post_body["disk"]) and
flv["ephemeral"] == post_body["ephemeral"])