Generate tempest.conf automatically using refstack-client

Usage: $ refstack-client config --use-test-accounts <path to test
         accounts file>

If not accounts.yaml is passed then:
  $ refstack-client config
  It will generate accounts.yaml and tempest.conf in etc folder

* It adds support for the above command
* Added zuul based devstack job to run the same
* let setup_env handles the installation of tempestconf
* updated git url for tempest
* It also generates accounts.yaml if no account file is
  passed
* we can --overrides flag to overrides the tempest.conf
  value.
* volume-feature-enabled.api_v2=True is added as default
  in overrides as it is deprecated in Rocky cycle but needed
  for interop tests.

Depends-On: https://review.openstack.org/589260
Story: 2001696
Task: 19758

Change-Id: I9cabfc52672e7a8a54792ca9d867c62babf12cb7
This commit is contained in:
Chandan Kumar 2018-04-24 11:02:58 +05:30
parent a13a5a4375
commit e1744ea1e4
8 changed files with 286 additions and 4 deletions

36
.zuul.yaml Normal file
View File

@ -0,0 +1,36 @@
- project:
check:
jobs:
- refstack-client-devstack-tempestconf
- openstack-tox-py35
gate:
jobs:
- refstack-client-devstack-tempestconf
- openstack-tox-py35
- job:
name: refstack-client-devstack-tempestconf
parent: devstack
description: |
Refstack client job for testing python-tempestconf and RefStack Integration
required-projects:
- openstack/refstack-client
- openstack/tempest
- openstack-dev/devstack
- openstack/python-tempestconf
roles:
- zuul: openstack/python-tempestconf
- zuul: openstack/tempest
- zuul: openstack-dev/devstack
- zuul: openstack/refstack-client
run: playbooks/tempestconf-refstack-devstack.yaml
vars:
user: demo
cloud_user: devstack
test_demo: True
cloud_admin: devstack-admin
irrelevant-files:
- config_tempest/tests/.*$
- ^doc/.*$
- ^releasenotes/.*$
- ^.*\.rst$

View File

@ -59,11 +59,24 @@ Usage
source .venv/bin/activate
4. Validate your setup by running a short test::
4. Generate tempest.conf using refstack-client::
refstack-client config --use-test-accounts <path to account file>
The above command will create the tempest.conf in `etc` folder.
Note: If account file is not available, then:
* Source the keystonerc file containing cloud credentials and run::
refstack-client config
It will create accounts.yaml and temepst.conf file in `etc` folder.
5. Validate your setup by running a short test::
refstack-client test -c <Path of the tempest configuration file to use> -v -- --regex tempest.api.identity.v3.test_tokens.TokensV3Test.test_create_token
5. Run tests.
6. Run tests.
To run the entire API test set::

View File

@ -0,0 +1,40 @@
- hosts: all
roles:
- run-devstack
- hosts: tempest
vars:
set_auth_url: "OS_AUTH_URL=$SERVICE_PROTOCOL://$SERVICE_HOST/identity/v3"
devstack_base_dir: "/opt/stack"
aditional_tempestconf_params: "auth.tempest_roles Member"
tasks:
- name: Setup Tempest Run Directory
include_role:
name: setup-tempest-run-dir
- name: Setup Tempest Data Directory
include_role:
name: setup-tempest-data-dir
- name: ACL devstack files
include_role:
name: acl-devstack-files
- name: Generate configuration file for Tempest as admin
include_role:
name: generate-tempestconf-file
vars:
output_path: "/etc/openstack/tempest_admin.conf"
source_credentials_commands: "export HOST_IP={{ ansible_default_ipv4.address }}; source {{ devstack_base_dir }}/devstack/openrc admin admin; {{ set_auth_url }}"
user: admin
- name: Generate accounts.yaml file for Demo
include_role:
name: generate-accounts-file
vars:
aditional_tempestconf_params: "auth.tempest_roles Member"
source_credentials_commands: "export HOST_IP={{ ansible_default_ipv4.address }}; source {{ devstack_base_dir }}/devstack/openrc admin admin; {{ set_auth_url }}"
accounts_file_destination: "/etc/openstack"
tempest_config_file: "/etc/openstack/tempest_admin.conf"
- name: Generate tempest.conf using refstack-client and run tempest tests
include_role:
name: generate-tempestconf-refstack
vars:
source_credentials_commands: "export HOST_IP={{ ansible_default_ipv4.address }}; source {{ devstack_base_dir }}/devstack/openrc {{ user }} {{ user }}; {{ set_auth_url }}"
user: demo

View File

@ -42,6 +42,11 @@ from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from config_tempest import main
from config_tempest import constants as C
from keystoneauth1 import exceptions as KE
from openstack import exceptions as OSE
import requests
import requests.exceptions
from six import moves
@ -408,6 +413,74 @@ class RefstackClient:
resp = response.json()
print('Test results uploaded!\nURL: %s' % resp.get('url', ''))
def generate_tempest_config(self):
'''Generate tempest.conf for a deployed OpenStack Cloud.'''
self.logger.info("Generating tempest.conf")
start_time = time.time()
# Write tempest.conf in refstack_client folder
if not self.args.out:
config_path = os.path.join(self.refstack_dir, 'tempest.conf')
else:
config_path = self.args.out
# Generate Tempest configuration
try:
cloud_creds = main.get_cloud_creds(self.args)
except KE.MissingRequiredOptions as e:
self.logger.error("Credentials are not sourced - %s" % e)
except OSE.ConfigException:
self.logger.error("Named cloud %s was not found"
% self.args.os_cloud)
# tempestconf arguments
kwargs = {'non_admin': True,
'test_accounts': self.args.test_accounts,
'image_path': self.args.image,
'network_id': self.args.network_id,
'out': config_path,
'cloud_creds': cloud_creds}
# Look for extra overrides to be replaced in tempest.conf
# (TODO:chkumar246) volume-feature-enabled.api_v2=True is deprecated
# in ROCKY release, but it is required for interop tests and it is out
# of scope of python-tempestconf, adding it hardcoded here as a extra
# overrides.
cinder_overrides = "volume-feature-enabled.api_v2=True"
overrides_format = cinder_overrides.replace('=', ' ').split()
if self.args.overrides:
if cinder_overrides not in self.args.overrides:
overrides = self.args.overrides.replace('=', ' ').split(',')
extra_overrides = overrides.append(overrides_format)
else:
extra_overrides = overrides_format
kwargs.update({'overrides': main.parse_overrides(extra_overrides)})
# Generate accounts.yaml if accounts.file is not given
if not self.args.test_accounts:
account_file = os.path.join(self.refstack_dir, 'accounts.yaml')
kwargs.update({'create_accounts_file': account_file})
self.logger.info('Account file will be generated at %s.'
% account_file)
# Generate tempest.conf
main.config_tempest(**kwargs)
if os.path.isfile(config_path):
end_time = time.time()
elapsed = end_time - start_time
duration = int(elapsed)
self.logger.info('Tempest Configuration successfully generated '
'in %s second at %s' % (duration, config_path))
else:
try:
import config_tempest # noqa
self.logging.warning('There is an error in syntax, please '
'check $ refstack-client config -h')
except ImportError:
self.logger.warning('Please make sure python-tempestconf'
'python package is installed')
def test(self):
'''Execute Tempest test against the cloud.'''
self._prep_test()
@ -707,6 +780,62 @@ def parse_cli_args(args=None):
parser_subunit_upload.set_defaults(func="upload_subunit")
# Config Command
parser_config = subparsers.add_parser(
'config', parents=[shared_args, network_args],
help='Generate tempest.conf for a cloud')
parser_config.add_argument('--use-test-accounts',
action='store',
required=False,
dest='test_accounts',
type=str,
help='Path of the accounts.yaml file.')
parser_config.add_argument('--network-id',
action='store',
required=False,
dest='network_id',
help='The ID of an existing network in our '
'openstack instance with external '
'connectivity')
parser_config.add_argument('--image',
action='store',
required=False,
dest='image',
help='An image name chosen from `$ openstack '
'image list` or a filepath/URL of an '
'image to be uploaded to glance and set '
'as a reference to be used by tests. The '
'name of the image is the leaf name of '
'the path. Default is %s'
% C.DEFAULT_IMAGE)
parser_config.add_argument('--out',
action='store',
required=False,
dest='out',
help='File path to write tempest.conf')
parser_config.add_argument('--os-cloud',
action='store',
required=False,
dest='os_cloud',
help='Named cloud to connect to.')
parser_config.add_argument('--overrides',
action='store',
required=False,
dest='overrides',
help='Comma seperated values which needs to be'
'overridden in tempest.conf.'
'Example --overrides'
'compute.image_ref=<value>,'
'compute.flavor_ref=<value>')
parser_config.set_defaults(func='generate_tempest_config')
# Test command
parser_test = subparsers.add_parser(
'test', parents=[shared_args, network_args],

View File

@ -0,0 +1,3 @@
cloud_user: "devstack"
virtualenvs:
refstack_client: "~/.virtualenvs/.refstack_client"

View File

@ -0,0 +1,49 @@
- block:
- name: Install refstack-client and python-tempestconf
shell: |
set -ex
export PATH=$PATH:/usr/local/sbin:/usr/sbin
./setup_env
args:
chdir: "{{ refstack_client_src_relative_path }}"
executable: /bin/bash
- name: Print Tempest account file
shell: |
set -ex
cat /etc/openstack/accounts.yaml
- name: Generate tempest configuration file
shell: |
set -ex
export PATH=$PATH:/usr/local/sbin:/usr/sbin
source .venv/bin/activate
{{ source_credentials_commands }}
printenv
refstack-client config --use-test-accounts /etc/openstack/accounts.yaml \
--image http://download.cirros-cloud.net/0.3.5/cirros-0.3.5-x86_64-disk.img \
--out /tmp/tempest.conf
args:
chdir: "{{ refstack_client_src_relative_path }}"
executable: /bin/bash
- name: Print generated tempest.conf
shell: |
set -ex
cat /tmp/tempest.conf
- name: Run refstack-client tests
shell: |
set -ex
export PATH=$PATH:/usr/local/sbin:/usr/sbin
source .venv/bin/activate
printenv
refstack-client test -c /tmp/tempest.conf \
-v --test-list "https://refstack.openstack.org/api/v1/guidelines/2017.09/tests?target=platform&type=required&alias=true&flag=false"
args:
chdir: "{{ refstack_client_src_relative_path }}"
executable: /bin/bash
vars:
refstack_client_src_relative_path: "{{ zuul.projects['git.openstack.org/openstack/refstack-client'].src_dir }}"
tempestconf_src_relative_path: "{{ zuul.projects['git.openstack.org/openstack/python-tempestconf'].src_dir }}"

View File

@ -62,7 +62,7 @@ done
WORKDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TEMPEST_DIR=${REFSTACK_CLIENT_TEMPEST_DIR:-${WORKDIR}/.tempest}
TEMPESTCONF_DIR=${REFSTACK_CLIENT_TEMPEST_DIR:-${WORKDIR}/.tempestconf}
# Checkout tempest on specified tag
if [ -d "${TEMPEST_DIR}" ]; then
[ ${QUIET_MODE} ] && echo 'Looks like RefStack client is already installed' && exit 0
@ -108,7 +108,9 @@ else
exit 1
fi
git clone https://github.com/openstack/tempest.git ${TEMPEST_DIR}
git clone https://git.openstack.org/openstack/python-tempestconf.git ${TEMPESTCONF_DIR}
git clone https://git.openstack.org/openstack/tempest.git ${TEMPEST_DIR}
cd ${TEMPEST_DIR}
git checkout $CHECKOUT_POINT || if [ $? -ne 0 ]; then exit 1; fi
@ -165,6 +167,9 @@ cd ..
rm -rf virtualenv-${VENV_VERSION}
rm virtualenv-${VENV_VERSION}.tar.gz
${WORKDIR}/.venv/bin/python -m pip install -e .
cd ${TEMPESTCONF_DIR}
${WORKDIR}/.venv/bin/python -m pip install -e .
cd ..
${TEMPEST_DIR}/.venv/bin/python -m pip install ${TEMPEST_DIR}
# Add additional packages to find more tests by tempest

View File

@ -11,7 +11,14 @@ setenv = VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
bash -c "if [ -d ./.tox/py27 ]; then \
pip install -q -U -e 'git+https://git.openstack.org/openstack/python-tempestconf@master#egg=python_tempestconf' ;\
elif [ -d ./.tox/py35 ]; then \
pip3 install -q -U -e 'git+https://git.openstack.org/openstack/python-tempestconf@master#egg=python_tempestconf' ; fi "
stestr run {posargs}
whitelist_externals =
bash
distribute = false
[testenv:pep8]