Merge "Add user key data debug script to instance user data"
diff --git a/HACKING.rst b/HACKING.rst
index 910a977..f97f97a 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -170,7 +170,7 @@
All negative tests should be based on `API-WG guideline`_ . Such negative
tests can block any changes from accurate failure code to invalid one.
-.. _API-WG guideline: https://github.com/openstack/api-wg/blob/master/guidelines/http.rst#failure-code-clarifications
+.. _API-WG guideline: http://specs.openstack.org/openstack/api-wg/guidelines/http.html#failure-code-clarifications
If facing some gray area which is not clarified on the above guideline, propose
a new guideline to the API-WG. With a proposal to the API-WG we will be able to
diff --git a/README.rst b/README.rst
index f44c503..c1c6a10 100644
--- a/README.rst
+++ b/README.rst
@@ -104,7 +104,7 @@
$ tempest run
from the Tempest workspace directory. Or you can use the ``--workspace``
- argument to run in the workspace you created regarless of your current
+ argument to run in the workspace you created regardless of your current
working directory. For example::
$ tempest run --workspace cloud-01
diff --git a/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml b/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml
new file mode 100644
index 0000000..233cc28
--- /dev/null
+++ b/releasenotes/notes/add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add versions_client module for volume service.
+ This new module provides list_versions() method which shows API versions
+ from Volume service.
diff --git a/releasenotes/notes/add-tempest-lib-remote-client-adbeb3f42a36910b.yaml b/releasenotes/notes/add-tempest-lib-remote-client-adbeb3f42a36910b.yaml
index c21751b..1b8cda2 100644
--- a/releasenotes/notes/add-tempest-lib-remote-client-adbeb3f42a36910b.yaml
+++ b/releasenotes/notes/add-tempest-lib-remote-client-adbeb3f42a36910b.yaml
@@ -1,10 +1,11 @@
---
features:
- - Add remote_client under tempest.lib.
+ - |
+ Add remote_client under tempest.lib.
This remote_client under tempest.lib is defined as stable
interface, and now this module provides the following
essential methods.
- * exec_command
- * validate_authentication
- * ping_host
+ - exec_command
+ - validate_authentication
+ - ping_host
diff --git a/releasenotes/notes/deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml b/releasenotes/notes/deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml
new file mode 100644
index 0000000..0660d9c
--- /dev/null
+++ b/releasenotes/notes/deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml
@@ -0,0 +1,12 @@
+---
+deprecations:
+ - |
+ Volume v1 API is deprecated and the v3 are CURRENT.
+ Tempest doesn't need to test the v1 API as the default.
+ The volume config option 'api_v1' has been marked as
+ deprecated.
+upgrade:
+ - |
+ The volume config option 'api_v1' default is changed to
+ ``False`` because the volume v1 API has been deprecated
+ since Juno release.
diff --git a/releasenotes/notes/remove-cinder-v1-api-tests-71e266b8d55d475f.yaml b/releasenotes/notes/remove-cinder-v1-api-tests-71e266b8d55d475f.yaml
new file mode 100644
index 0000000..710ad9e
--- /dev/null
+++ b/releasenotes/notes/remove-cinder-v1-api-tests-71e266b8d55d475f.yaml
@@ -0,0 +1,5 @@
+upgrade:
+ - Remove Cinder v1 API tests.
+ Cinder v1 API has been deprecated since Juno release, and Juno is
+ not supported by current Tempest. Then Cinder v1 API tests are
+ removed from Tempest.
diff --git a/tempest/api/compute/admin/test_volume_swap.py b/tempest/api/compute/admin/test_volume_swap.py
index 45472df..984f1a9 100644
--- a/tempest/api/compute/admin/test_volume_swap.py
+++ b/tempest/api/compute/admin/test_volume_swap.py
@@ -30,6 +30,9 @@
5. Swap volume from "volume1" to "volume2" as admin.
6. Check the swap volume is successful and "volume2"
is attached to "instance1" and "volume1" is in available state.
+ 7. Swap volume from "volume2" to "volume1" as admin.
+ 8. Check the swap volume is successful and "volume1"
+ is attached to "instance1" and "volume2" is in available state.
"""
@classmethod
@@ -58,13 +61,21 @@
volume1['id'], 'available')
waiters.wait_for_volume_resource_status(self.volumes_client,
volume2['id'], 'in-use')
- self.addCleanup(self.servers_client.detach_volume,
- server['id'], volume2['id'])
# Verify "volume2" is attached to the server
vol_attachments = self.servers_client.list_volume_attachments(
server['id'])['volumeAttachments']
self.assertEqual(1, len(vol_attachments))
self.assertIn(volume2['id'], vol_attachments[0]['volumeId'])
- # TODO(mriedem): Test swapping back from volume2 to volume1 after
- # nova bug 1490236 is fixed.
+ # Swap volume from "volume2" to "volume1"
+ self.admin_servers_client.update_attached_volume(
+ server['id'], volume2['id'], volumeId=volume1['id'])
+ waiters.wait_for_volume_resource_status(self.volumes_client,
+ volume2['id'], 'available')
+ waiters.wait_for_volume_resource_status(self.volumes_client,
+ volume1['id'], 'in-use')
+ # Verify "volume1" is attached to the server
+ vol_attachments = self.servers_client.list_volume_attachments(
+ server['id'])['volumeAttachments']
+ self.assertEqual(1, len(vol_attachments))
+ self.assertIn(volume1['id'], vol_attachments[0]['volumeId'])
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index 7e55b12..87265ec 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.common import compute
from tempest.lib import decorators
@@ -21,13 +22,16 @@
@decorators.idempotent_id('61e03386-89c3-449c-9bb1-a06f423fd9d1')
def test_multiple_create(self):
- body = self.create_test_server(wait_until='ACTIVE',
- min_count=1,
- max_count=2)
+ body, servers = compute.create_test_server(self.os,
+ wait_until='ACTIVE',
+ min_count=2)
+ for server in servers:
+ self.addCleanup(self.servers_client.delete_server, server['id'])
# NOTE(maurosr): do status response check and also make sure that
# reservation_id is not in the response body when the request send
# contains return_reservation_id=False
self.assertNotIn('reservation_id', body)
+ self.assertEqual(2, len(servers))
@decorators.idempotent_id('864777fb-2f1e-44e3-b5b9-3eb6fa84f2f7')
def test_multiple_create_with_reservation_return(self):
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index fbfcafc..742fe59 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -239,6 +239,36 @@
'enable_snat': False})
self._verify_gateway_port(router['id'])
+ @decorators.idempotent_id('cbe42f84-04c2-11e7-8adb-fa163e4fa634')
+ @test.requires_ext(extension='ext-gw-mode', service='network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
+ def test_create_router_set_gateway_with_fixed_ip(self):
+ # Don't know public_network_address, so at first create address
+ # from public_network and delete
+ port = self.admin_ports_client.create_port(
+ network_id=CONF.network.public_network_id)['port']
+ self.admin_ports_client.delete_port(port_id=port['id'])
+
+ fixed_ip = {
+ 'subnet_id': port['fixed_ips'][0]['subnet_id'],
+ 'ip_address': port['fixed_ips'][0]['ip_address']
+ }
+ external_gateway_info = {
+ 'network_id': CONF.network.public_network_id,
+ 'external_fixed_ips': [fixed_ip]
+ }
+
+ # Create a router and set gateway to fixed_ip
+ router = self.admin_routers_client.create_router(
+ external_gateway_info=external_gateway_info)['router']
+ self.addCleanup(self.admin_routers_client.delete_router,
+ router_id=router['id'])
+ # Examine router's gateway is equal to fixed_ip
+ self.assertEqual(router['external_gateway_info'][
+ 'external_fixed_ips'][0]['ip_address'],
+ fixed_ip['ip_address'])
+
@decorators.idempotent_id('ad81b7ee-4f81-407b-a19c-17e623f763e8')
@testtools.skipUnless(CONF.network.public_network_id,
'The public_network_id option must be specified.')
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index e945ac9..8d680e9 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -14,6 +14,7 @@
# under the License.
import netaddr
+import testtools
from tempest.api.network import base_routers as base
from tempest import config
@@ -82,6 +83,31 @@
subnet02['id'])
@test.attr(type=['negative'])
+ @decorators.idempotent_id('7101cc02-058a-11e7-93e1-fa163e4fa634')
+ @test.requires_ext(extension='ext-gw-mode', service='network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
+ def test_router_set_gateway_used_ip_returns_409(self):
+ # At first create a address from public_network_id
+ port = self.admin_ports_client.create_port(
+ network_id=CONF.network.public_network_id)['port']
+ self.addCleanup(self.admin_ports_client.delete_port,
+ port_id=port['id'])
+ # Add used ip and subnet_id in external_fixed_ips
+ fixed_ip = {
+ 'subnet_id': port['fixed_ips'][0]['subnet_id'],
+ 'ip_address': port['fixed_ips'][0]['ip_address']
+ }
+ external_gateway_info = {
+ 'network_id': CONF.network.public_network_id,
+ 'external_fixed_ips': [fixed_ip]
+ }
+ # Create a router and set gateway to used ip
+ self.assertRaises(lib_exc.Conflict,
+ self.admin_routers_client.create_router,
+ external_gateway_info=external_gateway_info)
+
+ @test.attr(type=['negative'])
@decorators.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
def test_router_remove_interface_in_use_returns_409(self):
self.routers_client.add_router_interface(self.router['id'],
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 4a46adc..5230708 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -140,7 +140,3 @@
msg = ("volumes %s were created in the same backend" % ", "
.join(volume_hosts))
six.assertCountEqual(self, volume_hosts, set(volume_hosts), msg)
-
-
-class VolumeMultiBackendV1Test(VolumeMultiBackendV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_qos.py b/tempest/api/volume/admin/test_qos.py
index 7a91985..aa6aa98 100644
--- a/tempest/api/volume/admin/test_qos.py
+++ b/tempest/api/volume/admin/test_qos.py
@@ -157,7 +157,3 @@
operation = 'disassociate-all'
waiters.wait_for_qos_operations(self.admin_volume_qos_client,
self.created_qos['id'], operation)
-
-
-class QosSpecsV1TestJSON(QosSpecsV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index e1c9492..4d8e5bf 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -107,7 +107,3 @@
def test_snapshot_force_delete_when_snapshot_is_error_deleting(self):
# test force delete when status of snapshot is error_deleting
self._create_reset_and_force_delete_temp_snapshot('error_deleting')
-
-
-class SnapshotsActionsV1Test(SnapshotsActionsV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index 73c927a..1686582 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -24,7 +24,3 @@
hosts = self.admin_hosts_client.list_hosts()['hosts']
self.assertGreaterEqual(len(hosts), 2, "No. of hosts are < 2,"
"response of list hosts is: % s" % hosts)
-
-
-class VolumeHostsAdminV1TestsJSON(VolumeHostsAdminV2TestsJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 3fd9b01..97f61c1 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -169,7 +169,3 @@
self.assertEqual(primary_quota['gigabytes']['in_use'] -
volume['size'],
new_primary_quota['gigabytes']['in_use'])
-
-
-class VolumeQuotasAdminV1TestJSON(BaseVolumeQuotasAdminV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index 8170626..1051445 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -70,7 +70,3 @@
self.assertRaises(lib_exc.OverLimit,
self.volumes_client.create_volume,
size=CONF.volume.volume_size)
-
-
-class VolumeQuotasNegativeV1TestJSON(BaseVolumeQuotasNegativeV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_services.py b/tempest/api/volume/admin/test_volume_services.py
index 5dfdfce..aa5145d 100644
--- a/tempest/api/volume/admin/test_volume_services.py
+++ b/tempest/api/volume/admin/test_volume_services.py
@@ -80,7 +80,3 @@
self.assertNotEqual(0, len(services))
self.assertEqual(self.host_name, _get_host(services[0]['host']))
self.assertEqual(self.binary_name, services[0]['binary'])
-
-
-class VolumesServicesV1TestJSON(VolumesServicesV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py b/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
index 90a0022..6320fb1 100644
--- a/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_snapshot_quotas_negative.py
@@ -75,7 +75,3 @@
self.assertRaises(lib_exc.OverLimit,
self.snapshots_client.create_snapshot,
volume_id=self.volume['id'])
-
-
-class VolumeSnapshotNegativeV1TestJSON(VolumeSnapshotQuotasNegativeV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 6e56be9..f75c940 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -183,7 +183,3 @@
self.assertEqual(name, updated_vol_type['name'])
self.assertEqual(description, updated_vol_type['description'])
self.assertEqual(is_public, updated_vol_type['is_public'])
-
-
-class VolumeTypesV1Test(VolumeTypesV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 1729d06..6a7ee3b 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -77,7 +77,3 @@
lib_exc.NotFound,
self.admin_volume_types_client.show_volume_type_extra_specs,
self.volume_type['id'], spec_key)
-
-
-class VolumeTypesExtraSpecsV1Test(VolumeTypesExtraSpecsV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index d491f23..37422ca 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -136,7 +136,3 @@
lib_exc.NotFound,
self.admin_volume_types_client.show_volume_type_extra_specs,
self.volume_type['id'], data_utils.rand_uuid())
-
-
-class ExtraSpecsNegativeV1Test(ExtraSpecsNegativeV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index 69e9cc0..8d0bf4a 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -64,7 +64,3 @@
volume_type = self.create_volume_type(**params)
self.assertRaises(lib_exc.NotFound,
self.create_volume, volume_type=volume_type['id'])
-
-
-class VolumeTypesNegativeV1Test(VolumeTypesNegativeV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 693ffe7..02b10f9 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -53,7 +53,3 @@
def test_volume_force_delete_when_volume_is_error(self):
# test force delete when status of volume is error
self._create_reset_and_force_delete_temp_volume('error')
-
-
-class VolumesActionsV1Test(VolumesActionsV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index b771d8a..29c79f9 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -136,7 +136,3 @@
status="error")
waiters.wait_for_volume_resource_status(self.admin_backups_client,
backup['id'], 'error')
-
-
-class VolumesBackupsAdminV1Test(VolumesBackupsAdminV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 496594c..f794920 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -37,11 +37,7 @@
if not CONF.service_available.cinder:
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
raise cls.skipException(skip_msg)
- if cls._api_version == 1:
- if not CONF.volume_feature_enabled.api_v1:
- msg = "Volume API v1 is disabled"
- raise cls.skipException(msg)
- elif cls._api_version == 2:
+ if cls._api_version == 2:
if not CONF.volume_feature_enabled.api_v2:
msg = "Volume API v2 is disabled"
raise cls.skipException(msg)
@@ -65,23 +61,13 @@
cls.compute_networks_client = cls.os.compute_networks_client
cls.compute_images_client = cls.os.compute_images_client
- if cls._api_version == 1:
- cls.snapshots_client = cls.os.snapshots_client
- cls.volumes_client = cls.os.volumes_client
- cls.backups_client = cls.os.backups_client
- cls.volume_services_client = cls.os.volume_services_client
- cls.volumes_extension_client = cls.os.volumes_extension_client
- cls.availability_zone_client = (
- cls.os.volume_availability_zone_client)
- cls.volume_limits_client = cls.os.volume_limits_client
- else:
- cls.snapshots_client = cls.os.snapshots_v2_client
- cls.volumes_client = cls.os.volumes_v2_client
- cls.backups_client = cls.os.backups_v2_client
- cls.volumes_extension_client = cls.os.volumes_v2_extension_client
- cls.availability_zone_client = (
- cls.os.volume_v2_availability_zone_client)
- cls.volume_limits_client = cls.os.volume_v2_limits_client
+ cls.snapshots_client = cls.os.snapshots_v2_client
+ cls.volumes_client = cls.os.volumes_v2_client
+ cls.backups_client = cls.os.backups_v2_client
+ cls.volumes_extension_client = cls.os.volumes_v2_extension_client
+ cls.availability_zone_client = (
+ cls.os.volume_v2_availability_zone_client)
+ cls.volume_limits_client = cls.os.volume_v2_limits_client
@classmethod
def resource_setup(cls):
@@ -94,14 +80,8 @@
cls.build_interval = CONF.volume.build_interval
cls.build_timeout = CONF.volume.build_timeout
- if cls._api_version == 1:
- # Special fields and resp code for cinder v1
- cls.special_fields = {'name_field': 'display_name',
- 'descrip_field': 'display_description'}
- else:
- # Special fields and resp code for cinder v2
- cls.special_fields = {'name_field': 'name',
- 'descrip_field': 'description'}
+ cls.special_fields = {'name_field': 'name',
+ 'descrip_field': 'description'}
@classmethod
def resource_cleanup(cls):
@@ -246,38 +226,24 @@
def setup_clients(cls):
super(BaseVolumeAdminTest, cls).setup_clients()
- if cls._api_version == 1:
- cls.admin_volume_qos_client = cls.os_adm.volume_qos_client
- cls.admin_volume_services_client = \
- cls.os_adm.volume_services_client
- cls.admin_volume_types_client = cls.os_adm.volume_types_client
- cls.admin_volume_client = cls.os_adm.volumes_client
- cls.admin_hosts_client = cls.os_adm.volume_hosts_client
- cls.admin_snapshots_client = cls.os_adm.snapshots_client
- cls.admin_backups_client = cls.os_adm.backups_client
- cls.admin_encryption_types_client = \
- cls.os_adm.encryption_types_client
- cls.admin_quotas_client = cls.os_adm.volume_quotas_client
- cls.admin_volume_limits_client = cls.os_adm.volume_limits_client
- elif cls._api_version == 2:
- cls.admin_volume_qos_client = cls.os_adm.volume_qos_v2_client
- cls.admin_volume_services_client = \
- cls.os_adm.volume_services_v2_client
- cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
- cls.admin_volume_client = cls.os_adm.volumes_v2_client
- cls.admin_hosts_client = cls.os_adm.volume_hosts_v2_client
- cls.admin_snapshot_manage_client = \
- cls.os_adm.snapshot_manage_v2_client
- cls.admin_snapshots_client = cls.os_adm.snapshots_v2_client
- cls.admin_backups_client = cls.os_adm.backups_v2_client
- cls.admin_encryption_types_client = \
- cls.os_adm.encryption_types_v2_client
- cls.admin_quotas_client = cls.os_adm.volume_quotas_v2_client
- cls.admin_volume_limits_client = cls.os_adm.volume_v2_limits_client
- cls.admin_capabilities_client = \
- cls.os_adm.volume_capabilities_v2_client
- cls.admin_scheduler_stats_client = \
- cls.os_adm.volume_scheduler_stats_v2_client
+ cls.admin_volume_qos_client = cls.os_adm.volume_qos_v2_client
+ cls.admin_volume_services_client = \
+ cls.os_adm.volume_services_v2_client
+ cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
+ cls.admin_volume_client = cls.os_adm.volumes_v2_client
+ cls.admin_hosts_client = cls.os_adm.volume_hosts_v2_client
+ cls.admin_snapshot_manage_client = \
+ cls.os_adm.snapshot_manage_v2_client
+ cls.admin_snapshots_client = cls.os_adm.snapshots_v2_client
+ cls.admin_backups_client = cls.os_adm.backups_v2_client
+ cls.admin_encryption_types_client = \
+ cls.os_adm.encryption_types_v2_client
+ cls.admin_quotas_client = cls.os_adm.volume_quotas_v2_client
+ cls.admin_volume_limits_client = cls.os_adm.volume_v2_limits_client
+ cls.admin_capabilities_client = \
+ cls.os_adm.volume_capabilities_v2_client
+ cls.admin_scheduler_stats_client = \
+ cls.os_adm.volume_scheduler_stats_v2_client
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/volume/test_availability_zone.py b/tempest/api/volume/test_availability_zone.py
index 25fe5ad..f0d653f 100644
--- a/tempest/api/volume/test_availability_zone.py
+++ b/tempest/api/volume/test_availability_zone.py
@@ -31,7 +31,3 @@
availability_zone = (self.client.list_availability_zones()
['availabilityZoneInfo'])
self.assertGreater(len(availability_zone), 0)
-
-
-class AvailabilityZoneV1TestJSON(AvailabilityZoneV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
index ca86748..ac3742c 100644
--- a/tempest/api/volume/test_extensions.py
+++ b/tempest/api/volume/test_extensions.py
@@ -43,7 +43,3 @@
self.assertIn(ext, map(lambda x: x['alias'], extensions))
else:
raise self.skipException('There are not any extensions configured')
-
-
-class ExtensionsV1TestJSON(ExtensionsV2TestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_snapshot_metadata.py b/tempest/api/volume/test_snapshot_metadata.py
index d5ad8d2..c1d4e05 100644
--- a/tempest/api/volume/test_snapshot_metadata.py
+++ b/tempest/api/volume/test_snapshot_metadata.py
@@ -102,7 +102,3 @@
body = self.snapshots_client.show_snapshot_metadata(
self.snapshot['id'])['metadata']
self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
-
-
-class SnapshotV1MetadataTestJSON(SnapshotV2MetadataTestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_volume_absolute_limits.py b/tempest/api/volume/test_volume_absolute_limits.py
index 36445b9..8e3c343 100644
--- a/tempest/api/volume/test_volume_absolute_limits.py
+++ b/tempest/api/volume/test_volume_absolute_limits.py
@@ -46,7 +46,3 @@
self.assertEqual(absolute_limits['totalSnapshotsUsed'], 0)
self.assertEqual(absolute_limits['totalBackupsUsed'], 0)
self.assertEqual(absolute_limits['totalBackupGigabytesUsed'], 0)
-
-
-class AbsoluteLimitsV1Tests(AbsoluteLimitsV2Tests):
- _api_version = 1
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index 9e7b0a7..bbe1765 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -89,7 +89,3 @@
body = self.volumes_client.show_volume_metadata(
self.volume['id'])['metadata']
self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
-
-
-class VolumesV1MetadataTest(VolumesV2MetadataTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 9f63b14..22cbd85 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -86,7 +86,3 @@
self.client.delete_volume_transfer(transfer_id)
waiters.wait_for_volume_resource_status(
self.client, volume['id'], 'available')
-
-
-class VolumesV1TransfersTest(VolumesV2TransfersTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index d39b07a..4fc1a69 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -153,7 +153,3 @@
# to compare here.
self.assertEqual(str(readonly),
fetched_volume['metadata']['readonly'])
-
-
-class VolumesV1ActionsTest(VolumesV2ActionsTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_backup.py b/tempest/api/volume/test_volumes_backup.py
index 83006c0..e0b54b5 100644
--- a/tempest/api/volume/test_volumes_backup.py
+++ b/tempest/api/volume/test_volumes_backup.py
@@ -134,7 +134,3 @@
restored_volume_id)['volume']
self.assertEqual('true', restored_volume_info['bootable'])
-
-
-class VolumesBackupsV1Test(VolumesBackupsV2Test):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_clone.py b/tempest/api/volume/test_volumes_clone.py
index d653808..620f3d4 100644
--- a/tempest/api/volume/test_volumes_clone.py
+++ b/tempest/api/volume/test_volumes_clone.py
@@ -60,7 +60,3 @@
self.assertEqual('true', cloned_vol_details['bootable'])
self.assertEqual(src_vol['id'], cloned_vol_details['source_volid'])
self.assertEqual(src_vol['size'], cloned_vol_details['size'])
-
-
-class VolumesV1CloneTest(VolumesV2CloneTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_clone_negative.py b/tempest/api/volume/test_volumes_clone_negative.py
index 5331243..28327f4 100644
--- a/tempest/api/volume/test_volumes_clone_negative.py
+++ b/tempest/api/volume/test_volumes_clone_negative.py
@@ -43,7 +43,3 @@
self.volumes_client.create_volume,
size=src_size - 1,
source_volid=src_vol['id'])
-
-
-class VolumesV1CloneNegativeTest(VolumesV2CloneNegativeTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index 3df9b00..3b09b60 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -31,7 +31,3 @@
volume['id'], 'available')
volume = self.volumes_client.show_volume(volume['id'])['volume']
self.assertEqual(volume['size'], extend_size)
-
-
-class VolumesV1ExtendTest(VolumesV2ExtendTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index d870534..8014e62 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -141,7 +141,3 @@
origin = self.create_volume()
self._volume_create_get_update_delete(source_volid=origin['id'],
size=CONF.volume.volume_size)
-
-
-class VolumesV1GetTest(VolumesV2GetTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 1d6d35f..a852cea 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -221,8 +221,3 @@
params = {self.name: volume[self.name],
'status': 'available'}
self._list_by_param_value_and_assert(params, with_detail=True)
-
-
-class VolumesV1ListTestJSON(VolumesV2ListTestJSON):
- _api_version = 1
- VOLUME_FIELDS = ('id', 'display_name')
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 76ffc03..da11ed9 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -294,7 +294,3 @@
self.volumes_client.list_volumes(detail=True,
params=params)['volumes']
self.assertEqual(0, len(fetched_volume))
-
-
-class VolumesV1NegativeTest(VolumesV2NegativeTest):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 82b4fc2..ce93512 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -158,7 +158,3 @@
# Should allow
self.assertEqual(volume['snapshot_id'], src_snap['id'])
self.assertEqual(volume['size'], src_size + 1)
-
-
-class VolumesV1SnapshotTestJSON(VolumesV2SnapshotTestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_snapshots_list.py b/tempest/api/volume/test_volumes_snapshots_list.py
index a0eaa00..237b276 100644
--- a/tempest/api/volume/test_volumes_snapshots_list.py
+++ b/tempest/api/volume/test_volumes_snapshots_list.py
@@ -103,7 +103,3 @@
def test_snapshot_list_param_limit_equals_zero(self):
# List returns zero elements
self._list_snapshots_by_param_limit(limit=0, expected_elements=0)
-
-
-class VolumesV1SnapshotLimitTestJSON(VolumesV2SnapshotListTestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/test_volumes_snapshots_negative.py b/tempest/api/volume/test_volumes_snapshots_negative.py
index d3e3c9b..285d3f5 100644
--- a/tempest/api/volume/test_volumes_snapshots_negative.py
+++ b/tempest/api/volume/test_volumes_snapshots_negative.py
@@ -68,7 +68,3 @@
self.assertRaises(lib_exc.BadRequest,
self.snapshots_client.list_snapshots,
limit='invalid')
-
-
-class VolumesV1SnapshotNegativeTestJSON(VolumesV2SnapshotNegativeTestJSON):
- _api_version = 1
diff --git a/tempest/api/volume/v3/base.py b/tempest/api/volume/v3/base.py
index 31fc1eb..7f76e6f 100644
--- a/tempest/api/volume/v3/base.py
+++ b/tempest/api/volume/v3/base.py
@@ -45,6 +45,7 @@
def setup_clients(cls):
super(VolumesV3Test, cls).setup_clients()
cls.messages_client = cls.os.volume_v3_messages_client
+ cls.versions_client = cls.os.volume_v3_versions_client
def setUp(self):
super(VolumesV3Test, self).setUp()
diff --git a/tempest/api/volume/v3/test_versions.py b/tempest/api/volume/v3/test_versions.py
new file mode 100644
index 0000000..20f1657
--- /dev/null
+++ b/tempest/api/volume/v3/test_versions.py
@@ -0,0 +1,28 @@
+# Copyright 2017 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.volume.v3 import base
+from tempest.lib import decorators
+from tempest import test
+
+
+class VersionsTest(base.VolumesV3Test):
+
+ @decorators.idempotent_id('77838fc4-b49b-4c64-9533-166762517369')
+ @test.attr(type='smoke')
+ def test_list_versions(self):
+ # NOTE: The version data is checked on service client side
+ # with JSON-Schema validation. It is enough to just call
+ # the API here.
+ self.versions_client.list_versions()['versions']
diff --git a/tempest/clients.py b/tempest/clients.py
index e75fa79..0654110 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -265,6 +265,7 @@
self.volumes_client = self.volume_v1.VolumesClient()
self.volumes_v2_client = self.volume_v2.VolumesClient()
self.volume_v3_messages_client = self.volume_v3.MessagesClient()
+ self.volume_v3_versions_client = self.volume_v3.VersionsClient()
self.volume_types_client = self.volume_v1.TypesClient()
self.volume_types_v2_client = self.volume_v2.TypesClient()
self.volume_hosts_client = self.volume_v1.HostsClient()
diff --git a/tempest/config.py b/tempest/config.py
index d5c8ea9..caa2ff0 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -812,8 +812,12 @@
'entry all which indicates every extension is enabled. '
'Empty list indicates all extensions are disabled'),
cfg.BoolOpt('api_v1',
- default=True,
- help="Is the v1 volume API enabled"),
+ default=False,
+ help="Is the v1 volume API enabled",
+ deprecated_for_removal=True,
+ deprecated_reason="The v1 volume API has been deprecated "
+ "since Juno release, and the API will be "
+ "removed."),
cfg.BoolOpt('api_v2',
default=True,
help="Is the v2 volume API enabled"),
diff --git a/tempest/lib/api_schema/response/compute/v2_26/servers.py b/tempest/lib/api_schema/response/compute/v2_26/servers.py
index d873402..b03bdf6 100644
--- a/tempest/lib/api_schema/response/compute/v2_26/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_26/servers.py
@@ -52,12 +52,7 @@
'response_body': {
'type': 'object',
'properties': {
- 'tags': {
- 'type': 'array',
- 'items': {
- 'type': 'string'
- }
- }
+ 'tags': tag_items,
},
'additionalProperties': False,
'required': ['tags']
diff --git a/tempest/lib/api_schema/response/volume/__init__.py b/tempest/lib/api_schema/response/volume/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/__init__.py
diff --git a/tempest/lib/api_schema/response/volume/versions.py b/tempest/lib/api_schema/response/volume/versions.py
new file mode 100644
index 0000000..2391a8c
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/versions.py
@@ -0,0 +1,60 @@
+# Copyright 2015 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.
+
+
+list_versions = {
+ 'status_code': [300],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'versions': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'status': {'type': 'string'},
+ 'updated': {'type': 'string'},
+ 'id': {'type': 'string'},
+ 'links': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'href': {'type': 'string',
+ 'format': 'uri'},
+ 'rel': {'type': 'string'},
+ 'type': {'type': 'string'},
+ },
+ 'required': ['href', 'rel']
+ }
+ },
+ 'min_version': {'type': 'string'},
+ 'version': {'type': 'string'},
+ 'media-types': {
+ 'type': 'array',
+ 'properties': {
+ 'base': {'type': 'string'},
+ 'type': {'type': 'string'}
+ },
+ 'required': ['base', 'type']
+ }
+ },
+ 'required': ['status', 'updated', 'id', 'links',
+ 'min_version', 'version', 'media-types']
+ }
+ }
+ },
+ 'required': ['versions'],
+ }
+}
diff --git a/tempest/lib/common/cred_client.py b/tempest/lib/common/cred_client.py
index ea06011..a81f53c 100644
--- a/tempest/lib/common/cred_client.py
+++ b/tempest/lib/common/cred_client.py
@@ -59,7 +59,8 @@
def _check_role_exists(self, role_name):
try:
roles = self._list_roles()
- role = next(r for r in roles if r['name'] == role_name)
+ lc_role_name = role_name.lower()
+ role = next(r for r in roles if r['name'].lower() == lc_role_name)
except StopIteration:
return None
return role
diff --git a/tempest/lib/services/volume/v3/__init__.py b/tempest/lib/services/volume/v3/__init__.py
index a4600a8..72ab785 100644
--- a/tempest/lib/services/volume/v3/__init__.py
+++ b/tempest/lib/services/volume/v3/__init__.py
@@ -14,5 +14,6 @@
from tempest.lib.services.volume.v3.base_client import BaseClient
from tempest.lib.services.volume.v3.messages_client import MessagesClient
+from tempest.lib.services.volume.v3.versions_client import VersionsClient
-__all__ = ['MessagesClient', 'BaseClient']
+__all__ = ['MessagesClient', 'BaseClient', 'VersionsClient']
diff --git a/tempest/lib/services/volume/v3/versions_client.py b/tempest/lib/services/volume/v3/versions_client.py
new file mode 100644
index 0000000..e2941c4
--- /dev/null
+++ b/tempest/lib/services/volume/v3/versions_client.py
@@ -0,0 +1,47 @@
+# Copyright 2017 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.
+
+import time
+
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.api_schema.response.volume import versions as schema
+from tempest.lib.common import rest_client
+from tempest.lib.services.volume.v3 import base_client
+
+
+class VersionsClient(base_client.BaseClient):
+
+ def list_versions(self):
+ """List API versions
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://developer.openstack.org/api-ref/block-storage/v3/#list-all-api-versions
+ """
+ version_url = self._get_base_version_url()
+
+ start = time.time()
+ resp, body = self.raw_request(version_url, 'GET')
+ end = time.time()
+ # NOTE: We need a raw_request() here instead of request() call because
+ # "list API versions" API doesn't require an authentication and we can
+ # skip it with raw_request() call.
+ self._log_request('GET', version_url, resp, secs=(end - start),
+ resp_body=body)
+ self._error_checker(resp, body)
+
+ body = json.loads(body)
+ self.validate_response(schema.list_versions, resp, body)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 5bbc039..15a0a70 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -104,7 +104,6 @@
def _setup_network_and_servers(self, **kwargs):
boot_with_port = kwargs.pop('boot_with_port', False)
- self.security_group = self._create_security_group()
self.network, self.subnet, self.router = self.create_networks(**kwargs)
self.check_networks()
@@ -152,7 +151,9 @@
def _create_server(self, network, port_id=None):
keypair = self.create_keypair()
self.keypairs[keypair['name']] = keypair
- security_groups = [{'name': self.security_group['name']}]
+ security_groups = [
+ {'name': self._create_security_group()['name']}
+ ]
network = {'uuid': network['id']}
if port_id is not None:
network['port'] = port_id
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index d9b93fe..cfd83d0 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -72,11 +72,11 @@
if dualnet - create IPv6 subnets on a different network
:return: list of created networks
"""
- self.network = self._create_network()
+ network = self._create_network()
if dualnet:
- self.network_v6 = self._create_network()
+ network_v6 = self._create_network()
- sub4 = self._create_subnet(network=self.network,
+ sub4 = self._create_subnet(network=network,
namestart='sub4',
ip_version=4)
@@ -90,7 +90,7 @@
self.subnets_v6 = []
for _ in range(n_subnets6):
- net6 = self.network_v6 if dualnet else self.network
+ net6 = network_v6 if dualnet else network
sub6 = self._create_subnet(network=net6,
namestart='sub6',
ip_version=6,
@@ -105,7 +105,7 @@
router['id'], subnet_id=sub6['id'])
self.subnets_v6.append(sub6)
- return [self.network, self.network_v6] if dualnet else [self.network]
+ return [network, network_v6] if dualnet else [network]
@staticmethod
def define_server_ips(srv):
@@ -121,8 +121,6 @@
def prepare_server(self, networks=None):
username = CONF.validation.image_ssh_user
- networks = networks or [self.network]
-
srv = self.create_server(
key_name=self.keypair['name'],
security_groups=[{'name': self.sec_grp['name']}],
@@ -134,7 +132,7 @@
username=username)
return ssh, ips, srv["id"]
- def turn_nic6_on(self, ssh, sid):
+ def turn_nic6_on(self, ssh, sid, network_id):
"""Turns the IPv6 vNIC on
Required because guest images usually set only the first vNIC on boot.
@@ -142,16 +140,18 @@
@param ssh: RemoteClient ssh instance to server
@param sid: server uuid
+ @param network_id: the network id the NIC is connected to
"""
ports = [
p["mac_address"] for p in
self.admin_manager.ports_client.list_ports(
- device_id=sid, network_id=self.network_v6['id'])['ports']
+ device_id=sid, network_id=network_id)['ports']
]
+
self.assertEqual(1, len(ports),
message=("Multiple IPv6 ports found on network %s. "
"ports: %s")
- % (self.network_v6, ports))
+ % (network_id, ports))
mac6 = ports[0]
ssh.set_nic_state(ssh.get_nic_name_by_mac(mac6))
@@ -168,8 +168,9 @@
# Turn on 2nd NIC for Cirros when dualnet
if dualnet:
- self.turn_nic6_on(sshv4_1, sid1)
- self.turn_nic6_on(sshv4_2, sid2)
+ network, network_v6 = net_list
+ self.turn_nic6_on(sshv4_1, sid1, network_v6['id'])
+ self.turn_nic6_on(sshv4_2, sid2, network_v6['id'])
# get addresses assigned to vNIC as reported by 'ip address' utility
ips_from_ip_1 = sshv4_1.exec_command("ip address")
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 1af0d95..98bf145 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -192,7 +192,7 @@
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, '_get_unversioned_endpoint',
return_value='http://fake_endpoint:5000'))
- fake_resp = {'versions': [{'id': 'v1.0'}, {'id': 'v2.0'}]}
+ fake_resp = {'versions': [{'id': 'v2.0'}]}
fake_resp = json.dumps(fake_resp)
mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
@@ -206,7 +206,7 @@
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, '_get_unversioned_endpoint',
return_value='http://fake_endpoint:5000'))
- fake_resp = {'versions': [{'id': 'v1.0'}, {'id': 'v3.0'}]}
+ fake_resp = {'versions': [{'id': 'v3.0'}]}
fake_resp = json.dumps(fake_resp)
mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
@@ -231,11 +231,9 @@
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_cinder_api_versions(fake_os, True)
- print_mock.assert_any_call('api_v1', 'volume-feature-enabled',
- False, True)
print_mock.assert_any_call('api_v3', 'volume-feature-enabled',
True, True)
- self.assertEqual(2, print_mock.call_count)
+ self.assertEqual(1, print_mock.call_count)
def test_verify_glance_version_no_v2_with_v1_1(self):
def fake_get_versions():
diff --git a/tempest/tests/lib/services/volume/v3/test_versions_client.py b/tempest/tests/lib/services/volume/v3/test_versions_client.py
new file mode 100644
index 0000000..9627b9a
--- /dev/null
+++ b/tempest/tests/lib/services/volume/v3/test_versions_client.py
@@ -0,0 +1,91 @@
+# Copyright 2017 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.lib.services.volume.v3 import versions_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestVersionsClient(base.BaseServiceTest):
+
+ FAKE_VERSIONS_INFO = {
+ "versions": [
+ {
+ "status": "DEPRECATED", "updated": "2016-05-02T20:25:19Z",
+ "links": [
+ {"href": "http://docs.openstack.org/", "type": "text/html",
+ "rel": "describedby"},
+ {"href": "https://10.30.197.39:8776/v1/", "rel": "self"}
+ ],
+ "min_version": "",
+ "version": "",
+ "media-types": [
+ {"base": "application/json",
+ "type": "application/vnd.openstack.volume+json;version=1"}
+ ],
+ "id": "v1.0"
+ },
+ {
+ "status": "DEPRECATED", "updated": "2017-02-25T12:00:00Z",
+ "links": [
+ {"href": "http://docs.openstack.org/", "type": "text/html",
+ "rel": "describedby"},
+ {"href": "https://10.30.197.39:8776/v2/", "rel": "self"}
+ ],
+ "min_version": "",
+ "version": "",
+ "media-types": [
+ {"base": "application/json",
+ "type": "application/vnd.openstack.volume+json;version=1"}
+ ],
+ "id": "v2.0"
+ },
+ {
+ "status": "CURRENT", "updated": "2016-02-08T12:20:21Z",
+ "links": [
+ {"href": "http://docs.openstack.org/", "type": "text/html",
+ "rel": "describedby"},
+ {"href": "https://10.30.197.39:8776/v3/", "rel": "self"}
+ ],
+ "min_version": "3.0",
+ "version": "3.28",
+ "media-types": [
+ {"base": "application/json",
+ "type": "application/vnd.openstack.volume+json;version=1"}
+ ],
+ "id": "v3.0"
+ }
+ ]
+ }
+
+ def setUp(self):
+ super(TestVersionsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = versions_client.VersionsClient(fake_auth,
+ 'volume',
+ 'regionOne')
+
+ def _test_list_versions(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_versions,
+ 'tempest.lib.common.rest_client.RestClient.raw_request',
+ self.FAKE_VERSIONS_INFO,
+ bytes_body,
+ 300)
+
+ def test_list_versions_with_str_body(self):
+ self._test_list_versions()
+
+ def test_list_versions_with_bytes_body(self):
+ self._test_list_versions(bytes_body=True)