Merge "Add noqa support to no_setupclass_for_unit_tests"
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 533c7d0..edeb2fc 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -30,6 +30,7 @@
class BaseComputeTest(tempest.test.BaseTestCase):
"""Base test case class for all Compute API tests."""
+ _api_version = 3
force_tenant_isolation = False
@classmethod
@@ -54,6 +55,57 @@
cls.multi_user = cls.get_multi_user()
cls.security_groups = []
+ if cls._api_version == 2:
+ cls.servers_client = cls.os.servers_client
+ cls.flavors_client = cls.os.flavors_client
+ cls.images_client = cls.os.images_client
+ cls.extensions_client = cls.os.extensions_client
+ cls.floating_ips_client = cls.os.floating_ips_client
+ cls.keypairs_client = cls.os.keypairs_client
+ cls.security_groups_client = cls.os.security_groups_client
+ cls.quotas_client = cls.os.quotas_client
+ cls.limits_client = cls.os.limits_client
+ cls.volumes_extensions_client = cls.os.volumes_extensions_client
+ cls.volumes_client = cls.os.volumes_client
+ cls.interfaces_client = cls.os.interfaces_client
+ cls.fixed_ips_client = cls.os.fixed_ips_client
+ cls.availability_zone_client = cls.os.availability_zone_client
+ cls.agents_client = cls.os.agents_client
+ cls.aggregates_client = cls.os.aggregates_client
+ cls.services_client = cls.os.services_client
+ cls.instance_usages_audit_log_client = \
+ cls.os.instance_usages_audit_log_client
+ cls.hypervisor_client = cls.os.hypervisor_client
+ cls.certificates_client = cls.os.certificates_client
+ cls.migrations_client = cls.os.migrations_client
+
+ elif cls._api_version == 3:
+ if not CONF.compute_feature_enabled.api_v3:
+ skip_msg = ("%s skipped as nova v3 api is not available" %
+ cls.__name__)
+ raise cls.skipException(skip_msg)
+ cls.servers_client = cls.os.servers_v3_client
+ cls.images_client = cls.os.image_client
+ cls.flavors_client = cls.os.flavors_v3_client
+ cls.services_client = cls.os.services_v3_client
+ cls.extensions_client = cls.os.extensions_v3_client
+ cls.availability_zone_client = cls.os.availability_zone_v3_client
+ cls.interfaces_client = cls.os.interfaces_v3_client
+ cls.hypervisor_client = cls.os.hypervisor_v3_client
+ cls.keypairs_client = cls.os.keypairs_v3_client
+ cls.volumes_client = cls.os.volumes_client
+ cls.certificates_client = cls.os.certificates_v3_client
+ cls.keypairs_client = cls.os.keypairs_v3_client
+ cls.aggregates_client = cls.os.aggregates_v3_client
+ cls.hosts_client = cls.os.hosts_v3_client
+ cls.quotas_client = cls.os.quotas_v3_client
+ cls.version_client = cls.os.version_v3_client
+ cls.migrations_client = cls.os.migrations_v3_client
+ else:
+ msg = ("Unexpected API version is specified (%s)" %
+ cls._api_version)
+ raise exceptions.InvalidConfiguration(message=msg)
+
@classmethod
def get_multi_user(cls):
multi_user = True
@@ -231,38 +283,6 @@
cls.set_network_resources(network=True, subnet=True, router=True,
dhcp=True)
-
-class BaseV2ComputeTest(BaseComputeTest):
-
- _interface = "json"
-
- @classmethod
- def setUpClass(cls):
- # By default compute tests do not create network resources
- super(BaseV2ComputeTest, cls).setUpClass()
- cls.servers_client = cls.os.servers_client
- cls.flavors_client = cls.os.flavors_client
- cls.images_client = cls.os.images_client
- cls.extensions_client = cls.os.extensions_client
- cls.floating_ips_client = cls.os.floating_ips_client
- cls.keypairs_client = cls.os.keypairs_client
- cls.security_groups_client = cls.os.security_groups_client
- cls.quotas_client = cls.os.quotas_client
- cls.limits_client = cls.os.limits_client
- cls.volumes_extensions_client = cls.os.volumes_extensions_client
- cls.volumes_client = cls.os.volumes_client
- cls.interfaces_client = cls.os.interfaces_client
- cls.fixed_ips_client = cls.os.fixed_ips_client
- cls.availability_zone_client = cls.os.availability_zone_client
- cls.agents_client = cls.os.agents_client
- cls.aggregates_client = cls.os.aggregates_client
- cls.services_client = cls.os.services_client
- cls.instance_usages_audit_log_client = \
- cls.os.instance_usages_audit_log_client
- cls.hypervisor_client = cls.os.hypervisor_client
- cls.certificates_client = cls.os.certificates_client
- cls.migrations_client = cls.os.migrations_client
-
@classmethod
def create_image_from_server(cls, server_id, **kwargs):
"""Wrapper utility that returns an image created from the server."""
@@ -270,21 +290,25 @@
if 'name' in kwargs:
name = kwargs.pop('name')
- resp, image = cls.images_client.create_image(
- server_id, name)
+ if cls._api_version == 2:
+ resp, image = cls.images_client.create_image(server_id, name)
+ elif cls._api_version == 3:
+ resp, image = cls.servers_client.create_image(server_id, name)
image_id = data_utils.parse_image_id(resp['location'])
cls.images.append(image_id)
if 'wait_until' in kwargs:
cls.images_client.wait_for_image_status(image_id,
kwargs['wait_until'])
- resp, image = cls.images_client.get_image(image_id)
+ if cls._api_version == 2:
+ resp, image = cls.images_client.get_image(image_id)
+ elif cls._api_version == 3:
+ resp, image = cls.images_client.get_image_meta(image_id)
if kwargs['wait_until'] == 'ACTIVE':
if kwargs.get('wait_for_server', True):
cls.servers_client.wait_for_server_status(server_id,
'ACTIVE')
-
return resp, image
@classmethod
@@ -298,13 +322,24 @@
LOG.exception('Failed to delete server %s' % server_id)
pass
resp, server = cls.create_test_server(wait_until='ACTIVE', **kwargs)
- cls.password = server['adminPass']
+ if cls._api_version == 2:
+ cls.password = server['adminPass']
+ elif cls._api_version == 3:
+ cls.password = server['admin_password']
return server['id']
@classmethod
def delete_volume(cls, volume_id):
"""Deletes the given volume and waits for it to be gone."""
- cls._delete_volume(cls.volumes_extensions_client, volume_id)
+ if cls._api_version == 2:
+ cls._delete_volume(cls.volumes_extensions_client, volume_id)
+ elif cls._api_version == 3:
+ cls._delete_volume(cls.volumes_client, volume_id)
+
+
+class BaseV2ComputeTest(BaseComputeTest):
+ _api_version = 2
+ _interface = "json"
class BaseV2ComputeAdminTest(BaseV2ComputeTest):
@@ -333,74 +368,9 @@
class BaseV3ComputeTest(BaseComputeTest):
-
+ _api_version = 3
_interface = "json"
- @classmethod
- def setUpClass(cls):
- # By default compute tests do not create network resources
- if not CONF.compute_feature_enabled.api_v3:
- skip_msg = ("%s skipped as nova v3 api is not available" %
- cls.__name__)
- raise cls.skipException(skip_msg)
-
- super(BaseV3ComputeTest, cls).setUpClass()
-
- cls.servers_client = cls.os.servers_v3_client
- cls.images_client = cls.os.image_client
- cls.flavors_client = cls.os.flavors_v3_client
- cls.services_client = cls.os.services_v3_client
- cls.extensions_client = cls.os.extensions_v3_client
- cls.availability_zone_client = cls.os.availability_zone_v3_client
- cls.interfaces_client = cls.os.interfaces_v3_client
- cls.hypervisor_client = cls.os.hypervisor_v3_client
- cls.keypairs_client = cls.os.keypairs_v3_client
- cls.volumes_client = cls.os.volumes_client
- cls.certificates_client = cls.os.certificates_v3_client
- cls.keypairs_client = cls.os.keypairs_v3_client
- cls.aggregates_client = cls.os.aggregates_v3_client
- cls.hosts_client = cls.os.hosts_v3_client
- cls.quotas_client = cls.os.quotas_v3_client
- cls.version_client = cls.os.version_v3_client
- cls.migrations_client = cls.os.migrations_v3_client
-
- @classmethod
- def create_image_from_server(cls, server_id, **kwargs):
- """Wrapper utility that returns an image created from the server."""
- name = data_utils.rand_name(cls.__name__ + "-image")
- if 'name' in kwargs:
- name = kwargs.pop('name')
-
- resp, image = cls.servers_client.create_image(
- server_id, name)
- image_id = data_utils.parse_image_id(resp['location'])
- cls.images.append(image_id)
-
- if 'wait_until' in kwargs:
- cls.images_client.wait_for_image_status(image_id,
- kwargs['wait_until'])
- resp, image = cls.images_client.get_image_meta(image_id)
-
- return resp, image
-
- @classmethod
- def rebuild_server(cls, server_id, **kwargs):
- # Destroy an existing server and creates a new one
- try:
- cls.servers_client.delete_server(server_id)
- cls.servers_client.wait_for_server_termination(server_id)
- except Exception:
- LOG.exception('Failed to delete server %s' % server_id)
- pass
- resp, server = cls.create_test_server(wait_until='ACTIVE', **kwargs)
- cls.password = server['admin_password']
- return server['id']
-
- @classmethod
- def delete_volume(cls, volume_id):
- """Deletes the given volume and waits for it to be gone."""
- cls._delete_volume(cls.volumes_client, volume_id)
-
class BaseV3ComputeAdminTest(BaseV3ComputeTest):
"""Base test case class for all Compute Admin API V3 tests."""
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index 7b12555..cf9837f 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -17,15 +17,15 @@
from tempest import test
-class AZTestJSON(base.BaseV2ComputeTest):
-
+class AZV3Test(base.BaseComputeTest):
"""
Tests Availability Zone API List
"""
+ _api_version = 3
@classmethod
def setUpClass(cls):
- super(AZTestJSON, cls).setUpClass()
+ super(AZV3Test, cls).setUpClass()
cls.client = cls.availability_zone_client
@test.attr(type='gate')
@@ -36,5 +36,9 @@
self.assertTrue(len(availability_zone) > 0)
-class AZTestXML(AZTestJSON):
+class AZV2TestJSON(AZV3Test):
+ _api_version = 2
+
+
+class AZV2TestXML(AZV2TestJSON):
_interface = 'xml'
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index ddfc1d5..b7e4e38 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -60,25 +60,6 @@
resp, server = self.create_test_server(personality=person)
self.assertEqual('202', resp['status'])
- @test.attr(type='gate')
- def test_create_server_with_existent_personality_file(self):
- # Any existing file that match specified file will be renamed to
- # include the bak extension appended with a time stamp
-
- # TODO(zhikunliu): will add validations when ssh instance validation
- # re-factor is ready
- file_contents = 'This is a test file.'
- personality = [{'path': '/test.txt',
- 'contents': base64.b64encode(file_contents)}]
- resp, server = self.create_test_server(personality=personality,
- wait_until="ACTIVE")
- resp, image = self.create_image_from_server(server['id'],
- wait_until="ACTIVE")
- resp, server = self.create_test_server(image_id=image['id'],
- personality=personality,
- wait_until="ACTIVE")
- self.assertEqual('202', resp['status'])
-
class ServerPersonalityTestXML(ServerPersonalityTestJSON):
_interface = "xml"
diff --git a/tempest/api/compute/v2/__init__.py b/tempest/api/compute/v2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/compute/v2/__init__.py
diff --git a/tempest/api/compute/v3/servers/test_availability_zone.py b/tempest/api/compute/v3/servers/test_availability_zone.py
deleted file mode 100644
index 5a1e07e..0000000
--- a/tempest/api/compute/v3/servers/test_availability_zone.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2014 NEC Corporation
-# 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.api.compute import base
-from tempest import test
-
-
-class AZV3Test(base.BaseV3ComputeTest):
-
- """
- Tests Availability Zone API List
- """
-
- @classmethod
- def setUpClass(cls):
- super(AZV3Test, cls).setUpClass()
- cls.client = cls.availability_zone_client
-
- @test.attr(type='gate')
- def test_get_availability_zone_list_with_non_admin_user(self):
- # List of availability zone with non-administrator user
- resp, availability_zone = self.client.get_availability_zone_list()
- self.assertEqual(200, resp.status)
- self.assertTrue(len(availability_zone) > 0)
diff --git a/tempest/api_schema/compute/hosts.py b/tempest/api_schema/compute/hosts.py
index a73e214..a9d6567 100644
--- a/tempest/api_schema/compute/hosts.py
+++ b/tempest/api_schema/compute/hosts.py
@@ -12,6 +12,15 @@
# License for the specific language governing permissions and limitations
# under the License.
+common_start_up_body = {
+ 'type': 'object',
+ 'properties': {
+ 'host': {'type': 'string'},
+ 'power_action': {'enum': ['startup']}
+ },
+ 'required': ['host', 'power_action']
+}
+
list_hosts = {
'status_code': [200],
'response_body': {
diff --git a/tempest/api_schema/compute/v2/hosts.py b/tempest/api_schema/compute/v2/hosts.py
index cd6bd7b..9ec8848 100644
--- a/tempest/api_schema/compute/v2/hosts.py
+++ b/tempest/api_schema/compute/v2/hosts.py
@@ -14,18 +14,12 @@
import copy
-body = {
- 'type': 'object',
- 'properties': {
- 'host': {'type': 'string'},
- 'power_action': {'enum': ['startup']}
- },
- 'required': ['host', 'power_action']
-}
+from tempest.api_schema.compute import hosts
+
startup_host = {
'status_code': [200],
- 'response_body': body
+ 'response_body': hosts.common_start_up_body
}
# The 'power_action' attribute of 'shutdown_host' API is 'shutdown'
diff --git a/tempest/api_schema/compute/v2/images.py b/tempest/api_schema/compute/v2/images.py
index e97752d..d121060 100644
--- a/tempest/api_schema/compute/v2/images.py
+++ b/tempest/api_schema/compute/v2/images.py
@@ -82,7 +82,17 @@
}
create_image = {
- 'status_code': [202]
+ 'status_code': [202],
+ 'response_header': {
+ 'type': 'object',
+ 'properties': {
+ 'location': {
+ 'type': 'string',
+ 'format': 'uri'
+ }
+ },
+ 'required': ['location']
+ }
}
delete = {
diff --git a/tempest/api_schema/compute/v3/hosts.py b/tempest/api_schema/compute/v3/hosts.py
index 2cf8f9b..575a6e2 100644
--- a/tempest/api_schema/compute/v3/hosts.py
+++ b/tempest/api_schema/compute/v3/hosts.py
@@ -13,14 +13,16 @@
# under the License.
import copy
-from tempest.api_schema.compute.v2 import hosts
+
+from tempest.api_schema.compute import hosts
+
startup_host = {
'status_code': [200],
'response_body': {
'type': 'object',
'properties': {
- 'host': hosts.body
+ 'host': hosts.common_start_up_body
},
'required': ['host']
}
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 9745cb4..8667445 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -371,7 +371,7 @@
# Parse one-item-like xmls (user, role, etc)
return common.xml_to_json(element)
- def response_checker(self, method, url, headers, body, resp, resp_body):
+ def response_checker(self, method, resp, resp_body):
if (resp.status in set((204, 205, 304)) or resp.status < 200 or
method.upper() == 'HEAD') and resp_body:
raise exceptions.ResponseWithNonEmptyBody(status=resp.status)
@@ -415,8 +415,7 @@
resp_body=resp_body)
# Verify HTTP response codes
- self.response_checker(method, url, req_headers, req_body, resp,
- resp_body)
+ self.response_checker(method, resp, resp_body)
return resp, resp_body
@@ -595,10 +594,12 @@
msg = ("The status code(%s) is different than the expected "
"one(%s)") % (resp.status, response_code)
raise exceptions.InvalidHttpSuccessCode(msg)
- response_schema = schema.get('response_body')
- if response_schema:
+
+ # Check the body of a response
+ body_schema = schema.get('response_body')
+ if body_schema:
try:
- jsonschema.validate(body, response_schema)
+ jsonschema.validate(body, body_schema)
except jsonschema.ValidationError as ex:
msg = ("HTTP response body is invalid (%s)") % ex
raise exceptions.InvalidHTTPResponseBody(msg)
@@ -607,6 +608,15 @@
msg = ("HTTP response body should not exist (%s)") % body
raise exceptions.InvalidHTTPResponseBody(msg)
+ # Check the header of a response
+ header_schema = schema.get('response_header')
+ if header_schema:
+ try:
+ jsonschema.validate(resp, header_schema)
+ except jsonschema.ValidationError as ex:
+ msg = ("HTTP response header is invalid (%s)") % ex
+ raise exceptions.InvalidHTTPResponseHeader(msg)
+
class NegativeRestClient(RestClient):
"""
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 857e1e8..2e2c5ec 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -197,6 +197,10 @@
message = "HTTP response body is invalid json or xml"
+class InvalidHTTPResponseHeader(RestClientException):
+ message = "HTTP response header is invalid"
+
+
class InvalidContentType(RestClientException):
message = "Invalid content type provided"
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index cf0fea8..40caf30 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -199,3 +199,199 @@
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_extensions_neutron(self):
+ def fake_list_extensions():
+ return (None, {'extensions': [{'alias': 'fake1'},
+ {'alias': 'fake2'},
+ {'alias': 'not_fake'}]})
+ fake_os = mock.MagicMock()
+ fake_os.network_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['fake1', 'fake2', 'fake3'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'neutron', {})
+ self.assertIn('neutron', results)
+ self.assertIn('fake1', results['neutron'])
+ self.assertTrue(results['neutron']['fake1'])
+ self.assertIn('fake2', results['neutron'])
+ self.assertTrue(results['neutron']['fake2'])
+ self.assertIn('fake3', results['neutron'])
+ self.assertFalse(results['neutron']['fake3'])
+ self.assertIn('not_fake', results['neutron'])
+ self.assertFalse(results['neutron']['not_fake'])
+
+ def test_verify_extensions_neutron_all(self):
+ def fake_list_extensions():
+ return (None, {'extensions': [{'alias': 'fake1'},
+ {'alias': 'fake2'},
+ {'alias': 'not_fake'}]})
+ fake_os = mock.MagicMock()
+ fake_os.network_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'neutron', {})
+ self.assertIn('neutron', results)
+ self.assertIn('extensions', results['neutron'])
+ self.assertEqual(['fake1', 'fake2', 'not_fake'],
+ results['neutron']['extensions'])
+
+ def test_verify_extensions_cinder(self):
+ def fake_list_extensions():
+ return (None, {'extensions': [{'name': 'fake1'},
+ {'name': 'fake2'},
+ {'name': 'not_fake'}]})
+ fake_os = mock.MagicMock()
+ fake_os.volumes_extension_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ 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'])
+ self.assertIn('fake2', results['cinder'])
+ self.assertTrue(results['cinder']['fake2'])
+ self.assertIn('fake3', results['cinder'])
+ self.assertFalse(results['cinder']['fake3'])
+ self.assertIn('not_fake', results['cinder'])
+ self.assertFalse(results['cinder']['not_fake'])
+
+ def test_verify_extensions_cinder_all(self):
+ def fake_list_extensions():
+ return (None, {'extensions': [{'name': 'fake1'},
+ {'name': 'fake2'},
+ {'name': 'not_fake'}]})
+ fake_os = mock.MagicMock()
+ fake_os.volumes_extension_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'cinder', {})
+ self.assertIn('cinder', results)
+ self.assertIn('extensions', results['cinder'])
+ self.assertEqual(['fake1', 'fake2', 'not_fake'],
+ results['cinder']['extensions'])
+
+ def test_verify_extensions_nova(self):
+ def fake_list_extensions():
+ return (None, {'extensions': [{'name': 'fake1'},
+ {'name': 'fake2'},
+ {'name': 'not_fake'}]})
+ fake_os = mock.MagicMock()
+ fake_os.extensions_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['fake1', 'fake2', 'fake3'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'nova', {})
+ self.assertIn('nova', results)
+ self.assertIn('fake1', results['nova'])
+ self.assertTrue(results['nova']['fake1'])
+ self.assertIn('fake2', results['nova'])
+ self.assertTrue(results['nova']['fake2'])
+ self.assertIn('fake3', results['nova'])
+ self.assertFalse(results['nova']['fake3'])
+ self.assertIn('not_fake', results['nova'])
+ self.assertFalse(results['nova']['not_fake'])
+
+ def test_verify_extensions_nova_all(self):
+ def fake_list_extensions():
+ return (None, {'extensions': [{'name': 'fake1'},
+ {'name': 'fake2'},
+ {'name': 'not_fake'}]})
+ fake_os = mock.MagicMock()
+ fake_os.extensions_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'nova', {})
+ self.assertIn('nova', results)
+ self.assertIn('extensions', results['nova'])
+ self.assertEqual(['fake1', 'fake2', 'not_fake'],
+ results['nova']['extensions'])
+
+ def test_verify_extensions_nova_v3(self):
+ def fake_list_extensions():
+ return (None, {'extensions': [{'name': 'fake1'},
+ {'name': 'fake2'},
+ {'name': 'not_fake'}]})
+ fake_os = mock.MagicMock()
+ fake_os.extensions_v3_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['fake1', 'fake2', 'fake3'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'nova_v3', {})
+ self.assertIn('nova_v3', results)
+ self.assertIn('fake1', results['nova_v3'])
+ self.assertTrue(results['nova_v3']['fake1'])
+ self.assertIn('fake2', results['nova_v3'])
+ self.assertTrue(results['nova_v3']['fake2'])
+ self.assertIn('fake3', results['nova_v3'])
+ self.assertFalse(results['nova_v3']['fake3'])
+ self.assertIn('not_fake', results['nova_v3'])
+ self.assertFalse(results['nova_v3']['not_fake'])
+
+ def test_verify_extensions_nova_v3_all(self):
+ def fake_list_extensions():
+ return (None, {'extensions': [{'name': 'fake1'},
+ {'name': 'fake2'},
+ {'name': 'not_fake'}]})
+ fake_os = mock.MagicMock()
+ fake_os.extensions_v3_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'nova_v3', {})
+ self.assertIn('nova_v3', results)
+ self.assertIn('extensions', results['nova_v3'])
+ self.assertEqual(['fake1', 'fake2', 'not_fake'],
+ results['nova_v3']['extensions'])
+
+ def test_verify_extensions_swift(self):
+ def fake_list_extensions():
+ return (None, {'fake1': 'metadata',
+ 'fake2': 'metadata',
+ 'not_fake': 'metadata',
+ 'swift': 'metadata'})
+ fake_os = mock.MagicMock()
+ fake_os.account_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['fake1', 'fake2', 'fake3'])))
+ results = verify_tempest_config.verify_extensions(fake_os, 'swift', {})
+ self.assertIn('swift', results)
+ self.assertIn('fake1', results['swift'])
+ self.assertTrue(results['swift']['fake1'])
+ self.assertIn('fake2', results['swift'])
+ self.assertTrue(results['swift']['fake2'])
+ self.assertIn('fake3', results['swift'])
+ self.assertFalse(results['swift']['fake3'])
+ self.assertIn('not_fake', results['swift'])
+ self.assertFalse(results['swift']['not_fake'])
+
+ def test_verify_extensions_swift_all(self):
+ def fake_list_extensions():
+ return (None, {'fake1': 'metadata',
+ 'fake2': 'metadata',
+ 'not_fake': 'metadata',
+ 'swift': 'metadata'})
+ fake_os = mock.MagicMock()
+ fake_os.account_client.list_extensions = fake_list_extensions
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'swift', {})
+ self.assertIn('swift', results)
+ self.assertIn('extensions', results['swift'])
+ self.assertEqual(['not_fake', 'fake1', 'fake2'],
+ results['swift']['extensions'])