From e1ff53d2df7b8642df395dd42b7f8da58cbeb67b Mon Sep 17 00:00:00 2001 From: Mehdi Abaakouk Date: Tue, 5 Apr 2016 09:59:20 +0200 Subject: [PATCH] tests: tempest plugin This change allows to run gabbits-live scenarios with tempest. Change-Id: I518b240c8f589b4b5440a148766cb79bdb216a77 --- devstack/gate/gate_hook.sh | 5 +- devstack/gate/post_test_hook.sh | 19 +++++- gnocchi/tempest/__init__.py | 0 gnocchi/tempest/config.py | 38 ++++++++++++ gnocchi/tempest/plugin.py | 44 ++++++++++++++ gnocchi/tempest/scenario/__init__.py | 87 ++++++++++++++++++++++++++++ setup.cfg | 3 + 7 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 gnocchi/tempest/__init__.py create mode 100644 gnocchi/tempest/config.py create mode 100644 gnocchi/tempest/plugin.py create mode 100644 gnocchi/tempest/scenario/__init__.py diff --git a/devstack/gate/gate_hook.sh b/devstack/gate/gate_hook.sh index 932009209..1d26ca44b 100755 --- a/devstack/gate/gate_hook.sh +++ b/devstack/gate/gate_hook.sh @@ -17,7 +17,7 @@ STORAGE_DRIVER="$1" SQL_DRIVER="$2" -ENABLED_SERVICES="key,gnocchi-api,gnocchi-metricd," +ENABLED_SERVICES="key,gnocchi-api,gnocchi-metricd,tempest," # Use efficient wsgi web server DEVSTACK_LOCAL_CONFIG+=$'\nexport GNOCCHI_DEPLOY=uwsgi' @@ -25,7 +25,8 @@ DEVSTACK_LOCAL_CONFIG+=$'\nexport KEYSTONE_DEPLOY=uwsgi' export DEVSTACK_GATE_INSTALL_TESTONLY=1 export DEVSTACK_GATE_NO_SERVICES=1 -export DEVSTACK_GATE_TEMPEST=0 +export DEVSTACK_GATE_TEMPEST=1 +export DEVSTACK_GATE_TEMPEST_NOTESTS=1 export DEVSTACK_GATE_EXERCISES=0 export KEEP_LOCALRC=1 diff --git a/devstack/gate/post_test_hook.sh b/devstack/gate/post_test_hook.sh index 6e4ab014c..6fe8e1397 100755 --- a/devstack/gate/post_test_hook.sh +++ b/devstack/gate/post_test_hook.sh @@ -50,7 +50,24 @@ sudo gnocchi-upgrade --create-legacy-resource-types gnocchi metric create sudo -E -H -u stack $GNOCCHI_DIR/tools/measures_injector.py --metrics 1 --batch-of-measures 2 --measures-per-batch 2 -# Run tests +# NOTE(sileht): on swift job permissions are wrong, I don't known why +sudo chown -R tempest:stack $BASE/new/tempest +sudo chown -R tempest:stack $BASE/data/tempest + +# Run tests with tempst +cd $BASE/new/tempest +set +e +sudo -H -u tempest OS_TEST_TIMEOUT=$TEMPEST_OS_TEST_TIMEOUT tox -eall-plugin -- --concurrency=$TEMPEST_CONCURRENCY gnocchi +TEMPEST_EXIT_CODE=$? +set -e +if [[ $TEMPEST_EXIT_CODE != 0 ]]; then + # Collect and parse result + generate_testr_results + exit $TEMPEST_EXIT_CODE +fi + +# Run tests with tox +cd $GNOCCHI_DIR echo "Running gnocchi functional test suite" set +e sudo -E -H -u stack tox -epy27-gate diff --git a/gnocchi/tempest/__init__.py b/gnocchi/tempest/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/gnocchi/tempest/config.py b/gnocchi/tempest/config.py new file mode 100644 index 000000000..54bf8ff91 --- /dev/null +++ b/gnocchi/tempest/config.py @@ -0,0 +1,38 @@ +# +# 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") + +service_available_opts = [ + cfg.BoolOpt("gnocchi", + default=True, + help="Whether or not Gnocchi is expected to be available"), +] + +metric_group = cfg.OptGroup(name='metric', + title='Metric Service Options') + +metric_opts = [ + cfg.StrOpt('catalog_type', + default='metric', + help="Catalog type of the Metric service."), + cfg.StrOpt('endpoint_type', + default='publicURL', + choices=['public', 'admin', 'internal', + 'publicURL', 'adminURL', 'internalURL'], + help="The endpoint type to use for the metric service."), +] diff --git a/gnocchi/tempest/plugin.py b/gnocchi/tempest/plugin.py new file mode 100644 index 000000000..b0a9fd824 --- /dev/null +++ b/gnocchi/tempest/plugin.py @@ -0,0 +1,44 @@ +# -*- encoding: utf-8 -*- +# +# 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 __future__ import absolute_import + +import os + +from tempest import config +from tempest.test_discover import plugins + +import gnocchi +from gnocchi.tempest import config as tempest_config + + +class GnocchiTempestPlugin(plugins.TempestPlugin): + def load_tests(self): + base_path = os.path.split(os.path.dirname( + os.path.abspath(gnocchi.__file__)))[0] + test_dir = "gnocchi/tempest" + 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, + tempest_config.service_available_group, + tempest_config.service_available_opts) + config.register_opt_group(conf, + tempest_config.metric_group, + tempest_config.metric_opts) + + def get_opt_lists(self): + return [(tempest_config.metric_group.name, + tempest_config.metric_opts)] diff --git a/gnocchi/tempest/scenario/__init__.py b/gnocchi/tempest/scenario/__init__.py new file mode 100644 index 000000000..7019963e9 --- /dev/null +++ b/gnocchi/tempest/scenario/__init__.py @@ -0,0 +1,87 @@ +# 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 __future__ import absolute_import + +import os +import unittest + +from gabbi import driver +import six.moves.urllib.parse as urlparse +from tempest import config +import tempest.test + +CONF = config.CONF + + +class GnocchiGabbiTest(tempest.test.BaseTestCase): + credentials = ['admin'] + + @classmethod + def skip_checks(cls): + super(GnocchiGabbiTest, cls).skip_checks() + if not CONF.service_available.gnocchi: + raise cls.skipException("Gnocchi support is required") + + @classmethod + def resource_setup(cls): + super(GnocchiGabbiTest, cls).resource_setup() + url, token = cls._get_gnocchi_auth() + parsed_url = urlparse.urlsplit(url) + prefix = parsed_url.path.rstrip('/') # turn it into a prefix + port = 443 if parsed_url.scheme == 'https' else 80 + host = parsed_url.hostname + if parsed_url.port: + port = parsed_url.port + + test_dir = os.path.join(os.path.dirname(__file__), '..', '..', + 'tests', 'gabbi', 'gabbits-live') + cls.tests = driver.build_tests( + test_dir, unittest.TestLoader(), + host=host, port=port, prefix=prefix, + test_loader_name='tempest.scenario.gnocchi.test') + + os.environ["GNOCCHI_SERVICE_TOKEN"] = token + + @classmethod + def clear_credentials(cls): + # FIXME(sileht): We don't want the token to be invalided, but + # for some obcurs reason, clear_credentials is called before/during run + # So, make the one used by tearDropClass a dump, and call it manually + # in run() + pass + + def run(self, result=None): + self.setUp() + try: + self.tests.run(result) + finally: + super(GnocchiGabbiTest, self).clear_credentials() + self.tearDown() + + @classmethod + def _get_gnocchi_auth(cls): + endpoint_type = CONF.metric.endpoint_type + if not endpoint_type.endswith("URL"): + endpoint_type += "URL" + + auth = cls.os_admin.auth_provider.get_auth() + endpoints = [e for e in auth[1]['serviceCatalog'] + if e['type'] == CONF.metric.catalog_type] + if not endpoints: + raise Exception("%s endpoint not found" % CONF.metric.catalog_type) + return endpoints[0]['endpoints'][0][endpoint_type], auth[0] + + def test_fake(self): + # NOTE(sileht): A fake test is needed to have the class loaded + # by the test runner + pass diff --git a/setup.cfg b/setup.cfg index 88a05cae0..021461570 100644 --- a/setup.cfg +++ b/setup.cfg @@ -118,6 +118,9 @@ console_scripts = oslo.config.opts = gnocchi = gnocchi.opts:list_opts +tempest.test_plugins = + gnocchi_tests = gnocchi.tempest.plugin:GnocchiTempestPlugin + [build_sphinx] all_files = 1 build-dir = doc/build