Fix Ranger issues

Fix up Ranger Dockerfile and README.rst.
Fix Dockerfile for tempest tests.
Also remove unnecessary directories.

Change-Id: I6d64755c6911919f8527e94a57113d886daf22bc
This commit is contained in:
stewie925 2018-08-17 13:08:51 -05:00 committed by STEW TY
parent 8d991116ad
commit 1231c83f42
98 changed files with 122 additions and 4884 deletions

View File

@ -1,4 +1,4 @@
FROM ubuntu:14.04 FROM ubuntu:16.04
ENV DEBIAN_FRONTEND noninteractive ENV DEBIAN_FRONTEND noninteractive
ENV container docker ENV container docker
@ -58,6 +58,3 @@ RUN chown -R ranger: /home/ranger \
USER root USER root
WORKDIR /opt/app/ranger WORKDIR /opt/app/ranger
ENTRYPOINT tools/start_services.sh \
&& /bin/bash

View File

@ -2,18 +2,14 @@
Ranger Ranger
=============================== ===============================
Ranger is an OpenStack Resource Management tool capable of managing different types of clouds into one platform. Here are the following of what it provides: Ranger is an OpenStack Resource Management tool capable of managing different types of clouds into
one platform. Here are the following of what it provides:
- Multi-region common resource management. - Multi-region common resource management.
- Light weight, stateless and interface with external self-service portals. - Light weight, stateless and interface with external self-service portals.
- Runs on DCP. - Runs on DCP.
- Resource agents will run on LCP to orchestrate and keep resources in sync from a centralized repository. - Resource agents will run on LCP to orchestrate and keep resources in sync from a
centralized repository.
Devstack Installation
---------------------
1. You can include ranger repository in `local.conf` when running devstack.
`enable_plugin ranger git://git.openstack.org/openstack/ranger`
2. Make sure `MYSQL_PASSWORD` is included for creating and accessing the database.
Before Setting Up Before Setting Up
----------------- -----------------
@ -21,6 +17,37 @@ Before Setting Up
Make sure ranger-agent is running before installing and running ranger since that Make sure ranger-agent is running before installing and running ranger since that
is required for connecting with Openstack. is required for connecting with Openstack.
Devstack Installation
---------------------
1. Add the following line in `local.conf` to include ranger repository in your devstack.
`enable_plugin ranger git://git.openstack.org/openstack/ranger`
2. Make sure `MYSQL_PASSWORD` is included for creating and accessing the database.
3. Run ./stack.sh from devstack directory.
Installation
------------
1. Navigate to ranger/tools directory:
$ `cd /opt/stack/ranger/tools`
2. To make changes to the port numbers and other configurations, please go to `base_config.py` under
the `orm` folder before continuing to the next steps.
3. Run `./ranger_create_db.sh` to create ranger databases.
4. Run `./setup_apache.sh` to create conf files for each of the services to apache.
5. Run `stack_orm.sh` to set up ranger.
6. If `stack_orm.sh` is not running properly, navigate to /opt/stack/ranger and run the following:
a. `sudo pip install -r requirements.txt`
b. `sudo python setup.py develop 2>&1 | tee $root_dir/tools/install.log`
Generate ranger.conf file Generate ranger.conf file
------------------------- -------------------------
@ -28,20 +55,6 @@ $tox -e genconfig
A blank configuration file will be generated at etc/ranger.conf A blank configuration file will be generated at etc/ranger.conf
Installation
------------
1. Clone the repo and go to the `tools` directory.
$ `git clone https://git.openstack.org/openstack/ranger`
$ `cd ranger/tools`
2. To make changes to the port numbers and other configurations, please go to `base_config.py` under the `orm` folder before continuing to the next steps.
3. Run `./ranger_create_db.sh` to create the database.
4. Run `./setup_apache.sh` to create conf files for each of the services to apache.
5. Run `stack_orm.sh` to run ranger.
6. If `stack_orm.sh` is not running properly, please do the following:
1. Go to the root of ranger.
2. `sudo pip install -r requirements.txt`
3. `sudo python setup.py develop 2>&1 | tee $root_dir/tools/install.log`
Running Ranger Services Running Ranger Services
----------------------- -----------------------
@ -55,4 +68,26 @@ To run each of the services, type in these commands in order to run each of the
- CMS (Customer Management Service): `orm-cms` - CMS (Customer Management Service): `orm-cms`
- IMS (Image Management Service): `orm-ims` - IMS (Image Management Service): `orm-ims`
For RMS, FMS, CMS, and IMS to be running, Audit, Uuidgen, and RDS must also be running properly as well in order to use them. For RMS, FMS, CMS, and IMS to be running, Audit, Uuidgen, and RDS must also be running properly as
well in order to use them.
Docker Container:
-----------------
1. $ `cd ranger`
2. Update /ranger/tools/.ssh/ranger with your ssh key to your git repo
containing heat templates.
You can clone https://github.com/ranger , but pull requests won't be accepted.
3. $ `sudo docker build -t ranger .`
4. $ `sudo docker run -h "ranger" --net host -it --privileged ranger bash`
Creating docker image and publish will be done by deployment jobs.
For Refernce and validation manually image could push using.
a). $ `docker login <docker_user_id>`
b). $ `docker tag ranger <docker_user_id>/ranger:0.1.0`
c). $ `docker push <docker_user_id>/ranger:0.1.0`
5. This docker container will be used by helm chart to deploy ranger.

View File

@ -124,11 +124,11 @@ allow_region_statuses = ['functional']
region_resource_id_status = { region_resource_id_status = {
# interval_time_validation in minutes # interval_time_validation in minutes
'max_interval_time': { 'max_interval_time': {
'images': 60, 'images': 2,
'tenants': 60, 'tenants': 2,
'flavors': 60, 'flavors': 2,
'users': 60, 'users': 2,
'default': 60 'default': 2
}, },
'allowed_status_values': { 'allowed_status_values': {
'Success', 'Success',
@ -203,5 +203,5 @@ authentication = {
"tenant_name": config.token_auth_tenant, "tenant_name": config.token_auth_tenant,
"token_role": config.token_auth_user_role, "token_role": config.token_auth_user_role,
# The Keystone version currently in use. Can be either "2.0" or "3" # The Keystone version currently in use. Can be either "2.0" or "3"
"keystone_version": "2.0" "keystone_version": "3"
} }

View File

@ -1,4 +1,4 @@
FROM ubuntu:14.04 FROM ubuntu:16.04
ENV DEBIAN_FRONTEND noninteractive ENV DEBIAN_FRONTEND noninteractive
ENV container docker ENV container docker
@ -18,6 +18,7 @@ python-dateutil \
ca-certificates \ ca-certificates \
openstack-pkg-tools \ openstack-pkg-tools \
apache2 \ apache2 \
libmysqlclient-dev \
gcc \ gcc \
g++ \ g++ \
libffi-dev \ libffi-dev \
@ -30,7 +31,7 @@ libssl-dev --no-install-recommends \
/usr/share/man \ /usr/share/man \
/usr/share/doc \ /usr/share/doc \
/usr/share/doc-base /usr/share/doc-base
RUN pip install -U pip setuptools --user RUN pip install -U setuptools --user
RUN pip install wheel --user RUN pip install wheel --user
# RUN pip install virtualenv # RUN pip install virtualenv
@ -39,10 +40,11 @@ RUN pip install wheel --user
### aic-orm-tempest-plugin setup ### aic-orm-tempest-plugin setup
########################################################################## ##########################################################################
WORKDIR / WORKDIR /
COPY aic-orm-tempest-plugin/. ranger-tempest-plugin/ # COPY ranger-tempest-plugin/. ranger-tempest-plugin/
### create egg-info for ranger-tempest-plugin (uncomment two lines below when ready) COPY . ranger-tempest-plugin/
WORKDIR /ranger-tempest-plugin/ WORKDIR /ranger-tempest-plugin/
RUN python /ranger-tempest-plugin/setup.py develop RUN python setup.py develop
########################################################################## ##########################################################################
### END OF ranger-tempest-plugin setup ### END OF ranger-tempest-plugin setup
@ -62,7 +64,7 @@ RUN git clone https://git.openstack.org/openstack/tempest
RUN sed -i 's/paramiko>=.*/paramiko<2.1.3,>=2.0/g' \ RUN sed -i 's/paramiko>=.*/paramiko<2.1.3,>=2.0/g' \
/tempest/requirements.txt /tempest/requirements.txt
# if os-testr exists, replace os-testr line else insert after PrettyTable line # if os-testr exists, replace os-testr line else insert after PrettyTable line
RUN grep -q 'os-testr.*' /tempest/tempest/requirements.txt \ RUN grep -q 'os-testr.*' /tempest/requirements.txt \
&& sed -i 's/os-testr.*/os-testr==0.8.0/' /tempest/requirements.txt \ && sed -i 's/os-testr.*/os-testr==0.8.0/' /tempest/requirements.txt \
|| sed -i '/PrettyTable.*/a os-testr==0.8.0' /tempest/requirements.txt || sed -i '/PrettyTable.*/a os-testr==0.8.0' /tempest/requirements.txt
@ -92,5 +94,12 @@ COPY tempest_setup/tempest.conf /tempest/etc
### create egg-info for tempest ### create egg-info for tempest
WORKDIR /tempest/ WORKDIR /tempest/
RUN python /tempest/setup.py develop RUN python /tempest/setup.py develop
ENTRYPOINT ostestr run aic_orm_tempest_plugin.tests.api.test_regions \ #ENTRYPOINT ostestr run ranger_tempest_plugin.tests.api.test_regions \
&& /bin/bash # && /bin/bash
#ENTRYPOINT ostestr run ranger_tempest_plugin.tests.api.test_flavors/ \
# && /bin/bash
#ENTRYPOINT ostestr run ranger_tempest_plugin.tests.api.test_customers/ \
# && /bin/bash
#ENTRYPOINT ostestr run ranger_tempest_plugin.tests.api.test_images/ \
# && /bin/bash

View File

@ -22,7 +22,7 @@ from tempest import config
from tempest.test_discover import plugins from tempest.test_discover import plugins
class OrmPlugin(plugins.TempestPlugin): class RangerPlugin(plugins.TempestPlugin):
def get_opt_lists(self): def get_opt_lists(self):
return [( return [(
project_config.orm_group.name, project_config.orm_group.name,

View File

@ -1,5 +1,5 @@
[metadata] [metadata]
name = aic_orm_plugin name = ranger-tempest-plugin
version = 0.0.1 version = 0.0.1
summary = Basic Tempest plugin for Orm with a mos tempest smoke test case summary = Basic Tempest plugin for Orm with a mos tempest smoke test case
description-file = description-file =
@ -23,9 +23,12 @@ keywords =
Tempest Tempest
OpenStack OpenStack
[files]
packages = ranger_tempest_plugin
[entry_points] [entry_points]
tempest.test_plugins = tempest.test_plugins =
aic_orm = aic_orm_tempest_plugin.plugin:OrmPlugin ranger-tempest-plugin = ranger_tempest_plugin.plugin:RangerPlugin
[pbr] [pbr]
warnerrors = true warnerrors = true

24
ranger-tempest-plugin/setup.py Executable file
View File

@ -0,0 +1,24 @@
# Copyright (c) 2012 OpenStack Foundation
# 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 setuptools
from setuptools import find_packages
setuptools.setup(name="ranger_tempest_plugin", version="0.0.1",
packages=find_packages(),
include_package_data=True,
setup_requires=['pbr'],
pbr=True)

View File

@ -7,4 +7,3 @@ test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
test_id_option=--load-list $IDFILE test_id_option=--load-list $IDFILE
test_list_option=--list test_list_option=--list
group_regex=([^\.]*\.)* group_regex=([^\.]*\.)*

View File

@ -1,7 +1,7 @@
[DEFAULT] [DEFAULT]
debug = true debug = true
log_file = tempest.log log_file = tempest.log
log_dir = /tempest/logs log_dir = /var/log
[auth] [auth]
test_accounts_file = /tempest/etc/accounts.yaml test_accounts_file = /tempest/etc/accounts.yaml
@ -106,5 +106,5 @@ storage_protocol = iSCSI
multi_backend = false multi_backend = false
[orm] [orm]
uri = http://192.168.56.101 uri = http://127.0.0.1
catalog_type = orm catalog_type = orm

View File

@ -1,11 +0,0 @@
*.pyc
*.log
.venv
.testrepository
.project
.pydevproject
build
dist
aic_orm_plugin.egg-info
.settings/
.tox/

View File

@ -1,85 +0,0 @@
=================================
Tempest Integration of ORM
=================================
This directory contains Tempest tests to cover the ORM project, as well
as a plugin to automatically load these tests into tempest.
See the tempest plugin docs for information on using it:
https://docs.openstack.org/tempest/latest/#using-plugins
See the tempest docs for information on writing new tests etc:
https://docs.openstack.org/tempest/latest/
Quickstart
----------
#. You first need to install Tempest in a venv. If virtual environment is not
installed install it using "sudo apt-get install python-virtualenv"::
$ virtualenv .venv
$ source .venv/bin/activate
$ cd tempest
$ pip install tox
$ pip install tempest
#. Clone/install the plugin::
$ pip install -e <path_of_the_plugin>
For example:
pip install -e /opt/stack/aic_orm
tempest.conf file
--------------------
This file should be present in tempest/etc
Following content must be added in tempest.conf file:
[auth]
# Use predefined credentials instead of creating users on the fly.
use_dynamic_credentials=false
admin_username = username
admin_password = password
admin_project_name= tenant/project/customer name
test_accounts_file=/opt/stack/tempest/etc/accounts.yaml -- Provide the accurate path of the accounts.yaml file
[oslo_concurrency]
lock_path = Provide respective path for oslo_concurrency
[orm]
uri = Provide orm url. For exmple: http://orm.***.***.***.att.com
catalog_type = orm
accounts.yaml file
------------------
accounts.yaml file must be added in the path tempest/etc
Following content must be present with the given format in accounts.yaml file:
- username: 'username1'
tenant_name: 'tenant_name1'
password: 'password1'
- username: 'username2'
tenant_name: 'tenant_name2'
password: 'password2'
Running the tests
-----------------
To run all tests from this plugin, run from the tempest repo::
$ tox -e all-plugin -- aic_orm
To run all tempest tests including this plugin, run::
$ tox -e all-plugin

View File

@ -1,6 +0,0 @@
###############################################################################################
# Blacklist ORM Tests since the tests are having issues.
# IST is looking into the same
# This will be removed once IST resolves the same [no ETA has been provided]
###############################################################################################
(?:aic_orm_tempest_plugin.*)

View File

@ -1,47 +0,0 @@
# 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.
from aic_orm_tempest_plugin.services import base_client
from aic_orm_tempest_plugin.services.cms_client import CmsClient
from aic_orm_tempest_plugin.services.fms_client import FmsClient
from aic_orm_tempest_plugin.services.ims_client import ImsClient
from aic_orm_tempest_plugin.services.rms_client import RmsClient
from tempest import clients
from tempest import config
CONF = config.CONF
class OrmClientManager(clients.Manager):
def __init__(self, credentials=None):
super(OrmClientManager, self).__init__(credentials)
self.cms_client = CmsClient(base_client.OrmAuthProvider(credentials),
CONF.identity.catalog_type,
CONF.identity.region,
CONF.orm.uri)
self.fms_client = FmsClient(base_client.OrmAuthProvider(credentials),
CONF.identity.catalog_type,
CONF.identity.region,
CONF.orm.uri)
self.rms_client = RmsClient(base_client.OrmAuthProvider(credentials),
CONF.identity.catalog_type,
CONF.identity.region,
CONF.orm.uri)
self.ims_client = ImsClient(base_client.OrmAuthProvider(credentials),
CONF.identity.catalog_type,
CONF.identity.region,
CONF.orm.uri)

View File

@ -1,55 +0,0 @@
# Copyright 2015
# 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.
from oslo_config import cfg
service_available_group = cfg.OptGroup(
name="service_available",
title="Available OpenStack Services"
)
ServiceAvailableGroup = [
cfg.BoolOpt("orm", default=False,
help="Whether or not orm is expected to be available")
]
orm_group = cfg.OptGroup(
name="orm",
title="Orm Service option"
)
OrmGroup = [
cfg.StrOpt("uri",
default="orm",
help="Uri of the orm service."),
cfg.StrOpt("cms_port",
default='7080',
help="cms port of the orm url."),
cfg.StrOpt("fms_port",
default='8082',
help="fms port of the orm url."),
cfg.StrOpt("region_port",
default='8080',
help="region port of the orm url."),
cfg.BoolOpt("alt_region_available",
default=None,
help="alt_region_available of the orm alternate region."),
cfg.StrOpt("ims_port",
default='8084',
help="ims port of the orm url."),
cfg.StrOpt("image_url",
help="swift container url where image is located")
]

View File

@ -1,88 +0,0 @@
# 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
from oslo_log import log as logging
from tempest import config
from tempest.lib.common.utils import data_utils
LOG = logging.getLogger(__name__)
CONF = config.CONF
def rand_region_status(exclude=[]):
statuses = {'functional', 'maintenance', 'down', 'building'}.difference(
exclude)
return random.choice(list(statuses))
def rand_region_metadata():
metadata = {}
for i in range(random.randint(2, 10)):
metadata[data_utils.rand_name()] = [data_utils.arbitrary_string()]
return metadata
def rand_region(id=None):
if id is None:
id = data_utils.rand_name()
region_dict = {
'status': rand_region_status(),
'id': id,
'name': id,
'designType': data_utils.arbitrary_string(),
'locationType': data_utils.arbitrary_string(),
'vlcpName': data_utils.arbitrary_string(),
'description': data_utils.arbitrary_string(),
'aicVersion': data_utils.arbitrary_string(),
'OSVersion': data_utils.arbitrary_string(),
'CLLI': data_utils.arbitrary_string(),
'address': {
'country': data_utils.arbitrary_string(),
'state': data_utils.arbitrary_string(),
'city': data_utils.arbitrary_string(),
'street': data_utils.arbitrary_string(),
'zip': str(data_utils.rand_int_id(start=10000, end=99999))
},
'metadata': {
data_utils.rand_name(): [data_utils.arbitrary_string()],
data_utils.rand_name(): [data_utils.arbitrary_string()]
},
'endpoints': [{
'publicURL': data_utils.rand_url(),
'type': 'dashboard'
}, {
'publicURL': data_utils.rand_url(),
'type': 'identity'
}, {
'publicURL': data_utils.rand_url(),
'type': 'ord'
}]
}
return region_dict
def rand_region_group(region_ids, id=None):
if id is None:
id = data_utils.rand_name()
group_dict = {
'name': id,
'id': id,
'description': data_utils.arbitrary_string(),
'regions': region_ids
}
return group_dict

View File

@ -1,46 +0,0 @@
# Copyright 2015
# 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 os
from aic_orm_tempest_plugin import config as project_config
from tempest import config
from tempest.test_discover import plugins
class OrmPlugin(plugins.TempestPlugin):
def get_opt_lists(self):
return [(
project_config.orm_group.name,
project_config.OrmGroup)]
def load_tests(self):
base_path = os.path.split(os.path.dirname(
os.path.abspath(__file__)))[0]
test_dir = "aic_orm_tempest_plugin/tests"
full_test_dir = os.path.join(base_path, test_dir)
return full_test_dir, base_path
def register_opts(self, conf):
config.register_opt_group(
conf,
project_config.service_available_group,
project_config.ServiceAvailableGroup)
config.register_opt_group(
conf,
project_config.orm_group,
project_config.OrmGroup)

View File

@ -1,206 +0,0 @@
# Copyright 2017
# 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
_metadata = {
'type': 'object',
'items': {
'type': 'array',
'items': {'type': 'string'}
}
}
_region = {
'type': 'object',
'properties': {
'status': {'type': 'string'},
'endpoints': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'publicURL': {'type': 'string'},
'type': {'type': 'string'}
},
'required': ['publicURL', 'type']
}
},
'CLLI': {'type': 'string'},
'name': {'type': 'string'},
'description': {'type': 'string'},
'designType': {'type': 'string'},
'locationType': {'type': 'string'},
'vlcpName': {'type': 'string'},
'address': {
'type': 'object',
'properties': {
'country': {'type': 'string'},
'state': {'type': 'string'},
'street': {'type': 'string'},
'zip': {'type': 'string'},
'city': {'type': 'string'},
},
'required': ['country', 'state', 'street', 'zip', 'city']
},
'aicVersion': {'type': 'string'},
'OSVersion': {'type': 'string'},
'id': {'type': 'string'},
'metadata': _metadata,
'created': {'type': 'string', 'format': 'date-time'},
'modified': {'type': 'string', 'format': 'date-time'}
},
'required': ['status', 'endpoints', 'aicVersion', 'OSVersion', 'CLLI',
'created', 'modified', 'metadata', 'address', 'locationType',
'designType', 'description', 'name', 'id', 'vlcpName']
}
get_region = {
'status_code': [200],
'response_body': _region
}
get_region_metadata = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {'metadata': _metadata},
'required': ['metadata']
}
}
create_region = {
'status_code': [201],
'response_body': _region
}
update_region = create_region
update_metadata = {
'status_code': [201],
'response_body': {
'type': 'object',
'properties': {'metadata': _metadata},
'required': ['metadata']
}
}
update_status = {
'status_code': [201],
'response_body': {
'type': 'object',
'properties': {
'status': {'type': 'string'},
'links': {
'type': 'object',
'properties': {
'self': {'type': 'string'}
}
}
},
'required': ['status', 'links']
}
}
delete_region = {
'status_code': [204]
}
list_region = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'regions': {
'type': 'array',
'items': _region
}
},
'required': ['regions']
}
}
list_region_v1 = {
'status_code': [200],
'response_body': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'status': {'type': 'string'},
'vLCP_name': {'type': 'string'},
'ORD_EP': {'type': 'string'},
'horizon_EP': {'type': 'string'},
'design_type': {'type': 'string'},
'AIC_version': {'type': 'string'},
'id': {'type': 'string'},
'OS_version': {'type': 'string'},
'keystone_EP': {'type': 'string'},
'zone_name': {'type': 'string'},
'location_type': {'type': 'string'}
}
}
}
}
_region_group = {
'type': 'object',
'properties': {
'description': {'type': 'string'},
'links': {
'type': 'object',
'properties': {'self': {'type': 'string'}}
},
'created': {'type': 'string', 'format': 'date-time'},
'modified': {'type': 'string', 'format': 'date-time'},
'id': {'type': 'string'},
'name': {'type': 'string'}
},
'required': ['description', 'created', 'modified', 'id', 'name']
}
create_region_group = {
'status_code': [201],
'response_body': {
'type': 'object',
'properties': {
'group': _region_group
},
'required': ['group']
}
}
update_region_group = create_region_group
get_region_group = {
'status_code': [200],
'response_body': _region_group
}
list_region_groups = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'groups': {
'type': 'array',
'items': _region_group
}
},
'required': ['groups']
}
}
delete_region_group = {
'status_code': [204]
}

View File

@ -1,83 +0,0 @@
# Copyright 2015
# 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 json
from tempest import config
from tempest.lib import auth
from tempest.lib.common import rest_client
CONF = config.CONF
class OrmClientBase(rest_client.RestClient):
def get_headers(self):
headers = {'X-Auth-Region': CONF.identity.region,
'X-AIC-ORM-Tracking-Id': 'test',
'X-AIC-ORM-Requester': CONF.auth.admin_username,
'X-AIC-ORM-Client': 'cli',
'Content-Type': 'application/json'
}
return headers
def get_request(self, uri, expected_body_schema):
ex_headers = self.get_headers()
resp, body = self.get(uri, extra_headers=ex_headers)
self.expected_success(200, resp.status)
body = json.loads(body)
self.validate_response(expected_body_schema, resp, body)
return resp, body
def put_request(self, uri, put_body, expected_body_schema):
ex_headers = self.get_headers()
resp, body = self.put(uri, body=put_body, extra_headers=ex_headers)
self.expected_success([200, 201], resp.status)
body = json.loads(body)
self.validate_response(expected_body_schema, resp, body)
return resp, body
def delete_request(self, uri, expected_body_schema):
ex_headers = self.get_headers()
resp, body = self.delete(uri, extra_headers=ex_headers)
self.expected_success(204, resp.status)
self.validate_response(expected_body_schema, resp, body)
return resp, body
def post_request(self, uri, post_body, expected_body_schema):
ex_headers = self.get_headers()
resp, body = self.post(uri, body=post_body,
extra_headers=ex_headers)
self.expected_success([200, 201], resp.status)
body = json.loads(body)
self.validate_response(expected_body_schema, resp, body)
return resp, body
class OrmAuthProvider(auth.KeystoneV2AuthProvider):
def __init__(self, credentials, auth_url=CONF.identity.uri):
super(OrmAuthProvider, self).__init__(credentials, auth_url)
def auth_request(self, method, url, headers=None, body=None, filters=None):
filters = {'service': 'identity'}
auth_headers = super(OrmAuthProvider,
self).auth_request(method,
url,
filters=filters)
base_headers = auth_headers[1]
base_headers.update(headers)
auth_req = dict(url=url, headers=base_headers, body=body)
return auth_req['url'], auth_req['headers'], auth_req['body']

View File

@ -1,129 +0,0 @@
# 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 json
import urllib
from aic_orm_tempest_plugin.schemas import customers_schema as schema
from aic_orm_tempest_plugin.services import base_client
from tempest import config
CONF = config.CONF
class CmsClient(base_client.OrmClientBase):
cms_url = '%s:%s' % (CONF.orm.uri, CONF.orm.cms_port)
version = 'v1'
# POST
def create_customer(self, **kwargs):
uri = '%s/%s/orm/customers' % (self.cms_url, self.version)
post_body = json.dumps(kwargs)
return self.post_request(uri, post_body, schema.create_customer)
def add_default_user(self, customer_id, *args):
uri = '%s/%s/orm/customers/%s/users' \
% (self.cms_url, self.version, customer_id)
post_body = json.dumps(args)
return self.post_request(uri, post_body, schema.add_users)
def add_regions(self, customer_id, regions):
uri = '%s/%s/orm/customers/%s/regions' \
% (self.cms_url, self.version, customer_id)
post_body = json.dumps(regions)
return self.post_request(uri, post_body, schema.add_regions)
def add_region_user(self, customer_id, region_id, *args):
uri = '%s/%s/orm/customers/%s/regions/%s/users' \
% (self.cms_url, self.version, customer_id, region_id)
post_body = json.dumps(args)
return self.post_request(uri, post_body, schema.add_users)
def add_metadata(self, customer_id, metadata):
uri = '%s/%s/orm/customers/%s/metadata' \
% (self.cms_url, self.version, customer_id)
post_body = json.dumps(metadata)
return self.post_request(uri, post_body, schema.add_metadata)
# PUT
def update_customer(self, customer_id, customer):
uri = '%s/%s/orm/customers/%s' \
% (self.cms_url, self.version, customer_id)
put_body = json.dumps(customer)
return self.put_request(uri, put_body, schema.update_customer)
def enable_customer(self, customer_id, value):
uri = '%s/%s/orm/customers/%s/enabled' \
% (self.cms_url, self.version, customer_id)
put_body = json.dumps({'enabled': value})
return self.put_request(uri, put_body, schema.enable_customer)
def replace_default_user(self, customer_id, *args):
uri = '%s/%s/orm/customers/%s/users' \
% (self.cms_url, self.version, customer_id)
put_body = json.dumps(args)
return self.put_request(uri, put_body, schema.replace_users)
def replace_region_user(self, customer_id, region_id, *args):
uri = '%s/%s/orm/customers/%s/regions/%s/users' \
% (self.cms_url, self.version, customer_id, region_id)
put_body = json.dumps(args)
return self.put_request(uri, put_body, schema.replace_users)
def replace_metadata(self, customer_id, metadata):
uri = '%s/%s/orm/customers/%s/metadata' \
% (self.cms_url, self.version, customer_id)
put_body = json.dumps(metadata)
return self.put_request(uri, put_body, schema.replace_metadata)
# GET
def get_customer(self, identifier):
uri = '%s/%s/orm/customers/%s' \
% (self.cms_url, self.version, identifier)
return self.get_request(uri, schema.get_customer)
def list_customers(self, filter=None):
uri = '%s/%s/orm/customers' % (self.cms_url, self.version)
if filter is not None:
uri += '?' + urllib.urlencode(filter)
return self.get_request(uri, schema.list_customer)
# DELETE
def delete_region_from_customer(self, customer_id, region_id):
uri = '%s/%s/orm/customers/%s/regions/%s' % (
self.cms_url, self.version, customer_id, region_id)
return self.delete_request(uri, schema.delete_region_from_customer)
def delete_customer(self, customer_id):
uri = '%s/%s/orm/customers/%s' \
% (self.cms_url, self.version, customer_id)
return self.delete_request(uri, schema.delete_customer)
def delete_default_user(self, customer_id, user_id):
uri = '%s/%s/orm/customers/%s/users/%s' \
% (self.cms_url, self.version, customer_id, user_id)
return self.delete_request(uri, schema.delete_default_user)
def delete_region_user(self, customer_id, region_id, user_id):
uri = '%s/%s/orm/customers/%s/regions/%s/users/%s' \
% (self.cms_url, self.version, customer_id, region_id, user_id)
return self.delete_request(uri, schema.delete_user_from_region)

View File

@ -1,169 +0,0 @@
# 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 json
from aic_orm_tempest_plugin.schemas import flavors_schema as schema
from aic_orm_tempest_plugin.services import base_client
from tempest import config
from tempest.lib.common import rest_client
CONF = config.CONF
class FmsClient(base_client.OrmClientBase):
fms_url = '%s:%s' % (CONF.orm.uri, CONF.orm.fms_port)
version = "v1"
def get_extra_headers(self):
headers = {'X-Auth-Region': CONF.identity.region,
'X-AIC-ORM-Tracking-Id': 'test',
'X-AIC-ORM-Requester': CONF.auth.admin_username,
'X-AIC-ORM-Client': 'cli'
}
return headers
def create_flavor(self, **kwargs):
uri = '%s/%s/orm/flavors' % (self.fms_url, self.version)
post_body = {"flavor": kwargs}
post_body = json.dumps(post_body)
# ex_headers = self.get_headers()
# resp, body = self.post(uri, body=post_body,
# extra_headers=ex_headers)
# body = json.loads(body)
# self.validate_response(schema.create_flavor, resp, body)
# return rest_client.ResponseBody(resp, body["flavor"])
return self.post_request(uri, post_body, schema.create_flavor)
def get_flavor(self, identifier, para=None):
if para is None:
uri = '%s/%s/orm/flavors/%s' % (self.fms_url, self.version,
identifier)
else:
uri = '%s/%s/orm/flavors/%s/%s' % (self.fms_url, self.version,
identifier, para)
return self.get_request(uri, schema.get_flavor)
def list_flavors(self, para=None):
if para is None:
uri = '%s/%s/orm/flavors' % (self.fms_url, self.version)
else:
uri = '%s/%s/orm/flavors/%s' % (self.fms_url, self.version, para)
# ex_headers = self.get_headers()
# resp, body = self.get(url, extra_headers=ex_headers)
# self.expected_success(200, resp.status)
# body = json.loads(body)
# self.validate_response(schema.list_flavors, resp, body)
# return rest_client.ResponseBody(resp, body)
return self.get_request(uri, schema.list_flavors)
def delete_region_from_flavor(self, flavor_id, region_id):
uri = '%s/%s/orm/flavors/%s/regions/%s' % (self.fms_url,
self.version, flavor_id,
region_id)
ex_headers = self.get_headers()
resp, body = self.delete(uri, extra_headers=ex_headers)
self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp, body)
def delete_flavor(self, flavor_id):
uri = '%s/%s/orm/flavors/%s' %\
(self.fms_url, self.version, flavor_id)
return self.delete_request(uri, schema.delete_flavor)
def delete_tags(self, flavor_id, para):
if para is None:
uri = '%s/%s/orm/flavors/%s/tags' % (self.fms_url, self.version,
flavor_id)
else:
uri = '%s/%s/orm/flavors/%s/tags/%s' % (self.fms_url, self.version,
flavor_id, para)
return self.delete_request(uri, schema.delete_tags)
def get_tags(self, flavor_id):
uri = '%s/%s/orm/flavors/%s/tags' % (self.fms_url, self.version,
flavor_id)
return self.get_request(uri, schema.get_tags)
def add_tags(self, flavor_id, tag_body):
uri = '%s/%s/orm/flavors/%s/tags' % (self.fms_url, self.version,
flavor_id)
post_body = json.dumps(tag_body)
return self.post_request(uri, post_body, schema.add_tags)
def update_tags(self, flavor_id, tag_body):
uri = '%s/%s/orm/flavors/%s/tags' % (self.fms_url, self.version,
flavor_id)
put_body = json.dumps(tag_body)
return self.put_request(uri, put_body, schema.update_tags)
def get_extra_specs(self, flavor_id):
uri = '%s/%s/orm/flavors/%s/os_extra_specs' % (self.fms_url,
self.version,
flavor_id)
return self.get_request(uri, schema.get_extra_specs)
def add_flvr_tenants(self, flavor_id, tenant_body):
uri = '%s/%s/orm/flavors/%s/tenants/' % (self.fms_url,
self.version,
flavor_id)
post_body = json.dumps(tenant_body)
return self.post_request(uri, post_body, schema.add_tenant)
def add_flvr_regions(self, flavor_id, region_body):
uri = '%s/%s/orm/flavors/%s/regions' % (self.fms_url,
self.version,
flavor_id)
post_body = json.dumps(region_body)
return self.post_request(uri, post_body, schema.add_region)
def delete_flvr_region(self, flavor_id, region_id):
uri = '%s/%s/orm/flavors/%s/regions/%s' % (self.fms_url,
self.version,
flavor_id, region_id)
return self.delete_request(uri, schema.delete_region)
def add_extra_specs(self, flavor_id, extra_specs_body):
uri = '%s/%s/orm/flavors/%s/os_extra_specs' % (self.fms_url,
self.version,
flavor_id)
post_body = json.dumps(extra_specs_body)
return self.post_request(uri, post_body, schema.add_extra_specs)
def update_extra_specs(self, flavor_id, extra_specs_body):
uri = '%s/%s/orm/flavors/%s/os_extra_specs' % (self.fms_url,
self.version,
flavor_id)
put_body = json.dumps(extra_specs_body)
return self.put_request(uri, put_body, schema.update_extra_specs)
def delete_extra_specs(self, flavor_id, para):
if para is None:
uri = '%s/%s/orm/flavors/%s/os_extra_specs' % (self.fms_url,
self.version,
flavor_id)
else:
uri = '%s/%s/orm/flavors/%s/os_extra_specs/%s' % (self.fms_url,
self.version,
flavor_id, para)
return self.delete_request(uri, schema.delete_extra_specs)
def delete_flvr_tenant(self, flavor_id, tenant):
uri = '%s/%s/orm/flavors/%s/tenants/%s' % (self.fms_url,
self.version,
flavor_id, tenant)
return self.delete_request(uri, schema.delete_tenant)

View File

@ -1,112 +0,0 @@
# 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 json
from aic_orm_tempest_plugin.schemas import images_schema as schema
from aic_orm_tempest_plugin.services import base_client
from tempest import config
CONF = config.CONF
class ImsClient(base_client.OrmClientBase):
ims_url = '%s:%s' % (CONF.orm.uri, CONF.orm.ims_port)
version = "v1"
def get_headers(self):
headers = {'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Auth-Region': CONF.identity.region,
'X-AIC-ORM-Tracking-Id': 'test',
'X-AIC-ORM-Requester': CONF.auth.admin_username,
'X-AIC-ORM-Client': 'cli'
}
return headers
def create_image(self, **kwargs):
uri = '%s/%s/orm/images' % (self.ims_url, self.version)
post_body = {"image": kwargs}
post_body = json.dumps(post_body)
return self.post_request(uri, post_body, schema.create_image)
def update_image(self, image_id, para=None, **kwargs):
if para is None:
uri = '%s/%s/orm/images/%s' % (
self.ims_url, self.version, image_id)
else:
uri = '%s/%s/orm/images/%s/%s' % (
self.ims_url, self.version, image_id, para)
put_body = {"image": kwargs}
put_body = json.dumps(put_body)
return self.put_request(uri, put_body, schema.update_image)
def get_image(self, identifier, para=None):
if para is None:
uri = '%s/%s/orm/images/%s' % (self.ims_url, self.version,
identifier)
else:
uri = '%s/%s/orm/images/%s/%s' % (self.ims_url, self.version,
identifier, para)
return self.get_request(uri, schema.get_image)
def list_images(self, para=None):
if para is None:
uri = '%s/%s/orm/images' % (self.ims_url, self.version)
else:
uri = '%s/%s/orm/images/%s' % (self.ims_url, self.version, para)
return self.get_request(uri, schema.list_images)
def enabled_image(self, image_id, bool):
uri = '%s/%s/orm/images/%s/enabled' \
% (self.ims_url, self.version, image_id)
put_body = json.dumps({'enabled': bool})
return self.put_request(uri, put_body, schema.enable_image_resp)
def add_region_to_image(self, image_id, region_id):
uri = '%s/%s/orm/images/%s/regions/' % (self.ims_url,
self.version, image_id)
post_body = json.dumps({"regions": [{"name": region_id}]})
return self.post_request(uri, post_body, schema.add_region)
def delete_region_from_image(self, image_id, region_id):
uri = '%s/%s/orm/images/%s/regions/%s' % (self.ims_url,
self.version, image_id,
region_id)
return self.delete_request(uri, schema.delete_region)
def delete_image(self, image_id):
uri = '%s/%s/orm/images/%s' % (self.ims_url, self.version, image_id)
return self.delete_request(uri, schema.delete_image)
def add_customer_to_image(self, image_id, tenant_id):
uri = '%s/%s/orm/images/%s/customers' % (
self.ims_url, self.version, image_id)
post_body = json.dumps({"customers": [tenant_id]})
return self.post_request(uri, post_body, schema.add_tenant_to_image)
def update_customer(self, image_id, tenant_id):
uri = '%s/%s/orm/images/%s/customers' % (self.ims_url, self.version,
image_id)
put_body = json.dumps({"customers": [tenant_id]})
return self.put_request(uri, put_body, schema.update_tenant)
def delete_customer_from_image(self, image_id, tenant_id):
uri = '%s/%s/orm/images/%s/customers/%s' % (self.ims_url,
self.version,
image_id,
tenant_id)
return self.delete_request(uri, schema.delete_tenant_from_image)

View File

@ -1,159 +0,0 @@
# 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 json
import urllib
from aic_orm_tempest_plugin.schemas import regions_schema as schema
from aic_orm_tempest_plugin.services import base_client
from tempest import config
CONF = config.CONF
class RmsClient(base_client.OrmClientBase):
rms_url = '%s:%s' % (CONF.orm.uri, CONF.orm.region_port)
version = "v2"
def create_region(self, region_id, **kwargs):
uri = '%s/%s/orm/regions' % (self.rms_url, self.version)
post_body = {
'status': 'functional',
'name': region_id,
'id': region_id,
'description': region_id,
'designType': 'compact',
'locationType': 'testlocation',
'vlcpName': 'testvlcp',
'address': {
'country': 'usa',
'state': 'tx',
'city': 'austin',
'street': '12 main',
'zip': '12345'
},
'metadata': {
'key': ["value"]
},
'endpoints': [
{
'publicURL':
'https://dashboard-aic.%s.cci.att.com' % region_id,
'type': 'dashboard'
},
{
'publicURL':
'https://identity-aic.%s.cci.att.com:5000' % region_id,
'type': 'identity'
},
{
'publicURL':
'https://ord-aic.%s.cci.att.com:9010' % region_id,
'type': 'ord'
},
],
'aicVersion': '3.6',
'OSVersion': 'kilo',
'CLLI': 'testclli'
}
if kwargs is not None:
for key in kwargs:
post_body[key] = kwargs[key]
post_body = json.dumps(post_body)
return self.post_request(uri, post_body, schema.create_region)
def update_region(self, region_id, **kwargs):
uri = '%s/%s/orm/regions/%s' % (self.rms_url, self.version, region_id)
put_body = json.dumps(kwargs)
return self.put_request(uri, put_body, schema.update_region)
def update_region_status(self, region_id, status):
uri = '%s/%s/orm/regions/%s/status' \
% (self.rms_url, self.version, region_id)
put_body = json.dumps(status)
return self.put_request(uri, put_body, schema.update_status)
def update_region_metadata(self, region_id, metadata):
uri = '%s/%s/orm/regions/%s/metadata' \
% (self.rms_url, self.version, region_id)
put_body = json.dumps(metadata)
return self.put_request(uri, put_body, schema.update_metadata)
def get_region(self, identifier):
uri = '%s/%s/orm/regions/%s' % (self.rms_url, self.version, identifier)
return self.get_request(uri, schema.get_region)
def get_region_metadata(self, identifier):
uri = '%s/%s/orm/regions/%s/metadata'\
% (self.rms_url, self.version, identifier)
return self.get_request(uri, schema.get_region_metadata)
def list_regions_v1(self):
uri = self.rms_url + '/lcp'
return self.get_request(uri, schema.list_region_v1)
def list_regions(self, filter=None):
uri = '%s/%s/orm/regions' % (self.rms_url, self.version)
if filter is not None:
uri += '?' + urllib.urlencode(filter)
return self.get_request(uri, schema.list_region)
def delete_region(self, region_id):
uri = '%s/%s/orm/regions/%s' % (self.rms_url, self.version, region_id)
return self.delete_request(uri, schema.delete_region)
def add_region_metadata(self, region_id, **kwargs):
uri = '%s/%s/orm/regions/%s/metadata'\
% (self.rms_url, self.version, region_id)
post_body = json.dumps(kwargs)
return self.post_request(uri, post_body, schema.update_metadata)
#
# def delete_region_metadata(self, region_id, key):
# uri = '%s/%s/orm/regions/%s/metadata/%s' % (
# self.rms_url, self.version, region_id, key)
# ex_headers = self.get_headers()
# resp, body = self.delete(uri, extra_headers=ex_headers)
# self.expected_success(200, resp.status)
# body = json.loads(body)
# return rest_client.ResponseBody(resp, body)
def create_region_group(self, **kwargs):
uri = '%s/%s/orm/groups' % (self.rms_url, self.version)
post_body = json.dumps(kwargs)
return self.post_request(uri, post_body, schema.create_region_group)
def update_region_group(self, group_id, **kwargs):
uri = '%s/%s/orm/groups/%s' % (self.rms_url, self.version, group_id)
put_body = json.dumps(kwargs)
return self.put_request(uri, put_body, schema.update_region_group)
def get_region_group(self, identifier):
uri = '%s/%s/orm/groups/%s'\
% (self.rms_url, self.version, identifier)
return self.get_request(uri, schema.get_region_group)
def list_region_groups(self):
uri = '%s/%s/orm/groups' % (self.rms_url, self.version)
return self.get_request(uri, schema.list_region_groups)
def delete_region_group(self, region_group_id):
uri = '%s/%s/orm/groups/%s' % (self.rms_url, self.version,
region_group_id)
return self.delete_request(uri, schema.delete_region_group)

View File

@ -1,52 +0,0 @@
# 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.
from aic_orm_tempest_plugin import clients
from oslo_log import log as logging
import six
from tempest import config
from tempest import test
CONF = config.CONF
LOG = logging.getLogger(__name__)
class BaseOrmTest(test.BaseTestCase):
credentials = ['admin', 'primary', 'alt']
client_manager = clients.OrmClientManager
build_timeout = 120
build_interval = 10
@classmethod
def setup_clients(cls):
super(BaseOrmTest, cls).setup_clients()
cls.identity_client = cls.os_admin.tenants_client
@classmethod
def skip_checks(cls):
super(BaseOrmTest, cls).skip_checks()
if not CONF.service_available.orm:
skip_msg = ("%s skipped as orm is not available" % cls.__name__)
raise cls.skipException(skip_msg)
def assertExpected(self, expected, actual, excluded_keys):
for key, value in six.iteritems(expected):
if key not in excluded_keys:
self.assertIn(key, actual)
self.assertEqual(value, actual[key], key)

View File

@ -1,326 +0,0 @@
# 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
from aic_orm_tempest_plugin.tests.api import base
from oslo_log import log as logging
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 setup_clients(cls):
super(CmsBaseOrmTest, cls).setup_clients()
cls.client = cls.os_primary.cms_client
@classmethod
def _get_quota(cls):
compute, storage, network, quota = {}, {}, {}, {}
compute["instances"] = "10"
compute["injected-files"] = "10"
compute["key-pairs"] = "10"
compute["ram"] = "10"
compute["vcpus"] = "51"
compute["metadata-items"] = "34"
compute["injected-file-content-bytes"] = "25"
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]["injected-file-path-bytes"] = "34"
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, payload = {}, {}, {}, {}
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'] = random.randint(0, 999999999)
payload["description"] = cust_name
payload["enabled"] = True if enabled else False
payload["name"] = cust_name
payload['metadata'] = metadata
payload["regions"] = regions
payload["defaultQuotas"] = [quota]
payload['users'] = [user] if default_users else []
return payload
@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'] = []
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(self, **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 = self.client.create_customer(**kwargs)
customer_id = body["customer"]["id"]
_, customer = self.client.get_customer(customer_id)
if customer["name"] == kwargs["name"]:
if customer["regions"] == []:
customer_status = "no regions"
else:
customer_status = "Success"
self._wait_for_status(customer_id, customer_status)
return customer_id
else:
message = "customer %s not created successfully" % kwargs["name"]
exceptions.TempestException(message)
@classmethod
def _wait_for_status(cls, customer_id, status):
customer_status = cls.client.get_customer(customer_id)[1]["status"]
start = int(time.time())
while customer_status != status:
time.sleep(cls.build_interval)
customer_status = cls.client.get_customer(customer_id)[1]["status"]
if customer_status == 'Error':
message = ('customer %s failed to reach %s status'
' and is in ERROR status on orm' %
(customer_id, status))
raise exceptions.TempestException(message)
if int(time.time()) - start >= cls.build_timeout:
message = ('customer %s failed to reach %s'
'status within the required time (%s s)'
'on orm 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
if expected_quota_count == actual_quota_count:
return True
else:
return False
@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.identity_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
if expected_users_count == actual_users_count:
return True
else:
return False
@classmethod
def _del_cust_validate_deletion_on_dcp_and_lcp(cls, customer_id):
_, customer = cls.client.get_customer(customer_id)
regions_on_customer = [region for region in customer["regions"]]
if regions_on_customer:
region_name_on_customer = regions_on_customer[0]["name"]
cls._delete_region_from_customer_and_validate_deletion(
customer_id, region_name_on_customer)
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)
# cls._wait_for_cust_status_on_dcp(customer_id, "no regions")
cls._wait_for_status(customer_id, "no regions")
_, body = cls.client.get_customer(customer_id)
regions_on_customer = [rgn for rgn in body["regions"]]
if regions_on_customer:
message = "Region %s failed to get deleted from customer %s " % (
rname, customer_id)
raise exceptions.TempestException(message)
cls._validate_customer_deletion_on_lcp(customer_id)
@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.identity_client.list_tenants()["tenants"]
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

View File

@ -1,261 +0,0 @@
# 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
from aic_orm_tempest_plugin.tests.api import base
from oslo_log import log as logging
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 stew
@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_tenant_id(
cls.os_primary.credentials.tenant_name)
cls.alt_tenant_id = cls._get_tenant_id(
cls.os_alt.credentials.tenant_name)
@classmethod
def _get_flavor_params(cls, set_region=True, single_tenant=True):
post_body, region = {}, {}
region["name"] = CONF.identity.region
ram = random.randint(1, 4) * 1024
swap = random.randint(1, 40) * 1024
vcpus = random.randint(2, 46)
disk = random.randint(2, 102)
post_body["description"] = \
"orm-plugin-BaseORMTest-flavor"
post_body["series"] = random.choice(["ns", "nd", "gv", "nv"])
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 single_tenant:
post_body["tenants"] = [cls.tenant_id]
else:
post_body["tenants"] = [cls.tenant_id, cls.alt_tenant_id]
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 on orm' %
(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) on orm 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
if expected_specs_count == actual_specs_count:
return True
else:
return False
if _validate_extra_specs(flavor_orm) and\
_validate_extra_specs(flavor_lcp):
return True
else:
return False
@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 for region in body["flavor"]["regions"]]
if regions_on_flavor:
region_name_on_flavor = regions_on_flavor[0]["name"]
cls._delete_region_from_flavor_and_validate_deletion(
flavor_id, region_name_on_flavor)
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):
_, body = cls.rms_client.get_region(rname)
region_id = body["id"]
cls.client.delete_region_from_flavor(flavor_id, region_id)
cls._wait_for_flavor_status_on_dcp(flavor_id, "no regions")
_, body = cls.client.get_flavor(flavor_id)
regions_on_flavor = body["flavor"]["regions"]
if regions_on_flavor:
message = \
"Region %s failed to get deleted from flavor %s " % (
rname, flavor_id)
raise exceptions.TempestException(message)
cls._validate_flavor_deletion_on_lcp(flavor_id)
@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"] == flavor_id]
if 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_tenant_id(cls, tenant_name):
body = cls.identity_client.list_tenants()
for tenant in body["tenants"]:
if(tenant["name"] == tenant_name):
return tenant["id"]
message = ('tenant %s not found on tenant list' % cls.tenant_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"]
if 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"]:
return True
else:
return False

View File

@ -1,248 +0,0 @@
# 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
from aic_orm_tempest_plugin.tests.api import base
from oslo_log import log as logging
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_tenant_id(
cls.os_primary.credentials.tenant_name)
cls.alt_tenant_id = cls._get_tenant_id(
cls.os_alt.credentials.tenant_name)
@classmethod
def _get_image_params(cls, set_region=True, single_tenant=True,
set_private=True, set_enabled=True):
region, post_body = {}, {}
post_body["name"] = data_utils.rand_name(
"orm-plugin-TestTempestIms-image")
# use ubuntu website for the image location URL
ubuntu_url = "http://archive.ubuntu.com/"
ubuntu_dir = "ubuntu/dists/xenial/main/installer-i386/current/images/"
ubuntu_iso = "netboot/mini.iso"
post_body["url"] = ubuntu_url + ubuntu_dir + ubuntu_iso
post_body["disk-format"] = "qcow2"
post_body["container-format"] = "bare"
region["name"] = cls.region_id
region["type"] = "single"
region["checksum"] = "7297321c2fa6424417a548c85edd6e98"
region["virtual_size"] = "None"
region["size"] = "38797312"
# set enabled status to True or False based on set_enabled value
post_body["enabled"] = True if set_enabled else False
# add region for the image as needed
post_body["regions"] = [region] if set_region else []
# create image with visibililty = "public" or "private"
post_body["visibility"] = "private" if set_private else "public"
# add tenant for the image only if set_private
if set_private:
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_tenant_id(cls, tenant_name):
body = cls.identity_client.list_tenants()
for tenant in body["tenants"]:
if(tenant["name"] == tenant_name):
return tenant["id"]
message = ('tenant %s not found on tenant list' % cls.tenant_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"]:
if image_detail["regions"] == []:
image_status = "no regions"
else:
image_status = "Success"
cls._wait_for_image_status_on_dcp(image_id, image_status)
return image
else:
message = ('image %s not created successfully' % kwargs["name"])
raise exceptions.TempestException(message)
@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 image_status != status:
time.sleep(cls.build_interval)
_, body = cls.client.get_image(image_id)
image_status = body["image"]["status"]
if image_status == 'Error':
message = ('Image %s failed to reach %s status'
' and is in ERROR status on orm' %
(image_id, status))
raise exceptions.TempestException(message)
if int(time.time()) - start >= cls.build_timeout:
message = ('Image %s failed to reach %s'
' status within ''the required time (%s s)'
' on orm and is in %s status.'
% (image_id, status,
cls.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)
else:
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 for region in image["regions"]]
if regions_on_image:
region_id = regions_on_image[0]["name"]
cls._delete_region_from_image_and_validate_deletion(
image_id, region_id)
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)
cls._wait_for_image_status_on_dcp(image_id, "no regions")
@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.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.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)

View File

@ -1,31 +0,0 @@
# 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.
from aic_orm_tempest_plugin.tests.api import base
from oslo_log import log as logging
from tempest import config
CONF = config.CONF
LOG = logging.getLogger(__name__)
class RmsBaseOrmTest(base.BaseOrmTest):
@classmethod
def setup_clients(cls):
cls.client = cls.os_primary.rms_client
super(RmsBaseOrmTest, cls).setup_clients()

View File

@ -1,342 +0,0 @@
# 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
from aic_orm_tempest_plugin.tests.api import cms_base
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
CONF = config.CONF
class TestTempestCms(cms_base.CmsBaseOrmTest):
@classmethod
def resource_setup(cls):
cls.setup_customer = cls._get_customer_params()
cls.setup_customer_id = \
cls._create_cust_validate_creation_on_dcp_and_lcp(
**cls.setup_customer)
cls.bare_customer = cls._get_bare_customer_params()
cls.bare_customer_id = \
cls._create_cust_validate_creation_on_dcp_and_lcp(
**cls.bare_customer)
super(TestTempestCms, cls).resource_setup()
@classmethod
def resource_cleanup(cls):
cls._del_cust_validate_deletion_on_dcp_and_lcp(cls.setup_customer_id)
cls._del_cust_validate_deletion_on_dcp_and_lcp(cls.bare_customer_id)
super(TestTempestCms, cls).resource_cleanup()
@decorators.idempotent_id('6072c438-1e45-4c0b-97a6-e5127bd33d89')
def test_get_customer(self):
''' Execute 'get_customer' using the following options:
- get customer by id (using cust_id parameter)
- get customer by name (using cust_name parameter)
'''
# execute get_customer using cust_id and cust_name
for identifier in [self.setup_customer_id,
self.setup_customer['name']]:
_, body = self.client.get_customer(identifier)
self.assertIn(self.setup_customer_id, body['uuid'])
@decorators.idempotent_id('6072c438-1e45-4c0b-97a6-e5127bd33d90')
def test_list_customers_with_filters(self):
''' this function executes 'list customer' with all available filters:
- no filter (i.e. list all customers)
- filter by metadata key
- filter by region
- filter by default user id
- customer name contains a substring
- customer name starting with a string
'''
# format filter parameter values
region_name = [
region['name'] for region in self.setup_customer['regions']]
userid = [user['id'] for user in self.setup_customer['users']]
cust_name = self.setup_customer['name']
substr_name = random.randint(0, len(cust_name))
# get the first key from metadata as the metadata key filter
metadata_key = list(self.setup_customer['metadata'].keys())[0]
# define the list customer filters to be used for this test
no_filter = None
metadata_filter = {'metadata': metadata_key}
region_filter = {'region': region_name[0]}
user_filter = {'user': userid[0]}
contains_filter = {'contains': cust_name[substr_name:]}
startswith_filter = {'starts_with': cust_name[:substr_name]}
# execute list_customers with the available filters
for list_filter in [no_filter, metadata_filter, region_filter,
user_filter, contains_filter, startswith_filter]:
_, body = self.client.list_customers(list_filter)
customers = [cust['id'] for cust in body['customers']]
self.assertIn(self.setup_customer_id, customers)
@decorators.idempotent_id('ac132678-fdb6-4037-a310-813313044055')
def test_enable_customer(self):
# setup data for test case
post_body = self._get_customer_params(enabled=False)
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
# update enabled status from 'False' to 'True' and validate update OK
_, body = self.client.get_customer(test_customer_id)
self.assertFalse(body['enabled'])
self.client.enable_customer(test_customer_id, True)
self._wait_for_status(test_customer_id, 'Success')
_, body = self.client.get_customer(test_customer_id)
self.assertTrue(body['enabled'])
@decorators.idempotent_id('7dfd5f7e-7031-4ee1-b355-cd5cdeb21bd1')
def test_add_default_user(self):
# setup data for "add_default_user" test case; leave default
# and region users blank at the initial data creation
post_body = self._get_customer_params(default_users=False,
region_users=False)
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
_, body = self.client.get_customer(test_customer_id)
self.assertFalse(body['users'])
self.assertFalse(body["regions"][0]['users'])
# now add a default user, then validate that new user is added to
# BOTH default user AND region user successfully
post_default_user = self._get_user_params()
new_user_id = post_default_user[0]["id"]
_, body = self.client.add_default_user(test_customer_id,
*post_default_user)
self._wait_for_status(test_customer_id, 'Success')
_, body = self.client.get_customer(test_customer_id)
self.assertIn(new_user_id, [x['id'] for x in body['users']])
self.assertIn(new_user_id, [x['id']
for x in body['regions'][0]['users']])
@decorators.idempotent_id('699e8487-035e-4ae0-97b4-ca51b9a08aea')
def test_delete_default_user(self):
# setup data for delete_default_user test case
post_body = self._get_customer_params()
default_user_id = post_body["users"][0]["id"]
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
_, body = self.client.get_customer(test_customer_id)
self.assertEqual(default_user_id, body['users'][0]['id'])
self.assertIn(default_user_id,
[x['id'] for x in body['regions'][0]['users']])
# delete default user and validate operation success by confirming
# user id no longer in both default users and region users list
_, body = self.client.delete_default_user(test_customer_id,
default_user_id)
self._wait_for_status(test_customer_id, 'Success')
_, body = self.client.get_customer(test_customer_id)
self.assertFalse(body['users'])
self.assertNotIn(default_user_id,
[x['id'] for x in body['regions'][0]['users']])
@decorators.idempotent_id('48ffd49f-2b36-40b4-b1b4-0c805b7ba7c2')
def test_replace_default_user(self):
# setup data for "replace_default_user" test case; no need to
# set region user as default user will also be assigned to it
post_body = self._get_customer_params(region_users=False)
default_user_id = post_body["users"][0]["id"]
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
_, body = self.client.get_customer(test_customer_id)
self.assertIn(default_user_id, [x['id'] for x in body['users']])
self.assertEqual(body['users'], body['regions'][0]['users'])
# replace default user
put_default_user = self._get_user_params(alt=True)
updated_user_id = put_default_user[0]["id"]
_, body = self.client.replace_default_user(test_customer_id,
*put_default_user)
self._wait_for_status(test_customer_id, 'Success')
# validate that BOTH the customer default user and region user
# are replaced with the new default_user successfully
_, body = self.client.get_customer(test_customer_id)
self.assertEqual(len(body['users']),
len(body['regions'][0]['users']))
self.assertIn(updated_user_id, [x['id'] for x in body['users']])
self.assertEqual(body['users'], body['regions'][0]['users'])
@decorators.idempotent_id('07a631f9-3aa5-4797-9ead-4531ced89e2a')
def test_add_region_user(self):
# We are leaving both default and region users as blank to ensure
# region user is empty on initial data creation for this test case
post_body = self._get_customer_params(region_users=False,
default_users=False)
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
_, body = self.client.get_customer(test_customer_id)
# confirm that the region users body is empty after data creation
self.assertFalse(body["regions"][0]["users"])
# now we shall add user to regions[0]
post_region_user = self._get_user_params()
_, body = self.client.add_region_user(test_customer_id,
CONF.identity.region,
*post_region_user)
self._wait_for_status(test_customer_id, 'Success')
_, customer = self.client.get_customer(test_customer_id)
# validate that the region user is no longer empty after the add
self.assertTrue(customer["regions"][0]["users"])
@decorators.idempotent_id('9b2b3af8-2444-4143-a9e6-78c33b36c823')
def test_delete_region_user(self):
# To test delete_region_users scenario, leave default user blank
# for the test customer data, or else default user info will be
# added as region user as well
post_body = self._get_customer_params(default_users=False)
region_user_id = post_body["regions"][0]["users"][0]["id"]
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
_, body = self.client.get_customer(test_customer_id)
self.assertTrue(body["regions"][0]["users"])
# delete the user from the region, then validate operation success
_, body = self.client.delete_region_user(test_customer_id,
CONF.identity.region,
region_user_id)
self._wait_for_status(test_customer_id, 'Success')
_, customer = self.client.get_customer(test_customer_id)
# validate that the region user is now empty
self.assertFalse(customer["regions"][0]["users"])
@decorators.idempotent_id('0ca59977-ef29-46b9-be92-14980a12c573')
def test_replace_region_user(self):
post_body = self._get_customer_params()
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
# update region user then confirm that update is successful
put_region_user = self._get_user_params(alt=True)
new_region_user_id = put_region_user[0]["id"]
_, body = self.client.replace_region_user(test_customer_id,
CONF.identity.region,
*put_region_user)
self._wait_for_status(test_customer_id, 'Success')
_, customer = self.client.get_customer(test_customer_id)
self.assertIn(new_region_user_id, [x['id']
for x in customer["regions"][0]['users']])
@decorators.idempotent_id('f1444965-c711-438d-ab86-a2412acbe8e0')
def test_replace_metadata(self):
metadata = {'metadata': {'replace_key': 'replace_value'}}
_, body = self.client.replace_metadata(self.setup_customer_id,
metadata)
self._wait_for_status(self.setup_customer_id, 'Success')
_, body = self.client.list_customers({'metadata': 'replace_key'})
self.assertIn(self.setup_customer_id,
[x['id'] for x in body['customers']])
@decorators.idempotent_id('80713a87-8e95-481f-a198-6b4515d48362')
def test_add_metadata(self):
metadata = {'metadata': {'add_key': 'add_value'}}
_, body = self.client.add_metadata(self.setup_customer_id,
metadata)
self._wait_for_status(self.setup_customer_id, 'Success')
_, body = self.client.list_customers({'metadata': 'add_key'})
self.assertIn(self.setup_customer_id,
[x['id'] for x in body['customers']])
@decorators.idempotent_id('19a6bbe2-92b9-46be-95b7-aa0d9f247d88')
def test_add_regions(self):
region = self._get_region_params()
_, body = self.client.add_regions(self.bare_customer_id,
region)
self._wait_for_status(self.setup_customer_id, 'Success')
_, body = self.client.list_customers({'region': region[0]['name']})
self.assertIn(self.setup_customer_id,
[x['id'] for x in body['customers']])
@decorators.idempotent_id('09a43bc1-439e-4497-a026-f2c3de451d29')
def test_delete_regions(self):
# setup data for delete_region
post_body = self._get_customer_params()
region_name = post_body["regions"][0]["name"]
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
_, customer = self.client.get_customer(test_customer_id)
self.assertTrue(customer["regions"])
_, body = self.client.delete_region_from_customer(test_customer_id,
region_name)
self._wait_for_status(test_customer_id, 'no regions')
_, customer = self.client.get_customer(test_customer_id)
self.assertFalse(customer["regions"])
@decorators.idempotent_id('c7a24667-2a99-41ac-a42d-6c1163ef48af')
def test_create_customer(self):
post_body = self._get_customer_params(quota=False)
test_cust_name = post_body['name']
_, body = self.client.create_customer(**post_body)
test_customer_id = body['customer']['id']
self.addCleanup(self._del_cust_validate_deletion_on_dcp_and_lcp,
test_customer_id)
self._wait_for_status(test_customer_id, 'Success')
_, body = self.client.get_customer(test_cust_name)
self.assertIn(test_customer_id, body['uuid'])
@decorators.idempotent_id('43785f87-27d5-408d-997f-de602caeb698')
def test_replace_customer(self):
customer = self._get_bare_customer_params()
customer['name'] = self.setup_customer['name']
customer['regions'] = [{'name': CONF.identity.region}]
_, body = self.client.update_customer(self.setup_customer_id,
customer)
self._wait_for_status(self.setup_customer_id, 'Success')
_, body = self.client.get_customer(self.setup_customer_id)
self.assertExpected(customer, body, ['name', 'regions'])
for region in customer['regions']:
self.assertIn(region['name'], [x['name'] for x in body['regions']])
@decorators.idempotent_id('e8b9077a-d45c-4e24-a433-e7dfa07486b9')
def test_delete_customer(self):
# setup data for test case
post_body = self._get_customer_params()
test_customer_id = self._create_cust_validate_creation_on_dcp_and_lcp(
**post_body)
# delete the data and do get_customer to ensure 404-NotFound response
self._del_cust_validate_deletion_on_dcp_and_lcp(test_customer_id)
self.assertRaises(exceptions.NotFound, self.client.get_customer,
test_customer_id)

View File

@ -1,42 +0,0 @@
# 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.
from aic_orm_tempest_plugin.tests.api import base
from tempest import config
CONF = config.CONF
class TestTempestCmsNegative(base.BaseOrmTest):
@classmethod
def setup_credentials(cls):
super(TestTempestCmsNegative, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(TestTempestCmsNegative, cls).setup_clients()
cls.client = cls.cmsclient
@classmethod
def resource_setup(cls):
cls.set_role_to_admin()
super(TestTempestCmsNegative, cls).resource_setup()
@classmethod
def resource_cleanup(cls):
cls.delete_role_to_admin()
super(TestTempestCmsNegative, cls).resource_cleanup()

View File

@ -1,408 +0,0 @@
# 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 json
from aic_orm_tempest_plugin.tests.api import fms_base
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
CONF = config.CONF
class TestTempestFms(fms_base.FmsBaseOrmTest):
@classmethod
def setup_credentials(cls):
super(TestTempestFms, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(TestTempestFms, cls).setup_clients()
cls.rms_client = cls.os_primary.rms_client
@classmethod
def resource_setup(cls):
# create flavor then save off flavor_id for use in test cases
body = cls._get_flavor_params()
cls.flavor = cls._create_flv_and_validate_creation_on_dcp_and_lcp(
**body)
# these variables will be used to test list filters
cls.flavor_id = cls.flavor['id']
cls.flavor_name = cls.flavor['name']
cls.visibility = cls.flavor['visibility']
cls.series = cls.flavor['series']
cls.tenant_id = cls.tenant_id
cls.region_id = CONF.identity.region
cls.alias = cls.flavor['alias']
cls.dflt_ex_specs = cls.flavor['extra-specs']
super(TestTempestFms, cls).resource_setup()
def _get_flavor_details(self, flavor_id):
_, body = self.client.get_flavor(flavor_id)
flavor = body["flavor"]
return flavor
def _data_setup(self, post_body):
flavor = self._create_flv_and_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_flv_and_validate_deletion_on_dcp_and_lcp,
flavor["id"])
return flavor
def _exec_tags_function(self, flavor_id, req_json, action, para):
if action == 'add':
_, body = self.client.add_tags(flavor_id, req_json)
elif action == 'update':
_, body = self.client.update_tags(flavor_id, req_json)
elif action == 'delete':
_, body = self.client.delete_tags(flavor_id, para)
self._wait_for_flavor_status_on_dcp(flavor_id, 'Success')
def _exec_ex_spec_function(self, flavor_id, es_body, action, para):
if action == 'add':
_, body = self.client.add_extra_specs(flavor_id, es_body)
elif action == 'update':
_, body = self.client.update_extra_specs(flavor_id, es_body)
elif action == 'delete':
_, body = self.client.delete_extra_specs(flavor_id, para)
self._wait_for_flavor_status_on_dcp(flavor_id, 'Success')
@classmethod
def resource_cleanup(cls):
# cls.delete_role_to_admin()
flavor_id = cls.flavor['id']
cls._del_flv_and_validate_deletion_on_dcp_and_lcp(flavor_id)
super(TestTempestFms, cls).resource_cleanup()
@decorators.idempotent_id('2a4481cd-acce-4a5d-af7c-940222a6238b')
def test_get_flavor(self):
""" execute get_flavor using flavor_id / flavor_name
"""
for para in [self.flavor_id, self.flavor_name]:
_, body = self.client.get_flavor(para)
self.assertIn(self.flavor_id, body["flavor"]["id"])
@decorators.idempotent_id('c46a503a-951c-4d00-afaa-46076b54db16')
def test_list_flavor_with_filters(self):
""" this function executes 'list flavors' with the following filters:
- None (no filters, i.e. list all flavors)
- alias filter
- region filter
- visibility filter
- 'contains' filter
- 'starts_with' filter
- 'series' filter
- "tenant" filter
"""
# for use by the 'constains and 'starts_with' filter
str_index1 = data_utils.rand_int_id(0, len(self.flavor_name) - 1)
str_index2 = data_utils.rand_int_id(str_index1 + 1,
len(self.flavor_name))
# define the list flavors filters to be used for this test
alias_filter = "?alias=%s" % self.alias
region_filter = "?region=%s" % self.region_id
visibility_filter = "?visibility=%s" % self.visibility
contains_filter = '?contains=%s' \
% self.flavor_name[str_index1:str_index2]
startswith_filter = "?starts_with=%s" % self.flavor_name[:str_index2]
series_filter = "?series=%s" % self.series
tenant_filter = "?tenant=%s" % self.tenant_id
for list_filter in [None, region_filter, visibility_filter,
alias_filter, contains_filter, startswith_filter,
series_filter, tenant_filter]:
_, body = self.client.list_flavors(list_filter)
flavor_ids = [flvr["id"] for flvr in body["flavors"]]
self.assertIn(self.flavor_id, flavor_ids)
@decorators.idempotent_id('7b9d1f91-a8a4-458d-aaad-a98b5bf033b4')
def test_create_flavor(self):
post_body = self._get_flavor_params()
# call client create_flavor and wait till status equals 'Success'
_, body = self.client.create_flavor(**post_body)
flavor = body["flavor"]
test_flvr_id = flavor['id']
self._wait_for_flavor_status_on_dcp(flavor["id"], 'Success')
# do not forget to add this account to addCleanUp
self.addCleanup(self._del_flv_and_validate_deletion_on_dcp_and_lcp,
flavor["id"])
# verify flavor record created successfully
flavor = self._get_flavor_details(test_flvr_id)
self.assertEqual(flavor["visibility"], "private")
self.assertEqual(flavor["regions"][0]["name"], CONF.identity.region)
self.assertEqual(flavor["status"], "Success")
@decorators.idempotent_id('4cad10ce-67d2-4633-b347-2c16783a31b9')
def test_add_flvr_tags(self):
# setup data for test case
post_body = self._get_flavor_params()
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
# test add_tags command with two sets of key:values
add_tag_body = {"tags": {"a": "b", "c": "d"}}
self._exec_tags_function(test_flvr_id, add_tag_body, 'add', None)
_, tag_body = self.client.get_tags(test_flvr_id)
self.assertDictEqual(add_tag_body.get("tags"), tag_body.get("tags"))
@decorators.idempotent_id('db8e5c0f-0041-45d4-9939-e079296123d8')
def test_replace_flvr_tags(self):
# setup data for test case and assign two tags
post_body = self._get_flavor_params()
tags = {}
tags["a"] = "b"
tags["c"] = "d"
post_body["tag"] = tags
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
# test replace_tags command
replace_tag_body = {"tags": {"e": "f", "g": "h"}}
self._exec_tags_function(test_flvr_id, replace_tag_body,
'update', None)
_, tag_body = self.client.get_tags(test_flvr_id)
self.assertDictEqual(replace_tag_body.get("tags"),
tag_body.get("tags"))
@decorators.idempotent_id('e0a0eca6-e120-45ab-a1a4-f5b95fdf97f1')
def test_delete_flvr_tag(self):
# setup data for test case and assign two tags
post_body = self._get_flavor_params()
tags = {}
tags["e"] = "f"
tags["g"] = "h"
post_body["tag"] = test_tag_body = tags
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
# test delete_tag command - delete the first key in tags body
delete_tag_key_e = "e"
self._exec_tags_function(test_flvr_id, None, 'delete',
delete_tag_key_e)
# do get_tag and confirm that resp body["tag"] now contains only
# second keypair
_, tag_body = self.client.get_tags(test_flvr_id)
test_tag_body.pop(delete_tag_key_e)
self.assertDictEqual(test_tag_body, tag_body.get("tags"))
@decorators.idempotent_id('9c511020-53ed-4139-8c53-451cb0ea8c75')
def test_delete_all_flvr_tags(self):
# setup data for test case
post_body = self._get_flavor_params()
tags = {}
tags["i"] = "j"
tags["k"] = "l"
post_body["tag"] = test_tag_body = tags
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
# before execute test, check that "tag" body is populated correctly
_, tag_body = self.client.get_tags(test_flvr_id)
self.assertDictEqual(test_tag_body, tag_body.get("tags"))
# test delete_all_tags command - run get_tag again and confirm
# that the tag dict is now empty
self._exec_tags_function(test_flvr_id, None, 'delete', None)
_, tag_body = self.client.get_tags(test_flvr_id)
# assert that tag_body contains nothing
self.assertFalse(tag_body["tags"])
@decorators.idempotent_id('ec74d68f-b42a-41a8-9685-ff5eca25ea0c')
def test_add_flvr_region(self):
# setup data for test case
post_body = self._get_flavor_params(set_region=False)
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
post_region_body = '{"regions": [{"name": "%s"}]}' % (self.region_id)
post_region_body = json.loads(post_region_body)
_, body = self.client.add_flvr_regions(test_flvr_id,
post_region_body)
self._wait_for_flavor_status_on_dcp(test_flvr_id, 'Success')
_, body = self.client.get_flavor(test_flvr_id)
self.assertEqual(body["flavor"]["regions"][0]["name"],
post_region_body["regions"][0]["name"])
@decorators.idempotent_id('5c7e6a94-89d2-4851-bf57-26371da7f47a')
def test_delete_flvr_region(self):
# setup data for test case
post_body = self._get_flavor_params()
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
# delete the region then check to confirm flavor status
_, body = self.client.delete_flvr_region(test_flvr_id,
self.region_id)
# flavor status must show 'no regions' when it has no region assigned
self._wait_for_flavor_status_on_dcp(test_flvr_id, 'no regions')
# flavor region is now empty after the lone region was removed
_, body = self.client.get_flavor(test_flvr_id)
self.assertTrue(len(body["flavor"]["regions"]) == 0)
@decorators.idempotent_id('71404409-5d95-472c-8dac-b49a1c0c4b37')
def test_add_flvr_extra_specs(self):
# setup data for test case
post_body = self._get_flavor_params()
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
test_dflt_ex_specs = flavor['extra-specs']
# add a custom extra spec
add_es_body = {"os_extra_specs": {"a": "apple"}}
self._exec_ex_spec_function(test_flvr_id, add_es_body, 'add',
None)
# assert extra specs add results match expected
test_dflt_ex_specs.update(add_es_body["os_extra_specs"])
_, flvr_ex_specs = self.client.get_extra_specs(test_flvr_id)
self.assertDictEqual(test_dflt_ex_specs,
flvr_ex_specs.get("os_extra_specs"))
@decorators.idempotent_id('043948fd-125b-4d96-bf40-42464066a7e1')
def test_update_flvr_extra_specs(self):
# setup data for test case
post_body = self._get_flavor_params()
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
test_dflt_ex_specs = flavor['extra-specs']
# run the test
add_es_body = {"os_extra_specs": {"a": "apple"}}
replace_es_body = {"os_extra_specs": {"a": "apple", "b": "banana"}}
# add one custom extra spec , then replace with additional extra spec
self._exec_ex_spec_function(test_flvr_id, add_es_body, 'add', None)
# then add another custom extra spec using update_extra_spec
self._exec_ex_spec_function(test_flvr_id, replace_es_body, 'update',
None)
# assert extra specs update results match expected
test_dflt_ex_specs.update(replace_es_body["os_extra_specs"])
_, flvr_ex_specs = self.client.get_extra_specs(test_flvr_id)
self.assertDictEqual(test_dflt_ex_specs,
flvr_ex_specs.get("os_extra_specs"))
@decorators.idempotent_id('df83e2cd-d202-4b2f-8459-391a73067ec5')
def test_delete_flvr_extra_spec(self):
# setup data for test case
post_body = self._get_flavor_params()
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
# run the test
add_es_body = {"os_extra_specs": {"g": "guava", "h": "honeydew"}}
delete_es_key_h = "h"
# add two custom extra specs then do get_extra_specs to save off
# the extra_spec add results
self._exec_ex_spec_function(test_flvr_id, add_es_body, 'add', None)
_, test_ex_specs = self.client.get_extra_specs(test_flvr_id)
# now delete one of the custom extra specs
self._exec_ex_spec_function(test_flvr_id, None, 'delete',
delete_es_key_h)
# assert extra specs update results match expected
test_ex_specs["os_extra_specs"].pop(delete_es_key_h)
_, flvr_ex_specs = self.client.get_extra_specs(test_flvr_id)
self.assertDictEqual(test_ex_specs["os_extra_specs"],
flvr_ex_specs.get("os_extra_specs"))
@decorators.idempotent_id('e3fc7ce3-c8fe-4805-8ad3-7be2c94fe7ad')
def test_delete_all_flvr_extra_specs(self):
# setup data for test case
post_body = self._get_flavor_params()
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
test_dflt_ex_specs = flavor['extra-specs']
# run the test
# add custom extra specs, then validate extra-spec add result
add_es_body = {"os_extra_specs": {"c": "carrots"}}
self._exec_ex_spec_function(test_flvr_id, add_es_body, 'add', None)
_, ex_specs_add_results = self.client.get_extra_specs(test_flvr_id)
self.assertIn("c", ex_specs_add_results["os_extra_specs"])
self.assertEqual("carrots",
ex_specs_add_results["os_extra_specs"]["c"])
# run delete ALL extra specs - note that this will only
# delete custom extra specs, NOT the default extra specs
self._exec_ex_spec_function(test_flvr_id, None, 'delete', None)
_, flvr_ex_specs = self.client.get_extra_specs(test_flvr_id)
# assert that flavor extra specs now contains only
# the default extra specs
self.assertDictEqual(test_dflt_ex_specs,
flvr_ex_specs.get("os_extra_specs"))
@decorators.idempotent_id('187195b5-adfb-4c73-a2f5-42117021f5f2')
def test_add_flvr_tenant(self):
# setup data for test case
post_body = self._get_flavor_params()
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
# check that flavor contains one tenant before testing add_flvr_tenant
flavor = self._get_flavor_details(test_flvr_id)
self.assertEqual(len(flavor["tenants"]), 1)
# test add_flvr_tenant by adding one more tenant
post_tenant_body = '{"tenants": ["%s"]}' % (self.alt_tenant_id)
post_tenant_body = json.loads(post_tenant_body)
_, body = self.client.add_flvr_tenants(test_flvr_id, post_tenant_body)
self._wait_for_flavor_status_on_dcp(test_flvr_id, 'Success')
# get flavor on same flavor id and confirm we have two tenants now
flavor = self._get_flavor_details(test_flvr_id)
self.assertEqual(len(flavor["tenants"]), 2)
@decorators.idempotent_id('a7c976cd-6064-4279-ab64-2575d091cdae')
def test_delete_flvr_tenant(self):
# setup data for test case and assign two tags
post_body = self._get_flavor_params(single_tenant=False)
flavor = self._data_setup(post_body)
test_flvr_id = flavor['id']
# checking that flavor created contains two tenants
flavor = self._get_flavor_details(test_flvr_id)
self.assertEqual(len(flavor["tenants"]), 2)
# delete one tenant, then wait until status = 'Success'
_, body = self.client.delete_flvr_tenant(test_flvr_id,
self.alt_tenant_id)
self._wait_for_flavor_status_on_dcp(test_flvr_id, 'Success')
# get flavor to confirm flavor["tenants"] now shows one tenant only
flavor = self._get_flavor_details(test_flvr_id)
self.assertEqual(len(flavor["tenants"]), 1)
@decorators.idempotent_id('36958bba-673e-4397-85a9-fddb01e9ca0d')
def test_delete_flavor(self):
# setup data for test case
post_body = self._get_flavor_params()
flavor = self._create_flv_and_validate_creation_on_dcp_and_lcp(
**post_body)
test_flvr_id = flavor['id']
# delete the data and do get_flavor to ensure 404-NotFound response
self._del_flv_and_validate_deletion_on_dcp_and_lcp(test_flvr_id)
self.assertRaises(exceptions.NotFound, self.client.get_flavor,
test_flvr_id)

View File

@ -1,44 +0,0 @@
# 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.
from aic_orm_tempest_plugin.tests.api import base
from tempest import config
CONF = config.CONF
class TestTempestFmsNegative(base.BaseOrmTest):
@classmethod
def setup_credentials(cls):
super(TestTempestFmsNegative, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(TestTempestFmsNegative, cls).setup_clients()
cls.client = cls.fmsclient
@classmethod
def resource_setup(cls):
cls.set_role_to_admin()
super(TestTempestFmsNegative, cls).resource_setup()
cls.env_name = cls.env_name
cls.tenant_id = cls.tenant_id
@classmethod
def resource_cleanup(cls):
cls.delete_role_to_admin()
super(TestTempestFmsNegative, cls).resource_cleanup()

View File

@ -1,299 +0,0 @@
# 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.
from aic_orm_tempest_plugin.tests.api import ims_base
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
CONF = config.CONF
class TestTempestIms(ims_base.ImsBaseOrmTest):
@classmethod
def setup_credentials(cls):
super(TestTempestIms, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(TestTempestIms, cls).setup_clients()
@classmethod
def resource_setup(cls):
# create an image for tempest testing
cls.image_params = cls._get_image_params()
cls.image = cls._create_img_and_validate_creation_on_dcp_and_lcp(
**cls.image_params)
# save off specific data needed for our tempest tests
cls.image_id = cls.image['id']
cls.image_name = cls.image['name']
# cls.visibility = cls.image['visibility']
# cls.tenant_id = cls.image["customers"][0]
super(TestTempestIms, cls).resource_setup()
@classmethod
def resource_cleanup(cls):
cls._del_img_validate_deletion_on_dcp_and_lcp(cls.image_id)
# cls.region_id)
super(TestTempestIms, cls).resource_cleanup()
def _data_setup(self, post_body):
image = self._create_img_and_validate_creation_on_dcp_and_lcp(
**post_body)
self.addCleanup(self._del_img_validate_deletion_on_dcp_and_lcp,
image["id"])
# only check for Success image status if "regions" is not empty
if image["regions"]:
self._wait_for_image_status_on_dcp(image["id"], 'Success')
return image
@decorators.idempotent_id('2b1bb28b-4151-4e75-ae1b-d21089c3418c')
def test_get_image(self):
''' Execute 'get_image' using the following options:
- get image by id (using cust_id parameter)
- get image by name (using cust_name parameter)
'''
# execute get_image using image ID and iamge_name
for identifier in [self.image_id, self.image_name]:
_, body = self.client.get_image(identifier)
self.assertIn(self.image_id, body['image']['id'])
@decorators.idempotent_id('6072c438-1e45-4c0b-97a6-e5127bd33d90')
def test_list_images_with_filters(self):
''' this function executes 'list customer' with all available filters:
- no filter (i.e. list all images)
- filter by region
- filter by customer
'''
# define the list customer filters to be used for this test
no_filter = None
customer_filter = "?customer=%s" % self.tenant_id
region_filter = "?region=%s" % self.region_id
# execute list_customers with the available filters
for list_filter in [no_filter, region_filter,
customer_filter]:
_, body = self.client.list_images(list_filter)
images = [image['id'] for image in body['images']]
self.assertIn(self.image_id, images)
@decorators.idempotent_id('eae7ca20-5383-4579-9f73-0138b8b3ec85')
def test_list_public_images(self):
''' list images with visibility = 'public'
'''
# set_private = False to create image with visibility = 'public'
post_body = self._get_image_params(set_private=False)
image = self._data_setup(post_body)
test_image_id = image['id']
# confirm image visibility is set to "public" after image is created
self.assertEqual(image["visibility"], "public")
filter_public_images = "?visibility=%s" % image["visibility"]
# list all public images and check if test_image_id is in the list
_, body = self.client.list_images(filter_public_images)
image_ids = [img['id'] for img in body['images']]
self.assertIn(test_image_id, image_ids)
@decorators.idempotent_id('dc321d60-f3bd-477c-b7bf-1594626f0a12')
def test_list_private_images(self):
''' list images with visibility = 'private'
'''
# image data created with visibility = private set by default
post_body = self._get_image_params()
image = self._data_setup(post_body)
test_image_id = image['id']
# confirm image visibility is set to "private" after image is created
self.assertEqual(image["visibility"], "private")
filter_private_images = "?visibility=%s" % image["visibility"]
# list all public images and check if test_image_id is in the list
_, body = self.client.list_images(filter_private_images)
image_ids = [img['id'] for img in body['images']]
self.assertIn(test_image_id, image_ids)
@decorators.idempotent_id('4435fef4-49a9-435b-8463-cf8a1e0b7cd8')
def test_disable_image(self):
# setup data for test case - "enabled" is set to "true" by default
post_body = self._get_image_params()
image = self._data_setup(post_body)
test_image_id = image['id']
# send False to IMS client enable_image function to disable customer
self.client.enabled_image(test_image_id, False)
self._wait_for_image_status_on_dcp(test_image_id, 'Success')
_, body = self.client.get_image(test_image_id)
image = body["image"]
# assert that the image["enabled"] value is 'False'
self.assertTrue(not image['enabled'])
@decorators.idempotent_id('f32a13e3-6f38-423b-a616-09c8d4e1c277')
def test_enable_image(self):
# setup data for test case - set_enabled is set to "False"
post_body = self._get_image_params(set_enabled=False)
image = self._data_setup(post_body)
test_image_id = image['id']
# send True to IMS client enable_image function to enable customer
self.client.enabled_image(test_image_id, True)
self._wait_for_image_status_on_dcp(test_image_id, 'Success')
_, body = self.client.get_image(test_image_id)
image = body["image"]
# assert that the image["enabled"] value is 'True'
self.assertTrue(image['enabled'])
@decorators.idempotent_id('cb9e3022-00d7-4a21-bdb2-67d3cd15a4f8')
def test_add_image_region(self):
# set_region = False to skip region assignment in data setup
post_body = self._get_image_params(set_region=False)
image = self._data_setup(post_body)
test_image_id = image['id']
# add region to image then check to confirm image status = "Success"
self.client.add_region_to_image(test_image_id, self.region_id)
# image status must show 'Success' when assigned to a region
self._wait_for_image_status_on_dcp(test_image_id, 'Success')
# check that image regions array is populated correctly
_, body = self.client.get_image(test_image_id)
image = body["image"]
self.assertEqual(image["regions"][0]["name"], self.region_id)
@decorators.idempotent_id('1be2d6fd-57b0-4acf-b895-1996f857739b')
def test_delete_image_region(self):
# setup data for test case
post_body = self._get_image_params()
image = self._data_setup(post_body)
test_image_id = image['id']
# delete the region then check to confirm image status = "no regions"
_, body = self.client.delete_region_from_image(test_image_id,
self.region_id)
# image status must show 'no regions' when it has no region assigned
self._wait_for_image_status_on_dcp(test_image_id, 'no regions')
# image region array should be empty after the region was removed
_, body = self.client.get_image(test_image_id)
image = body["image"]
self.assertFalse(image["regions"])
@decorators.idempotent_id('0ee68189-66a8-4213-ad68-bc12991c174a')
def test_add_image_tenant(self):
post_body = self._get_image_params()
image = self._data_setup(post_body)
test_image_id = image['id']
_, body = self.client.get_image(test_image_id)
self.assertNotIn(self.alt_tenant_id, body['image']['customers'])
# add another tenant to image then check if image status = "Success"
self.client.add_customer_to_image(test_image_id, self.alt_tenant_id)
self._wait_for_image_status_on_dcp(test_image_id, 'Success')
# check that image tenants array is populated correctly
_, body = self.client.get_image(test_image_id)
image = body["image"]
self.assertEqual(len(image["customers"]), 2)
self.assertIn(self.alt_tenant_id, body['image']['customers'])
@decorators.idempotent_id('bac99348-6b13-4b30-958b-3c039b27eda3')
def test_update_image_tenant(self):
post_body = self._get_image_params()
image = self._data_setup(post_body)
test_image_id = image['id']
_, body = self.client.get_image(test_image_id)
self.assertNotIn(self.alt_tenant_id, body['image']['customers'])
# add another tenant to image then check if image status = "Success"
self.client.update_customer(test_image_id, self.alt_tenant_id)
self._wait_for_image_status_on_dcp(test_image_id, 'Success')
# check that image tenants array is populated correctly
_, body = self.client.get_image(test_image_id)
image = body["image"]
self.assertEqual(len(image["customers"]), 1)
self.assertIn(self.alt_tenant_id, body['image']['customers'])
@decorators.idempotent_id('0506f23d-2d30-4214-9a4a-003ace86aa7d')
def test_delete_image_tenant(self):
# assign two tenants to image
post_body = self._get_image_params(single_tenant=False)
image = self._data_setup(post_body)
test_image_id = image['id']
_, body = self.client.get_image(test_image_id)
self.assertIn(self.alt_tenant_id, body['image']['customers'])
# delete one tenant then check if image status = "Success"
_, body = self.client.delete_customer_from_image(test_image_id,
self.alt_tenant_id)
self._wait_for_image_status_on_dcp(test_image_id, 'Success')
# image region array should be empty after the region was removed
_, body = self.client.get_image(test_image_id)
image = body["image"]
self.assertNotIn(self.alt_tenant_id, body['image']['customers'])
@decorators.idempotent_id('0331e02a-ab52-4341-b676-a02462244277')
def test_create_image(self):
post_body = self._get_image_params()
# call client create_IMAGE and wait till status equals 'Success'
_, body = self.client.create_image(**post_body)
image = body["image"]
test_image_id = image["id"]
self._wait_for_image_status_on_dcp(test_image_id, 'Success')
# do not forget to add this account to addCleanUp
self.addCleanup(self._del_img_validate_deletion_on_dcp_and_lcp,
test_image_id)
# verify image record created successfully
_, body = self.client.get_image(test_image_id)
image = body["image"]
self.assertEqual(image["regions"][0]["name"], CONF.identity.region)
@decorators.idempotent_id('01160918-e217-401d-a6a0-e7992ab76e41')
def test_update_image(self):
region = {}
post_body = self._get_image_params(set_region=False,
set_enabled=False)
image = self._data_setup(post_body)
test_image_id = image['id']
# setup region and change 'enabled' and 'customer' properties
region["name"] = self.region_id
region["type"] = "single"
region["checksum"] = "7297321c2fa6424417a548c85edd6e98"
region["virtual_size"] = "None"
region["size"] = "38797312"
post_body["regions"] = [region]
post_body["enabled"] = True
post_body["customers"] = [self.alt_tenant_id]
_, body = self.client.update_image(test_image_id, para=None,
**post_body)
self._wait_for_image_status_on_dcp(test_image_id, 'Success')
# verify image record updated successfully
_, body = self.client.get_image(test_image_id)
image = body["image"]
self.assertEqual(image["regions"][0]["name"], CONF.identity.region)
self.assertIn(self.alt_tenant_id, body['image']['customers'])
self.assertTrue(image['enabled'])
@decorators.idempotent_id('23e2e7e2-5b19-4c66-b35c-7c686a986627')
def test_delete_image(self):
# setup data for test case
post_body = self._get_image_params()
image = self._create_img_and_validate_creation_on_dcp_and_lcp(
**post_body)
test_image_id = image['id']
# delete the data and do get_image to ensure 404-NotFound response
self._del_img_validate_deletion_on_dcp_and_lcp(test_image_id)
self.assertRaises(exceptions.NotFound, self.client.get_image,
test_image_id)

View File

@ -1,47 +0,0 @@
# 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.
from aic_orm_tempest_plugin.tests.api import base
from tempest import config
CONF = config.CONF
class TestTempestImsNegative(base.BaseOrmTest):
@classmethod
def setup_credentials(cls):
super(TestTempestImsNegative, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(TestTempestImsNegative, cls).setup_clients()
cls.client = cls.imsclient
cls.servers_client = cls.servers_client
@classmethod
def resource_setup(cls):
cls.set_role_to_admin()
super(TestTempestImsNegative, cls).resource_setup()
cls.env_name = cls.env_name
cls.tenant_id = cls.tenant_id
cls.flavor_ref = CONF.compute.flavor_ref
cls.network_ref = CONF.network.public_network_id
@classmethod
def resource_cleanup(cls):
cls.delete_role_to_admin()
super(TestTempestImsNegative, cls).resource_cleanup()

View File

@ -1,85 +0,0 @@
# 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.
from aic_orm_tempest_plugin import data_utils as orm_data_utils
from aic_orm_tempest_plugin.tests.api import base
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
CONF = config.CONF
class TestTempestRegionGroup(base.BaseOrmTest):
@classmethod
def setup_credentials(cls):
super(TestTempestRegionGroup, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(TestTempestRegionGroup, cls).setup_clients()
cls.client = cls.os_primary.rms_client
@classmethod
def resource_setup(cls):
cls.setup_ids = []
cls.group_ids = []
# create standard region
_, cls.region_1 = cls.client.create_region(data_utils.rand_name())
cls.setup_ids.append(cls.region_1['id'])
# create region sharing region_1 properties
_, cls.region_2 = cls.client.create_region(data_utils.rand_name())
cls.setup_ids.append(cls.region_2['id'])
_, cls.group_1 = cls.client.create_region_group(
**orm_data_utils.rand_region_group([cls.setup_ids[0]])
)
cls.group_ids.append(cls.group_1['group']['id'])
_, cls.group_2 = cls.client.create_region_group(
**orm_data_utils.rand_region_group(cls.setup_ids)
)
cls.group_ids.append(cls.group_2['group']['id'])
super(TestTempestRegionGroup, cls).resource_setup()
@classmethod
def resource_cleanup(cls):
for region_id in cls.setup_ids:
cls.client.delete_region(region_id)
for group_id in cls.group_ids:
cls.client.delete_region_group(group_id)
super(TestTempestRegionGroup, cls).resource_cleanup()
@decorators.idempotent_id('0d377eb2-754d-49c1-9a4f-c7019dfe80ca')
def test_update_group(self):
id = self.group_ids[-1]
group = orm_data_utils.rand_region_group(self.setup_ids, id)
_, body = self.client.update_region_group(id, **group)
self.assertExpected(group, body['group'], ['regions'])
@decorators.idempotent_id('b946c6c4-d601-42b9-befd-ba40992a3c53')
def test_list_groups(self):
_, body = self.client.list_region_groups()
groups = [x['id'] for x in body['groups']]
self.assertIn(self.group_1['group']['id'], groups)
self.assertIn(self.group_2['group']['id'], groups)
@decorators.idempotent_id('9a37d966-4416-4ff3-8f3b-6847810662d7')
def test_get_group(self):
id = self.group_1['group']['id']
_, body = self.client.get_region_group(id)
self.assertExpected(self.group_1['group'], body, ['links'])

View File

@ -1,42 +0,0 @@
# 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.
from aic_orm_tempest_plugin.tests.api import base
from tempest import config
CONF = config.CONF
class TestTempestRegGroupNegative(base.BaseOrmTest):
@classmethod
def setup_credentials(cls):
super(TestTempestRegGroupNegative, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(TestTempestRegGroupNegative, cls).setup_clients()
cls.client = cls.rmsclient
@classmethod
def resource_setup(cls):
cls.set_role_to_admin()
super(TestTempestRegGroupNegative, cls).resource_setup()
@classmethod
def resource_cleanup(cls):
cls.delete_role_to_admin()
super(TestTempestRegGroupNegative, cls).resource_cleanup()

View File

@ -1,158 +0,0 @@
# 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.
from aic_orm_tempest_plugin import data_utils as orm_data_utils
from aic_orm_tempest_plugin.tests.api import rms_base
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
CONF = config.CONF
class TestTempestRegion(rms_base.RmsBaseOrmTest):
@classmethod
def resource_setup(cls):
cls.setup_ids = []
# create standard region
_, cls.region_1 = cls.client.create_region(data_utils.rand_name())
cls.setup_ids.append(cls.region_1['id'])
# create region sharing region_1 properties
_, cls.region_2 = cls.client.create_region(data_utils.rand_name())
cls.setup_ids.append(cls.region_2['id'])
# create region with differing properties
_, cls.region_3 = cls.client.create_region(
data_utils.rand_name(),
**{'status': 'down',
'aicVersion': '3.0',
'OSVersion': 'mitaka',
'CLLI': '123450',
'address': {'country': 'Mexico', 'state': 'Sonora',
'city': 'Nogales', 'street': '12 main',
'zip': '84000'},
'metadata': {'meta1': ['val1']},
'designType': 'large'})
cls.setup_ids.append(cls.region_3['id'])
super(TestTempestRegion, cls).resource_setup()
@classmethod
def resource_cleanup(cls):
for region_id in cls.setup_ids:
cls.client.delete_region(region_id)
super(TestTempestRegion, cls).resource_cleanup()
@decorators.idempotent_id('eecedcb0-9c96-453d-bd72-71dba26fa1c5')
def test_list_region(self):
_, body = self.client.list_regions()
regions = [x['id'] for x in body['regions']]
self.assertIn(self.region_1['id'], regions)
@decorators.idempotent_id('0164e040-7775-4837-9ac2-aaa0f71cdfca')
def test_list_region_v1(self):
_, body = self.client.list_regions_v1()
regions = [x['id'] for x in body]
self.assertIn(self.region_1['id'], regions)
@decorators.idempotent_id('e6c6fdfe-5fa2-45f5-8bd8-fb9cf79e99fc')
def test_list_region_with_name(self):
filter = {'regionname': self.region_1['name']}
self._list_regions_with_filter(filter, 'name')
@decorators.idempotent_id('b3310e32-0c31-4d37-9789-cc3c4639dabe')
def test_list_region_with_osversion(self):
filter = {'osversion': self.region_1['OSVersion']}
self._list_regions_with_filter(filter, 'OSVersion')
@decorators.idempotent_id('0b2d3e79-c14a-4527-94b0-04eeae053a80')
def test_list_region_with_status(self):
filter = {'status': self.region_1['status']}
self._list_regions_with_filter(filter, 'status')
@decorators.idempotent_id('871be582-ecaa-4a46-a403-4d6b5e59d7de')
def test_list_region_with_aicversion(self):
filter = {'aicversion': self.region_1['aicVersion']}
self._list_regions_with_filter(filter, 'aicVersion')
@decorators.idempotent_id('ac18be48-c787-4a65-913f-a0b0a80fbd1d')
def test_list_region_with_clli(self):
filter = {'clli': self.region_1['CLLI']}
self._list_regions_with_filter(filter, 'CLLI')
@decorators.idempotent_id('f2b2361d-ce71-43a8-9f01-acb529835880')
def test_list_region_with_metadata(self):
filter = {'metadata': self.region_1['metadata'].keys()[0]}
self._list_regions_with_filter(filter, 'metadata')
@decorators.idempotent_id('4533b31a-115d-466d-bf75-8ac24338c1a5')
def test_list_region_with_address(self):
filter = {
'country': self.region_1['address']['country'],
'city': self.region_1['address']['city'],
'street': self.region_1['address']['street'],
'zip': self.region_1['address']['zip']
}
self._list_regions_with_filter(filter, 'address')
@decorators.idempotent_id('726b8215-af10-4385-83c7-32b51502dff1')
def test_list_region_with_type(self):
filter = {'type': self.region_1['designType']}
self._list_regions_with_filter(filter, 'designType')
@decorators.idempotent_id('4875ea70-a5a1-4b46-b752-246221670d26')
def test_list_region_with_vlcp(self):
filter = {'vlcp_name': self.region_1['vlcpName']}
self._list_regions_with_filter(filter, 'vlcpName')
@decorators.idempotent_id('358f3cbc-4ae5-4b43-be36-6df55eae8fd9')
def test_get_region(self):
_, body = self.client.get_region(self.region_1['id'])
self.assertExpected(self.region_1, body, [])
@decorators.idempotent_id('cefb952f-7777-4878-87d2-d78ac345f0d2')
def test_get_region_metadata(self):
_, body = self.client.get_region_metadata(self.region_1['id'])
self.assertExpected(self.region_1['metadata'], body['metadata'], [])
@decorators.idempotent_id('b2c3baf5-22af-4bf9-bcad-b6a1a74e82d9')
def test_update_region(self):
id = self.setup_ids[-1]
region = orm_data_utils.rand_region(id)
_, body = self.client.update_region(id, **region)
self.assertExpected(region, body, [])
@decorators.idempotent_id('0d5644d8-92bc-497c-8fc5-b57417d86e6d')
def test_update_region_status(self):
status = {}
status['status'] = orm_data_utils.rand_region_status(
[self.region_1['status']])
_, body = self.client.update_region_status(self.region_1['id'], status)
self.assertExpected(status, body, ['links'])
@decorators.idempotent_id('5c1a2624-6abe-49e7-82c8-30e8df1377d0')
def test_update_region_metadata(self):
metadata = {}
metadata['metadata'] = orm_data_utils.rand_region_metadata()
_, body = self.client.update_region_metadata(self.region_1['id'],
metadata)
self.assertExpected(metadata, body, [])
def _list_regions_with_filter(self, filter, key):
_, body = self.client.list_regions(filter)
regions = [x for x in body['regions']]
self.assertTrue(
all([region[key] == self.region_1[key] for region in regions]))

View File

@ -1,42 +0,0 @@
# 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.
from aic_orm_tempest_plugin.tests.api import base
from tempest import config
CONF = config.CONF
class TestTempestRegionsNegative(base.BaseOrmTest):
@classmethod
def setup_credentials(cls):
super(TestTempestRegionsNegative, cls).setup_credentials()
@classmethod
def setup_clients(cls):
super(TestTempestRegionsNegative, cls).setup_clients()
cls.client = cls.rmsclient
@classmethod
def resource_setup(cls):
cls.set_role_to_admin()
super(TestTempestRegionsNegative, cls).resource_setup()
@classmethod
def resource_cleanup(cls):
cls.delete_role_to_admin()
super(TestTempestRegionsNegative, cls).resource_cleanup()

View File

@ -1,2 +0,0 @@
# An empty requirements file indicates the requirements are satisfied by
# openstack/tempest project's master branch on gerrit.mtn5.cci.att.com

View File

@ -1,6 +0,0 @@
import setuptools
setuptools.setup(
setup_requires=['pbr>=2.0.0'],
pbr=True
)

View File

@ -1,46 +0,0 @@
#!/bin/bash
set -e
export TERM=xterm-color
# =========================================================================
# This script will find all the changed python files and run
# 1. flake8
# 3. pylint
# for each of the changed file and provide the relevant output
# =========================================================================
TOXINIDIR=$1
CHECKTYPE=$2
POSTARGS=$3
PYLINTRCFILE=${TOXINIDIR}/pylintrc
FLAKERC=${TOXINIDIR}/flake8rc
# Find all the changed python files that needs to be checked / linted for
# ====================================================================
# If dev is passed as {postargs} then it is indicative that the
# check will be performed in a local dev environment
# Else it is indicative of a pipeline for container build process
# ====================================================================
if [[ "${POSTARGS}" = "dev" ]]; then
CHANGEDFILES=($(git status -s | grep -v 'D' | egrep '\.py' | awk -F ' ' '{print $2}' || true))
LENGTHARR=${#CHANGEDFILES[@]}
else
CHANGEDFILES=($(git diff-tree --no-commit-id --name-only --diff-filter AM -r HEAD | egrep '\.py' || true))
LENGTHARR=${#CHANGEDFILES[@]}
fi
for ((i=0;i<$LENGTHARR; i++));do
echo "$(tput setaf 4)============================================================$(tput setaf 9)"
echo "$(tput setaf 5) Performing check on ${CHANGEDFILES[i]}$(tput setaf 9)"
echo "$(tput setaf 4)============================================================$(tput setaf 9)"
echo ${CHANGEDFILES[i]}
if [[ "${CHECKTYPE}" = "flake" ]]; then
flake8 --config=$FLAKERC ${CHANGEDFILES[i]}
elif [[ "${CHECKTYPE}" = "pylint" ]]; then
pylint -rn --rcfile=$PYLINTRCFILE ${CHANGEDFILES[i]}
fi
done

View File

@ -1,18 +0,0 @@
[flake8]
ignore = E125,E123,E129
show-source = False
exclude =
.git,
.venv,
.tox,
dist,
doc,
*egg,
*.pyc,
*.egg-info,
.cache,
.eggs
enable-extensions = H106,H203,H904
import-order-style = google
filename = *.py

View File

@ -1,378 +0,0 @@
[MASTER]
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Pickle collected data for later comparisons.
persistent=yes
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=
# Use multiple processes to speed up Pylint.
jobs=1
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time. See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=protected-access,fixme,too-many-branches,
attribute-defined-outside-init,too-many-locals,
too-many-arguments,too-many-statements,
too-many-return-statements,too-few-public-methods,
import-error,too-many-lines,too-many-instance-attributes,
too-many-public-methods,duplicate-code,broad-except,
redefined-builtin,missing-docstring,no-member,bad-continuation,
bad-indentation,superfluous-parens,literal-comparison,unused-import,
no-self-use,unused-variable,anomalous-backslash-in-string,
line-too-long,len-as-condition,unnecessary-pass,
# Crashes, see #743.
redefined-variable-type,
# bug in 1.7.2 https://github.com/PyCQA/pylint/issues/1493
not-callable
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=parseable
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]".
files-output=no
# Tells whether to display a full report or only the messages
reports=no
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=4
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=no
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=_$|dummy
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=100
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
# List of optional constructs for which whitespace checking is disabled
no-space-check=trailing-comma,dict-separator
# Maximum number of lines in a module
max-module-lines=1000
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
[BASIC]
# List of builtins function names that should not be used, separated by a comma
bad-functions=map,filter,input
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$
# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,75}$
# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=__.*__
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# List of decorators that define properties, such as abc.abstractproperty.
property-classes=abc.abstractproperty
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis
ignored-modules=
# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set).
ignored-classes=SQLObject, optparse.Values, thread._local, _thread._local
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=REQUEST,acl_users,aq_parent
# List of decorators that create context managers from functions, such as
# contextlib.contextmanager.
contextmanager-decorators=contextlib.contextmanager
[SPELLING]
# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no
[DESIGN]
# Maximum number of arguments for function / method
max-args=5
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
[CLASSES]
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception

View File

@ -1,190 +0,0 @@
# Copyright 2017
# 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
_status = {
'type': 'string',
'enum': ['Success', 'no regions', 'Error', 'Pending', 'Submitted']
}
_links = {
'type': 'object',
'properties': {
'self': {'type': 'string'}
},
'required': ['self']
}
_region = {
'type': 'object',
'properties': {
'added': {'type': 'string'},
'id': {'type': 'string'},
'links': _links
},
'required': ['added', 'id', 'links']
}
_user = {
'type': 'object',
'properties': {
'added': {'type': 'string', 'format': 'date-time'},
'id': {'type': 'string'},
'links': _links
},
'required': ['added', 'id', 'links']
}
_customer = {
'type': 'object',
'properties': {
'id': {'type': 'string'},
'links': _links,
'created': {'type': 'string', 'format': 'date-time'}
},
'required': ['id', 'links', 'created']
}
create_customer = {
'status_code': [201],
'response_body': {
'type': 'object',
'properties': {
'customer': _customer,
'transaction_id': {'type': 'string'}
},
'required': ['customer', 'transaction_id']
}
}
update_customer = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'customer': _customer,
'transaction_id': {'type': 'string'}
},
'required': ['customer', 'transaction_id']
}
}
add_regions = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'regions': {
'type': 'array',
'items': _region
},
'transaction_id': {'type': 'string'}
},
'required': ['regions', 'transaction_id']
}
}
add_users = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'users': {
'type': 'array',
'items': _user
},
'transaction_id': {'type': 'string'}
},
'required': ['users', 'transaction_id']
}
}
replace_users = add_users
add_metadata = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'customer': _customer,
'transaction_id': {'type': 'string'}
},
'required': ['customer', 'transaction_id']
}
}
replace_metadata = add_metadata
enable_customer = add_metadata
get_customer = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'status': _status,
'uuid': {'type': 'string'},
'users': {'type': 'array'},
'description': {'type': 'string'},
'enabled': {'type': 'boolean'},
'defaultQuotas': {'type': 'array'},
'name': {'type': 'string'},
'regions': {'type': 'array'},
'custId': {'type': 'string'},
'metadata': {'type': 'object'}
},
'required': ['status', 'uuid', 'users', 'description', 'enabled',
'defaultQuotas', 'name', 'regions', 'custId', 'metadata']
}
}
list_customer = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'customers': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'status': _status,
'description': {'type': 'string'},
'enabled': {'type': 'boolean'},
'num_regions': {'type': 'integer'},
'regions': {
'type': 'array',
'items': {'type': 'string'}
},
'id': {'type': 'string'},
'name': {'type': 'string'}
},
'required': ['status', 'description', 'enabled',
'num_regions', 'regions', 'id', 'name']
}
}
},
'required': ['customers']
}
}
delete_customer = {
'status_code': [204]
}
delete_region_from_customer = delete_customer
delete_default_user = delete_customer
delete_user_from_region = delete_customer

View File

@ -1,257 +0,0 @@
# Copyright 2017
# 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
_regions = {
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {"type": "string"},
"type": {"type": "string"},
"name": {"type": "string"},
"error_message": {"type": "string"}
}
},
"required": ["status", "type", "name"]
}
_extra_specs = {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
_tags = {
"type": "object",
"items": {
"type": "array",
"items": {"type": "string"}
}
}
_tenants = {
"type": "array",
"items": {
"type": "string"
}
}
_flavor = {
"type": "object",
"properties": {
"flavor": {
"type": "object",
"properties": {
"status": {"type": "string"},
"alias": {"type": "string"},
"description": {"type": "string"},
"tags": _tags,
"series": {
"type": "string",
"enum": ["gv", "nd", "ns", "nv", "ss"]
},
"extra-specs": _extra_specs,
"ram": {
"type": "string",
"pattern": "^[0-9]+$"
},
"ephemeral": {
"type": "string",
"pattern": "^[0-9]+$"
},
"visibility": {
"type": "string",
"enum": ["public", "private"]
},
"options": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"regions": _regions,
"vcpus": {
"type": "string",
"pattern": "^[0-9]+$"
},
"swap": {
"type": "string",
"pattern": "^[0-9]+$"
},
"disk": {
"type": "string",
"pattern": "^[0-9]+$"
},
"tenants": _tenants,
"id": {"type": "string"},
"name": {"type": "string"}
},
"required": ["status", "series", "extra-specs",
"ram", "ephemeral", "visibility", "vcpus",
"regions", "swap", "disk", "tenants",
"id", "name"]
}
},
"required": ["flavor"]
}
create_flavor = {
"status_code": [201],
"response_body": _flavor
}
get_flavor = {
"status_code": [200],
"response_body": _flavor
}
delete_flavor = {
"status_code": [204]
}
list_flavors = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"flavors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {"type": "string"},
"description": {"type": "string"},
"tags": _tags,
"series": {
"type": "string",
"enum": ["gv", "nd", "ns", "nv", "ss"]
},
"extra-specs": _extra_specs,
"ram": {
"type": "string",
"pattern": "^[0-9]+$"
},
"ephemeral": {
"type": "string",
"pattern": "^[0-9]+$"
},
"visibiity": {
"type": "string",
"enum": ["public", "private"]
},
"options": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"regions": _regions,
"vcpus": {
"type": "string",
"pattern": "^[0-9]+$"
},
"swap": {
"type": "string",
"pattern": "^[0-9]+$"
},
"disk": {
"type": "string",
"pattern": "^[0-9]+$"
},
"tenants": _tenants,
"id": {"type": "string"},
"name": {"type": "string"}
},
"required": ["status", "description", "series",
"extra-specs", "ram", "ephemeral",
"visibility", "vcpus", "regions", "swap",
"disk", "tenants", "id", "name"]
}
}
},
"required": ["flavors"]
}
}
get_extra_specs = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
'os_extra_specs': _extra_specs
}
}
}
add_extra_specs = {
"status_code": [201],
'response_body': {
'type': 'object',
'properties': {
'os_extra_specs': _extra_specs
}
}
}
update_extra_specs = get_extra_specs
delete_extra_specs = {
"status_code": [204]
}
add_tags = {
'status_code': [201],
'response_body': _tags
}
delete_tags = {
"status_code": [204]
}
get_tags = {
'status_code': [200],
'response_body': _tags
}
update_tags = get_tags
add_region = {
'status_code': [201],
'response_body': {
'type': 'object',
'properties': {
'regions': _regions
}
}
}
delete_region = {
"status_code": [204]
}
add_tenant = {
'status_code': [201],
'response_body': {
'type': 'object',
'properties': {
'tenants': _tenants
}
}
}
delete_tenant = {
"status_code": [204]
}

View File

@ -1,201 +0,0 @@
# Copyright 2017
# 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
_region_status = {
"type": "string",
"enum": ["Submitted", "Pending", "Success", "Error"]
}
_regions = {
"type": "array",
"items": {
"type": "object",
"properties": {
"status": _region_status,
"name": {"type": "string"},
"checksum": {"type": "string"},
"size": {"type": "string"},
"virtual_size": {"type": "string"},
"type": {"type": "string"},
"error_message": {"type": "string"}
}
}
}
_tags = {
"type": "array",
"items": {
"type": "string"
}
}
_status = {
"type": "string",
"enum": ["Success", "no regions", "Error", "Pending"]
}
_links = {
"type": "object",
"properties": {
"self": {"type": "string"}
},
"required": ["self"]
}
_image = {
"type": "object",
"properties": {
"image": {
"type": "object",
"properties": {
"enabled": {"type": "boolean"},
"links": {
"type": "object",
"items": {
"self": {"type": "string"}
}
},
"locations": {
"type": "array",
"items": {
"type": "string"
}
},
"file": {"type": "string"},
"owner": {"type": "string"},
"id": {"type": "string"},
"self": {"type": "string"},
"created-at": {"type": "string"},
"updated-at": {"type": "string"},
"regions": _regions,
"disk-format": {"type": "string"},
"min-ram": {
"type": "number"
},
"schema": {"type": "string"},
"status": _status,
"customers": {
"type": "array",
"items": {
"type": "string"
}
},
"tags": _tags,
"visibility": {
"type": "string",
"enum": ["public", "private"]
},
"min-disk": {
"type": "number"
},
"properties": {
"type": "object",
"items": {
"type": "array",
"items": {"type": "string"}
}
},
"name": {"type": "string"},
"url": {"type": "string"},
"protected": {
"type": "boolean"
},
"container-format": {"type": "string"}
},
"required": ["links", "enabled", "locations", "file",
"status", "owner", "id", "self", "disk-format",
"min-ram", "properties", "visibility",
"regions", "schema", "min-disk", "customers",
"protected", "url", "name", "container-format"]
}
},
"required": ["image"]
}
create_image = {
"status_code": [201],
"response_body": _image
}
add_tenant_to_image = {
"status_code": [201],
"response_body": _image
}
get_image = {
"status_code": [200],
"response_body": _image
}
update_tenant = get_image
update_image = get_image
delete_image = {
"status_code": [204]
}
delete_tenant_from_image = {
"status_code": [204]
}
add_region = {
"status_code": [200, 201],
'response_body': {
'type': 'object',
'properties': {
'regions': _regions
}
}
}
delete_region = delete_image
_region_names_array = {
"type": "array",
"items": {
"type": "string"
}
}
list_images = {
"status_code": [200],
"response_body": {
"type": "object",
"properties": {
"images": {
"type": "array",
"items": {
"type": "object",
"properties": {
"status": _status,
"regions": _region_names_array,
"name": {"type": "string"},
"visibiity": {
"type": "string",
"enum": ["public", "private"]
},
"id": {"type": "string"}
},
"required": ["status", "regions", "name",
"visibility", "id"]
}
}
},
"required": ["images"]
}
}
enable_image_resp = get_image

View File

@ -1,31 +0,0 @@
[metadata]
name = ranger_plugin
version = 0.0.1
summary = Basic Tempest plugin for Orm with a mos tempest smoke test case
description-file =
author =
author-email =
home-page =
classifier =
Development Status :: 4 - Beta
Environment :: Console
Environment :: OpenStack
Intended Audience :: OpenStack Development Team
Intended Audience :: OpenStack QA Team
Intended Audience :: Information Technology
Operating System :: Linux
Natural Language :: English
Topic :: Software Development :: Quality Assurance
Topic :: Software Development :: Testing
Programming Language :: Python
keywords =
Plugin
Tempest
OpenStack
[entry_points]
tempest.test_plugins =
ranger = ranger_tempest_plugin.plugin:OrmPlugin
[pbr]
warnerrors = true

View File

@ -1,6 +0,0 @@
import setuptools
setuptools.setup(
setup_requires=['pbr>=2.0.0'],
pbr=True
)

View File

@ -1,71 +0,0 @@
[tox]
minversion = 1.6
envlist = py27,pep8,pylint
skipdist = True
[testenv]
usedevelop = True
install_command = pip install {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
commands =
find . -type f -name "*.pyc" -delete
whitelist_externals =
find
[testenv:venv]
commands = {posargs}
#Linters
[testenv:pep8]
sitepackages = True
basepython = python
deps =
flake8>=2.6.2, <3.4.0
flake8-import-order>=0.9, <0.13
commands =
bash changed_python_files.sh {toxinidir} "flake" {posargs}
whitelist_externals =
bash
# For use in development environment
[testenv:pep8dev]
sitepackages = True
basepython = python
skip_install = true
deps =
{[testenv:pep8]deps}
commands =
{[testenv:pep8]commands} dev
whitelist_externals =
bash
# At this time we are only checking for C0103(invalid-name) which in the near
# future will be expanded upon
[testenv:pylint]
sitepackages = True
basepython = python
deps =
pylint==1.7.2
commands =
bash changed_python_files.sh {toxinidir} "pylint" {posargs}
whitelist_externals =
bash
# For use in development environment
[testenv:pylintdev]
sitepackages = True
basepython = python
skip_install = true
deps =
{[testenv:pylint]deps}
commands =
{[testenv:pylint]commands} dev
whitelist_externals =
bash

View File

@ -4,31 +4,31 @@ set -e
echo "Starting the audit service" echo "Starting the audit service"
nohup orm-audit > /dev/null 2>&1 & nohup orm-audit > /dev/null 2>&1&
echo "Starting the uuidgen service" echo "Starting the uuidgen service"
nohup orm-uuidgen > /dev/null 2>&1 & nohup orm-uuidgen > /dev/null 2>&1&
echo "Starting the rds service" echo "Starting the rds service"
nohup orm-rds > /dev/null 2>&1 & nohup orm-rds > /dev/null 2>&1&
echo "Starting the rms service" echo "Starting the rms service"
nohup orm-rms > /dev/null 2>&1 & nohup orm-rms > /dev/null 2>&1&
echo "Starting the cms service" echo "Starting the cms service"
nohup orm-cms > /dev/null 2>&1 & nohup orm-cms > /dev/null 2>&1&
echo "Starting the ims service" echo "Starting the ims service"
nohup orm-ims > /dev/null 2>&1 & nohup orm-ims > /dev/null 2>&1&
echo "Starting the fms service" echo "Starting the fms service"
nohup orm-fms > /dev/null 2>&1 & nohup orm-fms > /dev/null 2>&1&