Merge "Fix _check_network_external_connectivity in test_network_basic_ops"
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index 6b87b4d..e7f71bc 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -243,3 +243,7 @@
* `2.37`_
.. _2.37: http://docs.openstack.org/developer/nova/api_microversion_history.html#id34
+
+ * `2.42`_
+
+ .. _2.42: http://docs.openstack.org/developer/nova/api_microversion_history.html#id38
diff --git a/releasenotes/notes/add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml b/releasenotes/notes/add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml
new file mode 100644
index 0000000..9116ef8
--- /dev/null
+++ b/releasenotes/notes/add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add the implied roles feature API to the roles_client library. This
+ feature enables the possibility to create inferences rules between
+ roles (a role being implied by another role).
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index d77ea90..c3c5460 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -304,14 +304,28 @@
cls.images.append(image_id)
if 'wait_until' in kwargs:
- waiters.wait_for_image_status(cls.compute_images_client,
- image_id, kwargs['wait_until'])
+ try:
+ waiters.wait_for_image_status(cls.compute_images_client,
+ image_id, kwargs['wait_until'])
+ except lib_exc.NotFound:
+ if kwargs['wait_until'].upper() == 'ACTIVE':
+ # If the image is not found after create_image returned
+ # that means the snapshot failed in nova-compute and nova
+ # deleted the image. There should be a compute fault
+ # recorded with the server in that case, so get the server
+ # and dump some details.
+ server = (
+ cls.servers_client.show_server(server_id)['server'])
+ if 'fault' in server:
+ raise exceptions.SnapshotNotFoundException(
+ server['fault'], image_id=image_id)
+ else:
+ raise exceptions.SnapshotNotFoundException(
+ image_id=image_id)
+ else:
+ raise
image = cls.compute_images_client.show_image(image_id)['image']
- if kwargs['wait_until'] == 'ACTIVE':
- if kwargs.get('wait_for_server', True):
- waiters.wait_for_server_status(cls.servers_client,
- server_id, 'ACTIVE')
return image
@classmethod
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index a0c860a..d9db0b5 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -60,7 +60,6 @@
snapshot_name = data_utils.rand_name('test-snap')
image = self.create_image_from_server(server['id'],
name=snapshot_name,
- wait_until='ACTIVE',
- wait_for_server=False)
+ wait_until='ACTIVE')
self.addCleanup(self.client.delete_image, image['id'])
self.assertEqual(snapshot_name, image['name'])
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index ae8f47d..d9e83a6 100644
--- a/tempest/api/compute/servers/test_device_tagging.py
+++ b/tempest/api/compute/servers/test_device_tagging.py
@@ -33,7 +33,11 @@
class DeviceTaggingTest(base.BaseV2ComputeTest):
min_microversion = '2.32'
- max_microversion = 'latest'
+ # NOTE(mriedem): max_version looks odd but it's actually correct. Due to a
+ # bug in the 2.32 microversion, tags on block devices only worked with the
+ # 2.32 microversion specifically. And tags on networks only worked between
+ # 2.32 and 2.36 inclusive; the 2.37 microversion broke tags for networks.
+ max_microversion = '2.32'
@classmethod
def skip_checks(cls):
@@ -262,3 +266,8 @@
cmd_md = 'sudo cat /mnt/openstack/latest/meta_data.json'
md_json = self.ssh_client.exec_command(cmd_md)
self.verify_device_metadata(md_json)
+
+
+class DeviceTaggingTestV2_42(DeviceTaggingTest):
+ min_microversion = '2.42'
+ max_microversion = 'latest'
diff --git a/tempest/api/compute/volumes/test_attach_volume_negative.py b/tempest/api/compute/volumes/test_attach_volume_negative.py
index acab4b1..c017690 100644
--- a/tempest/api/compute/volumes/test_attach_volume_negative.py
+++ b/tempest/api/compute/volumes/test_attach_volume_negative.py
@@ -30,6 +30,7 @@
skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
raise cls.skipException(skip_msg)
+ @test.attr(type=['negative'])
@test.related_bug('1630783', status_code=500)
@decorators.idempotent_id('a313b5cd-fbd0-49cc-94de-870e99f763c7')
def test_delete_attached_volume(self):
diff --git a/tempest/api/object_storage/test_account_bulk.py b/tempest/api/object_storage/test_account_bulk.py
index 1eda49a..d882731 100644
--- a/tempest/api/object_storage/test_account_bulk.py
+++ b/tempest/api/object_storage/test_account_bulk.py
@@ -17,6 +17,7 @@
from tempest.api.object_storage import base
from tempest.common import custom_matchers
+from tempest.lib import decorators
from tempest import test
@@ -68,7 +69,7 @@
self.assertHeaders(resp, 'Account', 'GET')
self.assertNotIn(container_name, body)
- @test.idempotent_id('a407de51-1983-47cc-9f14-47c2b059413c')
+ @decorators.idempotent_id('a407de51-1983-47cc-9f14-47c2b059413c')
@test.requires_ext(extension='bulk_upload', service='object')
def test_extract_archive(self):
# Test bulk operation of file upload with an archived file
@@ -104,7 +105,7 @@
self.assertIn(object_name, [c['name'] for c in contents_list])
- @test.idempotent_id('c075e682-0d2a-43b2-808d-4116200d736d')
+ @decorators.idempotent_id('c075e682-0d2a-43b2-808d-4116200d736d')
@test.requires_ext(extension='bulk_delete', service='object')
def test_bulk_delete(self):
# Test bulk operation of deleting multiple files
@@ -131,7 +132,7 @@
# Check if uploaded contents are completely deleted
self._check_contents_deleted(container_name)
- @test.idempotent_id('dbea2bcb-efbb-4674-ac8a-a5a0e33d1d79')
+ @decorators.idempotent_id('dbea2bcb-efbb-4674-ac8a-a5a0e33d1d79')
@test.requires_ext(extension='bulk_delete', service='object')
def test_bulk_delete_by_POST(self):
# Test bulk operation of deleting multiple files
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index fcbd6eb..cbf0d4b 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -15,6 +15,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -76,7 +77,7 @@
super(AccountQuotasTest, cls).resource_cleanup()
@test.attr(type="smoke")
- @test.idempotent_id('a22ef352-a342-4587-8f47-3bbdb5b039c4')
+ @decorators.idempotent_id('a22ef352-a342-4587-8f47-3bbdb5b039c4')
@test.requires_ext(extension='account_quotas', service='object')
def test_upload_valid_object(self):
object_name = data_utils.rand_name(name="TestObject")
@@ -87,7 +88,7 @@
self.assertHeaders(resp, 'Object', 'PUT')
@test.attr(type=["smoke"])
- @test.idempotent_id('63f51f9f-5f1d-4fc6-b5be-d454d70949d6')
+ @decorators.idempotent_id('63f51f9f-5f1d-4fc6-b5be-d454d70949d6')
@test.requires_ext(extension='account_quotas', service='object')
def test_admin_modify_quota(self):
"""Test ResellerAdmin can modify/remove the quota on a user's account
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index ae8dfcc..2e85a43 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -14,6 +14,7 @@
from tempest.api.object_storage import base
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -75,7 +76,7 @@
super(AccountQuotasNegativeTest, cls).resource_cleanup()
@test.attr(type=["negative"])
- @test.idempotent_id('d1dc5076-555e-4e6d-9697-28f1fe976324')
+ @decorators.idempotent_id('d1dc5076-555e-4e6d-9697-28f1fe976324')
@test.requires_ext(extension='account_quotas', service='object')
def test_user_modify_quota(self):
"""Test that a user cannot modify or remove a quota on its account."""
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 59129e5..d779d42 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -22,6 +22,7 @@
from tempest.common import custom_matchers
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -54,7 +55,7 @@
super(AccountTest, cls).resource_cleanup()
@test.attr(type='smoke')
- @test.idempotent_id('3499406a-ae53-4f8c-b43a-133d4dc6fe3f')
+ @decorators.idempotent_id('3499406a-ae53-4f8c-b43a-133d4dc6fe3f')
def test_list_containers(self):
# list of all containers should not be empty
resp, container_list = self.account_client.list_account_containers()
@@ -66,7 +67,7 @@
self.assertIn(six.text_type(container_name).encode('utf-8'),
container_list)
- @test.idempotent_id('884ec421-fbad-4fcc-916b-0580f2699565')
+ @decorators.idempotent_id('884ec421-fbad-4fcc-916b-0580f2699565')
def test_list_no_containers(self):
# List request to empty account
@@ -103,7 +104,7 @@
self.assertEqual(len(container_list), 0)
- @test.idempotent_id('1c7efa35-e8a2-4b0b-b5ff-862c7fd83704')
+ @decorators.idempotent_id('1c7efa35-e8a2-4b0b-b5ff-862c7fd83704')
def test_list_containers_with_format_json(self):
# list containers setting format parameter to 'json'
params = {'format': 'json'}
@@ -115,7 +116,7 @@
self.assertTrue([c['count'] for c in container_list])
self.assertTrue([c['bytes'] for c in container_list])
- @test.idempotent_id('4477b609-1ca6-4d4b-b25d-ad3f01086089')
+ @decorators.idempotent_id('4477b609-1ca6-4d4b-b25d-ad3f01086089')
def test_list_containers_with_format_xml(self):
# list containers setting format parameter to 'xml'
params = {'format': 'xml'}
@@ -130,7 +131,7 @@
self.assertEqual(container_list.find(".//count").tag, 'count')
self.assertEqual(container_list.find(".//bytes").tag, 'bytes')
- @test.idempotent_id('6eb04a6a-4860-4e31-ba91-ea3347d76b58')
+ @decorators.idempotent_id('6eb04a6a-4860-4e31-ba91-ea3347d76b58')
@testtools.skipIf(
not CONF.object_storage_feature_enabled.discoverability,
'Discoverability function is disabled')
@@ -139,7 +140,7 @@
self.assertThat(resp, custom_matchers.AreAllWellFormatted())
- @test.idempotent_id('5cfa4ab2-4373-48dd-a41f-a532b12b08b2')
+ @decorators.idempotent_id('5cfa4ab2-4373-48dd-a41f-a532b12b08b2')
def test_list_containers_with_limit(self):
# list containers one of them, half of them then all of them
for limit in (1, self.containers_count // 2,
@@ -151,7 +152,7 @@
self.assertEqual(len(container_list), limit)
- @test.idempotent_id('638f876d-6a43-482a-bbb3-0840bca101c6')
+ @decorators.idempotent_id('638f876d-6a43-482a-bbb3-0840bca101c6')
def test_list_containers_with_marker(self):
# list containers using marker param
# first expect to get 0 container as we specified last
@@ -172,7 +173,7 @@
self.assertEqual(len(container_list),
self.containers_count // 2 - 1)
- @test.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
+ @decorators.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
def test_list_containers_with_end_marker(self):
# list containers using end_marker param
# first expect to get 0 container as we specified first container as
@@ -190,7 +191,7 @@
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list), self.containers_count // 2)
- @test.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
+ @decorators.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
def test_list_containers_with_marker_and_end_marker(self):
# list containers combining marker and end_marker param
params = {'marker': self.containers[0],
@@ -200,7 +201,7 @@
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list), self.containers_count - 2)
- @test.idempotent_id('f7064ae8-dbcc-48da-b594-82feef6ea5af')
+ @decorators.idempotent_id('f7064ae8-dbcc-48da-b594-82feef6ea5af')
def test_list_containers_with_limit_and_marker(self):
# list containers combining marker and limit param
# result are always limitated by the limit whatever the marker
@@ -215,7 +216,7 @@
self.assertLessEqual(len(container_list), limit,
str(container_list))
- @test.idempotent_id('888a3f0e-7214-4806-8e50-5e0c9a69bb5e')
+ @decorators.idempotent_id('888a3f0e-7214-4806-8e50-5e0c9a69bb5e')
def test_list_containers_with_limit_and_end_marker(self):
# list containers combining limit and end_marker param
limit = random.randint(1, self.containers_count)
@@ -227,7 +228,7 @@
self.assertEqual(len(container_list),
min(limit, self.containers_count // 2))
- @test.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
+ @decorators.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
def test_list_containers_with_limit_and_marker_and_end_marker(self):
# list containers combining limit, marker and end_marker param
limit = random.randint(1, self.containers_count)
@@ -240,7 +241,7 @@
self.assertEqual(len(container_list),
min(limit, self.containers_count - 2))
- @test.idempotent_id('365e6fc7-1cfe-463b-a37c-8bd08d47b6aa')
+ @decorators.idempotent_id('365e6fc7-1cfe-463b-a37c-8bd08d47b6aa')
def test_list_containers_with_prefix(self):
# list containers that have a name that starts with a prefix
prefix = '{0}-a'.format(CONF.resources_prefix)
@@ -253,7 +254,7 @@
'utf-8').startswith(prefix))
@test.attr(type='smoke')
- @test.idempotent_id('4894c312-6056-4587-8d6f-86ffbf861f80')
+ @decorators.idempotent_id('4894c312-6056-4587-8d6f-86ffbf861f80')
def test_list_account_metadata(self):
# list all account metadata
@@ -268,14 +269,14 @@
self.assertIn('x-account-meta-test-account-meta2', resp)
self.account_client.delete_account_metadata(metadata)
- @test.idempotent_id('b904c2e3-24c2-4dba-ad7d-04e90a761be5')
+ @decorators.idempotent_id('b904c2e3-24c2-4dba-ad7d-04e90a761be5')
def test_list_no_account_metadata(self):
# list no account metadata
resp, _ = self.account_client.list_account_metadata()
self.assertHeaders(resp, 'Account', 'HEAD')
self.assertNotIn('x-account-meta-', str(resp))
- @test.idempotent_id('e2a08b5f-3115-4768-a3ee-d4287acd6c08')
+ @decorators.idempotent_id('e2a08b5f-3115-4768-a3ee-d4287acd6c08')
def test_update_account_metadata_with_create_metadata(self):
# add metadata to account
metadata = {'test-account-meta1': 'Meta1'}
@@ -289,7 +290,7 @@
self.account_client.delete_account_metadata(metadata)
- @test.idempotent_id('9f60348d-c46f-4465-ae06-d51dbd470953')
+ @decorators.idempotent_id('9f60348d-c46f-4465-ae06-d51dbd470953')
def test_update_account_metadata_with_delete_matadata(self):
# delete metadata from account
metadata = {'test-account-meta1': 'Meta1'}
@@ -300,7 +301,7 @@
resp, _ = self.account_client.list_account_metadata()
self.assertNotIn('x-account-meta-test-account-meta1', resp)
- @test.idempotent_id('64fd53f3-adbd-4639-af54-436e4982dbfb')
+ @decorators.idempotent_id('64fd53f3-adbd-4639-af54-436e4982dbfb')
def test_update_account_metadata_with_create_matadata_key(self):
# if the value of metadata is not set, the metadata is not
# registered at a server
@@ -311,7 +312,7 @@
resp, _ = self.account_client.list_account_metadata()
self.assertNotIn('x-account-meta-test-account-meta1', resp)
- @test.idempotent_id('d4d884d3-4696-4b85-bc98-4f57c4dd2bf1')
+ @decorators.idempotent_id('d4d884d3-4696-4b85-bc98-4f57c4dd2bf1')
def test_update_account_metadata_with_delete_matadata_key(self):
# Although the value of metadata is not set, the feature of
# deleting metadata is valid
@@ -324,7 +325,7 @@
resp, _ = self.account_client.list_account_metadata()
self.assertNotIn('x-account-meta-test-account-meta1', resp)
- @test.idempotent_id('8e5fc073-59b9-42ee-984a-29ed11b2c749')
+ @decorators.idempotent_id('8e5fc073-59b9-42ee-984a-29ed11b2c749')
def test_update_account_metadata_with_create_and_delete_metadata(self):
# Send a request adding and deleting metadata requests simultaneously
metadata_1 = {'test-account-meta1': 'Meta1'}
diff --git a/tempest/api/object_storage/test_account_services_negative.py b/tempest/api/object_storage/test_account_services_negative.py
index 254a9b3..d46534b 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -14,6 +14,7 @@
from tempest.api.object_storage import base
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -32,7 +33,7 @@
cls.os_operator = cls.os_roles_operator_alt
@test.attr(type=['negative'])
- @test.idempotent_id('070e6aca-6152-4867-868d-1118d68fb38c')
+ @decorators.idempotent_id('070e6aca-6152-4867-868d-1118d68fb38c')
def test_list_containers_with_non_authorized_user(self):
# list containers using non-authorized user
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index e555fd9..aa4e92c 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -16,7 +16,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -34,7 +34,7 @@
self.delete_containers()
super(ObjectTestACLs, self).tearDown()
- @test.idempotent_id('a3270f3f-7640-4944-8448-c7ea783ea5b6')
+ @decorators.idempotent_id('a3270f3f-7640-4944-8448-c7ea783ea5b6')
def test_read_object_with_rights(self):
# attempt to read object using authorized user
# update X-Container-Read metadata ACL
@@ -61,7 +61,7 @@
self.container_name, object_name)
self.assertHeaders(resp, 'Object', 'GET')
- @test.idempotent_id('aa58bfa5-40d9-4bc3-82b4-d07f4a9e392a')
+ @decorators.idempotent_id('aa58bfa5-40d9-4bc3-82b4-d07f4a9e392a')
def test_write_object_with_rights(self):
# attempt to write object using authorized user
# update X-Container-Write metadata ACL
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index 0055bf9..d5d5ea7 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -15,6 +15,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -47,7 +48,7 @@
super(ObjectACLsNegativeTest, self).tearDown()
@test.attr(type=['negative'])
- @test.idempotent_id('af587587-0c24-4e15-9822-8352ce711013')
+ @decorators.idempotent_id('af587587-0c24-4e15-9822-8352ce711013')
def test_write_object_without_using_creds(self):
# trying to create object with empty headers
# X-Auth-Token is not provided
@@ -61,7 +62,7 @@
self.container_name, object_name, 'data', headers={})
@test.attr(type=['negative'])
- @test.idempotent_id('af85af0b-a025-4e72-a90e-121babf55720')
+ @decorators.idempotent_id('af85af0b-a025-4e72-a90e-121babf55720')
def test_delete_object_without_using_creds(self):
# create object
object_name = data_utils.rand_name(name='Object')
@@ -78,7 +79,7 @@
self.container_name, object_name)
@test.attr(type=['negative'])
- @test.idempotent_id('63d84e37-55a6-42e2-9e5f-276e60e26a00')
+ @decorators.idempotent_id('63d84e37-55a6-42e2-9e5f-276e60e26a00')
def test_write_object_with_non_authorized_user(self):
# attempt to upload another file using non-authorized user
# User provided token is forbidden. ACL are not set
@@ -93,7 +94,7 @@
self.container_name, object_name, 'data', headers={})
@test.attr(type=['negative'])
- @test.idempotent_id('abf63359-be52-4feb-87dd-447689fc77fd')
+ @decorators.idempotent_id('abf63359-be52-4feb-87dd-447689fc77fd')
def test_read_object_with_non_authorized_user(self):
# attempt to read object using non-authorized user
# User provided token is forbidden. ACL are not set
@@ -111,7 +112,7 @@
self.container_name, object_name)
@test.attr(type=['negative'])
- @test.idempotent_id('7343ac3d-cfed-4198-9bb0-00149741a492')
+ @decorators.idempotent_id('7343ac3d-cfed-4198-9bb0-00149741a492')
def test_delete_object_with_non_authorized_user(self):
# attempt to delete object using non-authorized user
# User provided token is forbidden. ACL are not set
@@ -129,7 +130,7 @@
self.container_name, object_name)
@test.attr(type=['negative'])
- @test.idempotent_id('9ed01334-01e9-41ea-87ea-e6f465582823')
+ @decorators.idempotent_id('9ed01334-01e9-41ea-87ea-e6f465582823')
def test_read_object_without_rights(self):
# attempt to read object using non-authorized user
# update X-Container-Read metadata ACL
@@ -153,7 +154,7 @@
self.container_name, object_name)
@test.attr(type=['negative'])
- @test.idempotent_id('a3a585a7-d8cf-4b65-a1a0-edc2b1204f85')
+ @decorators.idempotent_id('a3a585a7-d8cf-4b65-a1a0-edc2b1204f85')
def test_write_object_without_rights(self):
# attempt to write object using non-authorized user
# update X-Container-Write metadata ACL
@@ -174,7 +175,7 @@
object_name, 'data', headers={})
@test.attr(type=['negative'])
- @test.idempotent_id('8ba512ad-aa6e-444e-b882-2906a0ea2052')
+ @decorators.idempotent_id('8ba512ad-aa6e-444e-b882-2906a0ea2052')
def test_write_object_without_write_rights(self):
# attempt to write object using non-authorized user
# update X-Container-Read and X-Container-Write metadata ACL
@@ -199,7 +200,7 @@
object_name, 'data', headers={})
@test.attr(type=['negative'])
- @test.idempotent_id('b4e366f8-f185-47ab-b789-df4416f9ecdb')
+ @decorators.idempotent_id('b4e366f8-f185-47ab-b789-df4416f9ecdb')
def test_delete_object_without_write_rights(self):
# attempt to delete object using non-authorized user
# update X-Container-Read and X-Container-Write metadata ACL
diff --git a/tempest/api/object_storage/test_container_quotas.py b/tempest/api/object_storage/test_container_quotas.py
index 8cbe441..d3b456a 100644
--- a/tempest/api/object_storage/test_container_quotas.py
+++ b/tempest/api/object_storage/test_container_quotas.py
@@ -15,6 +15,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -47,7 +48,7 @@
self.delete_containers()
super(ContainerQuotasTest, self).tearDown()
- @test.idempotent_id('9a0fb034-86af-4df0-86fa-f8bd7db21ae0')
+ @decorators.idempotent_id('9a0fb034-86af-4df0-86fa-f8bd7db21ae0')
@test.requires_ext(extension='container_quotas', service='object')
@test.attr(type="smoke")
def test_upload_valid_object(self):
@@ -64,7 +65,7 @@
nafter = self._get_bytes_used()
self.assertEqual(nbefore + len(data), nafter)
- @test.idempotent_id('22eeeb2b-3668-4160-baef-44790f65a5a0')
+ @decorators.idempotent_id('22eeeb2b-3668-4160-baef-44790f65a5a0')
@test.requires_ext(extension='container_quotas', service='object')
@test.attr(type="smoke")
def test_upload_large_object(self):
@@ -81,7 +82,7 @@
nafter = self._get_bytes_used()
self.assertEqual(nbefore, nafter)
- @test.idempotent_id('3a387039-697a-44fc-a9c0-935de31f426b')
+ @decorators.idempotent_id('3a387039-697a-44fc-a9c0-935de31f426b')
@test.requires_ext(extension='container_quotas', service='object')
@test.attr(type="smoke")
def test_upload_too_many_objects(self):
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index e4476a1..4b65584 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -15,6 +15,7 @@
from tempest.api.object_storage import base
from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
from tempest import test
@@ -24,14 +25,14 @@
super(ContainerTest, self).tearDown()
@test.attr(type='smoke')
- @test.idempotent_id('92139d73-7819-4db1-85f8-3f2f22a8d91f')
+ @decorators.idempotent_id('92139d73-7819-4db1-85f8-3f2f22a8d91f')
def test_create_container(self):
container_name = data_utils.rand_name(name='TestContainer')
resp, body = self.container_client.create_container(container_name)
self.containers.append(container_name)
self.assertHeaders(resp, 'Container', 'PUT')
- @test.idempotent_id('49f866ed-d6af-4395-93e7-4187eb56d322')
+ @decorators.idempotent_id('49f866ed-d6af-4395-93e7-4187eb56d322')
def test_create_container_overwrite(self):
# overwrite container with the same name
container_name = data_utils.rand_name(name='TestContainer')
@@ -41,7 +42,7 @@
resp, _ = self.container_client.create_container(container_name)
self.assertHeaders(resp, 'Container', 'PUT')
- @test.idempotent_id('c2ac4d59-d0f5-40d5-ba19-0635056d48cd')
+ @decorators.idempotent_id('c2ac4d59-d0f5-40d5-ba19-0635056d48cd')
def test_create_container_with_metadata_key(self):
# create container with the blank value of metadata
container_name = data_utils.rand_name(name='TestContainer')
@@ -58,7 +59,7 @@
# in the server
self.assertNotIn('x-container-meta-test-container-meta', resp)
- @test.idempotent_id('e1e8df32-7b22-44e1-aa08-ccfd8d446b58')
+ @decorators.idempotent_id('e1e8df32-7b22-44e1-aa08-ccfd8d446b58')
def test_create_container_with_metadata_value(self):
# create container with metadata value
container_name = data_utils.rand_name(name='TestContainer')
@@ -77,7 +78,7 @@
self.assertEqual(resp['x-container-meta-test-container-meta'],
metadata['test_container_meta'])
- @test.idempotent_id('24d16451-1c0c-4e4f-b59c-9840a3aba40e')
+ @decorators.idempotent_id('24d16451-1c0c-4e4f-b59c-9840a3aba40e')
def test_create_container_with_remove_metadata_key(self):
# create container with the blank value of remove metadata
container_name = data_utils.rand_name(name='TestContainer')
@@ -97,7 +98,7 @@
container_name)
self.assertNotIn('x-container-meta-test-container-meta', resp)
- @test.idempotent_id('8a21ebad-a5c7-4e29-b428-384edc8cd156')
+ @decorators.idempotent_id('8a21ebad-a5c7-4e29-b428-384edc8cd156')
def test_create_container_with_remove_metadata_value(self):
# create container with remove metadata
container_name = data_utils.rand_name(name='TestContainer')
@@ -115,7 +116,7 @@
container_name)
self.assertNotIn('x-container-meta-test-container-meta', resp)
- @test.idempotent_id('95d3a249-b702-4082-a2c4-14bb860cf06a')
+ @decorators.idempotent_id('95d3a249-b702-4082-a2c4-14bb860cf06a')
def test_delete_container(self):
# create a container
container_name = self.create_container()
@@ -124,7 +125,7 @@
self.assertHeaders(resp, 'Container', 'DELETE')
@test.attr(type='smoke')
- @test.idempotent_id('312ff6bd-5290-497f-bda1-7c5fec6697ab')
+ @decorators.idempotent_id('312ff6bd-5290-497f-bda1-7c5fec6697ab')
def test_list_container_contents(self):
# get container contents list
container_name = self.create_container()
@@ -135,7 +136,7 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual([object_name], object_list)
- @test.idempotent_id('4646ac2d-9bfb-4c7d-a3c5-0f527402b3df')
+ @decorators.idempotent_id('4646ac2d-9bfb-4c7d-a3c5-0f527402b3df')
def test_list_container_contents_with_no_object(self):
# get empty container contents list
container_name = self.create_container()
@@ -145,7 +146,7 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEmpty(object_list)
- @test.idempotent_id('fe323a32-57b9-4704-a996-2e68f83b09bc')
+ @decorators.idempotent_id('fe323a32-57b9-4704-a996-2e68f83b09bc')
def test_list_container_contents_with_delimiter(self):
# get container contents list using delimiter param
container_name = self.create_container()
@@ -159,7 +160,7 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual([object_name.split('/')[0] + '/'], object_list)
- @test.idempotent_id('55b4fa5c-e12e-4ca9-8fcf-a79afe118522')
+ @decorators.idempotent_id('55b4fa5c-e12e-4ca9-8fcf-a79afe118522')
def test_list_container_contents_with_end_marker(self):
# get container contents list using end_marker param
container_name = self.create_container()
@@ -172,7 +173,7 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual([object_name], object_list)
- @test.idempotent_id('196f5034-6ab0-4032-9da9-a937bbb9fba9')
+ @decorators.idempotent_id('196f5034-6ab0-4032-9da9-a937bbb9fba9')
def test_list_container_contents_with_format_json(self):
# get container contents list using format_json param
container_name = self.create_container()
@@ -191,7 +192,7 @@
self.assertTrue([c['content_type'] for c in object_list])
self.assertTrue([c['last_modified'] for c in object_list])
- @test.idempotent_id('655a53ca-4d15-408c-a377-f4c6dbd0a1fa')
+ @decorators.idempotent_id('655a53ca-4d15-408c-a377-f4c6dbd0a1fa')
def test_list_container_contents_with_format_xml(self):
# get container contents list using format_xml param
container_name = self.create_container()
@@ -215,7 +216,7 @@
self.assertEqual(object_list.find(".//last_modified").tag,
'last_modified')
- @test.idempotent_id('297ec38b-2b61-4ff4-bcd1-7fa055e97b61')
+ @decorators.idempotent_id('297ec38b-2b61-4ff4-bcd1-7fa055e97b61')
def test_list_container_contents_with_limit(self):
# get container contents list using limit param
container_name = self.create_container()
@@ -228,7 +229,7 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual([object_name], object_list)
- @test.idempotent_id('c31ddc63-2a58-4f6b-b25c-94d2937e6867')
+ @decorators.idempotent_id('c31ddc63-2a58-4f6b-b25c-94d2937e6867')
def test_list_container_contents_with_marker(self):
# get container contents list using marker param
container_name = self.create_container()
@@ -241,7 +242,7 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual([object_name], object_list)
- @test.idempotent_id('58ca6cc9-6af0-408d-aaec-2a6a7b2f0df9')
+ @decorators.idempotent_id('58ca6cc9-6af0-408d-aaec-2a6a7b2f0df9')
def test_list_container_contents_with_path(self):
# get container contents list using path param
container_name = self.create_container()
@@ -255,7 +256,7 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual([object_name], object_list)
- @test.idempotent_id('77e742c7-caf2-4ec9-8aa4-f7d509a3344c')
+ @decorators.idempotent_id('77e742c7-caf2-4ec9-8aa4-f7d509a3344c')
def test_list_container_contents_with_prefix(self):
# get container contents list using prefix param
container_name = self.create_container()
@@ -270,7 +271,7 @@
self.assertEqual([object_name], object_list)
@test.attr(type='smoke')
- @test.idempotent_id('96e68f0e-19ec-4aa2-86f3-adc6a45e14dd')
+ @decorators.idempotent_id('96e68f0e-19ec-4aa2-86f3-adc6a45e14dd')
def test_list_container_metadata(self):
# List container metadata
container_name = self.create_container()
@@ -286,7 +287,7 @@
self.assertIn('x-container-meta-name', resp)
self.assertEqual(resp['x-container-meta-name'], metadata['name'])
- @test.idempotent_id('a2faf936-6b13-4f8d-92a2-c2278355821e')
+ @decorators.idempotent_id('a2faf936-6b13-4f8d-92a2-c2278355821e')
def test_list_no_container_metadata(self):
# HEAD container without metadata
container_name = self.create_container()
@@ -296,7 +297,7 @@
self.assertHeaders(resp, 'Container', 'HEAD')
self.assertNotIn('x-container-meta-', str(resp))
- @test.idempotent_id('cf19bc0b-7e16-4a5a-aaed-cb0c2fe8deef')
+ @decorators.idempotent_id('cf19bc0b-7e16-4a5a-aaed-cb0c2fe8deef')
def test_update_container_metadata_with_create_and_delete_metadata(self):
# Send one request of adding and deleting metadata
container_name = data_utils.rand_name(name='TestContainer')
@@ -319,7 +320,7 @@
self.assertEqual(resp['x-container-meta-test-container-meta2'],
metadata_2['test-container-meta2'])
- @test.idempotent_id('2ae5f295-4bf1-4e04-bfad-21e54b62cec5')
+ @decorators.idempotent_id('2ae5f295-4bf1-4e04-bfad-21e54b62cec5')
def test_update_container_metadata_with_create_metadata(self):
# update container metadata using add metadata
container_name = self.create_container()
@@ -336,7 +337,7 @@
self.assertEqual(resp['x-container-meta-test-container-meta1'],
metadata['test-container-meta1'])
- @test.idempotent_id('3a5ce7d4-6e4b-47d0-9d87-7cd42c325094')
+ @decorators.idempotent_id('3a5ce7d4-6e4b-47d0-9d87-7cd42c325094')
def test_update_container_metadata_with_delete_metadata(self):
# update container metadata using delete metadata
container_name = data_utils.rand_name(name='TestContainer')
@@ -354,7 +355,7 @@
container_name)
self.assertNotIn('x-container-meta-test-container-meta1', resp)
- @test.idempotent_id('31f40a5f-6a52-4314-8794-cd89baed3040')
+ @decorators.idempotent_id('31f40a5f-6a52-4314-8794-cd89baed3040')
def test_update_container_metadata_with_create_metadata_key(self):
# update container metadata with a blank value of metadata
container_name = self.create_container()
@@ -369,7 +370,7 @@
container_name)
self.assertNotIn('x-container-meta-test-container-meta1', resp)
- @test.idempotent_id('a2e36378-6f1f-43f4-840a-ffd9cfd61914')
+ @decorators.idempotent_id('a2e36378-6f1f-43f4-840a-ffd9cfd61914')
def test_update_container_metadata_with_delete_metadata_key(self):
# update container metadata with a blank value of metadata
container_name = data_utils.rand_name(name='TestContainer')
diff --git a/tempest/api/object_storage/test_container_services_negative.py b/tempest/api/object_storage/test_container_services_negative.py
index 2856fab..be066ba 100644
--- a/tempest/api/object_storage/test_container_services_negative.py
+++ b/tempest/api/object_storage/test_container_services_negative.py
@@ -18,6 +18,7 @@
from tempest.api.object_storage import base
from tempest import config
from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions
from tempest import test
@@ -36,7 +37,7 @@
cls.constraints = body['swift']
@test.attr(type=["negative"])
- @test.idempotent_id('30686921-4bed-4764-a038-40d741ed4e78')
+ @decorators.idempotent_id('30686921-4bed-4764-a038-40d741ed4e78')
@testtools.skipUnless(
CONF.object_storage_feature_enabled.discoverability,
'Discoverability function is disabled')
@@ -52,7 +53,7 @@
' longer than ' + str(max_length), str(ex))
@test.attr(type=["negative"])
- @test.idempotent_id('41e645bf-2e68-4f84-bf7b-c71aa5cd76ce')
+ @decorators.idempotent_id('41e645bf-2e68-4f84-bf7b-c71aa5cd76ce')
@testtools.skipUnless(
CONF.object_storage_feature_enabled.discoverability,
'Discoverability function is disabled')
@@ -69,7 +70,7 @@
self.assertIn('Metadata name too long', str(ex))
@test.attr(type=["negative"])
- @test.idempotent_id('81e36922-326b-4b7c-8155-3bbceecd7a82')
+ @decorators.idempotent_id('81e36922-326b-4b7c-8155-3bbceecd7a82')
@testtools.skipUnless(
CONF.object_storage_feature_enabled.discoverability,
'Discoverability function is disabled')
@@ -86,7 +87,7 @@
self.assertIn('Metadata value longer than ' + str(max_length), str(ex))
@test.attr(type=["negative"])
- @test.idempotent_id('ac666539-d566-4f02-8ceb-58e968dfb732')
+ @decorators.idempotent_id('ac666539-d566-4f02-8ceb-58e968dfb732')
@testtools.skipUnless(
CONF.object_storage_feature_enabled.discoverability,
'Discoverability function is disabled')
@@ -106,7 +107,7 @@
str(ex))
@test.attr(type=["negative"])
- @test.idempotent_id('1a95ab2e-b712-4a98-8a4d-8ce21b7557d6')
+ @decorators.idempotent_id('1a95ab2e-b712-4a98-8a4d-8ce21b7557d6')
def test_get_metadata_headers_with_invalid_container_name(self):
# Attempts to retrieve metadata headers with an invalid
# container name.
@@ -115,7 +116,7 @@
'invalid_container_name')
@test.attr(type=["negative"])
- @test.idempotent_id('125a24fa-90a7-4cfc-b604-44e49d788390')
+ @decorators.idempotent_id('125a24fa-90a7-4cfc-b604-44e49d788390')
def test_update_metadata_with_nonexistent_container_name(self):
# Attempts to update metadata using a nonexistent container name.
metadata = {'animal': 'penguin'}
@@ -125,7 +126,7 @@
'nonexistent_container_name', metadata)
@test.attr(type=["negative"])
- @test.idempotent_id('65387dbf-a0e2-4aac-9ddc-16eb3f1f69ba')
+ @decorators.idempotent_id('65387dbf-a0e2-4aac-9ddc-16eb3f1f69ba')
def test_delete_with_nonexistent_container_name(self):
# Attempts to delete metadata using a nonexistent container name.
metadata = {'animal': 'penguin'}
@@ -135,7 +136,7 @@
'nonexistent_container_name', metadata)
@test.attr(type=["negative"])
- @test.idempotent_id('14331d21-1e81-420a-beea-19cb5e5207f5')
+ @decorators.idempotent_id('14331d21-1e81-420a-beea-19cb5e5207f5')
def test_list_all_container_objects_with_nonexistent_container(self):
# Attempts to get a listing of all objects on a container
# that doesn't exist.
@@ -145,7 +146,7 @@
'nonexistent_container_name', params)
@test.attr(type=["negative"])
- @test.idempotent_id('86b2ab08-92d5-493d-acd2-85f0c848819e')
+ @decorators.idempotent_id('86b2ab08-92d5-493d-acd2-85f0c848819e')
def test_list_all_container_objects_on_deleted_container(self):
# Attempts to get a listing of all objects on a container
# that was deleted.
@@ -159,7 +160,7 @@
container_name, params)
@test.attr(type=["negative"])
- @test.idempotent_id('42da116e-1e8c-4c96-9e06-2f13884ed2b1')
+ @decorators.idempotent_id('42da116e-1e8c-4c96-9e06-2f13884ed2b1')
def test_delete_non_empty_container(self):
# create a container and an object within it
# attempt to delete a container that isn't empty.
diff --git a/tempest/api/object_storage/test_container_staticweb.py b/tempest/api/object_storage/test_container_staticweb.py
index edc9271..a280248 100644
--- a/tempest/api/object_storage/test_container_staticweb.py
+++ b/tempest/api/object_storage/test_container_staticweb.py
@@ -15,6 +15,7 @@
from tempest.api.object_storage import base
from tempest.common import custom_matchers
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -43,7 +44,7 @@
cls.delete_containers()
super(StaticWebTest, cls).resource_cleanup()
- @test.idempotent_id('c1f055ab-621d-4a6a-831f-846fcb578b8b')
+ @decorators.idempotent_id('c1f055ab-621d-4a6a-831f-846fcb578b8b')
@test.requires_ext(extension='staticweb', service='object')
def test_web_index(self):
headers = {'web-index': self.object_name}
@@ -74,7 +75,7 @@
self.container_name)
self.assertNotIn('x-container-meta-web-index', body)
- @test.idempotent_id('941814cf-db9e-4b21-8112-2b6d0af10ee5')
+ @decorators.idempotent_id('941814cf-db9e-4b21-8112-2b6d0af10ee5')
@test.requires_ext(extension='staticweb', service='object')
def test_web_listing(self):
headers = {'web-listings': 'true'}
@@ -106,7 +107,7 @@
self.container_name)
self.assertNotIn('x-container-meta-web-listings', body)
- @test.idempotent_id('bc37ec94-43c8-4990-842e-0e5e02fc8926')
+ @decorators.idempotent_id('bc37ec94-43c8-4990-842e-0e5e02fc8926')
@test.requires_ext(extension='staticweb', service='object')
def test_web_listing_css(self):
headers = {'web-listings': 'true',
@@ -130,7 +131,7 @@
css = '<link rel="stylesheet" type="text/css" href="listings.css" />'
self.assertIn(css, body.decode())
- @test.idempotent_id('f18b4bef-212e-45e7-b3ca-59af3a465f82')
+ @decorators.idempotent_id('f18b4bef-212e-45e7-b3ca-59af3a465f82')
@test.requires_ext(extension='staticweb', service='object')
def test_web_error(self):
headers = {'web-listings': 'true',
diff --git a/tempest/api/object_storage/test_container_sync.py b/tempest/api/object_storage/test_container_sync.py
index f134335..63fb93d 100644
--- a/tempest/api/object_storage/test_container_sync.py
+++ b/tempest/api/object_storage/test_container_sync.py
@@ -131,7 +131,7 @@
@test.attr(type='slow')
@decorators.skip_because(bug='1317133')
- @test.idempotent_id('be008325-1bba-4925-b7dd-93b58f22ce9b')
+ @decorators.idempotent_id('be008325-1bba-4925-b7dd-93b58f22ce9b')
@testtools.skipIf(
not CONF.object_storage_feature_enabled.container_sync,
'Old-style container sync function is disabled')
diff --git a/tempest/api/object_storage/test_container_sync_middleware.py b/tempest/api/object_storage/test_container_sync_middleware.py
index 4491a84..df738b3 100644
--- a/tempest/api/object_storage/test_container_sync_middleware.py
+++ b/tempest/api/object_storage/test_container_sync_middleware.py
@@ -14,6 +14,7 @@
from tempest.api.object_storage import test_container_sync
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -37,7 +38,7 @@
cls.cluster_name = CONF.object_storage.cluster_name
@test.attr(type='slow')
- @test.idempotent_id('ea4645a1-d147-4976-82f7-e5a7a3065f80')
+ @decorators.idempotent_id('ea4645a1-d147-4976-82f7-e5a7a3065f80')
@test.requires_ext(extension='container_sync', service='object')
def test_container_synchronization(self):
def make_headers(cont, cont_client):
diff --git a/tempest/api/object_storage/test_crossdomain.py b/tempest/api/object_storage/test_crossdomain.py
index 18dc254..c47aa93 100644
--- a/tempest/api/object_storage/test_crossdomain.py
+++ b/tempest/api/object_storage/test_crossdomain.py
@@ -14,6 +14,7 @@
from tempest.api.object_storage import base
from tempest.common import custom_matchers
+from tempest.lib import decorators
from tempest import test
@@ -36,7 +37,7 @@
# Turning http://.../v1/foobar into http://.../
self.account_client.skip_path()
- @test.idempotent_id('d1b8b031-b622-4010-82f9-ff78a9e915c7')
+ @decorators.idempotent_id('d1b8b031-b622-4010-82f9-ff78a9e915c7')
@test.requires_ext(extension='crossdomain', service='object')
def test_get_crossdomain_policy(self):
resp, body = self.account_client.get("crossdomain.xml", {})
diff --git a/tempest/api/object_storage/test_healthcheck.py b/tempest/api/object_storage/test_healthcheck.py
index 104253a..a186f9e 100644
--- a/tempest/api/object_storage/test_healthcheck.py
+++ b/tempest/api/object_storage/test_healthcheck.py
@@ -15,7 +15,7 @@
from tempest.api.object_storage import base
from tempest.common import custom_matchers
-from tempest import test
+from tempest.lib import decorators
class HealthcheckTest(base.BaseObjectTest):
@@ -25,7 +25,7 @@
# Turning http://.../v1/foobar into http://.../
self.account_client.skip_path()
- @test.idempotent_id('db5723b1-f25c-49a9-bfeb-7b5640caf337')
+ @decorators.idempotent_id('db5723b1-f25c-49a9-bfeb-7b5640caf337')
def test_get_healthcheck(self):
resp, _ = self.account_client.get("healthcheck", {})
diff --git a/tempest/api/object_storage/test_object_expiry.py b/tempest/api/object_storage/test_object_expiry.py
index 11acb31..7768d23 100644
--- a/tempest/api/object_storage/test_object_expiry.py
+++ b/tempest/api/object_storage/test_object_expiry.py
@@ -16,8 +16,8 @@
import time
from tempest.api.object_storage import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
-from tempest import test
class ObjectExpiryTest(base.BaseObjectTest):
@@ -81,14 +81,14 @@
self.container_name,
self.object_name)
- @test.idempotent_id('fb024a42-37f3-4ba5-9684-4f40a7910b41')
+ @decorators.idempotent_id('fb024a42-37f3-4ba5-9684-4f40a7910b41')
def test_get_object_after_expiry_time(self):
# the 10s is important, because the get calls can take 3s each
# some times
metadata = {'X-Delete-After': '10'}
self._test_object_expiry(metadata)
- @test.idempotent_id('e592f18d-679c-48fe-9e36-4be5f47102c5')
+ @decorators.idempotent_id('e592f18d-679c-48fe-9e36-4be5f47102c5')
def test_get_object_at_expiry_time(self):
metadata = {'X-Delete-At': str(int(time.time()) + 10)}
self._test_object_expiry(metadata)
diff --git a/tempest/api/object_storage/test_object_formpost.py b/tempest/api/object_storage/test_object_formpost.py
index 0a87a64..2829ac7 100644
--- a/tempest/api/object_storage/test_object_formpost.py
+++ b/tempest/api/object_storage/test_object_formpost.py
@@ -20,6 +20,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest import test
@@ -104,7 +105,7 @@
content_type = 'multipart/form-data; boundary=%s' % boundary
return body, content_type
- @test.idempotent_id('80fac02b-6e54-4f7b-be0d-a965b5cbef76')
+ @decorators.idempotent_id('80fac02b-6e54-4f7b-be0d-a965b5cbef76')
@test.requires_ext(extension='formpost', service='object')
def test_post_object_using_form(self):
body, content_type = self.get_multipart_form()
diff --git a/tempest/api/object_storage/test_object_formpost_negative.py b/tempest/api/object_storage/test_object_formpost_negative.py
index f193111..2174940 100644
--- a/tempest/api/object_storage/test_object_formpost_negative.py
+++ b/tempest/api/object_storage/test_object_formpost_negative.py
@@ -20,6 +20,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -105,7 +106,7 @@
content_type = 'multipart/form-data; boundary=%s' % boundary
return body, content_type
- @test.idempotent_id('d3fb3c4d-e627-48ce-9379-a1631f21336d')
+ @decorators.idempotent_id('d3fb3c4d-e627-48ce-9379-a1631f21336d')
@test.requires_ext(extension='formpost', service='object')
@test.attr(type=['negative'])
def test_post_object_using_form_expired(self):
@@ -122,7 +123,7 @@
url, body, headers=headers)
self.assertIn('FormPost: Form Expired', str(exc))
- @test.idempotent_id('b277257f-113c-4499-b8d1-5fead79f7360')
+ @decorators.idempotent_id('b277257f-113c-4499-b8d1-5fead79f7360')
@test.requires_ext(extension='formpost', service='object')
def test_post_object_using_form_invalid_signature(self):
self.key = "Wrong"
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 7716bdb..58fd822 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -23,6 +23,7 @@
from tempest.common import custom_matchers
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -75,7 +76,7 @@
self.assertNotIn('x-object-meta-' + meta_key, resp)
@test.attr(type='smoke')
- @test.idempotent_id('5b4ce26f-3545-46c9-a2ba-5754358a4c62')
+ @decorators.idempotent_id('5b4ce26f-3545-46c9-a2ba-5754358a4c62')
def test_create_object(self):
# create object
object_name = data_utils.rand_name(name='TestObject')
@@ -94,7 +95,7 @@
object_name)
self.assertEqual(data, body)
- @test.idempotent_id('5daebb1d-f0d5-4dc9-b541-69672eff00b0')
+ @decorators.idempotent_id('5daebb1d-f0d5-4dc9-b541-69672eff00b0')
def test_create_object_with_content_disposition(self):
# create object with content_disposition
object_name = data_utils.rand_name(name='TestObject')
@@ -116,7 +117,7 @@
self.assertEqual(resp['content-disposition'], 'inline')
self.assertEqual(body, data)
- @test.idempotent_id('605f8317-f945-4bee-ae91-013f1da8f0a0')
+ @decorators.idempotent_id('605f8317-f945-4bee-ae91-013f1da8f0a0')
def test_create_object_with_content_encoding(self):
# create object with content_encoding
object_name = data_utils.rand_name(name='TestObject')
@@ -143,7 +144,7 @@
metadata=metadata)
self.assertEqual(body, data_before)
- @test.idempotent_id('73820093-0503-40b1-a478-edf0e69c7d1f')
+ @decorators.idempotent_id('73820093-0503-40b1-a478-edf0e69c7d1f')
def test_create_object_with_etag(self):
# create object with etag
object_name = data_utils.rand_name(name='TestObject')
@@ -162,7 +163,7 @@
object_name)
self.assertEqual(data, body)
- @test.idempotent_id('84dafe57-9666-4f6d-84c8-0814d37923b8')
+ @decorators.idempotent_id('84dafe57-9666-4f6d-84c8-0814d37923b8')
def test_create_object_with_expect_continue(self):
# create object with expect_continue
@@ -179,7 +180,7 @@
object_name)
self.assertEqual(data, body)
- @test.idempotent_id('4f84422a-e2f2-4403-b601-726a4220b54e')
+ @decorators.idempotent_id('4f84422a-e2f2-4403-b601-726a4220b54e')
def test_create_object_with_transfer_encoding(self):
# create object with transfer_encoding
object_name = data_utils.rand_name(name='TestObject')
@@ -196,7 +197,7 @@
object_name)
self.assertEqual(data, body)
- @test.idempotent_id('0f3d62a6-47e3-4554-b0e5-1a5dc372d501')
+ @decorators.idempotent_id('0f3d62a6-47e3-4554-b0e5-1a5dc372d501')
def test_create_object_with_x_fresh_metadata(self):
# create object with x_fresh_metadata
object_name_base = data_utils.rand_name(name='TestObject')
@@ -222,7 +223,7 @@
self.assertNotIn('x-object-meta-test-meta', resp)
self.assertEqual(data, body)
- @test.idempotent_id('1c7ed3e4-2099-406b-b843-5301d4811baf')
+ @decorators.idempotent_id('1c7ed3e4-2099-406b-b843-5301d4811baf')
def test_create_object_with_x_object_meta(self):
# create object with object_meta
object_name = data_utils.rand_name(name='TestObject')
@@ -241,7 +242,7 @@
self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
self.assertEqual(data, body)
- @test.idempotent_id('e4183917-33db-4153-85cc-4dacbb938865')
+ @decorators.idempotent_id('e4183917-33db-4153-85cc-4dacbb938865')
def test_create_object_with_x_object_metakey(self):
# create object with the blank value of metadata
object_name = data_utils.rand_name(name='TestObject')
@@ -260,7 +261,7 @@
self.assertEqual(resp['x-object-meta-test-meta'], '')
self.assertEqual(data, body)
- @test.idempotent_id('ce798afc-b278-45de-a5ce-2ea124b98b99')
+ @decorators.idempotent_id('ce798afc-b278-45de-a5ce-2ea124b98b99')
def test_create_object_with_x_remove_object_meta(self):
# create object with x_remove_object_meta
object_name = data_utils.rand_name(name='TestObject')
@@ -283,7 +284,7 @@
self.assertNotIn('x-object-meta-test-meta', resp)
self.assertEqual(data, body)
- @test.idempotent_id('ad21e342-7916-4f9e-ab62-a1f885f2aaf9')
+ @decorators.idempotent_id('ad21e342-7916-4f9e-ab62-a1f885f2aaf9')
def test_create_object_with_x_remove_object_metakey(self):
# create object with the blank value of remove metadata
object_name = data_utils.rand_name(name='TestObject')
@@ -306,7 +307,7 @@
self.assertNotIn('x-object-meta-test-meta', resp)
self.assertEqual(data, body)
- @test.idempotent_id('17738d45-03bd-4d45-9e0b-7b2f58f98687')
+ @decorators.idempotent_id('17738d45-03bd-4d45-9e0b-7b2f58f98687')
def test_delete_object(self):
# create object
object_name = data_utils.rand_name(name='TestObject')
@@ -319,7 +320,7 @@
self.assertHeaders(resp, 'Object', 'DELETE')
@test.attr(type='smoke')
- @test.idempotent_id('7a94c25d-66e6-434c-9c38-97d4e2c29945')
+ @decorators.idempotent_id('7a94c25d-66e6-434c-9c38-97d4e2c29945')
def test_update_object_metadata(self):
# update object metadata
object_name, _ = self.create_object(self.container_name)
@@ -338,7 +339,7 @@
self.assertIn('x-object-meta-test-meta', resp)
self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
- @test.idempotent_id('48650ed0-c189-4e1e-ad6b-1d4770c6e134')
+ @decorators.idempotent_id('48650ed0-c189-4e1e-ad6b-1d4770c6e134')
def test_update_object_metadata_with_remove_metadata(self):
# update object metadata with remove metadata
object_name = data_utils.rand_name(name='TestObject')
@@ -362,7 +363,7 @@
object_name)
self.assertNotIn('x-object-meta-test-meta1', resp)
- @test.idempotent_id('f726174b-2ded-4708-bff7-729d12ce1f84')
+ @decorators.idempotent_id('f726174b-2ded-4708-bff7-729d12ce1f84')
def test_update_object_metadata_with_create_and_remove_metadata(self):
# creation and deletion of metadata with one request
object_name = data_utils.rand_name(name='TestObject')
@@ -389,7 +390,7 @@
self.assertIn('x-object-meta-test-meta2', resp)
self.assertEqual(resp['x-object-meta-test-meta2'], 'Meta2')
- @test.idempotent_id('08854588-6449-4bb7-8cca-f2e1040f5e6f')
+ @decorators.idempotent_id('08854588-6449-4bb7-8cca-f2e1040f5e6f')
def test_update_object_metadata_with_x_object_manifest(self):
# update object metadata with x_object_manifest
@@ -416,7 +417,7 @@
self.assertIn('x-object-manifest', resp)
self.assertNotEqual(len(resp['x-object-manifest']), 0)
- @test.idempotent_id('0dbbe89c-6811-4d84-a2df-eca2bdd40c0e')
+ @decorators.idempotent_id('0dbbe89c-6811-4d84-a2df-eca2bdd40c0e')
def test_update_object_metadata_with_x_object_metakey(self):
# update object metadata with a blank value of metadata
object_name, _ = self.create_object(self.container_name)
@@ -435,7 +436,7 @@
self.assertIn('x-object-meta-test-meta', resp)
self.assertEqual(resp['x-object-meta-test-meta'], '')
- @test.idempotent_id('9a88dca4-b684-425b-806f-306cd0e57e42')
+ @decorators.idempotent_id('9a88dca4-b684-425b-806f-306cd0e57e42')
def test_update_object_metadata_with_x_remove_object_metakey(self):
# update object metadata with a blank value of remove metadata
object_name = data_utils.rand_name(name='TestObject')
@@ -460,7 +461,7 @@
self.assertNotIn('x-object-meta-test-meta', resp)
@test.attr(type='smoke')
- @test.idempotent_id('9a447cf6-de06-48de-8226-a8c6ed31caf2')
+ @decorators.idempotent_id('9a447cf6-de06-48de-8226-a8c6ed31caf2')
def test_list_object_metadata(self):
# get object metadata
object_name = data_utils.rand_name(name='TestObject')
@@ -478,7 +479,7 @@
self.assertIn('x-object-meta-test-meta', resp)
self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
- @test.idempotent_id('170fb90e-f5c3-4b1f-ae1b-a18810821172')
+ @decorators.idempotent_id('170fb90e-f5c3-4b1f-ae1b-a18810821172')
def test_list_no_object_metadata(self):
# get empty list of object metadata
object_name, _ = self.create_object(self.container_name)
@@ -489,7 +490,7 @@
self.assertHeaders(resp, 'Object', 'HEAD')
self.assertNotIn('x-object-meta-', str(resp))
- @test.idempotent_id('23a3674c-d6de-46c3-86af-ff92bfc8a3da')
+ @decorators.idempotent_id('23a3674c-d6de-46c3-86af-ff92bfc8a3da')
def test_list_object_metadata_with_x_object_manifest(self):
# get object metadata with x_object_manifest
@@ -530,7 +531,7 @@
'%s/%s' % (self.container_name, object_name))
@test.attr(type='smoke')
- @test.idempotent_id('02610ba7-86b7-4272-9ed8-aa8d417cb3cd')
+ @decorators.idempotent_id('02610ba7-86b7-4272-9ed8-aa8d417cb3cd')
def test_get_object(self):
# retrieve object's data (in response body)
@@ -543,7 +544,7 @@
self.assertEqual(body, data)
- @test.idempotent_id('005f9bf6-e06d-41ec-968e-96c78e0b1d82')
+ @decorators.idempotent_id('005f9bf6-e06d-41ec-968e-96c78e0b1d82')
def test_get_object_with_metadata(self):
# get object with metadata
object_name = data_utils.rand_name(name='TestObject')
@@ -562,7 +563,7 @@
self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
self.assertEqual(body, data)
- @test.idempotent_id('05a1890e-7db9-4a6c-90a8-ce998a2bddfa')
+ @decorators.idempotent_id('05a1890e-7db9-4a6c-90a8-ce998a2bddfa')
def test_get_object_with_range(self):
# get object with range
object_name = data_utils.rand_name(name='TestObject')
@@ -580,7 +581,7 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data[rand_num - 3: rand_num])
- @test.idempotent_id('11b4515b-7ba7-4ca8-8838-357ded86fc10')
+ @decorators.idempotent_id('11b4515b-7ba7-4ca8-8838-357ded86fc10')
def test_get_object_with_x_object_manifest(self):
# get object with x_object_manifest
@@ -623,7 +624,7 @@
self.assertEqual(''.join(data_segments), body.decode())
- @test.idempotent_id('c05b4013-e4de-47af-be84-e598062b16fc')
+ @decorators.idempotent_id('c05b4013-e4de-47af-be84-e598062b16fc')
def test_get_object_with_if_match(self):
# get object with if_match
object_name = data_utils.rand_name(name='TestObject')
@@ -643,7 +644,7 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.idempotent_id('be133639-e5d2-4313-9b1f-2d59fc054a16')
+ @decorators.idempotent_id('be133639-e5d2-4313-9b1f-2d59fc054a16')
def test_get_object_with_if_modified_since(self):
# get object with if_modified_since
object_name = data_utils.rand_name(name='TestObject')
@@ -663,7 +664,7 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.idempotent_id('641500d5-1612-4042-a04d-01fc4528bc30')
+ @decorators.idempotent_id('641500d5-1612-4042-a04d-01fc4528bc30')
def test_get_object_with_if_none_match(self):
# get object with if_none_match
object_name = data_utils.rand_name(name='TestObject')
@@ -685,7 +686,7 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.idempotent_id('0aa1201c-10aa-467a-bee7-63cbdd463152')
+ @decorators.idempotent_id('0aa1201c-10aa-467a-bee7-63cbdd463152')
def test_get_object_with_if_unmodified_since(self):
# get object with if_unmodified_since
object_name, data = self.create_object(self.container_name)
@@ -700,7 +701,7 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.idempotent_id('94587078-475f-48f9-a40f-389c246e31cd')
+ @decorators.idempotent_id('94587078-475f-48f9-a40f-389c246e31cd')
def test_get_object_with_x_newest(self):
# get object with x_newest
object_name, data = self.create_object(self.container_name)
@@ -713,7 +714,7 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.idempotent_id('1a9ab572-1b66-4981-8c21-416e2a5e6011')
+ @decorators.idempotent_id('1a9ab572-1b66-4981-8c21-416e2a5e6011')
def test_copy_object_in_same_container(self):
# create source object
src_object_name = data_utils.rand_name(name='SrcObject')
@@ -737,7 +738,7 @@
dst_object_name)
self.assertEqual(body, src_data)
- @test.idempotent_id('2248abba-415d-410b-9c30-22dff9cd6e67')
+ @decorators.idempotent_id('2248abba-415d-410b-9c30-22dff9cd6e67')
def test_copy_object_to_itself(self):
# change the content type of an existing object
@@ -758,7 +759,7 @@
object_name)
self.assertEqual(resp['content-type'], metadata['content-type'])
- @test.idempotent_id('06f90388-2d0e-40aa-934c-e9a8833e958a')
+ @decorators.idempotent_id('06f90388-2d0e-40aa-934c-e9a8833e958a')
def test_copy_object_2d_way(self):
# create source object
src_object_name = data_utils.rand_name(name='SrcObject')
@@ -782,7 +783,7 @@
# check data
self._check_copied_obj(dst_object_name, src_data)
- @test.idempotent_id('aa467252-44f3-472a-b5ae-5b57c3c9c147')
+ @decorators.idempotent_id('aa467252-44f3-472a-b5ae-5b57c3c9c147')
def test_copy_object_across_containers(self):
# create a container to use as a source container
src_container_name = data_utils.rand_name(name='TestSourceContainer')
@@ -821,7 +822,7 @@
self.assertIn(actual_meta_key, resp)
self.assertEqual(resp[actual_meta_key], meta_value)
- @test.idempotent_id('5a9e2cc6-85b6-46fc-916d-0cbb7a88e5fd')
+ @decorators.idempotent_id('5a9e2cc6-85b6-46fc-916d-0cbb7a88e5fd')
def test_copy_object_with_x_fresh_metadata(self):
# create source object
metadata = {'x-object-meta-src': 'src_value'}
@@ -842,7 +843,7 @@
# check that destination object does NOT have any object-meta
self._check_copied_obj(dst_object_name, data, not_in_meta=["src"])
- @test.idempotent_id('a28a8b99-e701-4d7e-9d84-3b66f121460b')
+ @decorators.idempotent_id('a28a8b99-e701-4d7e-9d84-3b66f121460b')
def test_copy_object_with_x_object_metakey(self):
# create source object
metadata = {'x-object-meta-src': 'src_value'}
@@ -865,7 +866,7 @@
# check destination object
self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
- @test.idempotent_id('edabedca-24c3-4322-9b70-d6d9f942a074')
+ @decorators.idempotent_id('edabedca-24c3-4322-9b70-d6d9f942a074')
def test_copy_object_with_x_object_meta(self):
# create source object
metadata = {'x-object-meta-src': 'src_value'}
@@ -888,7 +889,7 @@
# check destination object
self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
- @test.idempotent_id('e3e6a64a-9f50-4955-b987-6ce6767c97fb')
+ @decorators.idempotent_id('e3e6a64a-9f50-4955-b987-6ce6767c97fb')
def test_object_upload_in_segments(self):
# create object
object_name = data_utils.rand_name(name='LObject')
@@ -930,7 +931,7 @@
self.container_name, object_name)
self.assertEqual(''.join(data_segments), body.decode())
- @test.idempotent_id('50d01f12-526f-4360-9ac2-75dd508d7b68')
+ @decorators.idempotent_id('50d01f12-526f-4360-9ac2-75dd508d7b68')
def test_get_object_if_different(self):
# http://en.wikipedia.org/wiki/HTTP_ETag
# Make a conditional request for an object using the If-None-Match
@@ -984,7 +985,7 @@
self.delete_containers([self.container_name])
super(PublicObjectTest, self).tearDown()
- @test.idempotent_id('07c9cf95-c0d4-4b49-b9c8-0ef2c9b27193')
+ @decorators.idempotent_id('07c9cf95-c0d4-4b49-b9c8-0ef2c9b27193')
def test_access_public_container_object_without_using_creds(self):
# make container public-readable and access an object in it object
# anonymously, without using credentials
@@ -1021,7 +1022,7 @@
self.assertEqual(body, data)
- @test.idempotent_id('54e2a2fe-42dc-491b-8270-8e4217dd4cdc')
+ @decorators.idempotent_id('54e2a2fe-42dc-491b-8270-8e4217dd4cdc')
def test_access_public_object_with_another_user_creds(self):
# make container public-readable and access an object in it using
# another user's credentials
diff --git a/tempest/api/object_storage/test_object_slo.py b/tempest/api/object_storage/test_object_slo.py
index f9c1148..8ed9bf8 100644
--- a/tempest/api/object_storage/test_object_slo.py
+++ b/tempest/api/object_storage/test_object_slo.py
@@ -20,6 +20,7 @@
from tempest.common import custom_matchers
from tempest.common.utils import data_utils
from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
from tempest import test
# Each segment, except for the final one, must be at least 1 megabyte
@@ -105,7 +106,7 @@
resp['etag'] = resp['etag'].strip('"')
self.assertHeaders(resp, 'Object', method)
- @test.idempotent_id('2c3f24a6-36e8-4711-9aa2-800ee1fc7b5b')
+ @decorators.idempotent_id('2c3f24a6-36e8-4711-9aa2-800ee1fc7b5b')
@test.requires_ext(extension='slo', service='object')
def test_upload_manifest(self):
# create static large object from multipart manifest
@@ -120,7 +121,7 @@
self._assertHeadersSLO(resp, 'PUT')
- @test.idempotent_id('e69ad766-e1aa-44a2-bdd2-bf62c09c1456')
+ @decorators.idempotent_id('e69ad766-e1aa-44a2-bdd2-bf62c09c1456')
@test.requires_ext(extension='slo', service='object')
def test_list_large_object_metadata(self):
# list static large object metadata using multipart manifest
@@ -132,7 +133,7 @@
self._assertHeadersSLO(resp, 'HEAD')
- @test.idempotent_id('49bc49bc-dd1b-4c0f-904e-d9f10b830ee8')
+ @decorators.idempotent_id('49bc49bc-dd1b-4c0f-904e-d9f10b830ee8')
@test.requires_ext(extension='slo', service='object')
def test_retrieve_large_object(self):
# list static large object using multipart manifest
@@ -147,7 +148,7 @@
sum_data = self.content + self.content
self.assertEqual(body, sum_data)
- @test.idempotent_id('87b6dfa1-abe9-404d-8bf0-6c3751e6aa77')
+ @decorators.idempotent_id('87b6dfa1-abe9-404d-8bf0-6c3751e6aa77')
@test.requires_ext(extension='slo', service='object')
def test_delete_large_object(self):
# delete static large object using multipart manifest
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index bd0d213..5e3c9f7 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -20,6 +20,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest import test
@@ -85,7 +86,7 @@
return url
- @test.idempotent_id('f91c96d4-1230-4bba-8eb9-84476d18d991')
+ @decorators.idempotent_id('f91c96d4-1230-4bba-8eb9-84476d18d991')
@test.requires_ext(extension='tempurl', service='object')
def test_get_object_using_temp_url(self):
expires = self._get_expiry_date()
@@ -104,7 +105,7 @@
resp, body = self.object_client.head(url)
self.assertHeaders(resp, 'Object', 'HEAD')
- @test.idempotent_id('671f9583-86bd-4128-a034-be282a68c5d8')
+ @decorators.idempotent_id('671f9583-86bd-4128-a034-be282a68c5d8')
@test.requires_ext(extension='tempurl', service='object')
def test_get_object_using_temp_url_key_2(self):
key2 = 'Meta2-'
@@ -128,7 +129,7 @@
resp, body = self.object_client.get(url)
self.assertEqual(body, self.content)
- @test.idempotent_id('9b08dade-3571-4152-8a4f-a4f2a873a735')
+ @decorators.idempotent_id('9b08dade-3571-4152-8a4f-a4f2a873a735')
@test.requires_ext(extension='tempurl', service='object')
def test_put_object_using_temp_url(self):
new_data = data_utils.random_bytes(size=len(self.object_name))
@@ -154,7 +155,7 @@
_, body = self.object_client.get(url)
self.assertEqual(body, new_data)
- @test.idempotent_id('249a0111-5ad3-4534-86a7-1993d55f9185')
+ @decorators.idempotent_id('249a0111-5ad3-4534-86a7-1993d55f9185')
@test.requires_ext(extension='tempurl', service='object')
def test_head_object_using_temp_url(self):
expires = self._get_expiry_date()
@@ -168,7 +169,7 @@
resp, body = self.object_client.head(url)
self.assertHeaders(resp, 'Object', 'HEAD')
- @test.idempotent_id('9d9cfd90-708b-465d-802c-e4a8090b823d')
+ @decorators.idempotent_id('9d9cfd90-708b-465d-802c-e4a8090b823d')
@test.requires_ext(extension='tempurl', service='object')
def test_get_object_using_temp_url_with_inline_query_parameter(self):
expires = self._get_expiry_date()
diff --git a/tempest/api/object_storage/test_object_temp_url_negative.py b/tempest/api/object_storage/test_object_temp_url_negative.py
index df7a7f6..d0e0935 100644
--- a/tempest/api/object_storage/test_object_temp_url_negative.py
+++ b/tempest/api/object_storage/test_object_temp_url_negative.py
@@ -20,6 +20,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -91,7 +92,7 @@
return url
@test.attr(type=['negative'])
- @test.idempotent_id('5a583aca-c804-41ba-9d9a-e7be132bdf0b')
+ @decorators.idempotent_id('5a583aca-c804-41ba-9d9a-e7be132bdf0b')
@test.requires_ext(extension='tempurl', service='object')
def test_get_object_after_expiration_time(self):
diff --git a/tempest/api/object_storage/test_object_version.py b/tempest/api/object_storage/test_object_version.py
index 6d064a2..1b12dac 100644
--- a/tempest/api/object_storage/test_object_version.py
+++ b/tempest/api/object_storage/test_object_version.py
@@ -18,7 +18,7 @@
from tempest.api.object_storage import base
from tempest.common.utils import data_utils
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -44,7 +44,7 @@
header_value = resp.get('x-versions-location', 'Missing Header')
self.assertEqual(header_value, versioned)
- @test.idempotent_id('a151e158-dcbf-4a1f-a1e7-46cd65895a6f')
+ @decorators.idempotent_id('a151e158-dcbf-4a1f-a1e7-46cd65895a6f')
@testtools.skipIf(
not CONF.object_storage_feature_enabled.object_versioning,
'Object-versioning is disabled')
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 43f919a..45bbc11 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -25,6 +25,10 @@
message = "Server %(server_id)s failed to build and is in ERROR status"
+class SnapshotNotFoundException(exceptions.TempestException):
+ message = "Server snapshot image %(image_id)s not found."
+
+
class ImageKilledException(exceptions.TempestException):
message = "Image %(image_id)s 'killed' while waiting for '%(status)s'"
diff --git a/tempest/lib/services/identity/v3/roles_client.py b/tempest/lib/services/identity/v3/roles_client.py
index f1339dd..0df23ce 100644
--- a/tempest/lib/services/identity/v3/roles_client.py
+++ b/tempest/lib/services/identity/v3/roles_client.py
@@ -190,3 +190,40 @@
(domain_id, group_id, role_id))
self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp)
+
+ def create_role_inference_rule(self, prior_role, implies_role):
+ """Create a role inference rule."""
+ resp, body = self.put('roles/%s/implies/%s' %
+ (prior_role, implies_role), None)
+ self.expected_success(201, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def show_role_inference_rule(self, prior_role, implies_role):
+ """Get a role inference rule."""
+ resp, body = self.get('roles/%s/implies/%s' %
+ (prior_role, implies_role))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_role_inferences_rules(self, prior_role):
+ """List the inferences rules from a role."""
+ resp, body = self.get('roles/%s/implies' % prior_role)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def check_role_inference_rule(self, prior_role, implies_role):
+ """Check a role inference rule."""
+ resp, body = self.head('roles/%s/implies/%s' %
+ (prior_role, implies_role))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
+
+ def delete_role_inference_rule(self, prior_role, implies_role):
+ """Delete a role inference rule."""
+ resp, body = self.delete('roles/%s/implies/%s' %
+ (prior_role, implies_role))
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 076ac81..5422e16 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -708,13 +708,11 @@
raise cls.skipException('Neutron not available')
def _create_network(self, networks_client=None,
- routers_client=None, tenant_id=None,
+ tenant_id=None,
namestart='network-smoke-',
port_security_enabled=True):
if not networks_client:
networks_client = self.networks_client
- if not routers_client:
- routers_client = self.routers_client
if not tenant_id:
tenant_id = networks_client.tenant_id
name = data_utils.rand_name(namestart)
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 8de3561..50fe9c8 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -15,6 +15,7 @@
from tempest.common import tempest_fixtures as fixtures
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -95,7 +96,7 @@
self.assertEqual(aggregate['availability_zone'], availability_zone)
return aggregate
- @test.idempotent_id('cb2b4c4f-0c7c-4164-bdde-6285b302a081')
+ @decorators.idempotent_id('cb2b4c4f-0c7c-4164-bdde-6285b302a081')
@test.services('compute')
def test_aggregate_basic_ops(self):
self.useFixture(fixtures.LockFixture('availability_zone'))
diff --git a/tempest/scenario/test_encrypted_cinder_volumes.py b/tempest/scenario/test_encrypted_cinder_volumes.py
index 1659ebe..77bd10f 100644
--- a/tempest/scenario/test_encrypted_cinder_volumes.py
+++ b/tempest/scenario/test_encrypted_cinder_volumes.py
@@ -14,6 +14,7 @@
# under the License.
from tempest import config
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -62,7 +63,7 @@
attached_volume = self.nova_volume_attach(server, volume)
self.nova_volume_detach(server, attached_volume)
- @test.idempotent_id('79165fb4-5534-4b9d-8429-97ccffb8f86e')
+ @decorators.idempotent_id('79165fb4-5534-4b9d-8429-97ccffb8f86e')
@test.services('compute', 'volume', 'image')
def test_encrypted_cinder_volumes_luks(self):
server = self.launch_instance()
@@ -71,7 +72,7 @@
volume_type='luks')
self.attach_detach_volume(server, volume)
- @test.idempotent_id('cbc752ed-b716-4717-910f-956cce965722')
+ @decorators.idempotent_id('cbc752ed-b716-4717-910f-956cce965722')
@test.services('compute', 'volume', 'image')
def test_encrypted_cinder_volumes_cryptsetup(self):
server = self.launch_instance()
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index c454ae2..4b1c362 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -17,6 +17,7 @@
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
from tempest.lib import exceptions
from tempest.scenario import manager
from tempest import test
@@ -97,7 +98,7 @@
address['addr'] == floating_ip['ip']):
return address
- @test.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
+ @decorators.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
@test.services('compute', 'volume', 'image', 'network')
def test_minimum_basic_scenario(self):
image = self.glance_image_create()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 1279484..7843531 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -17,6 +17,7 @@
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -104,7 +105,7 @@
body = self.admin_servers_client.show_server(server_id)['server']
return body['OS-EXT-SRV-ATTR:host']
- @test.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
+ @decorators.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
@test.services('compute', 'network')
def test_server_connectivity_stop_start(self):
keypair = self.create_keypair()
@@ -119,7 +120,7 @@
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- @test.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
+ @decorators.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
@test.services('compute', 'network')
def test_server_connectivity_reboot(self):
keypair = self.create_keypair()
@@ -129,7 +130,7 @@
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- @test.idempotent_id('88a529c2-1daa-4c85-9aec-d541ba3eb699')
+ @decorators.idempotent_id('88a529c2-1daa-4c85-9aec-d541ba3eb699')
@test.services('compute', 'network')
def test_server_connectivity_rebuild(self):
keypair = self.create_keypair()
@@ -141,7 +142,7 @@
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- @test.idempotent_id('2b2642db-6568-4b35-b812-eceed3fa20ce')
+ @decorators.idempotent_id('2b2642db-6568-4b35-b812-eceed3fa20ce')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
@test.services('compute', 'network')
@@ -158,7 +159,7 @@
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- @test.idempotent_id('5cdf9499-541d-4923-804e-b9a60620a7f0')
+ @decorators.idempotent_id('5cdf9499-541d-4923-804e-b9a60620a7f0')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
@test.services('compute', 'network')
@@ -175,7 +176,7 @@
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- @test.idempotent_id('719eb59d-2f42-4b66-b8b1-bb1254473967')
+ @decorators.idempotent_id('719eb59d-2f42-4b66-b8b1-bb1254473967')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize is not available.')
@test.services('compute', 'network')
@@ -195,7 +196,7 @@
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- @test.idempotent_id('a4858f6c-401e-4155-9a49-d5cd053d1a2f')
+ @decorators.idempotent_id('a4858f6c-401e-4155-9a49-d5cd053d1a2f')
@testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
'Cold migration is not available.')
@testtools.skipUnless(CONF.compute.min_compute_nodes > 1,
@@ -220,7 +221,7 @@
self.assertNotEqual(src_host, dst_host)
- @test.idempotent_id('25b188d7-0183-4b1e-a11d-15840c8e2fd6')
+ @decorators.idempotent_id('25b188d7-0183-4b1e-a11d-15840c8e2fd6')
@testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
'Cold migration is not available.')
@testtools.skipUnless(CONF.compute.min_compute_nodes > 1,
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index a5411bf..c324261 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -357,7 +357,7 @@
raise
@test.attr(type='smoke')
- @test.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
+ @decorators.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
@test.services('compute', 'network')
def test_network_basic_ops(self):
"""Basic network operation test
@@ -409,7 +409,7 @@
msg="after re-associate "
"floating ip")
- @test.idempotent_id('b158ea55-472e-4086-8fa9-c64ac0c6c1d0')
+ @decorators.idempotent_id('b158ea55-472e-4086-8fa9-c64ac0c6c1d0')
@testtools.skipUnless(test.is_extension_enabled('net-mtu', 'network'),
'No way to calculate MTU for networks')
@test.services('compute', 'network')
@@ -419,7 +419,7 @@
self.check_public_network_connectivity(
should_connect=True, mtu=self.network['mtu'])
- @test.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
+ @decorators.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
@testtools.skipIf(CONF.network.shared_physical_network,
'Connectivity can only be tested when in a '
'multitenant network environment')
@@ -472,7 +472,7 @@
self._check_network_internal_connectivity(network=self.new_net,
should_connect=True)
- @test.idempotent_id('c5adff73-e961-41f1-b4a9-343614f18cfa')
+ @decorators.idempotent_id('c5adff73-e961-41f1-b4a9-343614f18cfa')
@testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
'NIC hotplug not available')
@testtools.skipIf(CONF.network.port_vnic_type in ['direct', 'macvtap'],
@@ -495,7 +495,7 @@
self._hotplug_server()
self._check_network_internal_connectivity(network=self.new_net)
- @test.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
+ @decorators.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
@testtools.skipIf(CONF.network.shared_physical_network,
'Router state can be altered only with multitenant '
'networks capabilities')
@@ -527,7 +527,7 @@
should_connect=True, msg="after updating "
"admin_state_up of router to True")
- @test.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
+ @decorators.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
@testtools.skipIf(CONF.network.shared_physical_network,
'network isolation not available')
@testtools.skipUnless(CONF.scenario.dhcp_client,
@@ -610,7 +610,7 @@
msg="DHCP renewal failed to fetch "
"new DNS nameservers")
- @test.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
+ @decorators.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
@testtools.skipUnless(CONF.network_feature_enabled.port_admin_state_change,
"Changing a port's admin state is not supported "
"by the test environment")
@@ -657,7 +657,7 @@
self._check_remote_connectivity(ssh_client, dest=server_pip,
should_succeed=True)
- @test.idempotent_id('759462e1-8535-46b0-ab3a-33aa45c55aaa')
+ @decorators.idempotent_id('759462e1-8535-46b0-ab3a-33aa45c55aaa')
@test.services('compute', 'network')
def test_preserve_preexisting_port(self):
"""Test preserve pre-existing port
@@ -708,7 +708,7 @@
self.assertEqual(port['id'], port_list[0]['id'])
@test.requires_ext(service='network', extension='l3_agent_scheduler')
- @test.idempotent_id('2e788c46-fb3f-4ac9-8f82-0561555bea73')
+ @decorators.idempotent_id('2e788c46-fb3f-4ac9-8f82-0561555bea73')
@test.services('compute', 'network')
def test_router_rescheduling(self):
"""Tests that router can be removed from agent and add to a new agent.
@@ -785,7 +785,7 @@
@test.requires_ext(service='network', extension='port-security')
@testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
'NIC hotplug not available')
- @test.idempotent_id('7c0bb1a2-d053-49a4-98f9-ca1a1d849f63')
+ @decorators.idempotent_id('7c0bb1a2-d053-49a4-98f9-ca1a1d849f63')
@test.services('compute', 'network')
def test_port_security_macspoofing_port(self):
"""Tests port_security extension enforces mac spoofing
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 7acf107..f235934 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -16,10 +16,10 @@
from tempest import config
from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
-
CONF = config.CONF
@@ -211,48 +211,48 @@
)
@test.attr(type='slow')
- @test.idempotent_id('2c92df61-29f0-4eaa-bee3-7c65bef62a43')
+ @decorators.idempotent_id('2c92df61-29f0-4eaa-bee3-7c65bef62a43')
@test.services('compute', 'network')
def test_slaac_from_os(self):
self._prepare_and_test(address6_mode='slaac')
@test.attr(type='slow')
- @test.idempotent_id('d7e1f858-187c-45a6-89c9-bdafde619a9f')
+ @decorators.idempotent_id('d7e1f858-187c-45a6-89c9-bdafde619a9f')
@test.services('compute', 'network')
def test_dhcp6_stateless_from_os(self):
self._prepare_and_test(address6_mode='dhcpv6-stateless')
@test.attr(type='slow')
- @test.idempotent_id('7ab23f41-833b-4a16-a7c9-5b42fe6d4123')
+ @decorators.idempotent_id('7ab23f41-833b-4a16-a7c9-5b42fe6d4123')
@test.services('compute', 'network')
def test_multi_prefix_dhcpv6_stateless(self):
self._prepare_and_test(address6_mode='dhcpv6-stateless', n_subnets6=2)
@test.attr(type='slow')
- @test.idempotent_id('dec222b1-180c-4098-b8c5-cc1b8342d611')
+ @decorators.idempotent_id('dec222b1-180c-4098-b8c5-cc1b8342d611')
@test.services('compute', 'network')
def test_multi_prefix_slaac(self):
self._prepare_and_test(address6_mode='slaac', n_subnets6=2)
@test.attr(type='slow')
- @test.idempotent_id('b6399d76-4438-4658-bcf5-0d6c8584fde2')
+ @decorators.idempotent_id('b6399d76-4438-4658-bcf5-0d6c8584fde2')
@test.services('compute', 'network')
def test_dualnet_slaac_from_os(self):
self._prepare_and_test(address6_mode='slaac', dualnet=True)
@test.attr(type='slow')
- @test.idempotent_id('76f26acd-9688-42b4-bc3e-cd134c4cb09e')
+ @decorators.idempotent_id('76f26acd-9688-42b4-bc3e-cd134c4cb09e')
@test.services('compute', 'network')
def test_dualnet_dhcp6_stateless_from_os(self):
self._prepare_and_test(address6_mode='dhcpv6-stateless', dualnet=True)
- @test.idempotent_id('cf1c4425-766b-45b8-be35-e2959728eb00')
+ @decorators.idempotent_id('cf1c4425-766b-45b8-be35-e2959728eb00')
@test.services('compute', 'network')
def test_dualnet_multi_prefix_dhcpv6_stateless(self):
self._prepare_and_test(address6_mode='dhcpv6-stateless', n_subnets6=2,
dualnet=True)
- @test.idempotent_id('9178ad42-10e4-47e9-8987-e02b170cc5cd')
+ @decorators.idempotent_id('9178ad42-10e4-47e9-8987-e02b170cc5cd')
@test.services('compute', 'network')
def test_dualnet_multi_prefix_slaac(self):
self._prepare_and_test(address6_mode='slaac', n_subnets6=2,
diff --git a/tempest/scenario/test_object_storage_basic_ops.py b/tempest/scenario/test_object_storage_basic_ops.py
index 1d2b2b6..c989e01 100644
--- a/tempest/scenario/test_object_storage_basic_ops.py
+++ b/tempest/scenario/test_object_storage_basic_ops.py
@@ -13,12 +13,13 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
class TestObjectStorageBasicOps(manager.ObjectStorageScenarioTest):
- @test.idempotent_id('b920faf1-7b8a-4657-b9fe-9c4512bfb381')
+ @decorators.idempotent_id('b920faf1-7b8a-4657-b9fe-9c4512bfb381')
@test.services('object_storage')
def test_swift_basic_ops(self):
"""Test swift basic ops.
@@ -44,7 +45,7 @@
not_present_obj=[obj_name])
self.delete_container(container_name)
- @test.idempotent_id('916c7111-cb1f-44b2-816d-8f760e4ea910')
+ @decorators.idempotent_id('916c7111-cb1f-44b2-816d-8f760e4ea910')
@test.services('object_storage')
def test_swift_acl_anonymous_download(self):
"""This test will cover below steps:
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index f8c5c0a..07f9d0f 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -18,6 +18,7 @@
from tempest.common.utils import data_utils
from tempest.common.utils import net_info
from tempest import config
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -459,7 +460,7 @@
subnet_id = tenant.subnet['id']
self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
- @test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
+ @decorators.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
@test.services('compute', 'network')
def test_cross_tenant_traffic(self):
if not self.credentials_provider.is_multi_tenant():
@@ -480,7 +481,7 @@
self._log_console_output(servers=tenant.servers)
raise
- @test.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
+ @decorators.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
@test.services('compute', 'network')
def test_in_tenant_traffic(self):
try:
@@ -494,7 +495,7 @@
self._log_console_output(servers=tenant.servers)
raise
- @test.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
+ @decorators.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
@test.services('compute', 'network')
def test_port_update_new_security_group(self):
"""Verifies the traffic after updating the vm port
@@ -547,7 +548,7 @@
self._log_console_output(servers=tenant.servers)
raise
- @test.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
+ @decorators.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
@test.services('compute', 'network')
def test_multiple_security_groups(self):
"""Verify multiple security groups and checks that rules
@@ -580,7 +581,7 @@
should_connect=True)
@test.requires_ext(service='network', extension='port-security')
- @test.idempotent_id('7c811dcc-263b-49a3-92d2-1b4d8405f50c')
+ @decorators.idempotent_id('7c811dcc-263b-49a3-92d2-1b4d8405f50c')
@test.services('compute', 'network')
def test_port_security_disable_security_group(self):
"""Verify the default security group rules is disabled."""
@@ -619,7 +620,7 @@
raise
@test.requires_ext(service='network', extension='port-security')
- @test.idempotent_id('13ccf253-e5ad-424b-9c4a-97b88a026699')
+ @decorators.idempotent_id('13ccf253-e5ad-424b-9c4a-97b88a026699')
@testtools.skipUnless(
CONF.compute_feature_enabled.allow_port_security_disabled,
'Port security must be enabled.')
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 504d72b..6cc5cd3 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -18,6 +18,7 @@
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -47,7 +48,7 @@
cls.set_network_resources()
super(TestServerAdvancedOps, cls).setup_credentials()
- @test.idempotent_id('e6c28180-7454-4b59-b188-0257af08a63b')
+ @decorators.idempotent_id('e6c28180-7454-4b59-b188-0257af08a63b')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize is not available.')
@test.services('compute', 'volume')
@@ -68,7 +69,7 @@
waiters.wait_for_server_status(self.servers_client, instance_id,
'ACTIVE')
- @test.idempotent_id('949da7d5-72c8-4808-8802-e3d70df98e2c')
+ @decorators.idempotent_id('949da7d5-72c8-4808-8802-e3d70df98e2c')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
@test.services('compute')
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 4a938f9..1af68ff 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -20,6 +20,7 @@
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
from tempest.lib import exceptions
from tempest.scenario import manager
from tempest import test
@@ -124,7 +125,7 @@
# TODO(clarkb) construct network_data from known network
# instance info and do direct comparison.
- @test.idempotent_id('7fff3fb3-91d8-4fd0-bd7d-0204f1f180ba')
+ @decorators.idempotent_id('7fff3fb3-91d8-4fd0-bd7d-0204f1f180ba')
@test.attr(type='smoke')
@test.services('compute', 'network')
def test_server_basic_ops(self):
diff --git a/tempest/scenario/test_server_multinode.py b/tempest/scenario/test_server_multinode.py
index 170d220..df83063 100644
--- a/tempest/scenario/test_server_multinode.py
+++ b/tempest/scenario/test_server_multinode.py
@@ -15,6 +15,7 @@
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions
from tempest.scenario import manager
from tempest import test
@@ -43,7 +44,7 @@
# scheduler hint, which is admin_only by default
cls.servers_client = cls.admin_manager.servers_client
- @test.idempotent_id('9cecbe35-b9d4-48da-a37e-7ce70aa43d30')
+ @decorators.idempotent_id('9cecbe35-b9d4-48da-a37e-7ce70aa43d30')
@test.attr(type='smoke')
@test.services('compute', 'network')
def test_schedule_to_all_nodes(self):
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index 7f04b0d..2264a98 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -16,6 +16,7 @@
from tempest.common import compute
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -73,12 +74,12 @@
private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp2)
- @test.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
+ @decorators.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
@test.services('compute', 'network', 'image')
def test_shelve_instance(self):
self._create_server_then_shelve_and_unshelve()
- @test.idempotent_id('c1b6318c-b9da-490b-9c67-9339b627271f')
+ @decorators.idempotent_id('c1b6318c-b9da-490b-9c67-9339b627271f')
@test.services('compute', 'volume', 'network', 'image')
def test_shelve_volume_backed_instance(self):
self._create_server_then_shelve_and_unshelve(boot_from_volume=True)
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 47c6e8d..374cdba 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -14,6 +14,7 @@
# under the License.
from tempest import config
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -37,7 +38,7 @@
if not CONF.compute_feature_enabled.snapshot:
raise cls.skipException("Snapshotting is not available.")
- @test.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
+ @decorators.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
@test.services('compute', 'network', 'image')
def test_snapshot_pattern(self):
# prepare for booting an instance
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index b10be11..a302b1c 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -95,7 +95,7 @@
raise lib_exc.TimeoutException
@decorators.skip_because(bug="1205344")
- @test.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
+ @decorators.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
@test.services('compute', 'network', 'volume', 'image')
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 9486b96..e34efca 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -15,6 +15,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -98,7 +99,7 @@
self.servers_client.delete_server(server['id'])
waiters.wait_for_server_termination(self.servers_client, server['id'])
- @test.idempotent_id('557cd2c2-4eb8-4dce-98be-f86765ff311b')
+ @decorators.idempotent_id('557cd2c2-4eb8-4dce-98be-f86765ff311b')
@test.attr(type='smoke')
@test.services('compute', 'volume', 'image')
def test_volume_boot_pattern(self):
@@ -178,7 +179,7 @@
private_key=keypair['private_key'])
self.assertEqual(timestamp, timestamp3)
- @test.idempotent_id('05795fb2-b2a7-4c9f-8fac-ff25aedb1489')
+ @decorators.idempotent_id('05795fb2-b2a7-4c9f-8fac-ff25aedb1489')
@test.services('compute', 'image', 'volume')
def test_create_server_from_volume_snapshot(self):
# Create a volume from an image
@@ -212,7 +213,7 @@
self.assertEqual(created_volume[0]['id'],
created_volume_info['attachments'][0]['volume_id'])
- @test.idempotent_id('36c34c67-7b54-4b59-b188-02a2f458a63b')
+ @decorators.idempotent_id('36c34c67-7b54-4b59-b188-02a2f458a63b')
@test.services('compute', 'volume', 'image')
def test_create_ebs_image_and_check_boot(self):
# create an instance from volume
diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py
index dfda18d..161e6f2 100644
--- a/tempest/scenario/test_volume_migrate_attached.py
+++ b/tempest/scenario/test_volume_migrate_attached.py
@@ -14,6 +14,7 @@
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.scenario import manager
from tempest import test
@@ -90,7 +91,7 @@
waiters.wait_for_volume_retype(self.volumes_client,
volume_id, new_volume_type)
- @test.idempotent_id('deadd2c2-beef-4dce-98be-f86765ff311b')
+ @decorators.idempotent_id('deadd2c2-beef-4dce-98be-f86765ff311b')
@test.services('compute', 'volume')
def test_volume_migrate_attached(self):
LOG.info("Creating keypair and security group")
diff --git a/tempest/tests/api/__init__.py b/tempest/tests/api/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/api/__init__.py
diff --git a/tempest/tests/api/compute/__init__.py b/tempest/tests/api/compute/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/api/compute/__init__.py
diff --git a/tempest/tests/api/compute/test_base.py b/tempest/tests/api/compute/test_base.py
new file mode 100644
index 0000000..a1da343
--- /dev/null
+++ b/tempest/tests/api/compute/test_base.py
@@ -0,0 +1,140 @@
+# Copyright 2017 IBM Corp.
+#
+# 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 mock
+
+from oslo_utils import uuidutils
+import six
+
+from tempest.api.compute import base as compute_base
+from tempest.common import waiters
+from tempest import exceptions
+from tempest.lib import exceptions as lib_exc
+from tempest.tests import base
+
+
+class TestBaseV2ComputeTest(base.TestCase):
+ """Unit tests for utility functions in BaseV2ComputeTest."""
+
+ @mock.patch.multiple(compute_base.BaseV2ComputeTest,
+ compute_images_client=mock.DEFAULT,
+ images=[], create=True)
+ def test_create_image_from_server_no_wait(self, compute_images_client):
+ """Tests create_image_from_server without the wait_until kwarg."""
+ # setup mocks
+ image_id = uuidutils.generate_uuid()
+ fake_image = mock.Mock(response={'location': image_id})
+ compute_images_client.create_image.return_value = fake_image
+ # call the utility method
+ image = compute_base.BaseV2ComputeTest.create_image_from_server(
+ mock.sentinel.server_id, name='fake-snapshot-name')
+ self.assertEqual(fake_image, image)
+ # make our assertions
+ compute_images_client.create_image.assert_called_once_with(
+ mock.sentinel.server_id, name='fake-snapshot-name')
+ self.assertEqual(1, len(compute_base.BaseV2ComputeTest.images))
+ self.assertEqual(image_id, compute_base.BaseV2ComputeTest.images[0])
+
+ @mock.patch.multiple(compute_base.BaseV2ComputeTest,
+ compute_images_client=mock.DEFAULT,
+ images=[], create=True)
+ @mock.patch.object(waiters, 'wait_for_image_status')
+ def test_create_image_from_server_wait_until_active(self,
+ wait_for_image_status,
+ compute_images_client):
+ """Tests create_image_from_server with wait_until='ACTIVE' kwarg."""
+ # setup mocks
+ image_id = uuidutils.generate_uuid()
+ fake_image = mock.Mock(response={'location': image_id})
+ compute_images_client.create_image.return_value = fake_image
+ compute_images_client.show_image.return_value = (
+ {'image': fake_image})
+ # call the utility method
+ image = compute_base.BaseV2ComputeTest.create_image_from_server(
+ mock.sentinel.server_id, wait_until='ACTIVE')
+ self.assertEqual(fake_image, image)
+ # make our assertions
+ wait_for_image_status.assert_called_once_with(
+ compute_images_client, image_id, 'ACTIVE')
+ compute_images_client.show_image.assert_called_once_with(image_id)
+
+ @mock.patch.multiple(compute_base.BaseV2ComputeTest,
+ compute_images_client=mock.DEFAULT,
+ servers_client=mock.DEFAULT,
+ images=[], create=True)
+ @mock.patch.object(waiters, 'wait_for_image_status',
+ side_effect=lib_exc.NotFound)
+ def _test_create_image_from_server_wait_until_active_not_found(
+ self, wait_for_image_status, compute_images_client,
+ servers_client, fault=None):
+ # setup mocks
+ image_id = uuidutils.generate_uuid()
+ fake_image = mock.Mock(response={'location': image_id})
+ compute_images_client.create_image.return_value = fake_image
+ fake_server = {'id': mock.sentinel.server_id}
+ if fault:
+ fake_server['fault'] = fault
+ servers_client.show_server.return_value = {'server': fake_server}
+ # call the utility method
+ ex = self.assertRaises(
+ exceptions.SnapshotNotFoundException,
+ compute_base.BaseV2ComputeTest.create_image_from_server,
+ mock.sentinel.server_id, wait_until='active')
+ # make our assertions
+ if fault:
+ self.assertIn(fault, six.text_type(ex))
+ else:
+ self.assertNotIn(fault, six.text_type(ex))
+ wait_for_image_status.assert_called_once_with(
+ compute_images_client, image_id, 'active')
+ servers_client.show_server.assert_called_once_with(
+ mock.sentinel.server_id)
+
+ def test_create_image_from_server_wait_until_active_not_found_no_fault(
+ self):
+ # Tests create_image_from_server with wait_until='active' kwarg and
+ # the a 404 is raised while waiting for the image status to change. In
+ # this test the server does not have a fault associated with it.
+ self._test_create_image_from_server_wait_until_active_not_found()
+
+ def test_create_image_from_server_wait_until_active_not_found_with_fault(
+ self):
+ # Tests create_image_from_server with wait_until='active' kwarg and
+ # the a 404 is raised while waiting for the image status to change. In
+ # this test the server has a fault associated with it.
+ self._test_create_image_from_server_wait_until_active_not_found(
+ fault='Lost connection to hypervisor!')
+
+ @mock.patch.multiple(compute_base.BaseV2ComputeTest,
+ compute_images_client=mock.DEFAULT,
+ images=[], create=True)
+ @mock.patch.object(waiters, 'wait_for_image_status',
+ side_effect=lib_exc.NotFound)
+ def test_create_image_from_server_wait_until_saving_not_found(
+ self, wait_for_image_status, compute_images_client):
+ # Tests create_image_from_server with wait_until='SAVING' kwarg and
+ # the a 404 is raised while waiting for the image status to change. In
+ # this case we do not get the server details and just re-raise the 404.
+ # setup mocks
+ image_id = uuidutils.generate_uuid()
+ fake_image = mock.Mock(response={'location': image_id})
+ compute_images_client.create_image.return_value = fake_image
+ # call the utility method
+ self.assertRaises(
+ lib_exc.NotFound,
+ compute_base.BaseV2ComputeTest.create_image_from_server,
+ mock.sentinel.server_id, wait_until='SAVING')
+ # make our assertions
+ wait_for_image_status.assert_called_once_with(
+ compute_images_client, image_id, 'SAVING')
diff --git a/tempest/tests/lib/services/identity/v3/test_roles_client.py b/tempest/tests/lib/services/identity/v3/test_roles_client.py
index 4f70b47..41cea85 100644
--- a/tempest/tests/lib/services/identity/v3/test_roles_client.py
+++ b/tempest/tests/lib/services/identity/v3/test_roles_client.py
@@ -52,6 +52,65 @@
FAKE_LIST_ROLES = {"roles": [FAKE_ROLE_INFO, FAKE_ROLE_INFO_2]}
+ FAKE_ROLE_INFERENCE_RULE = {
+ "role_inference": {
+ "prior_role": {
+ "id": FAKE_ROLE_ID,
+ "name": FAKE_ROLE_NAME,
+ "links": {
+ "self": "http://example.com/identity/v3/roles/%s" % (
+ FAKE_ROLE_ID)
+ }
+ },
+ "implies": {
+ "id": FAKE_ROLE_ID_2,
+ "name": FAKE_ROLE_NAME_2,
+ "links": {
+ "self": "http://example.com/identity/v3/roles/%s" % (
+ FAKE_ROLE_ID_2)
+ }
+ }
+ },
+ "links": {
+ "self": "http://example.com/identity/v3/roles/"
+ "%s/implies/%s" % (FAKE_ROLE_ID, FAKE_ROLE_ID_2)
+ }
+ }
+
+ FAKE_LIST_ROLE_INFERENCES_RULES = {
+ "role_inference": {
+ "prior_role": {
+ "id": FAKE_ROLE_ID,
+ "name": FAKE_ROLE_NAME,
+ "links": {
+ "self": "http://example.com/identity/v3/roles/%s" % (
+ FAKE_ROLE_ID)
+ }
+ },
+ "implies": [
+ {
+ "id": FAKE_ROLE_ID_2,
+ "name": FAKE_ROLE_NAME_2,
+ "links": {
+ "self": "http://example.com/identity/v3/roles/%s" % (
+ FAKE_ROLE_ID_2)
+ }
+ },
+ {
+ "id": "3",
+ "name": "test3",
+ "links": {
+ "self": "http://example.com/identity/v3/roles/3"
+ }
+ }
+ ]
+ },
+ "links": {
+ "self": "http://example.com/identity/v3/roles/"
+ "%s/implies" % FAKE_ROLE_ID
+ }
+ }
+
def setUp(self):
super(TestRolesClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
@@ -172,6 +231,33 @@
domain_id="b344506af7644f6794d9cb316600b020",
group_id="123")
+ def _test_create_role_inference_rule(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_role_inference_rule,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ self.FAKE_ROLE_INFERENCE_RULE,
+ bytes_body,
+ status=201,
+ prior_role=self.FAKE_ROLE_ID,
+ implies_role=self.FAKE_ROLE_ID_2)
+
+ def _test_show_role_inference_rule(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_role_inference_rule,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_ROLE_INFERENCE_RULE,
+ bytes_body,
+ prior_role=self.FAKE_ROLE_ID,
+ implies_role=self.FAKE_ROLE_ID_2)
+
+ def _test_list_role_inferences_rules(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_role_inferences_rules,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_ROLE_INFERENCES_RULES,
+ bytes_body,
+ prior_role=self.FAKE_ROLE_ID)
+
def test_create_role_with_str_body(self):
self._test_create_role()
@@ -319,3 +405,39 @@
group_id="123",
role_id="1234",
status=204)
+
+ def test_create_role_inference_rule_with_str_body(self):
+ self._test_create_role_inference_rule()
+
+ def test_create_role_inference_rule_with_bytes_body(self):
+ self._test_create_role_inference_rule(bytes_body=True)
+
+ def test_show_role_inference_rule_with_str_body(self):
+ self._test_show_role_inference_rule()
+
+ def test_show_role_inference_rule_with_bytes_body(self):
+ self._test_show_role_inference_rule(bytes_body=True)
+
+ def test_list_role_inferences_rules_with_str_body(self):
+ self._test_list_role_inferences_rules()
+
+ def test_list_role_inferences_rules_with_bytes_body(self):
+ self._test_list_role_inferences_rules(bytes_body=True)
+
+ def test_check_role_inference_rule(self):
+ self.check_service_client_function(
+ self.client.check_role_inference_rule,
+ 'tempest.lib.common.rest_client.RestClient.head',
+ {},
+ status=204,
+ prior_role=self.FAKE_ROLE_ID,
+ implies_role=self.FAKE_ROLE_ID_2)
+
+ def test_delete_role_inference_rule(self):
+ self.check_service_client_function(
+ self.client.delete_role_inference_rule,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ status=204,
+ prior_role=self.FAKE_ROLE_ID,
+ implies_role=self.FAKE_ROLE_ID_2)