Add v2 Manila API path as base for microversions
To prevent a microversioned client from managing a non-microversioned
Manila server, Manila must update its REST endpoints by adding /v2 for
all microversioned APIs.
This commit does the following:
* Add /v2 to the URL map, connected to all the same /v1 API methods
* Renumber the microversion sequence starting from 2.0
* Update the versions API to reflect v2
* Publish the new endpoint to Keystone in the DevStack plug-in
* Update relevant documentation
* Update Tempest tests for microversions
APIImpact
Co-Authored-By: Andrew Kerr <andrew.kerr@netapp.com>
Closes-Bug: 1488624
Change-Id: I56a516b5f81914557dd2465746629431cfd6deac
diff --git a/manila_tempest_tests/tests/api/admin/test_admin_actions.py b/manila_tempest_tests/tests/api/admin/test_admin_actions.py
index 6acec11..e70fd6a 100644
--- a/manila_tempest_tests/tests/api/admin/test_admin_actions.py
+++ b/manila_tempest_tests/tests/api/admin/test_admin_actions.py
@@ -32,7 +32,7 @@
cls.bad_status = "error_deleting"
cls.sh = cls.create_share()
cls.sh_instance = (
- cls.shares_client.get_instances_of_share(cls.sh["id"])[0]
+ cls.shares_v2_client.get_instances_of_share(cls.sh["id"])[0]
)
if CONF.share.run_snapshot_tests:
cls.sn = cls.create_snapshot_wait_for_active(cls.sh["id"])
@@ -49,7 +49,7 @@
for status in self.states:
self.shares_client.reset_state(
id, s_type="share_instances", status=status)
- self.shares_client.wait_for_share_instance_status(id, status)
+ self.shares_v2_client.wait_for_share_instance_status(id, status)
@test.attr(type=["gate", ])
@testtools.skipUnless(CONF.share.run_snapshot_tests,
@@ -78,7 +78,7 @@
@test.attr(type=["gate", ])
def test_force_delete_share_instance(self):
share = self.create_share(cleanup_in_class=False)
- instances = self.shares_client.get_instances_of_share(share["id"])
+ instances = self.shares_v2_client.get_instances_of_share(share["id"])
# Check that instance was created
self.assertEqual(1, len(instances))
@@ -89,13 +89,13 @@
instance["id"], s_type="share_instances", status=self.bad_status)
# Check that status was changed
- check_status = self.shares_client.get_share_instance(instance["id"])
+ check_status = self.shares_v2_client.get_share_instance(instance["id"])
self.assertEqual(self.bad_status, check_status["status"])
# Share with status 'error_deleting' should be deleted
self.shares_client.force_delete(
instance["id"], s_type="share_instances")
- self.shares_client.wait_for_resource_deletion(
+ self.shares_v2_client.wait_for_resource_deletion(
share_instance_id=instance["id"])
@test.attr(type=["gate", ])
diff --git a/manila_tempest_tests/tests/api/admin/test_admin_actions_negative.py b/manila_tempest_tests/tests/api/admin/test_admin_actions_negative.py
index 7df3b30..d25dc75 100644
--- a/manila_tempest_tests/tests/api/admin/test_admin_actions_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_admin_actions_negative.py
@@ -31,11 +31,12 @@
super(AdminActionsNegativeTest, cls).resource_setup()
cls.sh = cls.create_share()
cls.sh_instance = (
- cls.shares_client.get_instances_of_share(cls.sh["id"])[0]
+ cls.shares_v2_client.get_instances_of_share(cls.sh["id"])[0]
)
if CONF.share.run_snapshot_tests:
cls.sn = cls.create_snapshot_wait_for_active(cls.sh["id"])
cls.member_shares_client = clients.Manager().shares_client
+ cls.member_shares_v2_client = clients.Manager().shares_v2_client
@test.attr(type=["gate", "negative", ])
def test_reset_nonexistent_share_state(self):
@@ -149,19 +150,19 @@
def test_try_get_share_instance_with_member(self):
# If a non-admin tries to get instance, it should be unauthorized
self.assertRaises(lib_exc.Forbidden,
- self.member_shares_client.get_share_instance,
+ self.member_shares_v2_client.get_share_instance,
self.sh_instance["id"])
@test.attr(type=["gate", "negative", ])
def test_try_list_share_instance_with_member(self):
# If a non-admin tries to list instances, it should be unauthorized
self.assertRaises(lib_exc.Forbidden,
- self.member_shares_client.list_share_instances)
+ self.member_shares_v2_client.list_share_instances)
@test.attr(type=["gate", "negative", ])
def test_try_get_instances_of_share_with_member(self):
# If a non-admin tries to list instances of given share, it should be
# unauthorized
self.assertRaises(lib_exc.Forbidden,
- self.member_shares_client.get_instances_of_share,
+ self.member_shares_v2_client.get_instances_of_share,
self.sh['id'])
diff --git a/manila_tempest_tests/tests/api/admin/test_consistency_group_actions.py b/manila_tempest_tests/tests/api/admin/test_consistency_group_actions.py
index c1fdb15..d5142b6 100644
--- a/manila_tempest_tests/tests/api/admin/test_consistency_group_actions.py
+++ b/manila_tempest_tests/tests/api/admin/test_consistency_group_actions.py
@@ -45,13 +45,19 @@
share_type_ids=[cls.share_type['id'], cls.share_type2['id']])
@test.attr(type=["gate", ])
- def test_create_cg_from_cgsnapshot_with_multiple_share_types(self):
+ def test_create_cg_from_cgsnapshot_with_multiple_share_types_v2_4(self):
# Create cgsnapshot
cgsnapshot = self.create_cgsnapshot_wait_for_active(
- self.consistency_group["id"], cleanup_in_class=False)
+ self.consistency_group["id"],
+ cleanup_in_class=False,
+ version='2.4',
+ )
new_consistency_group = self.create_consistency_group(
- cleanup_in_class=False, source_cgsnapshot_id=cgsnapshot['id'])
+ cleanup_in_class=False,
+ source_cgsnapshot_id=cgsnapshot['id'],
+ version='2.4',
+ )
# Verify share_types are the same
expected_types = sorted(self.consistency_group['share_types'])
@@ -61,7 +67,7 @@
expected_types, actual_types))
@test.attr(type=["gate", ])
- def test_create_cg_from_multi_typed_populated_cgsnapshot(self):
+ def test_create_cg_from_multi_typed_populated_cgsnapshot_v2_4(self):
share_name = data_utils.rand_name("tempest-share-name")
share_desc = data_utils.rand_name("tempest-share-description")
share_size = 1
@@ -71,7 +77,9 @@
description=share_desc,
size=share_size,
consistency_group_id=self.consistency_group['id'],
- share_type_id=self.share_type['id']
+ share_type_id=self.share_type['id'],
+ client=self.shares_v2_client,
+ version='2.4',
)
share_name2 = data_utils.rand_name("tempest-share-name")
@@ -83,11 +91,16 @@
description=share_desc2,
size=share_size2,
consistency_group_id=self.consistency_group['id'],
- share_type_id=self.share_type2['id']
+ share_type_id=self.share_type2['id'],
+ client=self.shares_v2_client,
+ version='2.4',
)
- cg_shares = self.shares_client.list_shares(detailed=True, params={
- 'consistency_group_id': self.consistency_group['id']})
+ cg_shares = self.shares_v2_client.list_shares(
+ detailed=True,
+ params={'consistency_group_id': self.consistency_group['id']},
+ version='2.4',
+ )
cg_share_ids = [s['id'] for s in cg_shares]
for share_id in [share['id'], share2['id']]:
@@ -101,10 +114,13 @@
self.consistency_group["id"],
name=cgsnap_name,
description=cgsnap_desc,
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4',
+ )
- self.create_consistency_group(
- cleanup_in_class=False, source_cgsnapshot_id=cgsnapshot['id'])
+ self.create_consistency_group(cleanup_in_class=False,
+ source_cgsnapshot_id=cgsnapshot['id'],
+ version='2.4')
# TODO(akerr): Skip until bug 1483886 is resolved
# Verify that the new shares correspond to correct share types
diff --git a/manila_tempest_tests/tests/api/admin/test_consistency_groups.py b/manila_tempest_tests/tests/api/admin/test_consistency_groups.py
index 4fbe7f9..d562e45 100644
--- a/manila_tempest_tests/tests/api/admin/test_consistency_groups.py
+++ b/manila_tempest_tests/tests/api/admin/test_consistency_groups.py
@@ -43,11 +43,13 @@
cls.share_type2 = share_type['share_type']
@test.attr(type=["gate", ])
- def test_create_cg_with_multiple_share_types(self):
+ def test_create_cg_with_multiple_share_types_v2_4(self):
# Create a consistency group
consistency_group = self.create_consistency_group(
- cleanup_in_class=False, share_type_ids=[self.share_type['id'],
- self.share_type2['id']])
+ cleanup_in_class=False,
+ share_type_ids=[self.share_type['id'], self.share_type2['id']],
+ version='2.4',
+ )
self.assertTrue(CG_REQUIRED_ELEMENTS.issubset(
consistency_group.keys()),
diff --git a/manila_tempest_tests/tests/api/admin/test_consistency_groups_negative.py b/manila_tempest_tests/tests/api/admin/test_consistency_groups_negative.py
index a7a715f..eafb5e8 100644
--- a/manila_tempest_tests/tests/api/admin/test_consistency_groups_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_consistency_groups_negative.py
@@ -51,6 +51,7 @@
size=cls.share_size,
consistency_group_id=cls.consistency_group['id'],
share_type_id=cls.share_type['id'],
+ client=cls.shares_v2_client,
)
# Create a cgsnapshot of the consistency group
@@ -69,91 +70,105 @@
self.share_type['id'])
@test.attr(type=["negative", "gate", ])
- def test_create_share_of_unsupported_type_in_cg(self):
+ def test_create_share_of_unsupported_type_in_cg_v2_4(self):
# Attempt to create share of default type in the cg
self.assertRaises(exceptions.BadRequest,
- self.shares_client.create_share, size=1,
- consistency_group_id=self.consistency_group['id'])
+ self.create_share,
+ size=1,
+ consistency_group_id=self.consistency_group['id'],
+ client=self.shares_v2_client,
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_create_share_in_cg_that_is_not_available(self):
+ def test_create_share_in_cg_that_is_not_available_v2_4(self):
consistency_group = self.create_consistency_group(
- cleanup_in_class=False)
- self.addCleanup(self.shares_client.consistency_group_reset_state,
+ cleanup_in_class=False, version='2.4')
+ self.addCleanup(self.shares_v2_client.consistency_group_reset_state,
consistency_group['id'],
- status='available')
+ status='available',
+ version='2.4')
# creating
- self.shares_client.consistency_group_reset_state(
- consistency_group['id'], status='creating')
- self.shares_client.wait_for_consistency_group_status(
+ self.shares_v2_client.consistency_group_reset_state(
+ consistency_group['id'], status='creating', version='2.4')
+ self.shares_v2_client.wait_for_consistency_group_status(
consistency_group['id'], 'creating')
self.assertRaises(exceptions.BadRequest, self.create_share,
name=self.share_name,
description=self.share_desc,
size=self.share_size,
consistency_group_id=consistency_group['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ client=self.shares_v2_client,
+ version='2.4')
# deleting
- self.shares_client.consistency_group_reset_state(
- consistency_group['id'], status='deleting')
- self.shares_client.wait_for_consistency_group_status(
+ self.shares_v2_client.consistency_group_reset_state(
+ consistency_group['id'], status='deleting', version='2.4')
+ self.shares_v2_client.wait_for_consistency_group_status(
consistency_group['id'], 'deleting')
self.assertRaises(exceptions.BadRequest, self.create_share,
name=self.share_name,
description=self.share_desc,
size=self.share_size,
consistency_group_id=consistency_group['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ client=self.shares_v2_client,
+ version='2.4')
# error
- self.shares_client.consistency_group_reset_state(
- consistency_group['id'], status='error')
- self.shares_client.wait_for_consistency_group_status(
+ self.shares_v2_client.consistency_group_reset_state(
+ consistency_group['id'], status='error', version='2.4')
+ self.shares_v2_client.wait_for_consistency_group_status(
consistency_group['id'], 'error')
self.assertRaises(exceptions.BadRequest, self.create_share,
name=self.share_name,
description=self.share_desc,
size=self.share_size,
consistency_group_id=consistency_group['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ client=self.shares_v2_client,
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_create_cgsnapshot_of_cg_that_is_not_available(self):
+ def test_create_cgsnapshot_of_cg_that_is_not_available_v2_4(self):
consistency_group = self.create_consistency_group(
- cleanup_in_class=False)
- self.addCleanup(self.shares_client.consistency_group_reset_state,
+ cleanup_in_class=False, version='2.4')
+ self.addCleanup(self.shares_v2_client.consistency_group_reset_state,
consistency_group['id'],
- status='available')
+ status='available',
+ version='2.4')
# creating
- self.shares_client.consistency_group_reset_state(
- consistency_group['id'], status='creating')
- self.shares_client.wait_for_consistency_group_status(
+ self.shares_v2_client.consistency_group_reset_state(
+ consistency_group['id'], status='creating', version='2.4')
+ self.shares_v2_client.wait_for_consistency_group_status(
consistency_group['id'], 'creating')
self.assertRaises(exceptions.Conflict,
self.create_cgsnapshot_wait_for_active,
consistency_group['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
# deleting
- self.shares_client.consistency_group_reset_state(
- consistency_group['id'], status='deleting')
- self.shares_client.wait_for_consistency_group_status(
+ self.shares_v2_client.consistency_group_reset_state(
+ consistency_group['id'], status='deleting', version='2.4')
+ self.shares_v2_client.wait_for_consistency_group_status(
consistency_group['id'], 'deleting')
self.assertRaises(exceptions.Conflict,
self.create_cgsnapshot_wait_for_active,
consistency_group['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
# error
- self.shares_client.consistency_group_reset_state(
- consistency_group['id'], status='error')
- self.shares_client.wait_for_consistency_group_status(
+ self.shares_v2_client.consistency_group_reset_state(
+ consistency_group['id'], status='error', version='2.4')
+ self.shares_v2_client.wait_for_consistency_group_status(
consistency_group['id'], 'error')
self.assertRaises(exceptions.Conflict,
self.create_cgsnapshot_wait_for_active,
consistency_group['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_create_cgsnapshot_of_cg_with_share_in_error_state(self):
- consistency_group = self.create_consistency_group()
+ def test_create_cgsnapshot_of_cg_with_share_in_error_state_v2_4(self):
+ consistency_group = self.create_consistency_group(version='2.4')
share_name = data_utils.rand_name("tempest-share-name")
share_desc = data_utils.rand_name("tempest-share-description")
share_size = 1
@@ -163,65 +178,79 @@
size=share_size,
consistency_group_id=consistency_group['id'],
cleanup_in_class=False,
+ client=self.shares_v2_client,
+ version='2.4',
)
self.shares_client.reset_state(s_id=share['id'])
self.shares_client.wait_for_share_status(share['id'], 'error')
self.assertRaises(exceptions.Conflict,
self.create_cgsnapshot_wait_for_active,
consistency_group['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_delete_cgsnapshot_not_in_available_or_error(self):
+ def test_delete_cgsnapshot_not_in_available_or_error_v2_4(self):
cgsnapshot = self.create_cgsnapshot_wait_for_active(
- self.consistency_group['id'], cleanup_in_class=False)
- self.addCleanup(self.shares_client.cgsnapshot_reset_state,
+ self.consistency_group['id'],
+ cleanup_in_class=False,
+ version='2.4',
+ )
+ self.addCleanup(self.shares_v2_client.cgsnapshot_reset_state,
cgsnapshot['id'],
- status='available')
+ status='available',
+ version='2.4')
# creating
- self.shares_client.cgsnapshot_reset_state(cgsnapshot['id'],
- status='creating')
- self.shares_client.wait_for_cgsnapshot_status(cgsnapshot['id'],
- 'creating')
+ self.shares_v2_client.cgsnapshot_reset_state(cgsnapshot['id'],
+ status='creating',
+ version='2.4')
+ self.shares_v2_client.wait_for_cgsnapshot_status(cgsnapshot['id'],
+ 'creating')
self.assertRaises(exceptions.Conflict,
- self.shares_client.delete_cgsnapshot,
- cgsnapshot['id'])
+ self.shares_v2_client.delete_cgsnapshot,
+ cgsnapshot['id'],
+ version='2.4')
# deleting
- self.shares_client.cgsnapshot_reset_state(cgsnapshot['id'],
- status='deleting')
- self.shares_client.wait_for_cgsnapshot_status(cgsnapshot['id'],
- 'deleting')
+ self.shares_v2_client.cgsnapshot_reset_state(cgsnapshot['id'],
+ status='deleting',
+ version='2.4')
+ self.shares_v2_client.wait_for_cgsnapshot_status(cgsnapshot['id'],
+ 'deleting')
self.assertRaises(exceptions.Conflict,
- self.shares_client.delete_cgsnapshot,
- cgsnapshot['id'])
+ self.shares_v2_client.delete_cgsnapshot,
+ cgsnapshot['id'],
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_delete_cg_not_in_available_or_error(self):
+ def test_delete_cg_not_in_available_or_error_v2_4(self):
consistency_group = self.create_consistency_group(
- cleanup_in_class=False)
- self.addCleanup(self.shares_client.consistency_group_reset_state,
+ cleanup_in_class=False, version='2.4')
+ self.addCleanup(self.shares_v2_client.consistency_group_reset_state,
consistency_group['id'],
- status='available')
+ status='available',
+ version='2.4')
# creating
- self.shares_client.consistency_group_reset_state(
- consistency_group['id'], status='creating')
- self.shares_client.wait_for_consistency_group_status(
+ self.shares_v2_client.consistency_group_reset_state(
+ consistency_group['id'], status='creating', version='2.4')
+ self.shares_v2_client.wait_for_consistency_group_status(
consistency_group['id'], 'creating')
self.assertRaises(exceptions.Conflict,
- self.shares_client.delete_consistency_group,
- consistency_group['id'])
+ self.shares_v2_client.delete_consistency_group,
+ consistency_group['id'],
+ version='2.4')
# deleting
- self.shares_client.consistency_group_reset_state(
- consistency_group['id'], status='deleting')
- self.shares_client.wait_for_consistency_group_status(
+ self.shares_v2_client.consistency_group_reset_state(
+ consistency_group['id'], status='deleting', version='2.4')
+ self.shares_v2_client.wait_for_consistency_group_status(
consistency_group['id'], 'deleting')
self.assertRaises(exceptions.Conflict,
- self.shares_client.delete_consistency_group,
- consistency_group['id'])
+ self.shares_v2_client.delete_consistency_group,
+ consistency_group['id'],
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_create_cg_with_conflicting_share_types(self):
+ def test_create_cg_with_conflicting_share_types_v2_4(self):
# Create conflicting share types
name = data_utils.rand_name("tempest-manila")
extra_specs = {"driver_handles_share_servers": False}
@@ -237,10 +266,12 @@
self.create_consistency_group,
share_type_ids=[single_tenant_share_type['id'],
multi_tenant_share_type['id']],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_create_cg_with_multi_tenant_share_type_and_no_share_network(self):
+ def test_create_cg_with_multi_tenant_share_type_and_no_share_network_v2_4(
+ self):
# Create multi tenant share type
name = data_utils.rand_name("tempest-manila")
extra_specs = {"driver_handles_share_servers": True}
@@ -248,12 +279,15 @@
multi_tenant_share_type = share_type['share_type']
def create_cg():
- cg = self.shares_client.create_consistency_group(
- share_type_ids=[multi_tenant_share_type['id']])
+ cg = self.shares_v2_client.create_consistency_group(
+ share_type_ids=[multi_tenant_share_type['id']],
+ version='2.4'
+ )
resource = {
"type": "consistency_group",
"id": cg["id"],
- "client": self.shares_client}
+ "client": self.shares_client
+ }
self.method_resources.insert(0, resource)
return cg
@@ -262,9 +296,10 @@
@test.attr(type=["negative", "gate", ])
def test_update_cg_share_types(self):
consistency_group = self.create_consistency_group(
- cleanup_in_class=False)
+ cleanup_in_class=False, version='2.4')
self.assertRaises(exceptions.BadRequest,
- self.shares_client.update_consistency_group,
+ self.shares_v2_client.update_consistency_group,
consistency_group['id'],
- share_types=[self.share_type['id']])
+ share_types=[self.share_type['id']],
+ version='2.4')
diff --git a/manila_tempest_tests/tests/api/admin/test_migration.py b/manila_tempest_tests/tests/api/admin/test_migration.py
index 4c6bacf..75b4ba7 100644
--- a/manila_tempest_tests/tests/api/admin/test_migration.py
+++ b/manila_tempest_tests/tests/api/admin/test_migration.py
@@ -37,7 +37,7 @@
raise cls.skipException(message)
@test.attr(type=["gate", "smoke", ])
- def test_migration_empty(self):
+ def test_migration_empty_v2_5(self):
if not CONF.share.migration_enabled:
raise self.skipException("Migration tests disabled. Skipping.")
@@ -60,7 +60,7 @@
old_export_location = share['export_locations'][0]
- share = self.migrate_share(share['id'], dest_pool)
+ share = self.migrate_share(share['id'], dest_pool, version='2.5')
self.assertEqual(dest_pool, share['host'])
self.assertNotEqual(old_export_location, share['export_locations'][0])
diff --git a/manila_tempest_tests/tests/api/admin/test_share_instances.py b/manila_tempest_tests/tests/api/admin/test_share_instances.py
new file mode 100644
index 0000000..1202b9d
--- /dev/null
+++ b/manila_tempest_tests/tests/api/admin/test_share_instances.py
@@ -0,0 +1,78 @@
+# Copyright 2015 Andrew Kerr
+# 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 import test
+
+from manila_tempest_tests.tests.api import base
+
+CONF = config.CONF
+
+
+class ShareInstancesTest(base.BaseSharesAdminTest):
+
+ @classmethod
+ def resource_setup(cls):
+ super(ShareInstancesTest, cls).resource_setup()
+ cls.share = cls.create_share()
+
+ @test.attr(type=["gate", ])
+ def test_get_instances_of_share_v2_3(self):
+ """Test that we get only the 1 share instance back for the share."""
+ share_instances = self.shares_v2_client.get_instances_of_share(
+ self.share['id'], version='2.3'
+ )
+
+ self.assertEqual(1, len(share_instances),
+ 'Too many share instances found; expected 1, '
+ 'found %s' % len(share_instances))
+
+ si = share_instances[0]
+ self.assertEqual(self.share['id'], si['share_id'],
+ 'Share instance %s has incorrect share id value; '
+ 'expected %s, got %s.' % (si['id'],
+ self.share['id'],
+ si['share_id']))
+
+ @test.attr(type=["gate", ])
+ def test_list_share_instances_v2_3(self):
+ """Test that we get at least the share instance back for the share."""
+ share_instances = self.shares_v2_client.get_instances_of_share(
+ self.share['id'], version='2.3'
+ )
+
+ share_ids = [si['share_id'] for si in share_instances]
+
+ msg = 'Share instance for share %s was not found.' % self.share['id']
+ self.assertIn(self.share['id'], share_ids, msg)
+
+ @test.attr(type=["gate", ])
+ def test_get_share_instance_v2_3(self):
+ """Test that we get the proper keys back for the instance."""
+ share_instances = self.shares_v2_client.get_instances_of_share(
+ self.share['id'], version='2.3'
+ )
+ si = self.shares_v2_client.get_share_instance(share_instances[0]['id'],
+ version='2.3')
+
+ expected_keys = ['host', 'share_id', 'id', 'share_network_id',
+ 'status', 'availability_zone', 'share_server_id',
+ 'export_locations', 'export_location', 'created_at']
+ actual_keys = si.keys()
+ self.assertEqual(sorted(expected_keys), sorted(actual_keys),
+ 'Share instance %s returned incorrect keys; '
+ 'expected %s, got %s.' % (si['id'],
+ sorted(expected_keys),
+ sorted(actual_keys)))
diff --git a/manila_tempest_tests/tests/api/base.py b/manila_tempest_tests/tests/api/base.py
index 65e299d..591347e 100644
--- a/manila_tempest_tests/tests/api/base.py
+++ b/manila_tempest_tests/tests/api/base.py
@@ -98,7 +98,8 @@
def get_client_with_isolated_creds(cls,
name=None,
type_of_creds="admin",
- cleanup_in_class=False):
+ cleanup_in_class=False,
+ client_version='1'):
"""Creates isolated creds.
:param name: name, will be used for naming ic and related stuff
@@ -126,7 +127,10 @@
# create client with isolated creds
os = clients.Manager(credentials=creds)
- client = os.shares_client
+ if client_version == '1':
+ client = os.shares_client
+ elif client_version == '2':
+ client = os.shares_v2_client
# Set place where will be deleted isolated creds
ic_res = {
@@ -183,7 +187,9 @@
nc = cls.os.network_client
share_network_id = cls.provide_share_network(sc, nc)
cls.os.shares_client.share_network_id = share_network_id
+ cls.os.shares_v2_client.share_network_id = share_network_id
cls.shares_client = cls.os.shares_client
+ cls.shares_v2_client = cls.os.shares_v2_client
def setUp(self):
super(BaseSharesTest, self).setUp()
@@ -281,12 +287,12 @@
snapshot_id=None, description=None, metadata=None,
share_network_id=None, share_type_id=None,
consistency_group_id=None, client=None,
- cleanup_in_class=True, is_public=False):
+ cleanup_in_class=True, is_public=False, **kwargs):
client = client or cls.shares_client
description = description or "Tempest's share"
share_network_id = share_network_id or client.share_network_id or None
metadata = metadata or {}
- kwargs = {
+ kwargs.update({
'share_protocol': share_protocol,
'size': size,
'name': name,
@@ -296,7 +302,7 @@
'share_network_id': share_network_id,
'share_type_id': share_type_id,
'is_public': is_public,
- }
+ })
if consistency_group_id:
kwargs['consistency_group_id'] = consistency_group_id
@@ -309,9 +315,9 @@
return share
@classmethod
- def migrate_share(cls, share_id, dest_host, client=None):
- client = client or cls.shares_client
- client.migrate_share(share_id, dest_host)
+ def migrate_share(cls, share_id, dest_host, client=None, **kwargs):
+ client = client or cls.shares_v2_client
+ client.migrate_share(share_id, dest_host, **kwargs)
share = client.wait_for_migration_completed(share_id, dest_host)
return share
@@ -383,7 +389,7 @@
@classmethod
def create_consistency_group(cls, client=None, cleanup_in_class=True,
share_network_id=None, **kwargs):
- client = client or cls.shares_client
+ client = client or cls.shares_v2_client
kwargs['share_network_id'] = (share_network_id or
client.share_network_id or None)
consistency_group = client.create_consistency_group(**kwargs)
@@ -440,12 +446,15 @@
@classmethod
def create_cgsnapshot_wait_for_active(cls, consistency_group_id,
name=None, description=None,
- client=None, cleanup_in_class=True):
- client = client or cls.shares_client
+ client=None, cleanup_in_class=True,
+ **kwargs):
+ client = client or cls.shares_v2_client
if description is None:
description = "Tempest's cgsnapshot"
- cgsnapshot = client.create_cgsnapshot(consistency_group_id, name=name,
- description=description)
+ cgsnapshot = client.create_cgsnapshot(consistency_group_id,
+ name=name,
+ description=description,
+ **kwargs)
resource = {
"type": "cgsnapshot",
"id": cgsnapshot["id"],
@@ -556,11 +565,12 @@
client = res["client"]
with handle_cleanup_exceptions():
if res["type"] is "share":
- params = None
cg_id = res.get('consistency_group_id')
if cg_id:
params = {'consistency_group_id': cg_id}
- client.delete_share(res_id, params=params)
+ client.delete_share(res_id, params=params)
+ else:
+ client.delete_share(res_id)
client.wait_for_resource_deletion(share_id=res_id)
elif res["type"] is "snapshot":
client.delete_snapshot(res_id)
@@ -679,6 +689,7 @@
cls.os = clients.AltManager()
alt_share_network_id = CONF.share.alt_share_network_id
cls.os.shares_client.share_network_id = alt_share_network_id
+ cls.os.shares_v2_client.share_network_id = alt_share_network_id
super(BaseSharesAltTest, cls).resource_setup()
@@ -694,4 +705,5 @@
cls.os = clients.AdminManager()
admin_share_network_id = CONF.share.admin_share_network_id
cls.os.shares_client.share_network_id = admin_share_network_id
+ cls.os.shares_v2_client.share_network_id = admin_share_network_id
super(BaseSharesAdminTest, cls).resource_setup()
diff --git a/manila_tempest_tests/tests/api/test_consistency_group_actions.py b/manila_tempest_tests/tests/api/test_consistency_group_actions.py
index 81bff8a..0bf6e58 100644
--- a/manila_tempest_tests/tests/api/test_consistency_group_actions.py
+++ b/manila_tempest_tests/tests/api/test_consistency_group_actions.py
@@ -57,6 +57,7 @@
size=cls.share_size,
consistency_group_id=cls.consistency_group['id'],
metadata={'key': 'value'},
+ client=cls.shares_v2_client,
)
cls.share_name2 = data_utils.rand_name("tempest-share-name")
@@ -67,6 +68,7 @@
description=cls.share_desc2,
size=cls.share_size2,
consistency_group_id=cls.consistency_group['id'],
+ client=cls.shares_v2_client,
)
cls.cgsnap_name = data_utils.rand_name("tempest-cgsnap-name")
@@ -93,6 +95,7 @@
description=cls.share_desc3,
size=cls.share_size,
consistency_group_id=cls.consistency_group2['id'],
+ client=cls.shares_v2_client,
)
cls.cgsnap_name2 = data_utils.rand_name("tempest-cgsnap-name")
@@ -103,11 +106,11 @@
description=cls.cgsnap_desc2)
@test.attr(type=["gate", ])
- def test_get_consistency_group(self):
+ def test_get_consistency_group_v2_4(self):
# Get consistency group
- consistency_group = self.shares_client.get_consistency_group(
- self.consistency_group['id'])
+ consistency_group = self.shares_v2_client.get_consistency_group(
+ self.consistency_group['id'], version='2.4')
# Verify keys
actual_keys = set(consistency_group.keys())
@@ -129,10 +132,11 @@
msg)
@test.attr(type=["gate", ])
- def test_get_share(self):
+ def test_get_share_v2_4(self):
# Get share
- share = self.shares_client.get_share(self.share['id'])
+ share = self.shares_v2_client.get_share(self.share['id'],
+ version='2.4')
# Verify keys
expected_keys = {"status", "description", "links", "availability_zone",
@@ -165,10 +169,11 @@
self.consistency_group["id"], share["consistency_group_id"], msg)
@test.attr(type=["gate", ])
- def test_list_consistency_groups(self):
+ def test_list_consistency_groups_v2_4(self):
# List consistency groups
- consistency_groups = self.shares_client.list_consistency_groups()
+ consistency_groups = self.shares_v2_client.list_consistency_groups(
+ version='2.4')
# Verify keys
[self.assertEqual(CG_SIMPLE_KEYS, set(cg.keys())) for cg in
@@ -184,11 +189,11 @@
self.assertEqual(1, len(gen), msg)
@test.attr(type=["gate", ])
- def test_list_consistency_groups_with_detail(self):
+ def test_list_consistency_groups_with_detail_v2_4(self):
# List consistency groups
- consistency_groups = self.shares_client.list_consistency_groups(
- detailed=True)
+ consistency_groups = self.shares_v2_client.list_consistency_groups(
+ detailed=True, version='2.4')
# Verify keys
[self.assertTrue(CG_DETAIL_REQUIRED_KEYS.issubset(set(cg.keys())))
@@ -204,10 +209,13 @@
self.assertEqual(1, len(gen), msg)
@test.attr(type=["gate", ])
- def test_filter_shares_by_consistency_group_id(self):
+ def test_filter_shares_by_consistency_group_id_v2_4(self):
- shares = self.shares_client.list_shares(detailed=True, params={
- 'consistency_group_id': self.consistency_group['id']})
+ shares = self.shares_v2_client.list_shares(
+ detailed=True,
+ params={'consistency_group_id': self.consistency_group['id']},
+ version='2.4'
+ )
share_ids = [share['id'] for share in shares]
@@ -222,10 +230,10 @@
% (self.share['id'], share_ids))
@test.attr(type=["gate", ])
- def test_get_cgsnapshot(self):
+ def test_get_cgsnapshot_v2_4(self):
# Get consistency group
- consistency_group = self.shares_client.get_consistency_group(
- self.consistency_group['id'])
+ consistency_group = self.shares_v2_client.get_consistency_group(
+ self.consistency_group['id'], version='2.4')
# Verify keys
actual_keys = set(consistency_group.keys())
@@ -247,10 +255,10 @@
msg)
@test.attr(type=["gate", ])
- def test_get_cgsnapshot_members(self):
+ def test_get_cgsnapshot_members_v2_4(self):
- cgsnapshot_members = self.shares_client.list_cgsnapshot_members(
- self.cgsnapshot['id'])
+ cgsnapshot_members = self.shares_v2_client.list_cgsnapshot_members(
+ self.cgsnapshot['id'], version='2.4')
member_share_ids = [member['share_id'] for member in
cgsnapshot_members]
self.assertEqual(2, len(cgsnapshot_members),
@@ -272,17 +280,22 @@
# member['share_type_id'])
@test.attr(type=["gate", "smoke", ])
- def test_create_consistency_group_from_populated_cgsnapshot(self):
+ def test_create_consistency_group_from_populated_cgsnapshot_v2_4(self):
- cgsnapshot_members = self.shares_client.list_cgsnapshot_members(
- self.cgsnapshot['id'])
+ cgsnapshot_members = self.shares_v2_client.list_cgsnapshot_members(
+ self.cgsnapshot['id'], version='2.4')
new_consistency_group = self.create_consistency_group(
- cleanup_in_class=False, source_cgsnapshot_id=self.cgsnapshot['id'])
+ cleanup_in_class=False,
+ source_cgsnapshot_id=self.cgsnapshot['id'],
+ version='2.4'
+ )
- new_shares = self.shares_client.list_shares(
+ new_shares = self.shares_v2_client.list_shares(
params={'consistency_group_id': new_consistency_group['id']},
- detailed=True)
+ detailed=True,
+ version='2.4'
+ )
# Verify each new share is available
for share in new_shares:
@@ -326,46 +339,58 @@
)
@test.attr(type=["gate", ])
- def test_update_consistency_group(self):
+ def test_update_consistency_group_v2_4(self):
# Get consistency_group
- consistency_group = self.shares_client.get_consistency_group(
- self.consistency_group['id'])
+ consistency_group = self.shares_v2_client.get_consistency_group(
+ self.consistency_group['id'], version='2.4')
self.assertEqual(self.cg_name, consistency_group["name"])
self.assertEqual(self.cg_desc, consistency_group["description"])
# Update consistency_group
new_name = data_utils.rand_name("tempest-new-name")
new_desc = data_utils.rand_name("tempest-new-description")
- updated = self.shares_client.update_consistency_group(
- consistency_group["id"], name=new_name, description=new_desc)
+ updated = self.shares_v2_client.update_consistency_group(
+ consistency_group["id"],
+ name=new_name,
+ description=new_desc,
+ version='2.4'
+ )
self.assertEqual(new_name, updated["name"])
self.assertEqual(new_desc, updated["description"])
# Get consistency_group
- consistency_group = self.shares_client.get_consistency_group(
- self.consistency_group['id'])
+ consistency_group = self.shares_v2_client.get_consistency_group(
+ self.consistency_group['id'], version='2.4')
self.assertEqual(new_name, consistency_group["name"])
self.assertEqual(new_desc, consistency_group["description"])
@test.attr(type=["gate", ])
- def test_create_update_read_consistency_group_with_unicode(self):
+ def test_create_update_read_consistency_group_with_unicode_v2_4(self):
value1 = u'ಠ_ಠ'
value2 = u'ಠ_ರೃ'
# Create consistency_group
consistency_group = self.create_consistency_group(
- cleanup_in_class=False, name=value1, description=value1)
+ cleanup_in_class=False,
+ name=value1,
+ description=value1,
+ version='2.4'
+ )
self.assertEqual(value1, consistency_group["name"])
self.assertEqual(value1, consistency_group["description"])
# Update consistency_group
- updated = self.shares_client.update_consistency_group(
- consistency_group["id"], name=value2, description=value2)
+ updated = self.shares_v2_client.update_consistency_group(
+ consistency_group["id"],
+ name=value2,
+ description=value2,
+ version='2.4'
+ )
self.assertEqual(value2, updated["name"])
self.assertEqual(value2, updated["description"])
# Get consistency_group
- consistency_group = self.shares_client.get_consistency_group(
- consistency_group['id'])
+ consistency_group = self.shares_v2_client.get_consistency_group(
+ consistency_group['id'], version='2.4')
self.assertEqual(value2, consistency_group["name"])
self.assertEqual(value2, consistency_group["description"])
diff --git a/manila_tempest_tests/tests/api/test_consistency_groups.py b/manila_tempest_tests/tests/api/test_consistency_groups.py
index 1ba3902..33ea334 100644
--- a/manila_tempest_tests/tests/api/test_consistency_groups.py
+++ b/manila_tempest_tests/tests/api/test_consistency_groups.py
@@ -33,10 +33,10 @@
"""Covers consistency group functionality."""
@test.attr(type=["gate", ])
- def test_create_populate_delete_consistency_group(self):
+ def test_create_populate_delete_consistency_group_v2_4(self):
# Create a consistency group
consistency_group = self.create_consistency_group(
- cleanup_in_class=False)
+ cleanup_in_class=False, version='2.4')
self.assertTrue(CG_REQUIRED_ELEMENTS.issubset(
consistency_group.keys()),
'At least one expected element missing from consistency group '
@@ -45,31 +45,35 @@
"actual": consistency_group.keys()})
# Populate
share = self.create_share(consistency_group_id=consistency_group['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ client=self.shares_v2_client,
+ version='2.4')
# Delete
params = {"consistency_group_id": consistency_group['id']}
- self.shares_client.delete_share(share['id'], params=params)
+ self.shares_v2_client.delete_share(share['id'], params=params,
+ version='2.4')
self.shares_client.wait_for_resource_deletion(share_id=share['id'])
- self.shares_client.delete_consistency_group(consistency_group['id'])
- self.shares_client.wait_for_resource_deletion(
+ self.shares_v2_client.delete_consistency_group(consistency_group['id'],
+ version='2.4')
+ self.shares_v2_client.wait_for_resource_deletion(
cg_id=consistency_group['id'])
# Verify
self.assertRaises(lib_exc.NotFound,
- self.shares_client.get_consistency_group,
+ self.shares_v2_client.get_consistency_group,
consistency_group['id'])
self.assertRaises(lib_exc.NotFound,
self.shares_client.get_share,
share['id'])
@test.attr(type=["gate", ])
- def test_create_delete_empty_cgsnapshot(self):
+ def test_create_delete_empty_cgsnapshot_v2_4(self):
# Create base consistency group
consistency_group = self.create_consistency_group(
- cleanup_in_class=False)
+ cleanup_in_class=False, version='2.4')
# Create cgsnapshot
cgsnapshot = self.create_cgsnapshot_wait_for_active(
- consistency_group["id"], cleanup_in_class=False)
+ consistency_group["id"], cleanup_in_class=False, version='2.4')
self.assertTrue(CGSNAPSHOT_REQUIRED_ELEMENTS.issubset(
cgsnapshot.keys()),
@@ -78,19 +82,22 @@
"expected": CGSNAPSHOT_REQUIRED_ELEMENTS,
"actual": cgsnapshot.keys()})
- cgsnapshot_members = self.shares_client.list_cgsnapshot_members(
- cgsnapshot['id'])
+ cgsnapshot_members = self.shares_v2_client.list_cgsnapshot_members(
+ cgsnapshot['id'], version='2.4')
self.assertEmpty(cgsnapshot_members,
'Expected 0 cgsnapshot members, got %s' % len(
cgsnapshot_members))
# delete snapshot
- self.shares_client.delete_cgsnapshot(cgsnapshot["id"])
- self.shares_client.wait_for_resource_deletion(
+ self.shares_v2_client.delete_cgsnapshot(cgsnapshot["id"],
+ version='2.4')
+ self.shares_v2_client.wait_for_resource_deletion(
cgsnapshot_id=cgsnapshot["id"])
self.assertRaises(lib_exc.NotFound,
- self.shares_client.get_cgsnapshot, cgsnapshot['id'])
+ self.shares_v2_client.get_cgsnapshot,
+ cgsnapshot['id'],
+ version='2.4')
@test.attr(type=["gate", "smoke", ])
def test_create_consistency_group_from_empty_cgsnapshot(self):
@@ -102,7 +109,7 @@
cgsnapshot = self.create_cgsnapshot_wait_for_active(
consistency_group["id"], cleanup_in_class=False)
- cgsnapshot_members = self.shares_client.list_cgsnapshot_members(
+ cgsnapshot_members = self.shares_v2_client.list_cgsnapshot_members(
cgsnapshot['id'])
self.assertEmpty(cgsnapshot_members,
@@ -123,8 +130,8 @@
self.assertEqual(new_consistency_group['source_cgsnapshot_id'],
cgsnapshot['id'], msg)
- msg = 'Unexpected share_types on new consistency group. Expected %s, ' \
- 'got %s.' % (consistency_group['share_types'],
- new_consistency_group['share_types'])
+ msg = ('Unexpected share_types on new consistency group. Expected '
+ '%s, got %s.' % (consistency_group['share_types'],
+ new_consistency_group['share_types']))
self.assertEqual(sorted(consistency_group['share_types']),
sorted(new_consistency_group['share_types']), msg)
diff --git a/manila_tempest_tests/tests/api/test_consistency_groups_negative.py b/manila_tempest_tests/tests/api/test_consistency_groups_negative.py
index 7c813c0..34c0a6d 100644
--- a/manila_tempest_tests/tests/api/test_consistency_groups_negative.py
+++ b/manila_tempest_tests/tests/api/test_consistency_groups_negative.py
@@ -46,7 +46,8 @@
name=cls.share_name,
description=cls.share_desc,
size=cls.share_size,
- consistency_group_id=cls.consistency_group['id']
+ consistency_group_id=cls.consistency_group['id'],
+ client=cls.shares_v2_client
)
# Create a cgsnapshot of the consistency group
cls.cgsnap_name = data_utils.rand_name("tempest-cgsnap-name")
@@ -57,149 +58,174 @@
description=cls.cgsnap_desc)
@test.attr(type=["negative", "smoke", "gate", ])
- def test_create_cg_with_invalid_source_cgsnapshot_id_value(
+ def test_create_cg_with_invalid_source_cgsnapshot_id_value_v2_4(
self):
self.assertRaises(lib_exc.BadRequest,
self.create_consistency_group,
source_cgsnapshot_id='foobar',
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_create_cg_with_nonexistent_source_cgsnapshot_id_value(self):
+ def test_create_cg_with_nonexistent_source_cgsnapshot_id_value_v2_4(self):
self.assertRaises(lib_exc.BadRequest,
self.create_consistency_group,
source_cgsnapshot_id=self.share['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_create_cg_with_invalid_share_network_id_value(
- self):
+ def test_create_cg_with_invalid_share_network_id_value_v2_4(self):
self.assertRaises(lib_exc.BadRequest,
self.create_consistency_group,
share_network_id='foobar',
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_create_cg_with_nonexistent_share_network_id_value(self):
+ def test_create_cg_with_nonexistent_share_network_id_value_v2_4(self):
self.assertRaises(lib_exc.BadRequest,
self.create_consistency_group,
share_network_id=self.share['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_create_cg_with_invalid_share_type_id_value(
- self):
+ def test_create_cg_with_invalid_share_type_id_value_v2_4(self):
self.assertRaises(lib_exc.BadRequest,
self.create_consistency_group,
share_type_ids=['foobar'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_create_cg_with_nonexistent_share_type_id_value(self):
+ def test_create_cg_with_nonexistent_share_type_id_value_v2_4(self):
self.assertRaises(lib_exc.BadRequest,
self.create_consistency_group,
share_type_ids=[self.share['id']],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_create_cgsnapshot_with_invalid_cg_id_value(
- self):
+ def test_create_cgsnapshot_with_invalid_cg_id_value_v2_4(self):
self.assertRaises(lib_exc.BadRequest,
self.create_cgsnapshot_wait_for_active,
'foobar',
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_create_cgsnapshot_with_nonexistent_cg_id_value(self):
+ def test_create_cgsnapshot_with_nonexistent_cg_id_value_v2_4(self):
self.assertRaises(lib_exc.BadRequest,
self.create_cgsnapshot_wait_for_active,
self.share['id'],
- cleanup_in_class=False)
+ cleanup_in_class=False,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_get_cg_with_wrong_id(self):
+ def test_get_cg_with_wrong_id_v2_4(self):
self.assertRaises(lib_exc.NotFound,
- self.shares_client.get_consistency_group,
- "wrong_consistency_group_id")
+ self.shares_v2_client.get_consistency_group,
+ "wrong_consistency_group_id",
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_get_cg_without_passing_cg_id(self):
+ def test_get_cg_without_passing_cg_id_v2_4(self):
self.assertRaises(lib_exc.NotFound,
- self.shares_client.get_consistency_group, '')
+ self.shares_v2_client.get_consistency_group,
+ '',
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_update_cg_with_wrong_id(self):
+ def test_update_cg_with_wrong_id_v2_4(self):
self.assertRaises(lib_exc.NotFound,
- self.shares_client.update_consistency_group,
+ self.shares_v2_client.update_consistency_group,
'wrong_consistency_group_id',
name='new_name',
- description='new_description')
+ description='new_description',
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_delete_cg_with_wrong_id(self):
+ def test_delete_cg_with_wrong_id_v2_4(self):
self.assertRaises(lib_exc.NotFound,
- self.shares_client.delete_consistency_group,
- "wrong_consistency_group_id")
+ self.shares_v2_client.delete_consistency_group,
+ "wrong_consistency_group_id",
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_delete_cg_without_passing_cg_id(self):
+ def test_delete_cg_without_passing_cg_id_v2_4(self):
self.assertRaises(lib_exc.NotFound,
- self.shares_client.delete_consistency_group, '')
+ self.shares_v2_client.delete_consistency_group,
+ '',
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_delete_cg_in_use_by_cgsnapshot(self):
+ def test_delete_cg_in_use_by_cgsnapshot_v2_4(self):
# Attempt delete of share type
self.assertRaises(lib_exc.Conflict,
- self.shares_client.delete_consistency_group,
- self.consistency_group['id'])
+ self.shares_v2_client.delete_consistency_group,
+ self.consistency_group['id'],
+ version='2.4')
@test.attr(type=["negative", "gate", ])
- def test_delete_share_in_use_by_cgsnapshot(self):
+ def test_delete_share_in_use_by_cgsnapshot_v2_4(self):
# Attempt delete of share type
params = {'consistency_group_id': self.share['consistency_group_id']}
self.assertRaises(lib_exc.Forbidden,
- self.shares_client.delete_share,
+ self.shares_v2_client.delete_share,
self.share['id'],
- params=params)
+ params=params,
+ version='2.4')
@test.attr(type=["negative", "smoke", "gate", ])
- def test_delete_cg_containing_a_share(self):
+ def test_delete_cg_containing_a_share_v2_4(self):
self.assertRaises(lib_exc.Conflict,
- self.shares_client.delete_consistency_group,
- self.consistency_group['id'])
+ self.shares_v2_client.delete_consistency_group,
+ self.consistency_group['id'],
+ version='2.4')
# Verify consistency group is not put into error state from conflict
- cg = self.shares_client.get_consistency_group(
- self.consistency_group['id'])
+ cg = self.shares_v2_client.get_consistency_group(
+ self.consistency_group['id'], version='2.4')
self.assertEqual('available', cg['status'])
@test.attr(type=["negative", "smoke", "gate", ])
- def test_filter_shares_on_invalid_cg_id(self):
- shares = self.shares_client.list_shares(detailed=True, params={
- 'consistency_group_id': 'foobar'})
+ def test_filter_shares_on_invalid_cg_id_v2_4(self):
+ shares = self.shares_v2_client.list_shares(
+ detailed=True,
+ params={'consistency_group_id': 'foobar'},
+ version='2.4'
+ )
- self.assertEqual(0, len(shares), 'Incorrect number of shares '
- 'returned. Expected 0, got %s.' %
- len(shares))
+ self.assertEqual(0, len(shares),
+ 'Incorrect number of shares returned. Expected 0, '
+ 'got %s.' % len(shares))
@test.attr(type=["negative", "smoke", "gate", ])
- def test_filter_shares_on_nonexistent_cg_id(self):
- shares = self.shares_client.list_shares(detailed=True, params={
- 'consistency_group_id': self.share['id']})
+ def test_filter_shares_on_nonexistent_cg_id_v2_4(self):
+ shares = self.shares_v2_client.list_shares(
+ detailed=True,
+ params={'consistency_group_id': self.share['id']},
+ version='2.4'
+ )
- self.assertEqual(0, len(shares), 'Incorrect number of shares '
- 'returned. Expected 0, got %s.' %
- len(shares))
+ self.assertEqual(0, len(shares),
+ 'Incorrect number of shares returned. Expected 0, '
+ 'got %s.' % len(shares))
@test.attr(type=["negative", "smoke", "gate", ])
- def test_filter_shares_on_empty_cg_id(self):
+ def test_filter_shares_on_empty_cg_id_v2_4(self):
consistency_group = self.create_consistency_group(
name='tempest_cg',
description='tempest_cg_desc',
cleanup_in_class=False,
+ version='2.4',
)
- shares = self.shares_client.list_shares(detailed=True, params={
- 'consistency_group_id': consistency_group['id']})
+ shares = self.shares_v2_client.list_shares(
+ detailed=True,
+ params={'consistency_group_id': consistency_group['id']},
+ version='2.4',
+ )
- self.assertEqual(0, len(shares), 'Incorrect number of shares '
- 'returned. Expected 0, got %s.' %
- len(shares))
+ self.assertEqual(0, len(shares),
+ 'Incorrect number of shares returned. Expected 0, '
+ 'got %s.' % len(shares))
diff --git a/manila_tempest_tests/tests/api/test_microversions.py b/manila_tempest_tests/tests/api/test_microversions.py
index 2984b04..1de8b59 100644
--- a/manila_tempest_tests/tests/api/test_microversions.py
+++ b/manila_tempest_tests/tests/api/test_microversions.py
@@ -1,4 +1,5 @@
# Copyright 2015 Goutham Pacha Ravi
+# Copyright 2015 Clinton Knight
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -20,90 +21,152 @@
CONF = config.CONF
+API_MICROVERSIONS_HEADER_LOWER = 'x-openstack-manila-api-version'
+API_MICROVERSIONS_HEADER = 'X-OpenStack-Manila-API-Version'
+_MIN_API_VERSION = CONF.share.min_api_microversion
+_MAX_API_VERSION = CONF.share.max_api_microversion
+
class MicroversionsTest(base.BaseSharesTest):
"""Request and validate REST API Microversions.
- Sends a HTTP GET request with the base endpoint to request a Microversion.
+ Sends HTTP GET requests to the version API to validate microversions.
"""
- _MIN_API_VERSION = CONF.share.min_api_microversion
- _MAX_API_VERSION = CONF.share.max_api_microversion
+ @test.attr(type=["gate", "smoke", ])
+ def test_microversions_root_version(self):
+
+ resp, resp_body = self.shares_v2_client.send_microversion_request()
+
+ self.assertEqual(300, resp.status)
+
+ version_list = resp_body['versions']
+ ids = [v['id'] for v in version_list]
+ self.assertEqual({'v1.0', 'v2.0'}, set(ids))
+
+ self.assertNotIn(API_MICROVERSIONS_HEADER_LOWER, resp)
+ self.assertNotIn('vary', resp)
+
+ v1 = [v for v in version_list if v['id'] == 'v1.0'][0]
+ self.assertEqual('', v1.get('min_version'))
+ self.assertEqual('', v1.get('version'))
+
+ v2 = [v for v in version_list if v['id'] == 'v2.0'][0]
+ self.assertEqual(_MIN_API_VERSION, v2.get('min_version'))
+ self.assertEqual(_MAX_API_VERSION, v2.get('version'))
@test.attr(type=["gate", "smoke", ])
- def test_microversions_no_version(self):
- resp, resp_body = self.shares_client.send_microversion_request()
+ def test_microversions_v1_no_version(self):
- self.assertEqual(self._MIN_API_VERSION,
- resp[self.shares_client.API_MICROVERSIONS_HEADER])
- self.assertTrue(len(resp_body['versions']) > 0)
- self.assertNotIn('min_version', resp_body['versions'][0])
- self.assertNotIn('version', resp_body['versions'][0])
+ resp, resp_body = self.shares_v2_client.send_microversion_request(
+ script_name='v1')
+
+ self.assertEqual(200, resp.status)
+
+ version_list = resp_body['versions']
+ ids = [v['id'] for v in version_list]
+ self.assertEqual({'v1.0'}, set(ids))
+
+ self.assertEqual('1.0', resp.get(API_MICROVERSIONS_HEADER_LOWER))
+ self.assertEqual(API_MICROVERSIONS_HEADER, resp.get('vary'))
+ self.assertEqual('', version_list[0].get('min_version'))
+ self.assertEqual('', version_list[0].get('version'))
@test.attr(type=["gate", "smoke", ])
- def test_microversions_version_min_version(self):
- """Requests base version 1.0."""
+ def test_microversions_v1_with_version(self):
- resp, resp_body = self.shares_client.send_microversion_request(
- self._MIN_API_VERSION)
+ resp, resp_body = self.shares_v2_client.send_microversion_request(
+ script_name='v1', version='5.0')
- self.assertEqual(self._MIN_API_VERSION,
- resp[self.shares_client.API_MICROVERSIONS_HEADER])
- self.assertTrue(len(resp_body['versions']) > 0)
- self.assertNotIn('min_version', resp_body['versions'][0])
- self.assertNotIn('version', resp_body['versions'][0])
+ self.assertEqual(200, resp.status)
+
+ version_list = resp_body['versions']
+ ids = [v['id'] for v in version_list]
+ self.assertEqual({'v1.0'}, set(ids))
+
+ self.assertEqual('1.0', resp.get(API_MICROVERSIONS_HEADER_LOWER))
+ self.assertEqual(API_MICROVERSIONS_HEADER, resp.get('vary'))
+ self.assertEqual('', version_list[0].get('min_version'))
+ self.assertEqual('', version_list[0].get('version'))
@test.attr(type=["gate", "smoke", ])
- def test_microversions_version_max_configured_version(self):
- """Requests maximum API microversion.
+ def test_microversions_v2_no_version(self):
- Requests the current maximum API microversion from the Manila API
- service, and confirms that version is the same as what Tempest is
- configured to request in other versioned API calls.
- """
+ resp, resp_body = self.shares_v2_client.send_microversion_request(
+ script_name='v2')
- resp, resp_body = self.shares_client.send_microversion_request(
- self._MAX_API_VERSION)
+ self.assertEqual(200, resp.status)
- self.assertEqual(self._MAX_API_VERSION,
- resp[self.shares_client.API_MICROVERSIONS_HEADER])
- self.assertTrue(len(resp_body['versions']) > 0)
- self.assertEqual(self._MAX_API_VERSION,
- resp_body['versions'][0]['version'])
+ version_list = resp_body['versions']
+ ids = [v['id'] for v in version_list]
+ self.assertEqual({'v2.0'}, set(ids))
+
+ self.assertEqual(_MIN_API_VERSION,
+ resp.get(API_MICROVERSIONS_HEADER_LOWER))
+ self.assertEqual(API_MICROVERSIONS_HEADER, resp.get('vary'))
+ self.assertEqual(_MIN_API_VERSION, version_list[0].get('min_version'))
+ self.assertEqual(_MAX_API_VERSION, version_list[0].get('version'))
@test.attr(type=["gate", "smoke", ])
- def test_microversions_version_1_1(self):
- """Requests version 1.1, the first Manila microversion."""
+ def test_microversions_v2_min_version(self):
- resp, resp_body = self.shares_client.send_microversion_request('1.1')
+ resp, resp_body = self.shares_v2_client.send_microversion_request(
+ script_name='v2', version=_MIN_API_VERSION)
- self.assertEqual('1.1',
- resp[self.shares_client.API_MICROVERSIONS_HEADER])
- self.assertTrue(len(resp_body['versions']) > 0)
- self.assertEqual(self._MIN_API_VERSION,
- resp_body['versions'][0]['min_version'])
+ self.assertEqual(200, resp.status)
+
+ version_list = resp_body['versions']
+ ids = [v['id'] for v in version_list]
+ self.assertEqual({'v2.0'}, set(ids))
+
+ self.assertEqual(_MIN_API_VERSION,
+ resp.get(API_MICROVERSIONS_HEADER_LOWER))
+ self.assertEqual(API_MICROVERSIONS_HEADER, resp.get('vary'))
+ self.assertEqual(_MIN_API_VERSION, version_list[0].get('min_version'))
+ self.assertEqual(_MAX_API_VERSION, version_list[0].get('version'))
@test.attr(type=["gate", "smoke", ])
- def test_microversions_unavailable_versions(self):
- """Requests a version greater than the latest available version."""
+ def test_microversions_v2_max_version(self):
- resp, resp_body = self.shares_client.send_microversion_request('1.1')
- self.assertTrue(len(resp_body['versions']) > 0)
- major_ver, minor_ver = [int(ver) for ver in
- resp_body['versions'][0]['version'].split(".")]
- req_version = ('%s.%s' % (major_ver + 1, minor_ver + 1))
- resp, _ = self.shares_client.send_microversion_request(req_version)
+ resp, resp_body = self.shares_v2_client.send_microversion_request(
+ script_name='v2', version=_MAX_API_VERSION)
+
+ self.assertEqual(200, resp.status)
+
+ version_list = resp_body['versions']
+ ids = [v['id'] for v in version_list]
+ self.assertEqual({'v2.0'}, set(ids))
+
+ self.assertEqual(_MAX_API_VERSION,
+ resp.get(API_MICROVERSIONS_HEADER_LOWER))
+ self.assertEqual(API_MICROVERSIONS_HEADER, resp.get('vary'))
+ self.assertEqual(_MIN_API_VERSION, version_list[0].get('min_version'))
+ self.assertEqual(_MAX_API_VERSION, version_list[0].get('version'))
+
+ @test.attr(type=["gate", "smoke", ])
+ def test_microversions_v2_invalid_version(self):
+
+ resp, _ = self.shares_v2_client.send_microversion_request(
+ script_name='v2', version='1.2.1')
+
+ self.assertEqual(400, resp.status)
+
+ @test.attr(type=["gate", "smoke", ])
+ def test_microversions_v2_unacceptable_version(self):
+
+ # First get max version from the server
+ resp, resp_body = self.shares_v2_client.send_microversion_request(
+ script_name='v2')
+
+ self.assertEqual(200, resp.status)
+
+ version_list = resp_body['versions']
+ latest_version = version_list[0].get('version')
+ major, minor = [int(ver) for ver in latest_version.split(".")]
+ next_version = ('%s.%s' % (major + 1, minor + 1))
+
+ # Request a version that is too high
+ resp, _ = self.shares_v2_client.send_microversion_request(
+ script_name='v2', version=next_version)
self.assertEqual(406, resp.status)
-
- @test.attr(type=["gate", "smoke", ])
- def test_microversions_invalid_versions(self):
- """Requests invalid versions."""
-
- resp, resp_body = self.shares_client.send_microversion_request('1.2.1')
-
- self.assertEqual(400, resp.status)
-
- resp, _ = self.shares_client.send_microversion_request('None')
-
- self.assertEqual(400, resp.status)