From 8760b9cde9994a3be3b2b4d4c970d14a6b5e2a73 Mon Sep 17 00:00:00 2001 From: vponomaryov Date: Mon, 27 Oct 2014 18:21:25 +0200 Subject: [PATCH] Implement functionality for functional tests using tempest-lib Add generic functionality for functional tests using tempest-lib and create related tox jobs. Run of functional tests requires: 1) Access to deployed OpenStack with running, at least, Keystone and Manila services. 2) Defined config options to be able to execute requests to Manila, Manilaclient should know auth related information like username, password, tenant_name, etc... 3) Run of functional tests searches for following optional env vars to be set: 'OS_MANILACLIENT_CONFIG_FILE' - name of conf file, default 'manilaclient.conf' 'OS_MANILACLIENT_CONFIG_DIR' - path to conf dir, default '%project_dir%/etc/manilaclient' 'OS_MANILA_EXEC_DIR' - path to dir with manilaclient executable, default '%project_dir%/.tox/functional/bin' 4) Config sample can be generated by following new tox job: $ tox -egenconfig it will create sample in "%project_dir%/etc/manilaclient/manilaclient.conf.sample" then just rename it removing ".sample" part and set option values. To run functional tests use following new tox job: $ tox -efunctional To run only some specific tests use following: $ tox -efunctional manilaclient.tests.functional.foo.bar Partially implements blueprint functional-tests Change-Id: I95a4e441d2143e51c54ec4fb47a069a91ed77dd7 --- .gitignore | 2 + .testr.conf | 2 +- etc/manilaclient/README.manilaclient.conf | 4 + etc/oslo-config-generator/manilaclient.conf | 3 + manilaclient/config.py | 106 ++++++++++++++++++++ manilaclient/tests/functional/__init__.py | 0 manilaclient/tests/functional/base.py | 48 +++++++++ manilaclient/tests/functional/client.py | 41 ++++++++ manilaclient/tests/functional/test_list.py | 27 +++++ requirements.txt | 1 + setup.cfg | 3 +- test-requirements.txt | 1 + tox.ini | 15 +++ 13 files changed, 251 insertions(+), 2 deletions(-) create mode 100644 etc/manilaclient/README.manilaclient.conf create mode 100644 etc/oslo-config-generator/manilaclient.conf create mode 100644 manilaclient/config.py create mode 100644 manilaclient/tests/functional/__init__.py create mode 100644 manilaclient/tests/functional/base.py create mode 100644 manilaclient/tests/functional/client.py create mode 100644 manilaclient/tests/functional/test_list.py diff --git a/.gitignore b/.gitignore index b17e97ef8..0127d2d55 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ .tox/* .venv cover/* +build/* +etc/manilaclient/manilaclient.conf* subunit.log python_manilaclient.egg-info setuptools_git*.egg diff --git a/.testr.conf b/.testr.conf index 660f3b4da..e8ed9250f 100644 --- a/.testr.conf +++ b/.testr.conf @@ -2,7 +2,7 @@ test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover -t ./ ./manilaclient/tests/unit $LISTOPT $IDOPTION + ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./manilaclient/tests/unit} $LISTOPT $IDOPTION test_id_option=--load-list $IDFILE test_list_option=--list diff --git a/etc/manilaclient/README.manilaclient.conf b/etc/manilaclient/README.manilaclient.conf new file mode 100644 index 000000000..9971713d6 --- /dev/null +++ b/etc/manilaclient/README.manilaclient.conf @@ -0,0 +1,4 @@ +To generate the sample manilaclient.conf file, run the following +command from the top level of the manilaclient directory: + +tox -egenconfig diff --git a/etc/oslo-config-generator/manilaclient.conf b/etc/oslo-config-generator/manilaclient.conf new file mode 100644 index 000000000..73548deba --- /dev/null +++ b/etc/oslo-config-generator/manilaclient.conf @@ -0,0 +1,3 @@ +[DEFAULT] +output_file = etc/manilaclient/manilaclient.conf.sample +namespace = manilaclient.config diff --git a/manilaclient/config.py b/manilaclient/config.py new file mode 100644 index 000000000..5fd591d53 --- /dev/null +++ b/manilaclient/config.py @@ -0,0 +1,106 @@ +# Copyright 2014 Mirantis Inc. +# 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 copy +import os + +from oslo.config import cfg + +# 1. Define opts + +# "auth_opts" are used by functional tests that are located in +# directory "%project_root%/manilaclient/tests/functional" +auth_opts = [ + cfg.StrOpt("username", + default=None, + help="This should be the username of a user WITHOUT " + "administrative privileges."), + cfg.StrOpt("tenant_name", + default=None, + help="The non-administrative user's tenant name."), + cfg.StrOpt("password", + default=None, + help="The non-administrative user's password."), + cfg.StrOpt("auth_url", + default=None, + help="URL for where to find the OpenStack Identity admin " + "API endpoint."), + cfg.StrOpt("admin_username", + default=None, + help="This should be the username of a user WITH " + "administrative privileges."), + cfg.StrOpt("admin_tenant_name", + default=None, + help="The administrative user's tenant name."), + cfg.StrOpt("admin_password", + default=None, + help="The administrative user's password."), + cfg.StrOpt("admin_auth_url", + default=None, + help="URL for where to find the OpenStack Identity admin " + "API endpoint."), +] + +base_opts = [ + cfg.StrOpt("manila_exec_dir", + default=os.environ.get( + 'OS_MANILA_EXEC_DIR', + os.path.join(os.path.abspath('.'), '.tox/functional/bin')), + help="The path to manilaclient to be executed."), +] + +# 2. Generate config + +PROJECT_NAME = 'manilaclient' + +DEFAULT_CONFIG_FILE = ( + os.environ.get('OS_%s_CONFIG_FILE' % PROJECT_NAME.upper()) or + '%s.conf' % PROJECT_NAME) +DEFAULT_CONFIG_DIR = ( + os.environ.get('OS_%s_CONFIG_DIR' % PROJECT_NAME.upper()) or + os.path.join(os.path.abspath(os.path.dirname( + os.path.dirname(os.path.dirname(__file__)))), "etc/manilaclient") +) +DEFAULT_CONFIG_PATH = os.path.join(DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILE) +FAILOVER_CONFIG_PATH = '/etc/%(pn)s/%(cn)s' % { + 'pn': PROJECT_NAME, 'cn': DEFAULT_CONFIG_FILE} +CONFIG_FILES = [] + +if os.path.isfile(DEFAULT_CONFIG_PATH): + CONFIG_FILES.append(DEFAULT_CONFIG_PATH) +if os.path.isfile(FAILOVER_CONFIG_PATH): + CONFIG_FILES.append(FAILOVER_CONFIG_PATH) + +CONF = cfg.CONF + +if CONFIG_FILES: + CONF([], project=PROJECT_NAME, default_config_files=CONFIG_FILES) +else: + CONF([], project=PROJECT_NAME) + +# 3. Register opts + +CONF.register_opts(auth_opts) +CONF.register_opts(base_opts) + +# 4. Define list_opts for config sample generator + + +def list_opts(): + """Return a list of oslo.config options available in Manilaclient.""" + return [ + (None, copy.deepcopy(auth_opts)), + (None, copy.deepcopy(base_opts)), + ] diff --git a/manilaclient/tests/functional/__init__.py b/manilaclient/tests/functional/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/manilaclient/tests/functional/base.py b/manilaclient/tests/functional/base.py new file mode 100644 index 000000000..d0fa25107 --- /dev/null +++ b/manilaclient/tests/functional/base.py @@ -0,0 +1,48 @@ +# Copyright 2014 Mirantis Inc. +# 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 tempest_lib.cli import base + +from manilaclient import config +from manilaclient.tests.functional import client + +CONF = config.CONF + + +class BaseTestCase(base.ClientTestBase): + def _get_clients(self): + cli_dir = os.environ.get( + 'OS_MANILA_EXEC_DIR', + os.path.join(os.path.abspath('.'), '.tox/functional/bin')) + + clients = { + 'admin': client.ManilaCLIClient( + username=CONF.admin_username, + password=CONF.admin_password, + tenant_name=CONF.admin_tenant_name, + uri=CONF.admin_auth_url or CONF.auth_url, + cli_dir=cli_dir, + ), + 'user': client.ManilaCLIClient( + username=CONF.username, + password=CONF.password, + tenant_name=CONF.tenant_name, + uri=CONF.auth_url, + cli_dir=cli_dir, + ), + } + return clients diff --git a/manilaclient/tests/functional/client.py b/manilaclient/tests/functional/client.py new file mode 100644 index 000000000..e029e4243 --- /dev/null +++ b/manilaclient/tests/functional/client.py @@ -0,0 +1,41 @@ +# Copyright 2014 Mirantis Inc. +# 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 tempest_lib.cli import base + + +class ManilaCLIClient(base.CLIClient): + + def manila(self, action, flags='', params='', fail_ok=False, + endpoint_type='publicURL', merge_stderr=False): + """Executes manila command for the given action. + + :param action: the cli command to run using manila + :type action: string + :param flags: any optional cli flags to use + :type flags: string + :param params: any optional positional args to use + :type params: string + :param fail_ok: if True an exception is not raised when the + cli return code is non-zero + :type fail_ok: boolean + :param endpoint_type: the type of endpoint for the service + :type endpoint_type: string + :param merge_stderr: if True the stderr buffer is merged into stdout + :type merge_stderr: boolean + """ + flags += ' --endpoint-type %s' % endpoint_type + return self.cmd_with_auth( + 'manila', action, flags, params, fail_ok, merge_stderr) diff --git a/manilaclient/tests/functional/test_list.py b/manilaclient/tests/functional/test_list.py new file mode 100644 index 000000000..744ed7019 --- /dev/null +++ b/manilaclient/tests/functional/test_list.py @@ -0,0 +1,27 @@ +# Copyright 2014 Mirantis Inc. +# 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 manilaclient.tests.functional import base + + +class ManilaClientTestList(base.BaseTestCase): + + # TODO(vponomaryov): add more tests + + def test_manila_list_by_admin(self): + self.clients['admin'].manila('list') + + def test_manila_list_by_user(self): + self.clients['user'].manila('list') diff --git a/requirements.txt b/requirements.txt index c03e260f7..ca3f8963a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,7 @@ pbr>=0.6,!=0.7,<1.0 argparse iso8601>=0.1.9 keyring>=2.1,!=3.3 +oslo.config>=1.4.0 # Apache-2.0 oslo.serialization>=1.0.0 # Apache-2.0 PrettyTable>=0.7,<0.8 pycrypto>=2.6 diff --git a/setup.cfg b/setup.cfg index 9594f0f9c..a10abcb0f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -18,7 +18,6 @@ classifier = Programming Language :: Python - [global] setup-hooks = pbr.hooks.setup_hook @@ -30,6 +29,8 @@ packages = [entry_points] console_scripts = manila = manilaclient.shell:main +oslo.config.opts = + manilaclient.config = manilaclient.config:list_opts [build_sphinx] all_files = 1 diff --git a/test-requirements.txt b/test-requirements.txt index f24f0469b..a71bac288 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -12,5 +12,6 @@ mock>=1.0 ordereddict oslosphinx>=2.2.0 # Apache-2.0 sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3 +tempest-lib testrepository>=0.0.18 testtools>=0.9.34 diff --git a/tox.ini b/tox.ini index a3cd2b3b1..b4b52c6f0 100644 --- a/tox.ini +++ b/tox.ini @@ -21,6 +21,21 @@ commands = [testenv:venv] commands = {posargs} +[testenv:functional] +setenv = + VIRTUAL_ENV = {envdir} + OS_TEST_PATH = ./manilaclient/tests/functional + OS_MANILA_EXEC_DIR = {envbindir} +commands = + {envbindir}/python setup.py install + {envbindir}/python setup.py testr --testr-args='{posargs}' + +[testenv:genconfig] +whitelist_externals = bash +commands = + {envbindir}/python setup.py install + {envbindir}/oslo-config-generator --config-file etc/oslo-config-generator/manilaclient.conf + [testenv:cover] commands = python setup.py testr --coverage --testr-args='{posargs}'