Merge "Fix verify config API version checks"
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 8e71ecc..714a476 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -30,6 +30,8 @@
from tempest.common import credentials_factory as credentials
from tempest import config
import tempest.lib.common.http
+from tempest.lib import exceptions as lib_exc
+from tempest.services import object_storage
CONF = config.CONF
@@ -69,7 +71,25 @@
def verify_glance_api_versions(os, update):
# Check glance api versions
- _, versions = os.image_client.get_versions()
+ # Since we want to verify that the configuration is correct, we cannot
+ # rely on a specific version of the API being available.
+ try:
+ _, versions = os.image_v1.ImagesClient().get_versions()
+ except lib_exc.NotFound:
+ # If not found, we use v2. The assumption is that either v1 or v2
+ # are available, since glance is marked as available in the catalog.
+ # If not, glance should be disabled in Tempest conf.
+ try:
+ versions = os.image_v2.VersionsClient().list_versions()['versions']
+ versions = [x['id'] for x in versions]
+ except lib_exc.NotFound:
+ msg = ('Glance is available in the catalog, but no known version, '
+ '(v1.x or v2.x) of Glance could be found, so Glance should '
+ 'be configured as not available')
+ LOG.warn(msg)
+ print_and_or_update('glance', 'service-available', False, update)
+ return
+
if CONF.image_feature_enabled.api_v1 != contains_version('v1.', versions):
print_and_or_update('api_v1', 'image-feature-enabled',
not CONF.image_feature_enabled.api_v1, update)
@@ -92,10 +112,15 @@
def _get_api_versions(os, service):
+ # Clients are used to obtain the base_url. Each client applies the
+ # appropriate filters to the catalog to extract a base_url which
+ # matches the configured region and endpoint_type.
+ # The base URL is used to obtain the list of versions available.
client_dict = {
- 'nova': os.servers_client,
- 'keystone': os.identity_client,
- 'cinder': os.volumes_client_latest,
+ 'nova': os.compute.ServersClient(),
+ 'keystone': os.identity_v3.IdentityClient(
+ endpoint_type=CONF.identity.v3_endpoint_type),
+ 'cinder': os.volume_v3.VolumesClient(),
}
if service != 'keystone' and service != 'cinder':
# Since keystone and cinder may be listening on a path,
@@ -166,14 +191,15 @@
def get_extension_client(os, service):
+ params = config.service_client_config('object-storage')
extensions_client = {
- 'nova': os.extensions_client,
- 'neutron': os.network_extensions_client,
- 'swift': os.capabilities_client,
+ 'nova': os.compute.ExtensionsClient(),
+ 'neutron': os.network.ExtensionsClient(),
+ 'swift': object_storage.CapabilitiesClient(os.auth_provider, **params),
# NOTE: Cinder v3 API is current and v2 and v1 are deprecated.
# V3 extension API is the same as v2, so we reuse the v2 client
# for v3 API also.
- 'cinder': os.volumes_v2_extension_client,
+ 'cinder': os.volume_v2.ExtensionsClient(),
}
if service not in extensions_client:
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 1415111..810f9e5 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -16,9 +16,13 @@
import mock
from oslo_serialization import jsonutils as json
+from tempest import clients
from tempest.cmd import verify_tempest_config
+from tempest.common import credentials_factory
from tempest import config
+from tempest.lib.common import rest_client
from tempest.lib.common.utils import data_utils
+from tempest.lib import exceptions as lib_exc
from tempest.tests import base
from tempest.tests import fake_config
@@ -234,10 +238,15 @@
print_mock.assert_not_called()
def test_verify_glance_version_no_v2_with_v1_1(self):
- def fake_get_versions():
- return (None, ['v1.1'])
+ # This test verifies that wrong config api_v2 = True is detected
+ class FakeClient(object):
+ def get_versions(self):
+ return (None, ['v1.0'])
+
fake_os = mock.MagicMock()
- fake_os.image_client.get_versions = fake_get_versions
+ fake_module = mock.MagicMock()
+ fake_module.ImagesClient = FakeClient
+ fake_os.image_v1 = fake_module
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
@@ -245,10 +254,15 @@
False, True)
def test_verify_glance_version_no_v2_with_v1_0(self):
- def fake_get_versions():
- return (None, ['v1.0'])
+ # This test verifies that wrong config api_v2 = True is detected
+ class FakeClient(object):
+ def get_versions(self):
+ return (None, ['v1.0'])
+
fake_os = mock.MagicMock()
- fake_os.image_client.get_versions = fake_get_versions
+ fake_module = mock.MagicMock()
+ fake_module.ImagesClient = FakeClient
+ fake_os.image_v1 = fake_module
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
@@ -256,24 +270,59 @@
False, True)
def test_verify_glance_version_no_v1(self):
- def fake_get_versions():
- return (None, ['v2.0'])
+ # This test verifies that wrong config api_v1 = True is detected
+ class FakeClient(object):
+ def get_versions(self):
+ raise lib_exc.NotFound()
+
+ def list_versions(self):
+ return {'versions': [{'id': 'v2.0'}]}
+
fake_os = mock.MagicMock()
- fake_os.image_client.get_versions = fake_get_versions
+ fake_module = mock.MagicMock()
+ fake_module.ImagesClient = FakeClient
+ fake_module.VersionsClient = FakeClient
+ fake_os.image_v1 = fake_module
+ fake_os.image_v2 = fake_module
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
print_mock.assert_called_once_with('api_v1', 'image-feature-enabled',
False, True)
+ def test_verify_glance_version_no_version(self):
+ # This test verifies that wrong config api_v1 = True is detected
+ class FakeClient(object):
+ def get_versions(self):
+ raise lib_exc.NotFound()
+
+ def list_versions(self):
+ raise lib_exc.NotFound()
+
+ fake_os = mock.MagicMock()
+ fake_module = mock.MagicMock()
+ fake_module.ImagesClient = FakeClient
+ fake_module.VersionsClient = FakeClient
+ fake_os.image_v1 = fake_module
+ fake_os.image_v2 = fake_module
+ with mock.patch.object(verify_tempest_config,
+ 'print_and_or_update') as print_mock:
+ verify_tempest_config.verify_glance_api_versions(fake_os, True)
+ print_mock.assert_called_once_with('glance',
+ 'service-available',
+ False, True)
+
def test_verify_extensions_neutron(self):
def fake_list_extensions():
return {'extensions': [{'alias': 'fake1'},
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
- fake_os.network_extensions_client.list_extensions = (
- fake_list_extensions)
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
self.useFixture(fixtures.MockPatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['fake1', 'fake2', 'fake3'])))
@@ -295,8 +344,11 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
- fake_os.network_extensions_client.list_extensions = (
- fake_list_extensions)
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
self.useFixture(fixtures.MockPatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['all'])))
@@ -313,15 +365,17 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
- # NOTE (e0ne): mock both v1 and v2 APIs
- fake_os.volumes_extension_client.list_extensions = fake_list_extensions
- fake_os.volumes_v2_extension_client.list_extensions = (
- fake_list_extensions)
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
self.useFixture(fixtures.MockPatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['fake1', 'fake2', 'fake3'])))
results = verify_tempest_config.verify_extensions(fake_os,
'cinder', {})
+
self.assertIn('cinder', results)
self.assertIn('fake1', results['cinder'])
self.assertTrue(results['cinder']['fake1'])
@@ -338,10 +392,11 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
- # NOTE (e0ne): mock both v1 and v2 APIs
- fake_os.volumes_extension_client.list_extensions = fake_list_extensions
- fake_os.volumes_v2_extension_client.list_extensions = (
- fake_list_extensions)
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
self.useFixture(fixtures.MockPatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['all'])))
@@ -357,7 +412,11 @@
return ([{'alias': 'fake1'}, {'alias': 'fake2'},
{'alias': 'not_fake'}])
fake_os = mock.MagicMock()
- fake_os.extensions_client.list_extensions = fake_list_extensions
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
self.useFixture(fixtures.MockPatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['fake1', 'fake2', 'fake3'])))
@@ -379,7 +438,11 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]})
fake_os = mock.MagicMock()
- fake_os.extensions_client.list_extensions = fake_list_extensions
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
self.useFixture(fixtures.MockPatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['all'])))
@@ -397,7 +460,11 @@
'not_fake': 'metadata',
'swift': 'metadata'}
fake_os = mock.MagicMock()
- fake_os.capabilities_client.list_capabilities = fake_list_extensions
+ fake_client = mock.MagicMock()
+ fake_client.list_capabilities = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
self.useFixture(fixtures.MockPatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['fake1', 'fake2', 'fake3'])))
@@ -419,7 +486,11 @@
'not_fake': 'metadata',
'swift': 'metadata'}
fake_os = mock.MagicMock()
- fake_os.capabilities_client.list_capabilities = fake_list_extensions
+ fake_client = mock.MagicMock()
+ fake_client.list_capabilities = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
self.useFixture(fixtures.MockPatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['all'])))
@@ -429,3 +500,13 @@
self.assertIn('extensions', results['swift'])
self.assertEqual(sorted(['not_fake', 'fake1', 'fake2']),
sorted(results['swift']['extensions']))
+
+ def test_get_extension_client(self):
+ creds = credentials_factory.get_credentials(
+ fill_in=False, username='fake_user', project_name='fake_project',
+ password='fake_password')
+ os = clients.Manager(creds)
+ for service in ['nova', 'neutron', 'swift', 'cinder']:
+ extensions_client = verify_tempest_config.get_extension_client(
+ os, service)
+ self.assertIsInstance(extensions_client, rest_client.RestClient)