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:
parent
a13a5a4375
commit
e1744ea1e4
36
.zuul.yaml
Normal file
36
.zuul.yaml
Normal 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$
|
17
README.rst
17
README.rst
@ -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::
|
||||
|
||||
|
40
playbooks/tempestconf-refstack-devstack.yaml
Normal file
40
playbooks/tempestconf-refstack-devstack.yaml
Normal 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
|
@ -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],
|
||||
|
3
roles/generate-tempestconf-refstack/defaults/main.yaml
Normal file
3
roles/generate-tempestconf-refstack/defaults/main.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
cloud_user: "devstack"
|
||||
virtualenvs:
|
||||
refstack_client: "~/.virtualenvs/.refstack_client"
|
49
roles/generate-tempestconf-refstack/tasks/main.yaml
Normal file
49
roles/generate-tempestconf-refstack/tasks/main.yaml
Normal 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 }}"
|
@ -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
|
||||
|
7
tox.ini
7
tox.ini
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user