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):