tests: tempest plugin

This change allows to run gabbits-live scenarios with
tempest.

Change-Id: I518b240c8f589b4b5440a148766cb79bdb216a77
This commit is contained in:
Mehdi Abaakouk 2016-04-05 09:59:20 +02:00
parent d160cae5de
commit e1ff53d2df
7 changed files with 193 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

38
gnocchi/tempest/config.py Normal file
View File

@ -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."),
]

44
gnocchi/tempest/plugin.py Normal file
View File

@ -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)]

View File

@ -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

View File

@ -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