From a08034e3d94d37db02d093f0f70150450a338e42 Mon Sep 17 00:00:00 2001 From: Cliff Parsons Date: Tue, 13 Feb 2018 11:20:28 -0600 Subject: [PATCH] Force API test listing even if auth fails If the heat-tempest-plugin is installed, and the command "tempest run --list-tests" is issued, the Heat API (Gabbi) tests will not be listed if the auth_url is unreachable/mis-provisioned, or if the key authorization-related variables are not provisioned in the tempest.conf file. The API tests should be listed regardless of whether or not the plugin can authenticate using keystone. In the event that the plugin is not configured (or not configured correctly), or if keystone is not reachable, this commit combined with the following gabbi fix: https://github.com/cdent/gabbi/commit/8354d545471f5a2dcdff7e5c05d298b2afd8e6ae ensures that Gabbi build_tests() returns the list of api tests, even when keystone cannot be reached due to whatever reason above. Note that even while running the tests, if the authorization information is not present or is incorrect, the user will be able to see the warning logs with the keystoneauth exceptions present. However, the exceptions will not prevent a test listing from being given to the user. Change-Id: I3921f0df245d3745b95d3a312c41b9f9b15c2ba9 Closes-Bug: #1749218 --- .../tests/api/test_heat_api.py | 57 +++++++++++++++---- requirements.txt | 2 +- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/heat_tempest_plugin/tests/api/test_heat_api.py b/heat_tempest_plugin/tests/api/test_heat_api.py index 0a44621..804f445 100644 --- a/heat_tempest_plugin/tests/api/test_heat_api.py +++ b/heat_tempest_plugin/tests/api/test_heat_api.py @@ -13,16 +13,19 @@ """A test module to exercise the Heat API with gabbi. """ +import keystoneauth1 import os +import sys import unittest from gabbi import driver -from six.moves.urllib import parse as urlparse +from oslo_log import log as logging from tempest import config from heat_tempest_plugin.common import test from heat_tempest_plugin.services import clients +LOG = logging.getLogger(__name__) TESTS_DIR = 'gabbits' @@ -30,16 +33,45 @@ def load_tests(loader, tests, pattern): """Provide a TestSuite to the discovery process.""" test_dir = os.path.join(os.path.dirname(__file__), TESTS_DIR) + endpoint = None conf = config.CONF.heat_plugin - if conf.auth_url is None: - # It's not configured, let's not load tests - return - manager = clients.ClientManager(conf) - endpoint = manager.identity_client.get_endpoint_url( - 'orchestration', region=conf.region, endpoint_type=conf.endpoint_type) - host = urlparse.urlparse(endpoint).hostname - os.environ['OS_TOKEN'] = manager.identity_client.auth_token - os.environ['PREFIX'] = test.rand_name('api') + if conf.auth_url: + try: + manager = clients.ClientManager(conf) + endpoint = manager.identity_client.get_endpoint_url( + 'orchestration', region=conf.region, + endpoint_type=conf.endpoint_type) + os.environ['OS_TOKEN'] = manager.identity_client.auth_token + os.environ['PREFIX'] = test.rand_name('api') + + # Catch the authentication exceptions that can happen if one of the + # following conditions occur: + # 1. conf.auth_url IP/port is incorrect or keystone not available + # (ConnectFailure) + # 2. conf.auth_url is malformed (BadRequest, UnknownConnectionError, + # EndpointNotFound, NotFound, or DiscoveryFailure) + # 3. conf.username/password is incorrect (Unauthorized) + # 4. conf.project_name is missing/incorrect (EmptyCatalog) + # These exceptions should not prevent a test list from being returned, + # so just issue a warning log and move forward with test listing. + except (keystoneauth1.exceptions.http.BadRequest, + keystoneauth1.exceptions.http.Unauthorized, + keystoneauth1.exceptions.http.NotFound, + keystoneauth1.exceptions.catalog.EmptyCatalog, + keystoneauth1.exceptions.catalog.EndpointNotFound, + keystoneauth1.exceptions.discovery.DiscoveryFailure, + keystoneauth1.exceptions.connection.UnknownConnectionError, + keystoneauth1.exceptions.connection.ConnectFailure): + LOG.warn("Keystone auth exception: %s: %s" % (sys.exc_info()[0], + sys.exc_info()[1])) + # Clear the auth_url, as there is no point in tempest trying + # to authenticate later with mis-configured or unreachable endpoint + conf.auth_url = None + + except Exception: + LOG.error("Fatal exception: %s: %s" % (sys.exc_info()[0], + sys.exc_info()[1])) + raise def register_test_case_id(test_case): tempest_id = test_case.test_data.get('desc') @@ -60,7 +92,8 @@ def load_tests(loader, tests, pattern): else: register_test_case_id(test_case) - api_tests = driver.build_tests(test_dir, loader, host=host, - url=endpoint, test_loader_name=__name__) + api_tests = driver.build_tests(test_dir, loader, url=endpoint, host="", + test_loader_name=__name__) + register_test_suite_ids(api_tests) return api_tests diff --git a/requirements.txt b/requirements.txt index d5dbc36..985e536 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,5 +18,5 @@ python-zaqarclient>=1.0.0 # Apache-2.0 testtools>=2.2.0 # MIT testscenarios>=0.4 # Apache-2.0/BSD tempest>=17.1.0 # Apache-2.0 -gabbi>=1.35.0 # Apache-2.0 +gabbi>=1.42.1 # Apache-2.0 kombu!=4.0.2,>=4.0.0 # BSD