From 36ee568e0ac4744013af8926d2b4af8c513d8c5d Mon Sep 17 00:00:00 2001 From: Bartosz Zurkowski Date: Wed, 1 Aug 2018 14:37:19 +0200 Subject: [PATCH] Make use of service clients interface This change makes use of features provided by stable "ServiceClients" interface that has been available in Tempest for some time. The interface enhances tests with a convenient way to access available service clients. When a plugin uses "ServiceClients" interface, all stable Tempest clients and all clients exposed by installed plugins will be automatically available and pre-configured. Instead of explicitly specifying parameters, such as "auth_provider", "build_timeout", etc., all these parameters will be read from the Tempest configuration and then installed automatically in the clients. Plugin adaptation was carried out in accordance with the requirements described in Tempest documentation[1] and inspired by changes introduced in other plugins[2][3]. [1] https://docs.openstack.org/tempest/latest/plugin.html#service-clients [2] https://review.openstack.org/#/c/338486/ [3] https://review.openstack.org/#/c/334596/ Change-Id: I0fbb12fb93f4411f23d95d54d8d5a7904a372333 Signed-off-by: Bartosz Zurkowski --- trove_tempest_plugin/clients.py | 34 +++++++++++++ trove_tempest_plugin/config.py | 9 +++- trove_tempest_plugin/plugin.py | 16 +++++++ trove_tempest_plugin/tests/api/base.py | 66 +++++++++++++++----------- 4 files changed, 94 insertions(+), 31 deletions(-) create mode 100644 trove_tempest_plugin/clients.py diff --git a/trove_tempest_plugin/clients.py b/trove_tempest_plugin/clients.py new file mode 100644 index 0000000..ac99c31 --- /dev/null +++ b/trove_tempest_plugin/clients.py @@ -0,0 +1,34 @@ +# Copyright 2018 Samsung Electronics +# 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 import config +from tempest.lib.services import clients + +CONF = config.CONF + + +class Manager(clients.ServiceClients): + """Service clients proxy. + + Enhances tests with a convenient way to access available service clients + configured for a specified set of credentials. + """ + + def __init__(self, credentials, service=None): + if CONF.identity.auth_version == 'v2': + identity_uri = CONF.identity.uri + else: + identity_uri = CONF.identity.uri_v3 + super(Manager, self).__init__(credentials, identity_uri) diff --git a/trove_tempest_plugin/config.py b/trove_tempest_plugin/config.py index 0048b7a..691d5c4 100644 --- a/trove_tempest_plugin/config.py +++ b/trove_tempest_plugin/config.py @@ -26,10 +26,15 @@ DatabaseGroup = [ cfg.StrOpt('catalog_type', default='database', help="Catalog type of the Database service."), + cfg.StrOpt('endpoint_type', + default='publicURL', + choices=['public', 'admin', 'internal', + 'publicURL', 'adminURL', 'internalURL'], + help="The endpoint type to use for the Database service."), cfg.StrOpt('db_flavor_ref', default="1", - help="Valid primary flavor to use in database tests."), + help="Valid primary flavor to use in Database tests."), cfg.StrOpt('db_current_version', default="v1.0", - help="Current database version to use in database tests."), + help="Current database version to use in Database tests."), ] diff --git a/trove_tempest_plugin/plugin.py b/trove_tempest_plugin/plugin.py index 2c8e8b0..8d8edcd 100644 --- a/trove_tempest_plugin/plugin.py +++ b/trove_tempest_plugin/plugin.py @@ -15,6 +15,7 @@ import os +from tempest import config from tempest.test_discover import plugins from trove_tempest_plugin import config as trove_config @@ -38,3 +39,18 @@ class TroveTempestPlugin(plugins.TempestPlugin): def get_opt_lists(self): return [('database', trove_config.DatabaseGroup), ('service_available', [trove_config.service_option])] + + def get_service_clients(self): + service_config = config.service_client_config('database') + service_params = { + 'name': 'database', + 'service_version': 'database', + 'module_path': 'trove_tempest_plugin.services.database', + 'client_names': [ + 'FlavorsClient', + 'LimitsClient', + 'VersionsClient' + ] + } + service_params.update(service_config) + return [service_params] diff --git a/trove_tempest_plugin/tests/api/base.py b/trove_tempest_plugin/tests/api/base.py index 962f5bc..04a71f9 100644 --- a/trove_tempest_plugin/tests/api/base.py +++ b/trove_tempest_plugin/tests/api/base.py @@ -16,10 +16,7 @@ from tempest import config import tempest.test -from trove_tempest_plugin.services.database import FlavorsClient -from trove_tempest_plugin.services.database import LimitsClient -from trove_tempest_plugin.services.database import VersionsClient - +from trove_tempest_plugin import clients CONF = config.CONF @@ -28,6 +25,7 @@ class BaseDatabaseTest(tempest.test.BaseTestCase): """Base test case class for all Database API tests.""" credentials = ['primary'] + client_manager = clients.Manager @classmethod def skip_checks(cls): @@ -38,32 +36,42 @@ class BaseDatabaseTest(tempest.test.BaseTestCase): @classmethod def setup_clients(cls): - super(BaseDatabaseTest, cls).setup_clients() - default_params = config.service_client_config() + """Setups service clients. - # NOTE: Tempest uses timeout values of compute API if project specific - # timeout values don't exist. - default_params_with_timeout_values = { - 'build_interval': CONF.compute.build_interval, - 'build_timeout': CONF.compute.build_timeout - } - default_params_with_timeout_values.update(default_params) - cls.database_flavors_client = FlavorsClient( - cls.os_primary.auth_provider, - CONF.database.catalog_type, - CONF.identity.region, - **default_params_with_timeout_values) - cls.os_flavors_client = cls.os_primary.flavors_client - cls.database_limits_client = LimitsClient( - cls.os_primary.auth_provider, - CONF.database.catalog_type, - CONF.identity.region, - **default_params_with_timeout_values) - cls.database_versions_client = VersionsClient( - cls.os_primary.auth_provider, - CONF.database.catalog_type, - CONF.identity.region, - **default_params_with_timeout_values) + Tempest provides a convenient fabrication interface, which can be used + to produce instances of clients configured with the required parameters + and a selected set of credentials. Thanks to this interface, the + complexity of client initialization is hidden from the developer. All + parameters such as "catalog_type", "auth_provider", "build_timeout" + etc. are read from Tempest configuration and then automatically + installed in the clients. + + The fabrication interface is enabled through the client manager, which + is hooked to the class by the "client_manager" property. + + To initialize a new client, one need to specify the set of credentials + (primary, admin) to be used and the category of client (eg compute, + image, database, etc.). Together, they constitute a proxy for the + fabricators of specific client classes from a given category. + + For example, initializing a new flavors client from the database + category with primary privileges boils down to the following call: + + flavors_client = cls.os_primary.database.FlavorsClient() + + In order to initialize a new networks client from the compute category + with administrator privilages: + + networks_client = cls.os_admin.compute.NetworksClient() + + Note, that selected set of credentials must be declared in the + "credentials" property of this class. + """ + super(BaseDatabaseTest, cls).setup_clients() + cls.database_flavors_client = cls.os_primary.database.FlavorsClient() + cls.os_flavors_client = cls.os_primary.compute.FlavorsClient() + cls.database_limits_client = cls.os_primary.database.LimitsClient() + cls.database_versions_client = cls.os_primary.database.VersionsClient() @classmethod def resource_setup(cls):