Merge "Add test_create_is_domain_project"
diff --git a/tempest/api/image/admin/v2/test_images.py b/tempest/api/image/admin/v2/test_images.py
index f22f321..fc5ed79 100644
--- a/tempest/api/image/admin/v2/test_images.py
+++ b/tempest/api/image/admin/v2/test_images.py
@@ -19,8 +19,8 @@
 from tempest.api.image import base
 from tempest import config
 from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
-from tempest import test
 
 CONF = config.CONF
 
@@ -30,7 +30,7 @@
 
     @testtools.skipUnless(CONF.image_feature_enabled.deactivate_image,
                           'deactivate-image is not available.')
-    @test.idempotent_id('951ebe01-969f-4ea9-9898-8a3f1f442ab0')
+    @decorators.idempotent_id('951ebe01-969f-4ea9-9898-8a3f1f442ab0')
     def test_admin_deactivate_reactivate_image(self):
         # Create image by non-admin tenant
         image_name = data_utils.rand_name('image')
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index 9c211ef..4902316 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -14,13 +14,13 @@
 
 
 from tempest.api.image import base
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
-from tempest import test
 
 
 class ImageMembersTest(base.BaseV1ImageMembersTest):
 
-    @test.idempotent_id('1d6ef640-3a20-4c84-8710-d95828fdb6ad')
+    @decorators.idempotent_id('1d6ef640-3a20-4c84-8710-d95828fdb6ad')
     def test_add_image_member(self):
         image = self._create_image()
         self.image_member_client.create_image_member(image, self.alt_tenant_id)
@@ -31,7 +31,7 @@
         # get image as alt user
         self.alt_img_cli.show_image(image)
 
-    @test.idempotent_id('6a5328a5-80e8-4b82-bd32-6c061f128da9')
+    @decorators.idempotent_id('6a5328a5-80e8-4b82-bd32-6c061f128da9')
     def test_get_shared_images(self):
         image = self._create_image()
         self.image_member_client.create_image_member(image, self.alt_tenant_id)
@@ -45,7 +45,7 @@
         self.assertIn(share_image, images)
         self.assertIn(image, images)
 
-    @test.idempotent_id('a76a3191-8948-4b44-a9d6-4053e5f2b138')
+    @decorators.idempotent_id('a76a3191-8948-4b44-a9d6-4053e5f2b138')
     def test_remove_member(self):
         image_id = self._create_image()
         self.image_member_client.create_image_member(image_id,
diff --git a/tempest/api/image/v1/test_image_members_negative.py b/tempest/api/image/v1/test_image_members_negative.py
index 2538781..d1aa801 100644
--- a/tempest/api/image/v1/test_image_members_negative.py
+++ b/tempest/api/image/v1/test_image_members_negative.py
@@ -14,6 +14,7 @@
 
 from tempest.api.image 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
 
@@ -21,7 +22,7 @@
 class ImageMembersNegativeTest(base.BaseV1ImageMembersTest):
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('147a9536-18e3-45da-91ea-b037a028f364')
+    @decorators.idempotent_id('147a9536-18e3-45da-91ea-b037a028f364')
     def test_add_member_with_non_existing_image(self):
         # Add member with non existing image.
         non_exist_image = data_utils.rand_uuid()
@@ -30,7 +31,7 @@
                           non_exist_image, self.alt_tenant_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('e1559f05-b667-4f1b-a7af-518b52dc0c0f')
+    @decorators.idempotent_id('e1559f05-b667-4f1b-a7af-518b52dc0c0f')
     def test_delete_member_with_non_existing_image(self):
         # Delete member with non existing image.
         non_exist_image = data_utils.rand_uuid()
@@ -39,7 +40,7 @@
                           non_exist_image, self.alt_tenant_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('f5720333-dd69-4194-bb76-d2f048addd56')
+    @decorators.idempotent_id('f5720333-dd69-4194-bb76-d2f048addd56')
     def test_delete_member_with_non_existing_tenant(self):
         # Delete member with non existing tenant.
         image_id = self._create_image()
@@ -49,7 +50,7 @@
                           image_id, non_exist_tenant)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('f25f89e4-0b6c-453b-a853-1f80b9d7ef26')
+    @decorators.idempotent_id('f25f89e4-0b6c-453b-a853-1f80b9d7ef26')
     def test_get_image_without_membership(self):
         # Image is hidden from another tenants.
         image_id = self._create_image()
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index b22ceed..a79c18c 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -20,8 +20,8 @@
 from tempest.common.utils import data_utils
 from tempest.common import waiters
 from tempest import config
+from tempest.lib import decorators
 from tempest.lib import exceptions
-from tempest import test
 
 CONF = config.CONF
 
@@ -54,7 +54,7 @@
 class CreateRegisterImagesTest(base.BaseV1ImageTest):
     """Here we test the registration and creation of images."""
 
-    @test.idempotent_id('3027f8e6-3492-4a11-8575-c3293017af4d')
+    @decorators.idempotent_id('3027f8e6-3492-4a11-8575-c3293017af4d')
     def test_register_then_upload(self):
         # Register, then upload an image
         properties = {'prop1': 'val1'}
@@ -76,7 +76,7 @@
         self.assertIn('size', body)
         self.assertEqual(1024, body.get('size'))
 
-    @test.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
+    @decorators.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
     def test_register_remote_image(self):
         # Register a new remote image
         container_format, disk_format = get_container_and_disk_format()
@@ -93,7 +93,7 @@
         self.assertEqual(properties['key1'], 'value1')
         self.assertEqual(properties['key2'], 'value2')
 
-    @test.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
+    @decorators.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
     def test_register_http_image(self):
         container_format, disk_format = get_container_and_disk_format()
         image = self.create_image(name='New Http Image',
@@ -105,7 +105,7 @@
         waiters.wait_for_image_status(self.client, image['id'], 'active')
         self.client.show_image(image['id'])
 
-    @test.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
+    @decorators.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
     def test_register_image_with_min_ram(self):
         # Register an image with min ram
         container_format, disk_format = get_container_and_disk_format()
@@ -210,7 +210,7 @@
                                  is_public=False, data=image_file)
         return image['id']
 
-    @test.idempotent_id('246178ab-3b33-4212-9a4b-a7fe8261794d')
+    @decorators.idempotent_id('246178ab-3b33-4212-9a4b-a7fe8261794d')
     def test_index_no_params(self):
         # Simple test to see all fixture images returned
         images_list = self.client.list_images()['images']
@@ -218,7 +218,7 @@
         for image_id in self.created_images:
             self.assertIn(image_id, image_list)
 
-    @test.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
+    @decorators.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
     def test_index_disk_format(self):
         images_list = self.client.list_images(
             disk_format=self.disk_format_alt)['images']
@@ -229,7 +229,7 @@
         self.assertFalse(self.created_set - self.same_disk_format_set
                          <= result_set)
 
-    @test.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
+    @decorators.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
     def test_index_container_format(self):
         images_list = self.client.list_images(
             container_format=self.container_format)['images']
@@ -240,7 +240,7 @@
         self.assertFalse(self.created_set - self.same_container_format_set
                          <= result_set)
 
-    @test.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
+    @decorators.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
     def test_index_max_size(self):
         images_list = self.client.list_images(size_max=42)['images']
         for image in images_list:
@@ -249,7 +249,7 @@
         self.assertTrue(self.size42_set <= result_set)
         self.assertFalse(self.created_set - self.size42_set <= result_set)
 
-    @test.idempotent_id('6ffc16d0-4cbf-4401-95c8-4ac63eac34d8')
+    @decorators.idempotent_id('6ffc16d0-4cbf-4401-95c8-4ac63eac34d8')
     def test_index_min_size(self):
         images_list = self.client.list_images(size_min=142)['images']
         for image in images_list:
@@ -258,7 +258,7 @@
         self.assertTrue(self.size142_set <= result_set)
         self.assertFalse(self.size42_set <= result_set)
 
-    @test.idempotent_id('e5dc26d9-9aa2-48dd-bda5-748e1445da98')
+    @decorators.idempotent_id('e5dc26d9-9aa2-48dd-bda5-748e1445da98')
     def test_index_status_active_detail(self):
         images_list = self.client.list_images(detail=True,
                                               status='active',
@@ -271,7 +271,7 @@
             top_size = size
             self.assertEqual(image['status'], 'active')
 
-    @test.idempotent_id('097af10a-bae8-4342-bff4-edf89969ed2a')
+    @decorators.idempotent_id('097af10a-bae8-4342-bff4-edf89969ed2a')
     def test_index_name(self):
         images_list = self.client.list_images(
             detail=True,
@@ -305,7 +305,7 @@
                                  properties={'key1': 'value1'})
         return image['id']
 
-    @test.idempotent_id('01752c1c-0275-4de3-9e5b-876e44541928')
+    @decorators.idempotent_id('01752c1c-0275-4de3-9e5b-876e44541928')
     def test_list_image_metadata(self):
         # All metadata key/value pairs for an image should be returned
         resp = self.client.check_image(self.image_id)
@@ -313,7 +313,7 @@
         expected = {'key1': 'value1'}
         self.assertEqual(expected, resp_metadata['properties'])
 
-    @test.idempotent_id('d6d7649c-08ce-440d-9ea7-e3dda552f33c')
+    @decorators.idempotent_id('d6d7649c-08ce-440d-9ea7-e3dda552f33c')
     def test_update_image_metadata(self):
         # The metadata for the image should match the updated values
         req_metadata = {'key1': 'alt1', 'key2': 'value2'}
diff --git a/tempest/api/image/v1/test_images_negative.py b/tempest/api/image/v1/test_images_negative.py
index 3493cc2..abec82a 100644
--- a/tempest/api/image/v1/test_images_negative.py
+++ b/tempest/api/image/v1/test_images_negative.py
@@ -16,6 +16,7 @@
 
 from tempest.api.image 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
 
@@ -24,7 +25,7 @@
     """Here are negative tests for the deletion and creation of images."""
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('036ede36-6160-4463-8c01-c781eee6369d')
+    @decorators.idempotent_id('036ede36-6160-4463-8c01-c781eee6369d')
     def test_register_with_invalid_container_format(self):
         # Negative tests for invalid data supplied to POST /images
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
@@ -33,7 +34,7 @@
                                    'x-image-meta-disk_format': 'vhd'})
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('993face5-921d-4e84-aabf-c1bba4234a67')
+    @decorators.idempotent_id('993face5-921d-4e84-aabf-c1bba4234a67')
     def test_register_with_invalid_disk_format(self):
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           headers={'x-image-meta-name': 'test',
@@ -41,7 +42,7 @@
                                    'x-image-meta-disk_format': 'wrong'})
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('ec652588-7e3c-4b67-a2f2-0fa96f57c8fc')
+    @decorators.idempotent_id('ec652588-7e3c-4b67-a2f2-0fa96f57c8fc')
     def test_delete_non_existent_image(self):
         # Return an error while trying to delete a non-existent image
 
@@ -50,13 +51,13 @@
                           non_existent_image_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('04f72aa3-fcec-45a3-81a3-308ef7cc82bc')
+    @decorators.idempotent_id('04f72aa3-fcec-45a3-81a3-308ef7cc82bc')
     def test_delete_image_blank_id(self):
         # Return an error while trying to delete an image with blank Id
         self.assertRaises(lib_exc.NotFound, self.client.delete_image, '')
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('950e5054-a3c7-4dee-ada5-e576f1087abd')
+    @decorators.idempotent_id('950e5054-a3c7-4dee-ada5-e576f1087abd')
     def test_delete_image_non_hex_string_id(self):
         # Return an error while trying to delete an image with non hex id
         invalid_image_id = data_utils.rand_uuid()[:-1] + "j"
@@ -64,13 +65,13 @@
                           invalid_image_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('4ed757cd-450c-44b1-9fd1-c819748c650d')
+    @decorators.idempotent_id('4ed757cd-450c-44b1-9fd1-c819748c650d')
     def test_delete_image_negative_image_id(self):
         # Return an error while trying to delete an image with negative id
         self.assertRaises(lib_exc.NotFound, self.client.delete_image, -1)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('a4a448ab-3db2-4d2d-b9b2-6a1271241dfe')
+    @decorators.idempotent_id('a4a448ab-3db2-4d2d-b9b2-6a1271241dfe')
     def test_delete_image_id_over_character_limit(self):
         # Return an error while trying to delete image with id over limit
         overlimit_image_id = data_utils.rand_uuid() + "1"
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 36dc6c3..56b3517 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -22,6 +22,7 @@
 from tempest.api.image 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
@@ -32,7 +33,7 @@
     """Here we test the basic operations of images"""
 
     @test.attr(type='smoke')
-    @test.idempotent_id('139b765e-7f3d-4b3d-8b37-3ca3876ee318')
+    @decorators.idempotent_id('139b765e-7f3d-4b3d-8b37-3ca3876ee318')
     def test_register_upload_get_image_file(self):
         """Here we test these functionalities
 
@@ -74,7 +75,7 @@
         self.assertEqual(file_content, body.data)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('f848bb94-1c6e-45a4-8726-39e3a5b23535')
+    @decorators.idempotent_id('f848bb94-1c6e-45a4-8726-39e3a5b23535')
     def test_delete_image(self):
         # Deletes an image by image_id
 
@@ -96,7 +97,7 @@
         self.assertNotIn(image['id'], images_id)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('f66891a7-a35c-41a8-b590-a065c2a1caa6')
+    @decorators.idempotent_id('f66891a7-a35c-41a8-b590-a065c2a1caa6')
     def test_update_image(self):
         # Updates an image by image_id
 
@@ -194,7 +195,7 @@
         msg = 'The list of images was not sorted correctly.'
         self.assertEqual(sorted(sorted_list, reverse=desc), sorted_list, msg)
 
-    @test.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
+    @decorators.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
     def test_list_no_params(self):
         # Simple test to see all fixture images returned
         images_list = self.client.list_images()['images']
@@ -203,25 +204,25 @@
         for image in self.created_images:
             self.assertIn(image, image_list)
 
-    @test.idempotent_id('9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e')
+    @decorators.idempotent_id('9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e')
     def test_list_images_param_container_format(self):
         # Test to get all images with a specific container_format
         params = {"container_format": self.test_data['container_format']}
         self._list_by_param_value_and_assert(params)
 
-    @test.idempotent_id('4a4735a7-f22f-49b6-b0d9-66e1ef7453eb')
+    @decorators.idempotent_id('4a4735a7-f22f-49b6-b0d9-66e1ef7453eb')
     def test_list_images_param_disk_format(self):
         # Test to get all images with disk_format = raw
         params = {"disk_format": "raw"}
         self._list_by_param_value_and_assert(params)
 
-    @test.idempotent_id('7a95bb92-d99e-4b12-9718-7bc6ab73e6d2')
+    @decorators.idempotent_id('7a95bb92-d99e-4b12-9718-7bc6ab73e6d2')
     def test_list_images_param_visibility(self):
         # Test to get all images with visibility = private
         params = {"visibility": "private"}
         self._list_by_param_value_and_assert(params)
 
-    @test.idempotent_id('cf1b9a48-8340-480e-af7b-fe7e17690876')
+    @decorators.idempotent_id('cf1b9a48-8340-480e-af7b-fe7e17690876')
     def test_list_images_param_size(self):
         # Test to get all images by size
         image_id = self.created_images[0]
@@ -231,7 +232,7 @@
         params = {"size": image['size']}
         self._list_by_param_value_and_assert(params)
 
-    @test.idempotent_id('4ad8c157-971a-4ba8-aa84-ed61154b1e7f')
+    @decorators.idempotent_id('4ad8c157-971a-4ba8-aa84-ed61154b1e7f')
     def test_list_images_param_min_max_size(self):
         # Test to get all images with size between 2000 to 3000
         image_id = self.created_images[0]
@@ -249,13 +250,13 @@
             self.assertLessEqual(image_size, params['size_max'],
                                  "Failed to get images by size_max")
 
-    @test.idempotent_id('7fc9e369-0f58-4d05-9aa5-0969e2d59d15')
+    @decorators.idempotent_id('7fc9e369-0f58-4d05-9aa5-0969e2d59d15')
     def test_list_images_param_status(self):
         # Test to get all active images
         params = {"status": "active"}
         self._list_by_param_value_and_assert(params)
 
-    @test.idempotent_id('e914a891-3cc8-4b40-ad32-e0a39ffbddbb')
+    @decorators.idempotent_id('e914a891-3cc8-4b40-ad32-e0a39ffbddbb')
     def test_list_images_param_limit(self):
         # Test to get images by limit
         params = {"limit": 1}
@@ -264,7 +265,7 @@
         self.assertEqual(len(images_list), params['limit'],
                          "Failed to get images by limit")
 
-    @test.idempotent_id('e9a44b91-31c8-4b40-a332-e0a39ffb4dbb')
+    @decorators.idempotent_id('e9a44b91-31c8-4b40-a332-e0a39ffb4dbb')
     def test_list_image_param_owner(self):
         # Test to get images by owner
         image_id = self.created_images[0]
@@ -274,13 +275,13 @@
         params = {"owner": image['owner']}
         self._list_by_param_value_and_assert(params)
 
-    @test.idempotent_id('55c8f5f5-bfed-409d-a6d5-4caeda985d7b')
+    @decorators.idempotent_id('55c8f5f5-bfed-409d-a6d5-4caeda985d7b')
     def test_list_images_param_name(self):
         # Test to get images by name
         params = {'name': self.test_data['name']}
         self._list_by_param_value_and_assert(params)
 
-    @test.idempotent_id('aa8ac4df-cff9-418b-8d0f-dd9c67b072c9')
+    @decorators.idempotent_id('aa8ac4df-cff9-418b-8d0f-dd9c67b072c9')
     def test_list_images_param_tag(self):
         # Test to get images matching a tag
         params = {'tag': self.test_data['tags'][0]}
@@ -295,24 +296,24 @@
                            observerd_tags=image['tags']))
             self.assertIn(self.test_data['tags'][0], image['tags'], msg)
 
-    @test.idempotent_id('eeadce49-04e0-43b7-aec7-52535d903e7a')
+    @decorators.idempotent_id('eeadce49-04e0-43b7-aec7-52535d903e7a')
     def test_list_images_param_sort(self):
         params = {'sort': 'size:desc'}
         self._list_sorted_by_image_size_and_assert(params, desc=True)
 
-    @test.idempotent_id('9faaa0c2-c3a5-43e1-8f61-61c54b409a49')
+    @decorators.idempotent_id('9faaa0c2-c3a5-43e1-8f61-61c54b409a49')
     def test_list_images_param_sort_key_dir(self):
         params = {'sort_key': 'size', 'sort_dir': 'desc'}
         self._list_sorted_by_image_size_and_assert(params, desc=True)
 
-    @test.idempotent_id('622b925c-479f-4736-860d-adeaf13bc371')
+    @decorators.idempotent_id('622b925c-479f-4736-860d-adeaf13bc371')
     def test_get_image_schema(self):
         # Test to get image schema
         schema = "image"
         body = self.schemas_client.show_schema(schema)
         self.assertEqual("image", body['name'])
 
-    @test.idempotent_id('25c8d7b2-df21-460f-87ac-93130bcdc684')
+    @decorators.idempotent_id('25c8d7b2-df21-460f-87ac-93130bcdc684')
     def test_get_images_schema(self):
         # Test to get images schema
         schema = "images"
@@ -331,7 +332,7 @@
         cls.image_member_client = cls.os.image_member_client_v2
         cls.alt_img_client = cls.os_alt.image_client_v2
 
-    @test.idempotent_id('3fa50be4-8e38-4c02-a8db-7811bb780122')
+    @decorators.idempotent_id('3fa50be4-8e38-4c02-a8db-7811bb780122')
     def test_list_images_param_member_status(self):
         # Create an image to be shared using default visibility
         image_file = six.BytesIO(data_utils.random_bytes(2048))
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index 8a4b334..7a495e7 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -11,12 +11,12 @@
 #    under the License.
 
 from tempest.api.image import base
-from tempest import test
+from tempest.lib import decorators
 
 
 class ImagesMemberTest(base.BaseV2MemberImageTest):
 
-    @test.idempotent_id('5934c6ea-27dc-4d6e-9421-eeb5e045494a')
+    @decorators.idempotent_id('5934c6ea-27dc-4d6e-9421-eeb5e045494a')
     def test_image_share_accept(self):
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
@@ -39,7 +39,7 @@
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'accepted')
 
-    @test.idempotent_id('d9e83e5f-3524-4b38-a900-22abcb26e90e')
+    @decorators.idempotent_id('d9e83e5f-3524-4b38-a900-22abcb26e90e')
     def test_image_share_reject(self):
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
@@ -55,7 +55,7 @@
                                                          status='rejected')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
 
-    @test.idempotent_id('a6ee18b9-4378-465e-9ad9-9a6de58a3287')
+    @decorators.idempotent_id('a6ee18b9-4378-465e-9ad9-9a6de58a3287')
     def test_get_image_member(self):
         image_id = self._create_image()
         self.image_member_client.create_image_member(
@@ -73,7 +73,7 @@
         self.assertEqual(image_id, member['image_id'])
         self.assertEqual('accepted', member['status'])
 
-    @test.idempotent_id('72989bc7-2268-48ed-af22-8821e835c914')
+    @decorators.idempotent_id('72989bc7-2268-48ed-af22-8821e835c914')
     def test_remove_image_member(self):
         image_id = self._create_image()
         self.image_member_client.create_image_member(
@@ -87,17 +87,17 @@
                                                      self.alt_tenant_id)
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
 
-    @test.idempotent_id('634dcc3f-f6e2-4409-b8fd-354a0bb25d83')
+    @decorators.idempotent_id('634dcc3f-f6e2-4409-b8fd-354a0bb25d83')
     def test_get_image_member_schema(self):
         body = self.schemas_client.show_schema("member")
         self.assertEqual("member", body['name'])
 
-    @test.idempotent_id('6ae916ef-1052-4e11-8d36-b3ae14853cbb')
+    @decorators.idempotent_id('6ae916ef-1052-4e11-8d36-b3ae14853cbb')
     def test_get_image_members_schema(self):
         body = self.schemas_client.show_schema("members")
         self.assertEqual("members", body['name'])
 
-    @test.idempotent_id('cb961424-3f68-4d21-8e36-30ad66fb6bfb')
+    @decorators.idempotent_id('cb961424-3f68-4d21-8e36-30ad66fb6bfb')
     def test_get_private_image(self):
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
diff --git a/tempest/api/image/v2/test_images_member_negative.py b/tempest/api/image/v2/test_images_member_negative.py
index fa29a92..ae9630a 100644
--- a/tempest/api/image/v2/test_images_member_negative.py
+++ b/tempest/api/image/v2/test_images_member_negative.py
@@ -11,6 +11,7 @@
 #    under the License.
 
 from tempest.api.image import base
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -18,7 +19,7 @@
 class ImagesMemberNegativeTest(base.BaseV2MemberImageTest):
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('b79efb37-820d-4cf0-b54c-308b00cf842c')
+    @decorators.idempotent_id('b79efb37-820d-4cf0-b54c-308b00cf842c')
     def test_image_share_invalid_status(self):
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
@@ -30,7 +31,7 @@
                           status='notavalidstatus')
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('27002f74-109e-4a37-acd0-f91cd4597967')
+    @decorators.idempotent_id('27002f74-109e-4a37-acd0-f91cd4597967')
     def test_image_share_owner_cannot_accept(self):
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
diff --git a/tempest/api/image/v2/test_images_metadefs_namespace_objects.py b/tempest/api/image/v2/test_images_metadefs_namespace_objects.py
index 95d1521..38e56d4 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespace_objects.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespace_objects.py
@@ -13,7 +13,7 @@
 from tempest.api.image import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
-from tempest import test
+from tempest.lib import decorators
 
 
 class MetadataNamespaceObjectsTest(base.BaseV2ImageTest):
@@ -28,7 +28,7 @@
                         namespace['namespace'], object_name)
         return namespace_object
 
-    @test.idempotent_id('b1a3775e-3b5c-4f6a-a3b4-1ba3574ae718')
+    @decorators.idempotent_id('b1a3775e-3b5c-4f6a-a3b4-1ba3574ae718')
     def test_create_update_delete_meta_namespace_objects(self):
         # Create a namespace
         namespace = self.create_namespace()
@@ -50,7 +50,7 @@
                 namespace['namespace'])['objects']]
         self.assertNotIn(up_object_name, namespace_objects)
 
-    @test.idempotent_id('a2a3615e-3b5c-3f6a-a2b1-1ba3574ae738')
+    @decorators.idempotent_id('a2a3615e-3b5c-3f6a-a2b1-1ba3574ae738')
     def test_list_meta_namespace_objects(self):
         # Create a namespace object
         namespace = self.create_namespace()
@@ -62,7 +62,7 @@
                 namespace['namespace'])['objects']]
         self.assertIn(meta_namespace_object['name'], namespace_objects)
 
-    @test.idempotent_id('b1a3674e-3b4c-3f6a-a3b4-1ba3573ca768')
+    @decorators.idempotent_id('b1a3674e-3b4c-3f6a-a3b4-1ba3573ca768')
     def test_show_meta_namespace_objects(self):
         # Create a namespace object
         namespace = self.create_namespace()
diff --git a/tempest/api/image/v2/test_images_metadefs_namespace_properties.py b/tempest/api/image/v2/test_images_metadefs_namespace_properties.py
index 7113db4..ead70f2 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespace_properties.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespace_properties.py
@@ -12,13 +12,13 @@
 
 from tempest.api.image import base
 from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
 
 
 class MetadataNamespacePropertiesTest(base.BaseV2ImageTest):
     """Test the Metadata definition namespace property basic functionality"""
 
-    @test.idempotent_id('b1a3765e-3a5d-4f6d-a3a7-3ca3476ae768')
+    @decorators.idempotent_id('b1a3765e-3a5d-4f6d-a3a7-3ca3476ae768')
     def test_basic_meta_def_namespace_property(self):
         # Get the available resource types and use one resource_type
         body = self.resource_types_client.list_resource_types()
diff --git a/tempest/api/image/v2/test_images_metadefs_namespace_tags.py b/tempest/api/image/v2/test_images_metadefs_namespace_tags.py
index 186d9c8..608d9fc 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespace_tags.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespace_tags.py
@@ -13,7 +13,7 @@
 from tempest.api.image import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
-from tempest import test
+from tempest.lib import decorators
 
 
 class MetadataNamespaceTagsTest(base.BaseV2ImageTest):
@@ -41,7 +41,7 @@
                         namespace['namespace'])
         return namespace_tags
 
-    @test.idempotent_id('a2a3765e-3a6d-4f6d-a3a7-3cc3476aa876')
+    @decorators.idempotent_id('a2a3765e-3a6d-4f6d-a3a7-3cc3476aa876')
     def test_create_list_delete_namespace_tags(self):
         # Create a namespace
         namespace = self.create_namespace()
@@ -60,7 +60,7 @@
             namespace['namespace'])
         self.assertEqual([], body['tags'])
 
-    @test.idempotent_id('a2a3765e-1a2c-3f6d-a3a7-3cc3466ab875')
+    @decorators.idempotent_id('a2a3765e-1a2c-3f6d-a3a7-3cc3466ab875')
     def test_create_update_delete_tag(self):
         # Create a namespace
         namespace = self.create_namespace()
diff --git a/tempest/api/image/v2/test_images_metadefs_namespaces.py b/tempest/api/image/v2/test_images_metadefs_namespaces.py
index a80a0cf..9fda937 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespaces.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespaces.py
@@ -16,14 +16,14 @@
 from tempest.api.image import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
-from tempest import test
 
 
 class MetadataNamespacesTest(base.BaseV2ImageTest):
     """Test the Metadata definition Namespaces basic functionality"""
 
-    @test.idempotent_id('319b765e-7f3d-4b3d-8b37-3ca3876ee768')
+    @decorators.idempotent_id('319b765e-7f3d-4b3d-8b37-3ca3876ee768')
     def test_basic_metadata_definition_namespaces(self):
         # get the available resource types and use one resource_type
         body = self.resource_types_client.list_resource_types()
diff --git a/tempest/api/image/v2/test_images_metadefs_resource_types.py b/tempest/api/image/v2/test_images_metadefs_resource_types.py
index 3dd432b..c60b3f7 100644
--- a/tempest/api/image/v2/test_images_metadefs_resource_types.py
+++ b/tempest/api/image/v2/test_images_metadefs_resource_types.py
@@ -14,13 +14,13 @@
 #    under the License.
 
 from tempest.api.image import base
-from tempest import test
+from tempest.lib import decorators
 
 
 class MetadataResourceTypesTest(base.BaseV2ImageTest):
     """Test the Metadata definition resource types basic functionality"""
 
-    @test.idempotent_id('6f358a4e-5ef0-11e6-a795-080027d0d606')
+    @decorators.idempotent_id('6f358a4e-5ef0-11e6-a795-080027d0d606')
     def test_basic_meta_def_resource_type_association(self):
         # Get the available resource types and use one resource_type
         body = self.resource_types_client.list_resource_types()
diff --git a/tempest/api/image/v2/test_images_metadefs_schema.py b/tempest/api/image/v2/test_images_metadefs_schema.py
index 7edf1af..95cc310 100644
--- a/tempest/api/image/v2/test_images_metadefs_schema.py
+++ b/tempest/api/image/v2/test_images_metadefs_schema.py
@@ -14,67 +14,67 @@
 #    under the License.
 
 from tempest.api.image import base
-from tempest import test
+from tempest.lib import decorators
 
 
 class MetadataSchemaTest(base.BaseV2ImageTest):
     """Test to get metadata schema"""
 
-    @test.idempotent_id('e9e44891-3cb8-3b40-a532-e0a39fea3dab')
+    @decorators.idempotent_id('e9e44891-3cb8-3b40-a532-e0a39fea3dab')
     def test_get_metadata_namespace_schema(self):
         # Test to get namespace schema
         body = self.schemas_client.show_schema("metadefs/namespace")
         self.assertEqual("namespace", body['name'])
 
-    @test.idempotent_id('ffe44891-678b-3ba0-a3e2-e0a3967b3aeb')
+    @decorators.idempotent_id('ffe44891-678b-3ba0-a3e2-e0a3967b3aeb')
     def test_get_metadata_namespaces_schema(self):
         # Test to get namespaces schema
         body = self.schemas_client.show_schema("metadefs/namespaces")
         self.assertEqual("namespaces", body['name'])
 
-    @test.idempotent_id('fde34891-678b-3b40-ae32-e0a3e67b6beb')
+    @decorators.idempotent_id('fde34891-678b-3b40-ae32-e0a3e67b6beb')
     def test_get_metadata_resource_type_schema(self):
         # Test to get resource_type schema
         body = self.schemas_client.show_schema("metadefs/resource_type")
         self.assertEqual("resource_type_association", body['name'])
 
-    @test.idempotent_id('dfe4a891-b38b-3bf0-a3b2-e03ee67b3a3a')
+    @decorators.idempotent_id('dfe4a891-b38b-3bf0-a3b2-e03ee67b3a3a')
     def test_get_metadata_resources_types_schema(self):
         # Test to get resource_types schema
         body = self.schemas_client.show_schema("metadefs/resource_types")
         self.assertEqual("resource_type_associations", body['name'])
 
-    @test.idempotent_id('dff4a891-b38b-3bf0-a3b2-e03ee67b3a3b')
+    @decorators.idempotent_id('dff4a891-b38b-3bf0-a3b2-e03ee67b3a3b')
     def test_get_metadata_object_schema(self):
         # Test to get object schema
         body = self.schemas_client.show_schema("metadefs/object")
         self.assertEqual("object", body['name'])
 
-    @test.idempotent_id('dee4a891-b38b-3bf0-a3b2-e03ee67b3a3c')
+    @decorators.idempotent_id('dee4a891-b38b-3bf0-a3b2-e03ee67b3a3c')
     def test_get_metadata_objects_schema(self):
         # Test to get objects schema
         body = self.schemas_client.show_schema("metadefs/objects")
         self.assertEqual("objects", body['name'])
 
-    @test.idempotent_id('dae4a891-b38b-3bf0-a3b2-e03ee67b3a3d')
+    @decorators.idempotent_id('dae4a891-b38b-3bf0-a3b2-e03ee67b3a3d')
     def test_get_metadata_property_schema(self):
         # Test to get property schema
         body = self.schemas_client.show_schema("metadefs/property")
         self.assertEqual("property", body['name'])
 
-    @test.idempotent_id('dce4a891-b38b-3bf0-a3b2-e03ee67b3a3e')
+    @decorators.idempotent_id('dce4a891-b38b-3bf0-a3b2-e03ee67b3a3e')
     def test_get_metadata_properties_schema(self):
         # Test to get properties schema
         body = self.schemas_client.show_schema("metadefs/properties")
         self.assertEqual("properties", body['name'])
 
-    @test.idempotent_id('dde4a891-b38b-3bf0-a3b2-e03ee67b3a3e')
+    @decorators.idempotent_id('dde4a891-b38b-3bf0-a3b2-e03ee67b3a3e')
     def test_get_metadata_tag_schema(self):
         # Test to get tag schema
         body = self.schemas_client.show_schema("metadefs/tag")
         self.assertEqual("tag", body['name'])
 
-    @test.idempotent_id('cde4a891-b38b-3bf0-a3b2-e03ee67b3a3a')
+    @decorators.idempotent_id('cde4a891-b38b-3bf0-a3b2-e03ee67b3a3a')
     def test_get_metadata_tags_schema(self):
         # Test to get tags schema
         body = self.schemas_client.show_schema("metadefs/tags")
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index cd1bca0..04c752a 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -16,6 +16,7 @@
 
 from tempest.api.image import base
 from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -34,7 +35,7 @@
      """
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('668743d5-08ad-4480-b2b8-15da34f81d9f')
+    @decorators.idempotent_id('668743d5-08ad-4480-b2b8-15da34f81d9f')
     def test_get_non_existent_image(self):
         # get the non-existent image
         non_existent_id = data_utils.rand_uuid()
@@ -42,14 +43,14 @@
                           non_existent_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('ef45000d-0a72-4781-866d-4cb7bf2562ad')
+    @decorators.idempotent_id('ef45000d-0a72-4781-866d-4cb7bf2562ad')
     def test_get_image_null_id(self):
         # get image with image_id = NULL
         image_id = ""
         self.assertRaises(lib_exc.NotFound, self.client.show_image, image_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('e57fc127-7ba0-4693-92d7-1d8a05ebcba9')
+    @decorators.idempotent_id('e57fc127-7ba0-4693-92d7-1d8a05ebcba9')
     def test_get_delete_deleted_image(self):
         # get and delete the deleted image
         # create and delete image
@@ -68,7 +69,7 @@
                           image['id'])
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('6fe40f1c-57bd-4918-89cc-8500f850f3de')
+    @decorators.idempotent_id('6fe40f1c-57bd-4918-89cc-8500f850f3de')
     def test_delete_non_existing_image(self):
         # delete non-existent image
         non_existent_image_id = data_utils.rand_uuid()
@@ -76,7 +77,7 @@
                           non_existent_image_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('32248db1-ab88-4821-9604-c7c369f1f88c')
+    @decorators.idempotent_id('32248db1-ab88-4821-9604-c7c369f1f88c')
     def test_delete_image_null_id(self):
         # delete image with image_id=NULL
         image_id = ""
@@ -84,7 +85,7 @@
                           image_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('292bd310-369b-41c7-a7a3-10276ef76753')
+    @decorators.idempotent_id('292bd310-369b-41c7-a7a3-10276ef76753')
     def test_register_with_invalid_container_format(self):
         # Negative tests for invalid data supplied to POST /images
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
@@ -92,7 +93,7 @@
                           disk_format='vhd')
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('70c6040c-5a97-4111-9e13-e73665264ce1')
+    @decorators.idempotent_id('70c6040c-5a97-4111-9e13-e73665264ce1')
     def test_register_with_invalid_disk_format(self):
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           name='test', container_format='bare',
diff --git a/tempest/api/image/v2/test_images_tags.py b/tempest/api/image/v2/test_images_tags.py
index 03f29bd..fd9591f 100644
--- a/tempest/api/image/v2/test_images_tags.py
+++ b/tempest/api/image/v2/test_images_tags.py
@@ -14,12 +14,12 @@
 
 from tempest.api.image import base
 from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
 
 
 class ImagesTagsTest(base.BaseV2ImageTest):
 
-    @test.idempotent_id('10407036-6059-4f95-a2cd-cbbbee7ed329')
+    @decorators.idempotent_id('10407036-6059-4f95-a2cd-cbbbee7ed329')
     def test_update_delete_tags_for_image(self):
         image = self.create_image(container_format='bare',
                                   disk_format='raw',
diff --git a/tempest/api/image/v2/test_images_tags_negative.py b/tempest/api/image/v2/test_images_tags_negative.py
index af4ffcf..2a08f3a 100644
--- a/tempest/api/image/v2/test_images_tags_negative.py
+++ b/tempest/api/image/v2/test_images_tags_negative.py
@@ -14,6 +14,7 @@
 
 from tempest.api.image 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
 
@@ -21,7 +22,7 @@
 class ImagesTagsNegativeTest(base.BaseV2ImageTest):
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('8cd30f82-6f9a-4c6e-8034-c1b51fba43d9')
+    @decorators.idempotent_id('8cd30f82-6f9a-4c6e-8034-c1b51fba43d9')
     def test_update_tags_for_non_existing_image(self):
         # Update tag with non existing image.
         tag = data_utils.rand_name('tag')
@@ -30,7 +31,7 @@
                           non_exist_image, tag)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('39c023a2-325a-433a-9eea-649bf1414b19')
+    @decorators.idempotent_id('39c023a2-325a-433a-9eea-649bf1414b19')
     def test_delete_non_existing_tag(self):
         # Delete non existing tag.
         image = self.create_image(container_format='bare',
diff --git a/tempest/api/network/admin/test_agent_management.py b/tempest/api/network/admin/test_agent_management.py
index 61f8e15..6389489 100644
--- a/tempest/api/network/admin/test_agent_management.py
+++ b/tempest/api/network/admin/test_agent_management.py
@@ -14,6 +14,7 @@
 
 from tempest.api.network import base
 from tempest.common import tempest_fixtures as fixtures
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -33,7 +34,7 @@
         agents = body['agents']
         cls.agent = agents[0]
 
-    @test.idempotent_id('9c80f04d-11f3-44a4-8738-ed2f879b0ff4')
+    @decorators.idempotent_id('9c80f04d-11f3-44a4-8738-ed2f879b0ff4')
     def test_list_agent(self):
         body = self.admin_agents_client.list_agents()
         agents = body['agents']
@@ -45,18 +46,18 @@
             agent.pop('configurations', None)
         self.assertIn(self.agent, agents)
 
-    @test.idempotent_id('e335be47-b9a1-46fd-be30-0874c0b751e6')
+    @decorators.idempotent_id('e335be47-b9a1-46fd-be30-0874c0b751e6')
     def test_list_agents_non_admin(self):
         body = self.agents_client.list_agents()
         self.assertEqual(len(body["agents"]), 0)
 
-    @test.idempotent_id('869bc8e8-0fda-4a30-9b71-f8a7cf58ca9f')
+    @decorators.idempotent_id('869bc8e8-0fda-4a30-9b71-f8a7cf58ca9f')
     def test_show_agent(self):
         body = self.admin_agents_client.show_agent(self.agent['id'])
         agent = body['agent']
         self.assertEqual(agent['id'], self.agent['id'])
 
-    @test.idempotent_id('371dfc5b-55b9-4cb5-ac82-c40eadaac941')
+    @decorators.idempotent_id('371dfc5b-55b9-4cb5-ac82-c40eadaac941')
     def test_update_agent_status(self):
         origin_status = self.agent['admin_state_up']
         # Try to update the 'admin_state_up' to the original
@@ -67,7 +68,7 @@
         updated_status = body['agent']['admin_state_up']
         self.assertEqual(origin_status, updated_status)
 
-    @test.idempotent_id('68a94a14-1243-46e6-83bf-157627e31556')
+    @decorators.idempotent_id('68a94a14-1243-46e6-83bf-157627e31556')
     def test_update_agent_description(self):
         self.useFixture(fixtures.LockFixture('agent_description'))
         description = 'description for update agent.'
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index b3555b6..868771f 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -13,6 +13,7 @@
 #    under the License.
 
 from tempest.api.network import base
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -34,12 +35,12 @@
         cls.subnet = cls.create_subnet(cls.network)
         cls.port = cls.create_port(cls.network)
 
-    @test.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
+    @decorators.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
     def test_list_dhcp_agent_hosting_network(self):
         self.admin_networks_client.list_dhcp_agents_on_hosting_network(
             self.network['id'])
 
-    @test.idempotent_id('30c48f98-e45d-4ffb-841c-b8aad57c7587')
+    @decorators.idempotent_id('30c48f98-e45d-4ffb-841c-b8aad57c7587')
     def test_list_networks_hosted_by_one_dhcp(self):
         body = self.admin_networks_client.list_dhcp_agents_on_hosting_network(
             self.network['id'])
@@ -58,7 +59,7 @@
             network_ids.append(network['id'])
         return network_id in network_ids
 
-    @test.idempotent_id('a0856713-6549-470c-a656-e97c8df9a14d')
+    @decorators.idempotent_id('a0856713-6549-470c-a656-e97c8df9a14d')
     def test_add_remove_network_from_dhcp_agent(self):
         # The agent is now bound to the network, we can free the port
         self.ports_client.delete_port(self.port['id'])
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index 2d53265..dc440d3 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -13,7 +13,7 @@
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
-from tempest import test
+from tempest.lib import decorators
 
 
 class ExternalNetworksTestJSON(base.BaseAdminNetworkTest):
@@ -33,7 +33,7 @@
             self.admin_networks_client.delete_network, network['id'])
         return network
 
-    @test.idempotent_id('462be770-b310-4df9-9c42-773217e4c8b1')
+    @decorators.idempotent_id('462be770-b310-4df9-9c42-773217e4c8b1')
     def test_create_external_network(self):
         # Create a network as an admin user specifying the
         # external network extension attribute
@@ -42,7 +42,7 @@
         self.assertIsNotNone(ext_network['id'])
         self.assertTrue(ext_network['router:external'])
 
-    @test.idempotent_id('4db5417a-e11c-474d-a361-af00ebef57c5')
+    @decorators.idempotent_id('4db5417a-e11c-474d-a361-af00ebef57c5')
     def test_update_external_network(self):
         # Update a network as an admin user specifying the
         # external network extension attribute
@@ -55,7 +55,7 @@
         # Verify that router:external parameter was updated
         self.assertTrue(updated_network['router:external'])
 
-    @test.idempotent_id('39be4c9b-a57e-4ff9-b7c7-b218e209dfcc')
+    @decorators.idempotent_id('39be4c9b-a57e-4ff9-b7c7-b218e209dfcc')
     def test_list_external_networks(self):
         # Create external_net
         external_network = self._create_network()
@@ -72,7 +72,7 @@
             elif net['id'] == external_network['id']:
                 self.assertTrue(net['router:external'])
 
-    @test.idempotent_id('2ac50ab2-7ebd-4e27-b3ce-a9e399faaea2')
+    @decorators.idempotent_id('2ac50ab2-7ebd-4e27-b3ce-a9e399faaea2')
     def test_show_external_networks_attribute(self):
         # Create external_net
         external_network = self._create_network()
@@ -90,7 +90,7 @@
         self.assertEqual(self.network['id'], show_net['id'])
         self.assertFalse(show_net['router:external'])
 
-    @test.idempotent_id('82068503-2cf2-4ed4-b3be-ecb89432e4bb')
+    @decorators.idempotent_id('82068503-2cf2-4ed4-b3be-ecb89432e4bb')
     def test_delete_external_networks_with_floating_ip(self):
         # Verifies external network can be deleted while still holding
         # (unassociated) floating IPs
diff --git a/tempest/api/network/admin/test_external_networks_negative.py b/tempest/api/network/admin/test_external_networks_negative.py
index 94d65c3..743089a 100644
--- a/tempest/api/network/admin/test_external_networks_negative.py
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base
 from tempest import config
 from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -25,7 +26,7 @@
 class ExternalNetworksAdminNegativeTestJSON(base.BaseAdminNetworkTest):
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('d402ae6c-0be0-4d8e-833b-a738895d98d0')
+    @decorators.idempotent_id('d402ae6c-0be0-4d8e-833b-a738895d98d0')
     def test_create_port_with_precreated_floatingip_as_fixed_ip(self):
         # NOTE: External networks can be used to create both floating-ip as
         # well as instance-ip. So, creating an instance-ip with a value of a
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index a32e7da..c36323a 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -15,6 +15,7 @@
 
 from tempest.api.network import base
 from tempest import config
+from tempest.lib import decorators
 from tempest import test
 
 CONF = config.CONF
@@ -47,7 +48,7 @@
         cls.create_router_interface(cls.router['id'], cls.subnet['id'])
         cls.port = cls.create_port(cls.network)
 
-    @test.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
+    @decorators.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
     def test_list_floating_ips_from_admin_and_nonadmin(self):
         # Create floating ip from admin user
         floating_ip_admin = self.admin_floating_ips_client.create_floatingip(
@@ -78,7 +79,7 @@
                          floating_ip_ids)
         self.assertNotIn(floating_ip_alt['id'], floating_ip_ids)
 
-    @test.idempotent_id('32727cc3-abe2-4485-a16e-48f2d54c14f2')
+    @decorators.idempotent_id('32727cc3-abe2-4485-a16e-48f2d54c14f2')
     def test_create_list_show_floating_ip_with_tenant_id_by_admin(self):
         # Creates a floating IP
         body = self.admin_floating_ips_client.create_floatingip(
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index c2ff038..5a54ae0 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -14,6 +14,7 @@
 
 from tempest.api.network import base
 from tempest import config
+from tempest.lib import decorators
 from tempest.lib import exceptions
 from tempest import test
 
@@ -103,11 +104,11 @@
                                                        port_id=cls.port['id'])
         super(L3AgentSchedulerTestJSON, cls).resource_cleanup()
 
-    @test.idempotent_id('b7ce6e89-e837-4ded-9b78-9ed3c9c6a45a')
+    @decorators.idempotent_id('b7ce6e89-e837-4ded-9b78-9ed3c9c6a45a')
     def test_list_routers_on_l3_agent(self):
         self.admin_agents_client.list_routers_on_l3_agent(self.agent['id'])
 
-    @test.idempotent_id('9464e5e7-8625-49c3-8fd1-89c52be59d66')
+    @decorators.idempotent_id('9464e5e7-8625-49c3-8fd1-89c52be59d66')
     def test_add_list_remove_router_on_l3_agent(self):
         l3_agent_ids = list()
         self.admin_agents_client.create_router_on_l3_agent(
diff --git a/tempest/api/network/admin/test_negative_quotas.py b/tempest/api/network/admin/test_negative_quotas.py
index beb6ce6..435e672 100644
--- a/tempest/api/network/admin/test_negative_quotas.py
+++ b/tempest/api/network/admin/test_negative_quotas.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.api.network import base
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -38,7 +39,7 @@
             msg = "quotas extension not enabled."
             raise cls.skipException(msg)
 
-    @test.idempotent_id('644f4e1b-1bf9-4af0-9fd8-eb56ac0f51cf')
+    @decorators.idempotent_id('644f4e1b-1bf9-4af0-9fd8-eb56ac0f51cf')
     def test_network_quota_exceeding(self):
         # Set the network quota to two
         self.admin_quotas_client.update_quotas(self.networks_client.tenant_id,
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 8695ebd..7b6ebef 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -78,7 +79,7 @@
         for q in non_default_quotas['quotas']:
             self.assertNotEqual(project_id, q['tenant_id'])
 
-    @test.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
+    @decorators.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
     def test_quotas(self):
         new_quotas = {'network': 0, 'port': 0}
         self._check_quotas(new_quotas)
diff --git a/tempest/api/network/admin/test_routers_dvr.py b/tempest/api/network/admin/test_routers_dvr.py
index aaac921..78ca494 100644
--- a/tempest/api/network/admin/test_routers_dvr.py
+++ b/tempest/api/network/admin/test_routers_dvr.py
@@ -17,6 +17,7 @@
 
 from tempest.api.network import base_routers as base
 from tempest.common.utils import data_utils
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -42,7 +43,7 @@
             msg = "'distributed' flag not found. DVR Possibly not enabled"
             raise cls.skipException(msg)
 
-    @test.idempotent_id('08a2a0a8-f1e4-4b34-8e30-e522e836c44e')
+    @decorators.idempotent_id('08a2a0a8-f1e4-4b34-8e30-e522e836c44e')
     def test_distributed_router_creation(self):
         """Test distributed router creation
 
@@ -61,7 +62,7 @@
                         router['router']['id'])
         self.assertTrue(router['router']['distributed'])
 
-    @test.idempotent_id('8a0a72b4-7290-4677-afeb-b4ffe37bc352')
+    @decorators.idempotent_id('8a0a72b4-7290-4677-afeb-b4ffe37bc352')
     def test_centralized_router_creation(self):
         """Test centralized router creation
 
@@ -81,7 +82,7 @@
                         router['router']['id'])
         self.assertFalse(router['router']['distributed'])
 
-    @test.idempotent_id('acd43596-c1fb-439d-ada8-31ad48ae3c2e')
+    @decorators.idempotent_id('acd43596-c1fb-439d-ada8-31ad48ae3c2e')
     @testtools.skipUnless(test.is_extension_enabled('l3-ha', 'network'),
                           'HA routers are not available.')
     def test_centralized_router_update_to_dvr(self):
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index 92dfc56..a90e4bf 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -18,6 +18,7 @@
 
 from tempest.api.network import base
 from tempest import config
+from tempest.lib import decorators
 from tempest import test
 
 CONF = config.CONF
@@ -56,7 +57,7 @@
         cls.ip_address = port['fixed_ips'][0]['ip_address']
         cls.mac_address = port['mac_address']
 
-    @test.idempotent_id('86c3529b-1231-40de-803c-00e40882f043')
+    @decorators.idempotent_id('86c3529b-1231-40de-803c-00e40882f043')
     def test_create_list_port_with_address_pair(self):
         # Create port with allowed address pair attribute
         allowed_address_pairs = [{'ip_address': self.ip_address,
@@ -94,18 +95,18 @@
         six.assertCountEqual(self, allowed_address_pair,
                              allowed_address_pairs)
 
-    @test.idempotent_id('9599b337-272c-47fd-b3cf-509414414ac4')
+    @decorators.idempotent_id('9599b337-272c-47fd-b3cf-509414414ac4')
     def test_update_port_with_address_pair(self):
         # Update port with allowed address pair
         self._update_port_with_address(self.ip_address)
 
-    @test.idempotent_id('4d6d178f-34f6-4bff-a01c-0a2f8fe909e4')
+    @decorators.idempotent_id('4d6d178f-34f6-4bff-a01c-0a2f8fe909e4')
     def test_update_port_with_cidr_address_pair(self):
         # Update allowed address pair with cidr
         cidr = str(netaddr.IPNetwork(CONF.network.project_network_cidr))
         self._update_port_with_address(cidr)
 
-    @test.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
+    @decorators.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
     def test_update_port_with_multiple_ip_mac_address_pair(self):
         # Create an ip _address and mac_address through port create
         resp = self.ports_client.create_port(network_id=self.network['id'])
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 3c96a93..fa4010d 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -20,8 +20,8 @@
 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.lib import exceptions as lib_exc
-from tempest import test
 
 CONF = config.CONF
 
@@ -95,7 +95,7 @@
                                                    port_mac).format()
         return real_ip, eui_ip
 
-    @test.idempotent_id('e5517e62-6f16-430d-a672-f80875493d4c')
+    @decorators.idempotent_id('e5517e62-6f16-430d-a672-f80875493d4c')
     def test_dhcpv6_stateless_eui64(self):
         # NOTE: When subnets configured with RAs SLAAC (AOM=100) and DHCP
         # stateless (AOM=110) both for radvd and dnsmasq, port shall receive
@@ -113,7 +113,7 @@
                               'ipv6_ra_mode=%s and ipv6_address_mode=%s') % (
                                  real_ip, eui_ip, ra_mode, add_mode))
 
-    @test.idempotent_id('ae2f4a5d-03ff-4c42-a3b0-ce2fcb7ea832')
+    @decorators.idempotent_id('ae2f4a5d-03ff-4c42-a3b0-ce2fcb7ea832')
     def test_dhcpv6_stateless_no_ra(self):
         # NOTE: When subnets configured with dnsmasq SLAAC and DHCP stateless
         # and there is no radvd, port shall receive IP address calculated
@@ -134,7 +134,7 @@
                                  ra_mode if ra_mode else "Off",
                                  add_mode if add_mode else "Off"))
 
-    @test.idempotent_id('81f18ef6-95b5-4584-9966-10d480b7496a')
+    @decorators.idempotent_id('81f18ef6-95b5-4584-9966-10d480b7496a')
     def test_dhcpv6_invalid_options(self):
         """Different configurations for radvd and dnsmasq are not allowed"""
         for ra_mode, add_mode in (
@@ -152,7 +152,7 @@
                               self.network,
                               **kwargs)
 
-    @test.idempotent_id('21635b6f-165a-4d42-bf49-7d195e47342f')
+    @decorators.idempotent_id('21635b6f-165a-4d42-bf49-7d195e47342f')
     def test_dhcpv6_stateless_no_ra_no_dhcp(self):
         # NOTE: If no radvd option and no dnsmasq option is configured
         # port shall receive IP from fixed IPs list of subnet.
@@ -164,7 +164,7 @@
                              'but shall be taken from fixed IPs') % (
                                 real_ip, eui_ip))
 
-    @test.idempotent_id('4544adf7-bb5f-4bdc-b769-b3e77026cef2')
+    @decorators.idempotent_id('4544adf7-bb5f-4bdc-b769-b3e77026cef2')
     def test_dhcpv6_two_subnets(self):
         # NOTE: When one IPv6 subnet configured with dnsmasq SLAAC or DHCP
         # stateless and other IPv6 is with DHCP stateful, port shall receive
@@ -213,7 +213,7 @@
                 self.assertIn(netaddr.IPAddress(real_dhcp_ip),
                               netaddr.IPNetwork(subnet_dhcp['cidr']), msg)
 
-    @test.idempotent_id('4256c61d-c538-41ea-9147-3c450c36669e')
+    @decorators.idempotent_id('4256c61d-c538-41ea-9147-3c450c36669e')
     def test_dhcpv6_64_subnets(self):
         # NOTE: When one IPv6 subnet configured with dnsmasq SLAAC or DHCP
         # stateless and other IPv4 is with DHCP of IPv4, port shall receive
@@ -256,7 +256,7 @@
                 self.assertIn(netaddr.IPAddress(real_dhcp_ip),
                               netaddr.IPNetwork(subnet_dhcp['cidr']), msg)
 
-    @test.idempotent_id('4ab211a0-276f-4552-9070-51e27f58fecf')
+    @decorators.idempotent_id('4ab211a0-276f-4552-9070-51e27f58fecf')
     def test_dhcp_stateful(self):
         # NOTE: With all options below, DHCPv6 shall allocate address from
         # subnet pool to port.
@@ -277,7 +277,7 @@
             self.assertIn(netaddr.IPAddress(port_ip),
                           netaddr.IPNetwork(subnet['cidr']), msg)
 
-    @test.idempotent_id('51a5e97f-f02e-4e4e-9a17-a69811d300e3')
+    @decorators.idempotent_id('51a5e97f-f02e-4e4e-9a17-a69811d300e3')
     def test_dhcp_stateful_fixedips(self):
         # NOTE: With all options below, port shall be able to get
         # requested IP from fixed IP range not depending on
@@ -305,7 +305,7 @@
                               "port create request: %s") % (
                                  port_ip, ip))
 
-    @test.idempotent_id('98244d88-d990-4570-91d4-6b25d70d08af')
+    @decorators.idempotent_id('98244d88-d990-4570-91d4-6b25d70d08af')
     def test_dhcp_stateful_fixedips_outrange(self):
         # NOTE: When port gets IP address from fixed IP range it
         # shall be checked if it's from subnets range.
@@ -322,7 +322,7 @@
                           fixed_ips=[{'subnet_id': subnet['id'],
                                       'ip_address': ip}])
 
-    @test.idempotent_id('57b8302b-cba9-4fbb-8835-9168df029051')
+    @decorators.idempotent_id('57b8302b-cba9-4fbb-8835-9168df029051')
     def test_dhcp_stateful_fixedips_duplicate(self):
         # NOTE: When port gets IP address from fixed IP range it
         # shall be checked if it's not duplicate.
@@ -352,7 +352,7 @@
         body = self.ports_client.show_port(port['port_id'])
         return subnet, body['port']
 
-    @test.idempotent_id('e98f65db-68f4-4330-9fea-abd8c5192d4d')
+    @decorators.idempotent_id('e98f65db-68f4-4330-9fea-abd8c5192d4d')
     def test_dhcp_stateful_router(self):
         # NOTE: With all options below the router interface shall
         # receive DHCPv6 IP address from allocation pool.
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index 84150b4..2662e9c 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -15,6 +15,7 @@
 
 
 from tempest.api.network import base
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -29,7 +30,7 @@
     """
 
     @test.attr(type='smoke')
-    @test.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
+    @decorators.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
     def test_list_show_extensions(self):
         # List available extensions for the project
         expected_alias = ['security-group', 'l3_agent_scheduler',
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index 062bc69..52507f9 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -15,6 +15,7 @@
 
 from tempest.api.network import base
 from tempest.common.utils import data_utils
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -54,7 +55,7 @@
             {'opt_value': cls.ip_server, 'opt_name': 'server-ip-address'}
         ]
 
-    @test.idempotent_id('d2c17063-3767-4a24-be4f-a23dbfa133c9')
+    @decorators.idempotent_id('d2c17063-3767-4a24-be4f-a23dbfa133c9')
     def test_create_list_port_with_extra_dhcp_options(self):
         # Create a port with Extra DHCP Options
         body = self.ports_client.create_port(
@@ -70,7 +71,7 @@
         self.assertTrue(port)
         self._confirm_extra_dhcp_options(port[0], self.extra_dhcp_opts)
 
-    @test.idempotent_id('9a6aebf4-86ee-4f47-b07a-7f7232c55607')
+    @decorators.idempotent_id('9a6aebf4-86ee-4f47-b07a-7f7232c55607')
     def test_update_show_port_with_extra_dhcp_options(self):
         # Update port with extra dhcp options
         name = data_utils.rand_name('new-port-name')
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index efe8982..23614d6 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base
 from tempest.common.utils import net_utils
 from tempest import config
+from tempest.lib import decorators
 from tempest import test
 
 CONF = config.CONF
@@ -61,7 +62,7 @@
             cls.create_port(cls.network)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
+    @decorators.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
     def test_create_list_show_update_delete_floating_ip(self):
         # Creates a floating IP
         body = self.floating_ips_client.create_floatingip(
@@ -116,7 +117,7 @@
         self.assertIsNone(updated_floating_ip['fixed_ip_address'])
         self.assertIsNone(updated_floating_ip['router_id'])
 
-    @test.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
+    @decorators.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
     def test_floating_ip_delete_port(self):
         # Create a floating IP
         body = self.floating_ips_client.create_floatingip(
@@ -142,7 +143,7 @@
         self.assertIsNone(shown_floating_ip['fixed_ip_address'])
         self.assertIsNone(shown_floating_ip['router_id'])
 
-    @test.idempotent_id('1bb2f731-fe5a-4b8c-8409-799ade1bed4d')
+    @decorators.idempotent_id('1bb2f731-fe5a-4b8c-8409-799ade1bed4d')
     def test_floating_ip_update_different_router(self):
         # Associate a floating IP to a port on a router
         body = self.floating_ips_client.create_floatingip(
@@ -168,7 +169,7 @@
         self.assertIsNotNone(updated_floating_ip['fixed_ip_address'])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5')
+    @decorators.idempotent_id('36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5')
     def test_create_floating_ip_specifying_a_fixed_ip_address(self):
         body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
@@ -185,7 +186,7 @@
             port_id=None)
         self.assertIsNone(floating_ip['floatingip']['port_id'])
 
-    @test.idempotent_id('45c4c683-ea97-41ef-9c51-5e9802f2f3d7')
+    @decorators.idempotent_id('45c4c683-ea97-41ef-9c51-5e9802f2f3d7')
     def test_create_update_floatingip_with_port_multiple_ip_address(self):
         # Find out ips that can be used for tests
         list_ips = net_utils.get_unused_ip_addresses(
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index 7ffc30f..9ccda05 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -16,6 +16,7 @@
 
 from tempest.api.network import base
 from tempest import config
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -49,7 +50,7 @@
         cls.port = cls.create_port(cls.network)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('22996ea8-4a81-4b27-b6e1-fa5df92fa5e8')
+    @decorators.idempotent_id('22996ea8-4a81-4b27-b6e1-fa5df92fa5e8')
     def test_create_floatingip_with_port_ext_net_unreachable(self):
         self.assertRaises(
             lib_exc.NotFound, self.floating_ips_client.create_floatingip,
@@ -58,7 +59,7 @@
                                       ['ip_address'])
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('50b9aeb4-9f0b-48ee-aa31-fa955a48ff54')
+    @decorators.idempotent_id('50b9aeb4-9f0b-48ee-aa31-fa955a48ff54')
     def test_create_floatingip_in_private_network(self):
         self.assertRaises(lib_exc.BadRequest,
                           self.floating_ips_client.create_floatingip,
@@ -68,7 +69,7 @@
                                                     ['ip_address'])
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('6b3b8797-6d43-4191-985c-c48b773eb429')
+    @decorators.idempotent_id('6b3b8797-6d43-4191-985c-c48b773eb429')
     def test_associate_floatingip_port_ext_net_unreachable(self):
         # Create floating ip
         body = self.floating_ips_client.create_floatingip(
diff --git a/tempest/api/network/test_metering_extensions.py b/tempest/api/network/test_metering_extensions.py
index 299700f..42fa9e4 100644
--- a/tempest/api/network/test_metering_extensions.py
+++ b/tempest/api/network/test_metering_extensions.py
@@ -14,6 +14,7 @@
 
 from tempest.api.network import base
 from tempest.common.utils import data_utils
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -61,14 +62,14 @@
         rules = client.list_metering_label_rules(id=metering_label_rule_id)
         self.assertEqual(len(rules['metering_label_rules']), 0)
 
-    @test.idempotent_id('e2fb2f8c-45bf-429a-9f17-171c70444612')
+    @decorators.idempotent_id('e2fb2f8c-45bf-429a-9f17-171c70444612')
     def test_list_metering_labels(self):
         # Verify label filtering
         body = self.admin_metering_labels_client.list_metering_labels(id=33)
         metering_labels = body['metering_labels']
         self.assertEqual(0, len(metering_labels))
 
-    @test.idempotent_id('ec8e15ff-95d0-433b-b8a6-b466bddb1e50')
+    @decorators.idempotent_id('ec8e15ff-95d0-433b-b8a6-b466bddb1e50')
     def test_create_delete_metering_label_with_filters(self):
         # Creates a label
         name = data_utils.rand_name('metering-label-')
@@ -84,7 +85,7 @@
                   id=metering_label['id']))
         self.assertEqual(len(labels['metering_labels']), 1)
 
-    @test.idempotent_id('30abb445-0eea-472e-bd02-8649f54a5968')
+    @decorators.idempotent_id('30abb445-0eea-472e-bd02-8649f54a5968')
     def test_show_metering_label(self):
         # Verifies the details of a label
         body = self.admin_metering_labels_client.show_metering_label(
@@ -97,7 +98,7 @@
         self.assertEqual(self.metering_label['description'],
                          metering_label['description'])
 
-    @test.idempotent_id('cc832399-6681-493b-9d79-0202831a1281')
+    @decorators.idempotent_id('cc832399-6681-493b-9d79-0202831a1281')
     def test_list_metering_label_rules(self):
         client = self.admin_metering_label_rules_client
         # Verify rule filtering
@@ -105,7 +106,7 @@
         metering_label_rules = body['metering_label_rules']
         self.assertEqual(0, len(metering_label_rules))
 
-    @test.idempotent_id('f4d547cd-3aee-408f-bf36-454f8825e045')
+    @decorators.idempotent_id('f4d547cd-3aee-408f-bf36-454f8825e045')
     def test_create_delete_metering_label_rule_with_filters(self):
         # Creates a rule
         remote_ip_prefix = ("10.0.1.0/24" if self._ip_version == 4
@@ -123,7 +124,7 @@
         rules = client.list_metering_label_rules(id=metering_label_rule['id'])
         self.assertEqual(len(rules['metering_label_rules']), 1)
 
-    @test.idempotent_id('b7354489-96ea-41f3-9452-bace120fb4a7')
+    @decorators.idempotent_id('b7354489-96ea-41f3-9452-bace120fb4a7')
     def test_show_metering_label_rule(self):
         # Verifies the details of a rule
         client = self.admin_metering_label_rules_client
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 8e2f3f6..1426798 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -21,6 +21,7 @@
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -175,7 +176,7 @@
     """
 
     @test.attr(type='smoke')
-    @test.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
+    @decorators.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
     def test_create_update_delete_network_subnet(self):
         # Create a network
         network = self.create_network()
@@ -197,7 +198,7 @@
         self.assertEqual(updated_subnet['name'], new_name)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
+    @decorators.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
     def test_show_network(self):
         # Verify the details of a network
         body = self.networks_client.show_network(self.network['id'])
@@ -205,7 +206,7 @@
         for key in ['id', 'name']:
             self.assertEqual(network[key], self.network[key])
 
-    @test.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
+    @decorators.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
     def test_show_network_fields(self):
         # Verify specific fields of a network
         fields = ['id', 'name']
@@ -221,7 +222,7 @@
         self.assertNotIn('project_id', network)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
+    @decorators.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
     def test_list_networks(self):
         # Verify the network exists in the list of all networks
         body = self.networks_client.list_networks()
@@ -229,7 +230,7 @@
                     if network['id'] == self.network['id']]
         self.assertNotEmpty(networks, "Created network not found in the list")
 
-    @test.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
+    @decorators.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
     def test_list_networks_fields(self):
         # Verify specific fields of the networks
         fields = ['id', 'name']
@@ -242,7 +243,7 @@
             self.assertEqual(sorted(network.keys()), sorted(fields))
 
     @test.attr(type='smoke')
-    @test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
+    @decorators.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
     def test_show_subnet(self):
         # Verify the details of a subnet
         body = self.subnets_client.show_subnet(self.subnet['id'])
@@ -252,7 +253,7 @@
             self.assertIn(key, subnet)
             self.assertEqual(subnet[key], self.subnet[key])
 
-    @test.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
+    @decorators.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
     def test_show_subnet_fields(self):
         # Verify specific fields of a subnet
         fields = ['id', 'network_id']
@@ -264,7 +265,7 @@
             self.assertEqual(subnet[field_name], self.subnet[field_name])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
+    @decorators.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
     def test_list_subnets(self):
         # Verify the subnet exists in the list of all subnets
         body = self.subnets_client.list_subnets()
@@ -272,7 +273,7 @@
                    if subnet['id'] == self.subnet['id']]
         self.assertNotEmpty(subnets, "Created subnet not found in the list")
 
-    @test.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
+    @decorators.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
     def test_list_subnets_fields(self):
         # Verify specific fields of subnets
         fields = ['id', 'network_id']
@@ -282,7 +283,7 @@
         for subnet in subnets:
             self.assertEqual(sorted(subnet.keys()), sorted(fields))
 
-    @test.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
+    @decorators.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
     def test_delete_network_with_subnet(self):
         # Creates a network
         network = self.create_network()
@@ -301,35 +302,35 @@
         self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
                           subnet_id)
 
-    @test.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
+    @decorators.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
     def test_create_delete_subnet_without_gateway(self):
         self._create_verify_delete_subnet()
 
-    @test.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
+    @decorators.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
     def test_create_delete_subnet_with_gw(self):
         self._create_verify_delete_subnet(
             **self.subnet_dict(['gateway']))
 
-    @test.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
+    @decorators.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
     def test_create_delete_subnet_with_allocation_pools(self):
         self._create_verify_delete_subnet(
             **self.subnet_dict(['allocation_pools']))
 
-    @test.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
+    @decorators.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
     def test_create_delete_subnet_with_gw_and_allocation_pools(self):
         self._create_verify_delete_subnet(**self.subnet_dict(
             ['gateway', 'allocation_pools']))
 
-    @test.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
+    @decorators.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
     def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
         self._create_verify_delete_subnet(
             **self.subnet_dict(['host_routes', 'dns_nameservers']))
 
-    @test.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
+    @decorators.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
     def test_create_delete_subnet_with_dhcp_enabled(self):
         self._create_verify_delete_subnet(enable_dhcp=True)
 
-    @test.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
+    @decorators.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
     def test_update_subnet_gw_dns_host_routes_dhcp(self):
         network = self.create_network()
         self.addCleanup(self._delete_network, network)
@@ -362,14 +363,14 @@
 
         self._compare_resource_attrs(updated_subnet, kwargs)
 
-    @test.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
+    @decorators.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
     def test_create_delete_subnet_all_attributes(self):
         self._create_verify_delete_subnet(
             enable_dhcp=True,
             **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
 
     @test.attr(type='smoke')
-    @test.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
+    @decorators.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
     @test.requires_ext(extension='external-net', service='network')
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
@@ -391,7 +392,7 @@
             network_id=CONF.network.public_network_id)
         self.assertEmpty(body['subnets'], "Public subnets visible")
 
-    @test.idempotent_id('c72c1c0c-2193-4aca-ccc4-b1442640bbbb')
+    @decorators.idempotent_id('c72c1c0c-2193-4aca-ccc4-b1442640bbbb')
     @test.requires_ext(extension="standard-attr-description",
                        service="network")
     def test_create_update_network_description(self):
@@ -453,7 +454,7 @@
             self.assertNotIn(n['id'], ports_list)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
+    @decorators.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
     def test_bulk_create_delete_network(self):
         # Creates 2 networks in one request
         network_list = [{'name': data_utils.rand_name('network-')},
@@ -469,7 +470,7 @@
             self.assertIn(n['id'], networks_list)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
+    @decorators.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
     def test_bulk_create_delete_subnet(self):
         networks = [self.create_network(), self.create_network()]
         # Creates 2 subnets in one request
@@ -504,7 +505,7 @@
             self.assertIn(n['id'], subnets_list)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
+    @decorators.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
     def test_bulk_create_delete_port(self):
         networks = [self.create_network(), self.create_network()]
         # Creates 2 ports in one request
@@ -537,7 +538,7 @@
 class NetworksIpV6Test(NetworksTest):
     _ip_version = 6
 
-    @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
+    @decorators.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
     def test_create_delete_subnet_with_gw(self):
         net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
         gateway = str(netaddr.IPAddress(net.first + 2))
@@ -546,7 +547,7 @@
         # Verifies Subnet GW in IPv6
         self.assertEqual(subnet['gateway_ip'], gateway)
 
-    @test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
+    @decorators.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
     def test_create_delete_subnet_with_default_gw(self):
         net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
         gateway_ip = str(netaddr.IPAddress(net.first + 1))
@@ -555,7 +556,7 @@
         # Verifies Subnet GW in IPv6
         self.assertEqual(subnet['gateway_ip'], gateway_ip)
 
-    @test.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
+    @decorators.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
     def test_create_list_subnet_with_no_gw64_one_network(self):
         network = self.create_network()
         ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
@@ -594,20 +595,20 @@
             raise cls.skipException("IPv6 extended attributes for "
                                     "subnets not available")
 
-    @test.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
+    @decorators.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
     def test_create_delete_subnet_with_v6_attributes_stateful(self):
         self._create_verify_delete_subnet(
             gateway=self._subnet_data[self._ip_version]['gateway'],
             ipv6_ra_mode='dhcpv6-stateful',
             ipv6_address_mode='dhcpv6-stateful')
 
-    @test.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
+    @decorators.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
     def test_create_delete_subnet_with_v6_attributes_slaac(self):
         self._create_verify_delete_subnet(
             ipv6_ra_mode='slaac',
             ipv6_address_mode='slaac')
 
-    @test.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
+    @decorators.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
     def test_create_delete_subnet_with_v6_attributes_stateless(self):
         self._create_verify_delete_subnet(
             ipv6_ra_mode='dhcpv6-stateless',
@@ -633,7 +634,7 @@
             self.networks_client.delete_network,
             slaac_network['id'])
 
-    @test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
+    @decorators.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
     def test_create_delete_slaac_subnet_with_ports(self):
         """Test deleting subnet with SLAAC ports
 
@@ -643,7 +644,7 @@
         """
         self._test_delete_subnet_with_ports("slaac")
 
-    @test.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
+    @decorators.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
     def test_create_delete_stateless_subnet_with_ports(self):
         """Test deleting subnet with DHCPv6 stateless ports
 
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index d87c2b6..3cc6fb7 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -16,6 +16,7 @@
 
 from tempest.api.network 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
 
@@ -23,28 +24,28 @@
 class NetworksNegativeTestJSON(base.BaseNetworkTest):
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
+    @decorators.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
     def test_show_non_existent_network(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.networks_client.show_network,
                           non_exist_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
+    @decorators.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
     def test_show_non_existent_subnet(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
                           non_exist_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('a954861d-cbfd-44e8-b0a9-7fab111f235d')
+    @decorators.idempotent_id('a954861d-cbfd-44e8-b0a9-7fab111f235d')
     def test_show_non_existent_port(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.ports_client.show_port,
                           non_exist_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('98bfe4e3-574e-4012-8b17-b2647063de87')
+    @decorators.idempotent_id('98bfe4e3-574e-4012-8b17-b2647063de87')
     def test_update_non_existent_network(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(
@@ -52,7 +53,7 @@
             non_exist_id, name="new_name")
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('03795047-4a94-4120-a0a1-bd376e36fd4e')
+    @decorators.idempotent_id('03795047-4a94-4120-a0a1-bd376e36fd4e')
     def test_delete_non_existent_network(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
@@ -60,21 +61,21 @@
                           non_exist_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('1cc47884-ac52-4415-a31c-e7ce5474a868')
+    @decorators.idempotent_id('1cc47884-ac52-4415-a31c-e7ce5474a868')
     def test_update_non_existent_subnet(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.subnets_client.update_subnet,
                           non_exist_id, name='new_name')
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('a176c859-99fb-42ec-a208-8a85b552a239')
+    @decorators.idempotent_id('a176c859-99fb-42ec-a208-8a85b552a239')
     def test_delete_non_existent_subnet(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.subnets_client.delete_subnet, non_exist_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('13d3b106-47e6-4b9b-8d53-dae947f092fe')
+    @decorators.idempotent_id('13d3b106-47e6-4b9b-8d53-dae947f092fe')
     def test_create_port_on_non_existent_network(self):
         non_exist_net_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
@@ -82,14 +83,14 @@
                           network_id=non_exist_net_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('cf8eef21-4351-4f53-adcd-cc5cb1e76b92')
+    @decorators.idempotent_id('cf8eef21-4351-4f53-adcd-cc5cb1e76b92')
     def test_update_non_existent_port(self):
         non_exist_port_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.ports_client.update_port,
                           non_exist_port_id, name='new_name')
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('49ec2bbd-ac2e-46fd-8054-798e679ff894')
+    @decorators.idempotent_id('49ec2bbd-ac2e-46fd-8054-798e679ff894')
     def test_delete_non_existent_port(self):
         non_exist_port_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index e7153f0..3908aae 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.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.lib import exceptions
 from tempest import test
 
@@ -52,7 +53,7 @@
         self.assertFalse(port_id in [n['id'] for n in ports_list])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('c72c1c0c-2193-4aca-aaa4-b1442640f51c')
+    @decorators.idempotent_id('c72c1c0c-2193-4aca-aaa4-b1442640f51c')
     def test_create_update_delete_port(self):
         # Verify port creation
         body = self.ports_client.create_port(network_id=self.network['id'])
@@ -69,7 +70,7 @@
         self.assertEqual(updated_port['name'], new_name)
         self.assertFalse(updated_port['admin_state_up'])
 
-    @test.idempotent_id('67f1b811-f8db-43e2-86bd-72c074d4a42c')
+    @decorators.idempotent_id('67f1b811-f8db-43e2-86bd-72c074d4a42c')
     def test_create_bulk_port(self):
         network1 = self.network
         network2 = self.create_network()
@@ -100,7 +101,7 @@
         return cidr
 
     @test.attr(type='smoke')
-    @test.idempotent_id('0435f278-40ae-48cb-a404-b8a087bc09b1')
+    @decorators.idempotent_id('0435f278-40ae-48cb-a404-b8a087bc09b1')
     def test_create_port_in_allowed_allocation_pools(self):
         network = self.create_network()
         net_id = network['id']
@@ -125,7 +126,7 @@
         self.assertIn(ip_address, ip_range)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
+    @decorators.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
     def test_show_port(self):
         # Verify the details of port
         body = self.ports_client.show_port(self.port['id'])
@@ -141,7 +142,7 @@
                                               'created_at',
                                               'updated_at']))
 
-    @test.idempotent_id('45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd')
+    @decorators.idempotent_id('45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd')
     def test_show_port_fields(self):
         # Verify specific fields of a port
         fields = ['id', 'mac_address']
@@ -153,7 +154,7 @@
             self.assertEqual(port[field_name], self.port[field_name])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('cf95b358-3e92-4a29-a148-52445e1ac50e')
+    @decorators.idempotent_id('cf95b358-3e92-4a29-a148-52445e1ac50e')
     def test_list_ports(self):
         # Verify the port exists in the list of all ports
         body = self.ports_client.list_ports()
@@ -161,7 +162,7 @@
                  if port['id'] == self.port['id']]
         self.assertNotEmpty(ports, "Created port not found in the list")
 
-    @test.idempotent_id('e7fe260b-1e79-4dd3-86d9-bec6a7959fc5')
+    @decorators.idempotent_id('e7fe260b-1e79-4dd3-86d9-bec6a7959fc5')
     def test_port_list_filter_by_ip(self):
         # Create network and subnet
         network = self.create_network()
@@ -192,7 +193,7 @@
         self.assertIn(port_1_fixed_ip, port_ips)
         self.assertIn(network['id'], port_net_ids)
 
-    @test.idempotent_id('5ad01ed0-0e6e-4c5d-8194-232801b15c72')
+    @decorators.idempotent_id('5ad01ed0-0e6e-4c5d-8194-232801b15c72')
     def test_port_list_filter_by_router_id(self):
         # Create a router
         network = self.create_network()
@@ -214,7 +215,7 @@
         self.assertEqual(ports[0]['id'], port['port']['id'])
         self.assertEqual(ports[0]['device_id'], router['id'])
 
-    @test.idempotent_id('ff7f117f-f034-4e0e-abff-ccef05c454b4')
+    @decorators.idempotent_id('ff7f117f-f034-4e0e-abff-ccef05c454b4')
     def test_list_ports_fields(self):
         # Verify specific fields of ports
         fields = ['id', 'mac_address']
@@ -225,7 +226,7 @@
         for port in ports:
             self.assertEqual(sorted(fields), sorted(port.keys()))
 
-    @test.idempotent_id('63aeadd4-3b49-427f-a3b1-19ca81f06270')
+    @decorators.idempotent_id('63aeadd4-3b49-427f-a3b1-19ca81f06270')
     def test_create_update_port_with_second_ip(self):
         # Create a network with two subnets
         network = self.create_network()
@@ -307,7 +308,7 @@
         for security_group in security_groups_list:
             self.assertIn(security_group, port_show['security_groups'])
 
-    @test.idempotent_id('58091b66-4ff4-4cc1-a549-05d60c7acd1a')
+    @decorators.idempotent_id('58091b66-4ff4-4cc1-a549-05d60c7acd1a')
     @testtools.skipUnless(
         test.is_extension_enabled('security-group', 'network'),
         'security-group extension not enabled.')
@@ -315,7 +316,7 @@
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup')])
 
-    @test.idempotent_id('edf6766d-3d40-4621-bc6e-2521a44c257d')
+    @decorators.idempotent_id('edf6766d-3d40-4621-bc6e-2521a44c257d')
     @testtools.skipUnless(
         test.is_extension_enabled('security-group', 'network'),
         'security-group extension not enabled.')
@@ -324,7 +325,7 @@
             [data_utils.rand_name('secgroup'),
              data_utils.rand_name('secgroup')])
 
-    @test.idempotent_id('13e95171-6cbd-489c-9d7c-3f9c58215c18')
+    @decorators.idempotent_id('13e95171-6cbd-489c-9d7c-3f9c58215c18')
     def test_create_show_delete_port_user_defined_mac(self):
         # Create a port for a legal mac
         body = self.ports_client.create_port(network_id=self.network['id'])
@@ -342,7 +343,7 @@
                          show_port['mac_address'])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('4179dcb9-1382-4ced-84fe-1b91c54f5735')
+    @decorators.idempotent_id('4179dcb9-1382-4ced-84fe-1b91c54f5735')
     @testtools.skipUnless(
         test.is_extension_enabled('security-group', 'network'),
         'security-group extension not enabled.')
@@ -365,7 +366,7 @@
         cls.network = cls.create_network()
         cls.host_id = socket.gethostname()
 
-    @test.idempotent_id('8e8569c1-9ac7-44db-8bc1-f5fb2814f29b')
+    @decorators.idempotent_id('8e8569c1-9ac7-44db-8bc1-f5fb2814f29b')
     def test_create_port_binding_ext_attr(self):
         post_body = {"network_id": self.network['id'],
                      "binding:host_id": self.host_id}
@@ -376,7 +377,7 @@
         self.assertIsNotNone(host_id)
         self.assertEqual(self.host_id, host_id)
 
-    @test.idempotent_id('6f6c412c-711f-444d-8502-0ac30fbf5dd5')
+    @decorators.idempotent_id('6f6c412c-711f-444d-8502-0ac30fbf5dd5')
     def test_update_port_binding_ext_attr(self):
         post_body = {"network_id": self.network['id']}
         body = self.admin_ports_client.create_port(**post_body)
@@ -389,7 +390,7 @@
         self.assertIsNotNone(host_id)
         self.assertEqual(self.host_id, host_id)
 
-    @test.idempotent_id('1c82a44a-6c6e-48ff-89e1-abe7eaf8f9f8')
+    @decorators.idempotent_id('1c82a44a-6c6e-48ff-89e1-abe7eaf8f9f8')
     def test_list_ports_binding_ext_attr(self):
         # Create a new port
         post_body = {"network_id": self.network['id']}
@@ -414,7 +415,7 @@
                          '%s' % (port['id'], ports_list))
         self.assertEqual(self.host_id, listed_port[0]['binding:host_id'])
 
-    @test.idempotent_id('b54ac0ff-35fc-4c79-9ca3-c7dbd4ea4f13')
+    @decorators.idempotent_id('b54ac0ff-35fc-4c79-9ca3-c7dbd4ea4f13')
     def test_show_port_binding_ext_attr(self):
         body = self.admin_ports_client.create_port(
             network_id=self.network['id'])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 101e4dd..524ab9e 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -18,6 +18,7 @@
 from tempest.api.network import base_routers as base
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest.lib import decorators
 from tempest import test
 
 CONF = config.CONF
@@ -40,7 +41,7 @@
                            CONF.network.project_network_v6_cidr)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('f64403e2-8483-4b34-8ccd-b09a87bcc68c')
+    @decorators.idempotent_id('f64403e2-8483-4b34-8ccd-b09a87bcc68c')
     def test_create_show_list_update_delete_router(self):
         # Create a router
         router = self._create_router(
@@ -69,7 +70,7 @@
             router['id'])['router']
         self.assertEqual(router_show['name'], updated_name)
 
-    @test.idempotent_id('e54dd3a3-4352-4921-b09d-44369ae17397')
+    @decorators.idempotent_id('e54dd3a3-4352-4921-b09d-44369ae17397')
     def test_create_router_setting_project_id(self):
         # Test creating router from admin user setting project_id.
         project = data_utils.rand_name('test_tenant_')
@@ -86,7 +87,7 @@
                         create_body['router']['id'])
         self.assertEqual(project_id, create_body['router']['tenant_id'])
 
-    @test.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
+    @decorators.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     def test_create_router_with_default_snat_value(self):
         # Create a router with default snat rule
@@ -96,7 +97,7 @@
             router['id'], {'network_id': CONF.network.public_network_id,
                            'enable_snat': True})
 
-    @test.idempotent_id('ea74068d-09e9-4fd7-8995-9b6a1ace920f')
+    @decorators.idempotent_id('ea74068d-09e9-4fd7-8995-9b6a1ace920f')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     def test_create_router_with_snat_explicit(self):
         name = data_utils.rand_name('snat-router')
@@ -115,7 +116,7 @@
                                         exp_ext_gw_info=external_gateway_info)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('b42e6e39-2e37-49cc-a6f4-8467e940900a')
+    @decorators.idempotent_id('b42e6e39-2e37-49cc-a6f4-8467e940900a')
     def test_add_remove_router_interface_with_subnet_id(self):
         network = self.create_network()
         subnet = self.create_subnet(network)
@@ -134,7 +135,7 @@
                          router['id'])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('2b7d2f37-6748-4d78-92e5-1d590234f0d5')
+    @decorators.idempotent_id('2b7d2f37-6748-4d78-92e5-1d590234f0d5')
     def test_add_remove_router_interface_with_port_id(self):
         network = self.create_network()
         self.create_subnet(network)
@@ -182,7 +183,7 @@
             subnet_id = fixed_ip['subnet_id']
             self.assertIn(subnet_id, public_subnet_ids)
 
-    @test.idempotent_id('6cc285d8-46bf-4f36-9b1a-783e3008ba79')
+    @decorators.idempotent_id('6cc285d8-46bf-4f36-9b1a-783e3008ba79')
     def test_update_router_set_gateway(self):
         router = self._create_router()
         self.routers_client.update_router(
@@ -195,7 +196,7 @@
             {'network_id': CONF.network.public_network_id})
         self._verify_gateway_port(router['id'])
 
-    @test.idempotent_id('b386c111-3b21-466d-880c-5e72b01e1a33')
+    @decorators.idempotent_id('b386c111-3b21-466d-880c-5e72b01e1a33')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     def test_update_router_set_gateway_with_snat_explicit(self):
         router = self._create_router()
@@ -210,7 +211,7 @@
              'enable_snat': True})
         self._verify_gateway_port(router['id'])
 
-    @test.idempotent_id('96536bc7-8262-4fb2-9967-5c46940fa279')
+    @decorators.idempotent_id('96536bc7-8262-4fb2-9967-5c46940fa279')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     def test_update_router_set_gateway_without_snat(self):
         router = self._create_router()
@@ -225,7 +226,7 @@
              'enable_snat': False})
         self._verify_gateway_port(router['id'])
 
-    @test.idempotent_id('ad81b7ee-4f81-407b-a19c-17e623f763e8')
+    @decorators.idempotent_id('ad81b7ee-4f81-407b-a19c-17e623f763e8')
     def test_update_router_unset_gateway(self):
         router = self._create_router(
             external_network_id=CONF.network.public_network_id)
@@ -238,7 +239,7 @@
             device_id=router['id'])
         self.assertFalse(list_body['ports'])
 
-    @test.idempotent_id('f2faf994-97f4-410b-a831-9bc977b64374')
+    @decorators.idempotent_id('f2faf994-97f4-410b-a831-9bc977b64374')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     def test_update_router_reset_gateway_without_snat(self):
         router = self._create_router(
@@ -254,7 +255,7 @@
              'enable_snat': False})
         self._verify_gateway_port(router['id'])
 
-    @test.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
+    @decorators.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
     @test.requires_ext(extension='extraroute', service='network')
     def test_update_delete_extra_route(self):
         # Create different cidr for each subnet to avoid cidr duplicate
@@ -316,7 +317,7 @@
     def _delete_extra_routes(self, router_id):
         self.routers_client.update_router(router_id, routes=None)
 
-    @test.idempotent_id('a8902683-c788-4246-95c7-ad9c6d63a4d9')
+    @decorators.idempotent_id('a8902683-c788-4246-95c7-ad9c6d63a4d9')
     def test_update_router_admin_state(self):
         router = self._create_router()
         self.assertFalse(router['admin_state_up'])
@@ -328,7 +329,7 @@
         self.assertTrue(show_body['router']['admin_state_up'])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('802c73c9-c937-4cef-824b-2191e24a6aab')
+    @decorators.idempotent_id('802c73c9-c937-4cef-824b-2191e24a6aab')
     def test_add_multiple_router_interfaces(self):
         network01 = self.create_network(
             network_name=data_utils.rand_name('router-network01-'))
@@ -347,7 +348,7 @@
         self._verify_router_interface(router['id'], subnet02['id'],
                                       interface02['port_id'])
 
-    @test.idempotent_id('96522edf-b4b5-45d9-8443-fa11c26e6eff')
+    @decorators.idempotent_id('96522edf-b4b5-45d9-8443-fa11c26e6eff')
     def test_router_interface_port_update_with_fixed_ip(self):
         network = self.create_network()
         subnet = self.create_subnet(network)
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index b3983de..2bda431 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -18,6 +18,7 @@
 from tempest.api.network import base_routers as 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
 
@@ -44,7 +45,7 @@
                            CONF.network.project_network_v6_cidr)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('37a94fc0-a834-45b9-bd23-9a81d2fd1e22')
+    @decorators.idempotent_id('37a94fc0-a834-45b9-bd23-9a81d2fd1e22')
     def test_router_add_gateway_invalid_network_returns_404(self):
         self.assertRaises(lib_exc.NotFound,
                           self.routers_client.update_router,
@@ -53,7 +54,7 @@
                               'network_id': self.router['id']})
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('11836a18-0b15-4327-a50b-f0d9dc66bddd')
+    @decorators.idempotent_id('11836a18-0b15-4327-a50b-f0d9dc66bddd')
     def test_router_add_gateway_net_not_external_returns_400(self):
         alt_network = self.create_network()
         sub_cidr = netaddr.IPNetwork(self.tenant_cidr).next()
@@ -65,7 +66,7 @@
                               'network_id': alt_network['id']})
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('957751a3-3c68-4fa2-93b6-eb52ea10db6e')
+    @decorators.idempotent_id('957751a3-3c68-4fa2-93b6-eb52ea10db6e')
     def test_add_router_interfaces_on_overlapping_subnets_returns_400(self):
         network01 = self.create_network(
             network_name=data_utils.rand_name('router-network01-'))
@@ -81,7 +82,7 @@
                           subnet02['id'])
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
+    @decorators.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
     def test_router_remove_interface_in_use_returns_409(self):
         self.routers_client.add_router_interface(self.router['id'],
                                                  subnet_id=self.subnet['id'])
@@ -90,21 +91,21 @@
                           self.router['id'])
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('c2a70d72-8826-43a7-8208-0209e6360c47')
+    @decorators.idempotent_id('c2a70d72-8826-43a7-8208-0209e6360c47')
     def test_show_non_existent_router_returns_404(self):
         router = data_utils.rand_name('non_exist_router')
         self.assertRaises(lib_exc.NotFound, self.routers_client.show_router,
                           router)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('b23d1569-8b0c-4169-8d4b-6abd34fad5c7')
+    @decorators.idempotent_id('b23d1569-8b0c-4169-8d4b-6abd34fad5c7')
     def test_update_non_existent_router_returns_404(self):
         router = data_utils.rand_name('non_exist_router')
         self.assertRaises(lib_exc.NotFound, self.routers_client.update_router,
                           router, name="new_name")
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('c7edc5ad-d09d-41e6-a344-5c0c31e2e3e4')
+    @decorators.idempotent_id('c7edc5ad-d09d-41e6-a344-5c0c31e2e3e4')
     def test_delete_non_existent_router_returns_404(self):
         router = data_utils.rand_name('non_exist_router')
         self.assertRaises(lib_exc.NotFound, self.routers_client.delete_router,
@@ -132,7 +133,7 @@
         cls.subnet = cls.create_subnet(cls.network)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('4990b055-8fc7-48ab-bba7-aa28beaad0b9')
+    @decorators.idempotent_id('4990b055-8fc7-48ab-bba7-aa28beaad0b9')
     def test_router_create_tenant_distributed_returns_forbidden(self):
         self.assertRaises(lib_exc.Forbidden, self.create_router,
                           distributed=True)
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index be01852..607baf0 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base_security_groups as base
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest.lib import decorators
 from tempest import test
 
 CONF = config.CONF
@@ -67,7 +68,7 @@
                              (key, value))
 
     @test.attr(type='smoke')
-    @test.idempotent_id('e30abd17-fef9-4739-8617-dc26da88e686')
+    @decorators.idempotent_id('e30abd17-fef9-4739-8617-dc26da88e686')
     def test_list_security_groups(self):
         # Verify the security group belonging to project exist in list
         body = self.security_groups_client.list_security_groups()
@@ -80,7 +81,7 @@
         self.assertIsNotNone(found, msg)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('bfd128e5-3c92-44b6-9d66-7fe29d22c802')
+    @decorators.idempotent_id('bfd128e5-3c92-44b6-9d66-7fe29d22c802')
     def test_create_list_update_show_delete_security_group(self):
         group_create_body, name = self._create_security_group()
 
@@ -109,7 +110,7 @@
                          new_description)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('cfb99e0e-7410-4a3d-8a0c-959a63ee77e9')
+    @decorators.idempotent_id('cfb99e0e-7410-4a3d-8a0c-959a63ee77e9')
     def test_create_show_delete_security_group_rule(self):
         group_create_body, _ = self._create_security_group()
 
@@ -142,7 +143,7 @@
             self.assertIn(rule_create_body['security_group_rule']['id'],
                           rule_list)
 
-    @test.idempotent_id('87dfbcf9-1849-43ea-b1e4-efa3eeae9f71')
+    @decorators.idempotent_id('87dfbcf9-1849-43ea-b1e4-efa3eeae9f71')
     def test_create_security_group_rule_with_additional_args(self):
         """Verify security group rule with additional arguments works.
 
@@ -160,7 +161,7 @@
                                                 port_range_min,
                                                 port_range_max)
 
-    @test.idempotent_id('c9463db8-b44d-4f52-b6c0-8dbda99f26ce')
+    @decorators.idempotent_id('c9463db8-b44d-4f52-b6c0-8dbda99f26ce')
     def test_create_security_group_rule_with_icmp_type_code(self):
         """Verify security group rule for icmp protocol works.
 
@@ -180,7 +181,7 @@
                                                     self.ethertype, protocol,
                                                     icmp_type, icmp_code)
 
-    @test.idempotent_id('c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b')
+    @decorators.idempotent_id('c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b')
     def test_create_security_group_rule_with_remote_group_id(self):
         # Verify creating security group rule with remote_group_id works
         sg1_body, _ = self._create_security_group()
@@ -198,7 +199,7 @@
                                                 port_range_max,
                                                 remote_group_id=remote_id)
 
-    @test.idempotent_id('16459776-5da2-4634-bce4-4b55ee3ec188')
+    @decorators.idempotent_id('16459776-5da2-4634-bce4-4b55ee3ec188')
     def test_create_security_group_rule_with_remote_ip_prefix(self):
         # Verify creating security group rule with remote_ip_prefix works
         sg1_body, _ = self._create_security_group()
@@ -215,7 +216,7 @@
                                                 port_range_max,
                                                 remote_ip_prefix=ip_prefix)
 
-    @test.idempotent_id('0a307599-6655-4220-bebc-fd70c64f2290')
+    @decorators.idempotent_id('0a307599-6655-4220-bebc-fd70c64f2290')
     def test_create_security_group_rule_with_protocol_integer_value(self):
         # Verify creating security group rule with the
         # protocol as integer value
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index a3b0a82..f46b873 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -16,6 +16,7 @@
 from tempest.api.network import base_security_groups as base
 from tempest import config
 from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -33,7 +34,7 @@
             raise cls.skipException(msg)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('424fd5c3-9ddc-486a-b45f-39bf0c820fc6')
+    @decorators.idempotent_id('424fd5c3-9ddc-486a-b45f-39bf0c820fc6')
     def test_show_non_existent_security_group(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(
@@ -41,7 +42,7 @@
             non_exist_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('4c094c09-000b-4e41-8100-9617600c02a6')
+    @decorators.idempotent_id('4c094c09-000b-4e41-8100-9617600c02a6')
     def test_show_non_existent_security_group_rule(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(
@@ -50,7 +51,7 @@
             non_exist_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('1f1bb89d-5664-4956-9fcd-83ee0fa603df')
+    @decorators.idempotent_id('1f1bb89d-5664-4956-9fcd-83ee0fa603df')
     def test_delete_non_existent_security_group(self):
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
@@ -59,7 +60,7 @@
                           )
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('981bdc22-ce48-41ed-900a-73148b583958')
+    @decorators.idempotent_id('981bdc22-ce48-41ed-900a-73148b583958')
     def test_create_security_group_rule_with_bad_protocol(self):
         group_create_body, _ = self._create_security_group()
 
@@ -72,7 +73,7 @@
             protocol=pname, direction='ingress', ethertype=self.ethertype)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('5f8daf69-3c5f-4aaa-88c9-db1d66f68679')
+    @decorators.idempotent_id('5f8daf69-3c5f-4aaa-88c9-db1d66f68679')
     def test_create_security_group_rule_with_bad_remote_ip_prefix(self):
         group_create_body, _ = self._create_security_group()
 
@@ -87,7 +88,7 @@
                 remote_ip_prefix=remote_ip_prefix)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('4bf786fd-2f02-443c-9716-5b98e159a49a')
+    @decorators.idempotent_id('4bf786fd-2f02-443c-9716-5b98e159a49a')
     def test_create_security_group_rule_with_non_existent_remote_groupid(self):
         group_create_body, _ = self._create_security_group()
         non_exist_id = data_utils.rand_uuid()
@@ -103,7 +104,7 @@
                 remote_group_id=remote_group_id)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('b5c4b247-6b02-435b-b088-d10d45650881')
+    @decorators.idempotent_id('b5c4b247-6b02-435b-b088-d10d45650881')
     def test_create_security_group_rule_with_remote_ip_and_group(self):
         sg1_body, _ = self._create_security_group()
         sg2_body, _ = self._create_security_group()
@@ -119,7 +120,7 @@
             remote_group_id=sg2_body['security_group']['id'])
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('5666968c-fff3-40d6-9efc-df1c8bd01abb')
+    @decorators.idempotent_id('5666968c-fff3-40d6-9efc-df1c8bd01abb')
     def test_create_security_group_rule_with_bad_ethertype(self):
         group_create_body, _ = self._create_security_group()
 
@@ -132,7 +133,7 @@
             protocol='udp', direction='ingress', ethertype=ethertype)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d')
+    @decorators.idempotent_id('0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d')
     def test_create_security_group_rule_with_invalid_ports(self):
         group_create_body, _ = self._create_security_group()
 
@@ -166,7 +167,7 @@
             self.assertIn(msg, str(ex))
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('2323061e-9fbf-4eb0-b547-7e8fafc90849')
+    @decorators.idempotent_id('2323061e-9fbf-4eb0-b547-7e8fafc90849')
     def test_create_additional_default_security_group_fails(self):
         # Create security group named 'default', it should be failed.
         name = 'default'
@@ -175,7 +176,7 @@
                           name=name)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('8fde898f-ce88-493b-adc9-4e4692879fc5')
+    @decorators.idempotent_id('8fde898f-ce88-493b-adc9-4e4692879fc5')
     def test_create_duplicate_security_group_rule_fails(self):
         # Create duplicate security group rule, it should fail.
         body, _ = self._create_security_group()
@@ -201,7 +202,7 @@
             port_range_min=min_port, port_range_max=max_port)
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('be308db6-a7cf-4d5c-9baf-71bafd73f35e')
+    @decorators.idempotent_id('be308db6-a7cf-4d5c-9baf-71bafd73f35e')
     def test_create_security_group_rule_with_non_existent_security_group(self):
         # Create security group rules with not existing security group.
         non_existent_sg = data_utils.rand_uuid()
@@ -217,7 +218,7 @@
     _project_network_cidr = CONF.network.project_network_v6_cidr
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('7607439c-af73-499e-bf64-f687fd12a842')
+    @decorators.idempotent_id('7607439c-af73-499e-bf64-f687fd12a842')
     def test_create_security_group_rule_wrong_ip_prefix_version(self):
         group_create_body, _ = self._create_security_group()
 
diff --git a/tempest/api/network/test_service_providers.py b/tempest/api/network/test_service_providers.py
index be17b3e..b90c81b 100644
--- a/tempest/api/network/test_service_providers.py
+++ b/tempest/api/network/test_service_providers.py
@@ -13,12 +13,13 @@
 import testtools
 
 from tempest.api.network import base
+from tempest.lib import decorators
 from tempest import test
 
 
 class ServiceProvidersTest(base.BaseNetworkTest):
 
-    @test.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
+    @decorators.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
     @testtools.skipUnless(
         test.is_extension_enabled('service-type', 'network'),
         'service-type extension not enabled.')
diff --git a/tempest/api/network/test_subnetpools_extensions.py b/tempest/api/network/test_subnetpools_extensions.py
index d574d72..d9599c4 100644
--- a/tempest/api/network/test_subnetpools_extensions.py
+++ b/tempest/api/network/test_subnetpools_extensions.py
@@ -16,6 +16,7 @@
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -46,7 +47,7 @@
             raise cls.skipException(msg)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e9811')
+    @decorators.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e9811')
     def test_create_list_show_update_delete_subnetpools(self):
         subnetpool_name = data_utils.rand_name('subnetpools')
         # create subnet pool
diff --git a/tempest/api/network/test_versions.py b/tempest/api/network/test_versions.py
index 9cf93f6..4f6d5ac 100644
--- a/tempest/api/network/test_versions.py
+++ b/tempest/api/network/test_versions.py
@@ -13,12 +13,13 @@
 # under the License.
 
 from tempest.api.network import base
+from tempest.lib import decorators
 from tempest import test
 
 
 class NetworksApiDiscovery(base.BaseNetworkTest):
     @test.attr(type='smoke')
-    @test.idempotent_id('cac8a836-c2e0-4304-b556-cd299c7281d1')
+    @decorators.idempotent_id('cac8a836-c2e0-4304-b556-cd299c7281d1')
     def test_api_version_resources(self):
         """Test that GET / returns expected resources.
 
diff --git a/tempest/api/orchestration/stacks/test_environment.py b/tempest/api/orchestration/stacks/test_environment.py
index f2ffbd7..0a9b3e5 100644
--- a/tempest/api/orchestration/stacks/test_environment.py
+++ b/tempest/api/orchestration/stacks/test_environment.py
@@ -12,12 +12,12 @@
 
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
 
 
 class StackEnvironmentTest(base.BaseOrchestrationTest):
 
-    @test.idempotent_id('37d4346b-1abd-4442-b7b1-2a4e5749a1e3')
+    @decorators.idempotent_id('37d4346b-1abd-4442-b7b1-2a4e5749a1e3')
     def test_environment_parameter(self):
         """Test passing a stack parameter via the environment."""
         stack_name = data_utils.rand_name('heat')
@@ -34,7 +34,7 @@
         random_value = self.get_stack_output(stack_identifier, 'random_value')
         self.assertEqual(20, len(random_value))
 
-    @test.idempotent_id('73bce717-ad22-4853-bbef-6ed89b632701')
+    @decorators.idempotent_id('73bce717-ad22-4853-bbef-6ed89b632701')
     def test_environment_provider_resource(self):
         """Test passing resource_registry defining a provider resource."""
         stack_name = data_utils.rand_name('heat')
@@ -63,7 +63,7 @@
             'random_length']['default']
         self.assertEqual(expected_length, len(random_value))
 
-    @test.idempotent_id('9d682e5a-f4bb-47d5-8472-9d3cacb855df')
+    @decorators.idempotent_id('9d682e5a-f4bb-47d5-8472-9d3cacb855df')
     def test_files_provider_resource(self):
         """Test untyped defining of a provider resource via "files"."""
         # It's also possible to specify the filename directly in the template.
diff --git a/tempest/api/orchestration/stacks/test_limits.py b/tempest/api/orchestration/stacks/test_limits.py
index d85aa96..b079435 100644
--- a/tempest/api/orchestration/stacks/test_limits.py
+++ b/tempest/api/orchestration/stacks/test_limits.py
@@ -13,15 +13,15 @@
 from tempest.api.orchestration 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
 
 CONF = config.CONF
 
 
 class TestServerStackLimits(base.BaseOrchestrationTest):
 
-    @test.idempotent_id('ec9bed71-c460-45c9-ab98-295caa9fd76b')
+    @decorators.idempotent_id('ec9bed71-c460-45c9-ab98-295caa9fd76b')
     def test_exceed_max_template_size_fails(self):
         stack_name = data_utils.rand_name('heat')
         fill = 'A' * CONF.orchestration.max_template_size
@@ -34,7 +34,7 @@
                                stack_name, template)
         self.assertIn('exceeds maximum allowed size', str(ex))
 
-    @test.idempotent_id('d1b83e73-7cad-4a22-9839-036548c5387c')
+    @decorators.idempotent_id('d1b83e73-7cad-4a22-9839-036548c5387c')
     def test_exceed_max_resources_per_stack(self):
         stack_name = data_utils.rand_name('heat')
         # Create a big template, one resource more than the limit
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 5d680d2..3a52108 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -16,6 +16,7 @@
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest.lib import decorators
 from tempest.lib import exceptions
 from tempest import test
 
@@ -94,7 +95,7 @@
         for resource in resources:
             cls.test_resources[resource['logical_resource_id']] = resource
 
-    @test.idempotent_id('f9e2664c-bc44-4eef-98b6-495e4f9d74b3')
+    @decorators.idempotent_id('f9e2664c-bc44-4eef-98b6-495e4f9d74b3')
     def test_created_resources(self):
         """Verifies created neutron resources."""
         resources = [('Network', self.neutron_basic_template['resources'][
@@ -112,7 +113,7 @@
             self.assertEqual(resource_type, resource['resource_type'])
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
-    @test.idempotent_id('c572b915-edb1-4e90-b196-c7199a6848c0')
+    @decorators.idempotent_id('c572b915-edb1-4e90-b196-c7199a6848c0')
     @test.services('network')
     def test_created_network(self):
         """Verifies created network."""
@@ -124,7 +125,7 @@
         self.assertEqual(self.neutron_basic_template['resources'][
             'Network']['properties']['name'], network['name'])
 
-    @test.idempotent_id('e8f84b96-f9d7-4684-ad5f-340203e9f2c2')
+    @decorators.idempotent_id('e8f84b96-f9d7-4684-ad5f-340203e9f2c2')
     @test.services('network')
     def test_created_subnet(self):
         """Verifies created subnet."""
@@ -142,7 +143,7 @@
             'Subnet']['properties']['ip_version'], subnet['ip_version'])
         self.assertEqual(str(self.subnet_cidr), subnet['cidr'])
 
-    @test.idempotent_id('96af4c7f-5069-44bc-bdcf-c0390f8a67d1')
+    @decorators.idempotent_id('96af4c7f-5069-44bc-bdcf-c0390f8a67d1')
     @test.services('network')
     def test_created_router(self):
         """Verifies created router."""
@@ -155,7 +156,7 @@
                          router['external_gateway_info']['network_id'])
         self.assertEqual(True, router['admin_state_up'])
 
-    @test.idempotent_id('89f605bd-153e-43ee-a0ed-9919b63423c5')
+    @decorators.idempotent_id('89f605bd-153e-43ee-a0ed-9919b63423c5')
     @test.services('network')
     def test_created_router_interface(self):
         """Verifies created router interface."""
@@ -178,7 +179,7 @@
         self.assertEqual(str(self.subnet_cidr.iter_hosts().next()),
                          router_interface_ip)
 
-    @test.idempotent_id('75d85316-4ac2-4c0e-a1a9-edd2148fc10e')
+    @decorators.idempotent_id('75d85316-4ac2-4c0e-a1a9-edd2148fc10e')
     @test.services('compute', 'network')
     def test_created_server(self):
         """Verifies created sever."""
diff --git a/tempest/api/orchestration/stacks/test_non_empty_stack.py b/tempest/api/orchestration/stacks/test_non_empty_stack.py
index 4ead084..f106349 100644
--- a/tempest/api/orchestration/stacks/test_non_empty_stack.py
+++ b/tempest/api/orchestration/stacks/test_non_empty_stack.py
@@ -13,7 +13,7 @@
 from tempest.api.orchestration 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
 
@@ -49,14 +49,14 @@
             self.assertEqual(expected_num, len(stacks))
         return stacks
 
-    @test.idempotent_id('065c652a-720d-4760-9132-06aedeb8e3ab')
+    @decorators.idempotent_id('065c652a-720d-4760-9132-06aedeb8e3ab')
     def test_stack_list(self):
         """Created stack should be in the list of existing stacks."""
         stacks = self._list_stacks()
         stacks_names = map(lambda stack: stack['stack_name'], stacks)
         self.assertIn(self.stack_name, stacks_names)
 
-    @test.idempotent_id('992f96e3-41ee-4ff6-91c7-bcfb670c0919')
+    @decorators.idempotent_id('992f96e3-41ee-4ff6-91c7-bcfb670c0919')
     def test_stack_show(self):
         """Getting details about created stack should be possible."""
         stack = self.client.show_stack(self.stack_name)['stack']
@@ -75,7 +75,7 @@
         self.assertEqual(self.stack_id, stack['id'])
         self.assertEqual('fluffy', stack['outputs'][0]['output_key'])
 
-    @test.idempotent_id('fe719f7a-305a-44d8-bbb5-c91e93d9da17')
+    @decorators.idempotent_id('fe719f7a-305a-44d8-bbb5-c91e93d9da17')
     def test_suspend_resume_stack(self):
         """Suspend and resume a stack."""
         self.client.suspend_stack(self.stack_identifier)
@@ -85,13 +85,13 @@
         self.client.wait_for_stack_status(self.stack_identifier,
                                           'RESUME_COMPLETE')
 
-    @test.idempotent_id('c951d55e-7cce-4c1f-83a0-bad735437fa6')
+    @decorators.idempotent_id('c951d55e-7cce-4c1f-83a0-bad735437fa6')
     def test_list_resources(self):
         """Get list of created resources for the stack should be possible."""
         resources = self.list_resources(self.stack_identifier)
         self.assertEqual({self.resource_name: self.resource_type}, resources)
 
-    @test.idempotent_id('2aba03b3-392f-4237-900b-1f5a5e9bd962')
+    @decorators.idempotent_id('2aba03b3-392f-4237-900b-1f5a5e9bd962')
     def test_show_resource(self):
         """Getting details about created resource should be possible."""
         resource = self.client.show_resource(self.stack_identifier,
@@ -105,7 +105,7 @@
         self.assertEqual(self.resource_name, resource['logical_resource_id'])
         self.assertEqual(self.resource_type, resource['resource_type'])
 
-    @test.idempotent_id('898070a9-eba5-4fae-b7d6-cf3ffa03090f')
+    @decorators.idempotent_id('898070a9-eba5-4fae-b7d6-cf3ffa03090f')
     def test_resource_metadata(self):
         """Getting metadata for created resources should be possible."""
         metadata = self.client.show_resource_metadata(
@@ -114,7 +114,7 @@
         self.assertIsInstance(metadata, dict)
         self.assertEqual(['Tom', 'Stinky'], metadata.get('kittens', None))
 
-    @test.idempotent_id('46567533-0a7f-483b-8942-fa19e0f17839')
+    @decorators.idempotent_id('46567533-0a7f-483b-8942-fa19e0f17839')
     def test_list_events(self):
         """Getting list of created events for the stack should be possible."""
         events = self.client.list_events(self.stack_identifier)['events']
@@ -129,7 +129,7 @@
         self.assertIn('CREATE_IN_PROGRESS', resource_statuses)
         self.assertIn('CREATE_COMPLETE', resource_statuses)
 
-    @test.idempotent_id('92465723-1673-400a-909d-4773757a3f21')
+    @decorators.idempotent_id('92465723-1673-400a-909d-4773757a3f21')
     def test_show_event(self):
         """Getting details about an event should be possible."""
         events = self.client.list_resource_events(self.stack_identifier,
diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
index 16d8180..4d1db6d 100644
--- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -12,7 +12,7 @@
 
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
 
 
 class NovaKeyPairResourcesYAMLTest(base.BaseOrchestrationTest):
@@ -43,7 +43,7 @@
         for resource in resources:
             cls.test_resources[resource['logical_resource_id']] = resource
 
-    @test.idempotent_id('b476eac2-a302-4815-961f-18c410a2a537')
+    @decorators.idempotent_id('b476eac2-a302-4815-961f-18c410a2a537')
     def test_created_resources(self):
         """Verifies created keypair resource."""
 
@@ -63,7 +63,7 @@
             self.assertEqual(resource_type, resource['resource_type'])
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
-    @test.idempotent_id('8d77dec7-91fd-45a6-943d-5abd45e338a4')
+    @decorators.idempotent_id('8d77dec7-91fd-45a6-943d-5abd45e338a4')
     def test_stack_keypairs_output(self):
         stack = self.client.show_stack(self.stack_name)['stack']
         self.assertIsInstance(stack, dict)
diff --git a/tempest/api/orchestration/stacks/test_resource_types.py b/tempest/api/orchestration/stacks/test_resource_types.py
index 8cf40de..63376d5 100644
--- a/tempest/api/orchestration/stacks/test_resource_types.py
+++ b/tempest/api/orchestration/stacks/test_resource_types.py
@@ -11,13 +11,14 @@
 #    under the License.
 
 from tempest.api.orchestration import base
+from tempest.lib import decorators
 from tempest import test
 
 
 class ResourceTypesTest(base.BaseOrchestrationTest):
 
     @test.attr(type='smoke')
-    @test.idempotent_id('7123d082-3577-4a30-8f00-f805327c4ffd')
+    @decorators.idempotent_id('7123d082-3577-4a30-8f00-f805327c4ffd')
     def test_resource_type_list(self):
         """Verify it is possible to list resource types."""
         resource_types = self.client.list_resource_types()['resource_types']
@@ -25,7 +26,7 @@
         self.assertIn('OS::Nova::Server', resource_types)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('0e85a483-828b-4a28-a0e3-f0a21809192b')
+    @decorators.idempotent_id('0e85a483-828b-4a28-a0e3-f0a21809192b')
     def test_resource_type_show(self):
         """Verify it is possible to get schema about resource types."""
         resource_types = self.client.list_resource_types()['resource_types']
@@ -38,7 +39,7 @@
             self.assertEqual(resource_type, type_schema['resource_type'])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('8401821d-65fe-4d43-9fa3-57d5ce3a35c7')
+    @decorators.idempotent_id('8401821d-65fe-4d43-9fa3-57d5ce3a35c7')
     def test_resource_type_template(self):
         """Verify it is possible to get template about resource types."""
         type_template = self.client.show_resource_type_template(
diff --git a/tempest/api/orchestration/stacks/test_soft_conf.py b/tempest/api/orchestration/stacks/test_soft_conf.py
index b660f6e..89b10cc 100644
--- a/tempest/api/orchestration/stacks/test_soft_conf.py
+++ b/tempest/api/orchestration/stacks/test_soft_conf.py
@@ -12,6 +12,7 @@
 
 from tempest.api.orchestration 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
 
@@ -75,7 +76,7 @@
             lib_exc.NotFound, self.client.show_software_config, config_id)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('136162ed-9445-4b9c-b7fc-306af8b5da99')
+    @decorators.idempotent_id('136162ed-9445-4b9c-b7fc-306af8b5da99')
     def test_get_software_config(self):
         """Testing software config get."""
         for conf in self.configs:
@@ -83,7 +84,7 @@
             self._validate_config(conf, api_config)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('1275c835-c967-4a2c-8d5d-ad533447ed91')
+    @decorators.idempotent_id('1275c835-c967-4a2c-8d5d-ad533447ed91')
     def test_get_deployment_list(self):
         """Getting a list of all deployments"""
         deploy_list = self.client.list_software_deployments()
@@ -92,7 +93,7 @@
         self.assertIn(self.deployment_id, deploy_ids)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('fe7cd9f9-54b1-429c-a3b7-7df8451db913')
+    @decorators.idempotent_id('fe7cd9f9-54b1-429c-a3b7-7df8451db913')
     def test_get_deployment_metadata(self):
         """Testing deployment metadata get"""
         metadata = self.client.show_software_deployment_metadata(
@@ -110,7 +111,7 @@
                          deployment['software_deployment']['config_id'])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('f29d21f3-ed75-47cf-8cdc-ef1bdeb4c674')
+    @decorators.idempotent_id('f29d21f3-ed75-47cf-8cdc-ef1bdeb4c674')
     def test_software_deployment_create_validate(self):
         """Testing software deployment was created as expected."""
         # Asserting that all fields were created
@@ -123,7 +124,7 @@
                                   self.status_reason, self.configs[0]['id'])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('2ac43ab3-34f2-415d-be2e-eabb4d14ee32')
+    @decorators.idempotent_id('2ac43ab3-34f2-415d-be2e-eabb4d14ee32')
     def test_software_deployment_update_no_metadata_change(self):
         """Testing software deployment update without metadata change."""
         metadata = self.client.show_software_deployment_metadata(
@@ -149,7 +150,7 @@
                 test_metadata['metadata'][0][key])
 
     @test.attr(type='smoke')
-    @test.idempotent_id('92c48944-d79d-4595-a840-8e1a581c1a72')
+    @decorators.idempotent_id('92c48944-d79d-4595-a840-8e1a581c1a72')
     def test_software_deployment_update_with_metadata_change(self):
         """Testing software deployment update with metadata change."""
         metadata = self.client.show_software_deployment_metadata(
diff --git a/tempest/api/orchestration/stacks/test_stacks.py b/tempest/api/orchestration/stacks/test_stacks.py
index f13a2d9..7b5f161 100644
--- a/tempest/api/orchestration/stacks/test_stacks.py
+++ b/tempest/api/orchestration/stacks/test_stacks.py
@@ -12,6 +12,7 @@
 
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -19,13 +20,13 @@
     empty_template = "HeatTemplateFormatVersion: '2012-12-12'\n"
 
     @test.attr(type='smoke')
-    @test.idempotent_id('d35d628c-07f6-4674-85a1-74db9919e986')
+    @decorators.idempotent_id('d35d628c-07f6-4674-85a1-74db9919e986')
     def test_stack_list_responds(self):
         stacks = self.client.list_stacks()['stacks']
         self.assertIsInstance(stacks, list)
 
     @test.attr(type='smoke')
-    @test.idempotent_id('10498bd5-a83e-4b62-a817-ce24afe938fe')
+    @decorators.idempotent_id('10498bd5-a83e-4b62-a817-ce24afe938fe')
     def test_stack_crud_no_resources(self):
         stack_name = data_utils.rand_name('heat')
 
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
index 3672526..505abe7 100644
--- a/tempest/api/orchestration/stacks/test_swift_resources.py
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -15,6 +15,7 @@
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest.lib import decorators
 from tempest import test
 
 
@@ -59,7 +60,7 @@
         for resource in resources:
             cls.test_resources[resource['logical_resource_id']] = resource
 
-    @test.idempotent_id('1a6fe69e-4be4-4990-9a7a-84b6f18019cb')
+    @decorators.idempotent_id('1a6fe69e-4be4-4990-9a7a-84b6f18019cb')
     def test_created_resources(self):
         """Created stack should be in the list of existing stacks."""
         swift_basic_template = self.load_template('swift_basic')
@@ -74,7 +75,7 @@
             self.assertEqual(resource_name, resource['logical_resource_id'])
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
-    @test.idempotent_id('bd438b18-5494-4d5a-9ce6-d2a942ec5060')
+    @decorators.idempotent_id('bd438b18-5494-4d5a-9ce6-d2a942ec5060')
     @test.services('object_storage')
     def test_created_containers(self):
         params = {'format': 'json'}
@@ -84,7 +85,7 @@
                               if cont['name'].startswith(self.stack_name)]
         self.assertEqual(2, len(created_containers))
 
-    @test.idempotent_id('73d0c093-9922-44a0-8b1d-1fc092dee367')
+    @decorators.idempotent_id('73d0c093-9922-44a0-8b1d-1fc092dee367')
     @test.services('object_storage')
     def test_acl(self):
         acl_headers = ('x-container-meta-web-index', 'x-container-read')
@@ -102,7 +103,7 @@
         for h in acl_headers:
             self.assertIn(h, headers)
 
-    @test.idempotent_id('fda06135-6777-4594-aefa-0f6107169698')
+    @decorators.idempotent_id('fda06135-6777-4594-aefa-0f6107169698')
     @test.services('object_storage')
     def test_metadata(self):
         swift_basic_template = self.load_template('swift_basic')
diff --git a/tempest/api/orchestration/stacks/test_templates.py b/tempest/api/orchestration/stacks/test_templates.py
index 9154175..21548a0 100644
--- a/tempest/api/orchestration/stacks/test_templates.py
+++ b/tempest/api/orchestration/stacks/test_templates.py
@@ -12,7 +12,7 @@
 
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
 
 
 class TemplateYAMLTestJSON(base.BaseOrchestrationTest):
@@ -35,12 +35,12 @@
         cls.stack_id = cls.stack_identifier.split('/')[1]
         cls.parameters = {}
 
-    @test.idempotent_id('47430699-c368-495e-a1db-64c26fd967d7')
+    @decorators.idempotent_id('47430699-c368-495e-a1db-64c26fd967d7')
     def test_show_template(self):
         """Getting template used to create the stack."""
         self.client.show_template(self.stack_identifier)
 
-    @test.idempotent_id('ed53debe-8727-46c5-ab58-eba6090ec4de')
+    @decorators.idempotent_id('ed53debe-8727-46c5-ab58-eba6090ec4de')
     def test_validate_template(self):
         """Validating template passing it content."""
         self.client.validate_template(self.template,
diff --git a/tempest/api/orchestration/stacks/test_templates_negative.py b/tempest/api/orchestration/stacks/test_templates_negative.py
index f8245c1..a90abe2 100644
--- a/tempest/api/orchestration/stacks/test_templates_negative.py
+++ b/tempest/api/orchestration/stacks/test_templates_negative.py
@@ -13,6 +13,7 @@
 #    under the License.
 
 from tempest.api.orchestration import base
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -35,7 +36,7 @@
         cls.parameters = {}
 
     @test.attr(type=['negative'])
-    @test.idempotent_id('5586cbca-ddc4-4152-9db8-fa1ce5fc1876')
+    @decorators.idempotent_id('5586cbca-ddc4-4152-9db8-fa1ce5fc1876')
     def test_validate_template_url(self):
         """Validating template passing url to it."""
         self.assertRaises(lib_exc.BadRequest,
diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py
index a5aaf6e..d34eb89 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -13,6 +13,7 @@
 from tempest.api.orchestration 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
 
@@ -58,7 +59,7 @@
         self.assertEqual(template['resources']['volume']['properties'][
             'name'], self.get_stack_output(stack_identifier, 'display_name'))
 
-    @test.idempotent_id('c3243329-7bdd-4730-b402-4d19d50c41d8')
+    @decorators.idempotent_id('c3243329-7bdd-4730-b402-4d19d50c41d8')
     @test.services('volume')
     def test_cinder_volume_create_delete(self):
         """Create and delete a volume via OS::Cinder::Volume."""
@@ -92,7 +93,7 @@
         self.volumes_client.delete_volume(volume_id)
         self.volumes_client.wait_for_resource_deletion(volume_id)
 
-    @test.idempotent_id('ea8b3a46-b932-4c18-907a-fe23f00b33f8')
+    @decorators.idempotent_id('ea8b3a46-b932-4c18-907a-fe23f00b33f8')
     @test.services('volume')
     def test_cinder_volume_create_delete_retain(self):
         """Ensure the 'Retain' deletion policy is respected."""
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index bcdbd22..4c31a89 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -51,10 +51,10 @@
         # Should not be able to create volume with invalid size
         # in request
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.BadRequest,
                           self.volumes_client.create_volume,
-                          size='#$%', display_name=v_name, metadata=metadata)
+                          size='#$%', params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('9387686f-334f-4d31-a439-33494b9e2683')
@@ -62,89 +62,85 @@
         # Should not be able to create volume without passing size
         # in request
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.BadRequest,
                           self.volumes_client.create_volume,
-                          size='', display_name=v_name, metadata=metadata)
+                          size='', params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('41331caa-eaf4-4001-869d-bc18c1869360')
     def test_create_volume_with_size_zero(self):
         # Should not be able to create volume with size zero
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.BadRequest,
                           self.volumes_client.create_volume,
-                          size='0', display_name=v_name, metadata=metadata)
+                          size='0', params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('8b472729-9eba-446e-a83b-916bdb34bef7')
     def test_create_volume_with_size_negative(self):
         # Should not be able to create volume with size negative
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.BadRequest,
                           self.volumes_client.create_volume,
-                          size='-1', display_name=v_name, metadata=metadata)
+                          size='-1', params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('10254ed8-3849-454e-862e-3ab8e6aa01d2')
     def test_create_volume_with_nonexistent_volume_type(self):
         # Should not be able to create volume with non-existent volume type
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
                           size='1', volume_type=data_utils.rand_uuid(),
-                          display_name=v_name, metadata=metadata)
+                          params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('0c36f6ae-4604-4017-b0a9-34fdc63096f9')
     def test_create_volume_with_nonexistent_snapshot_id(self):
         # Should not be able to create volume with non-existent snapshot
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
                           size='1', snapshot_id=data_utils.rand_uuid(),
-                          display_name=v_name, metadata=metadata)
+                          params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('47c73e08-4be8-45bb-bfdf-0c4e79b88344')
     def test_create_volume_with_nonexistent_source_volid(self):
         # Should not be able to create volume with non-existent source volume
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.NotFound, self.volumes_client.create_volume,
                           size='1', source_volid=data_utils.rand_uuid(),
-                          display_name=v_name, metadata=metadata)
+                          params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('0186422c-999a-480e-a026-6a665744c30c')
     def test_update_volume_with_nonexistent_volume_id(self):
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
-                          volume_id=data_utils.rand_uuid(),
-                          display_name=v_name,
-                          metadata=metadata)
+                          volume_id=data_utils.rand_uuid(), params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('e66e40d6-65e6-4e75-bdc7-636792fa152d')
     def test_update_volume_with_invalid_volume_id(self):
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
                           volume_id=data_utils.rand_name('invalid'),
-                          display_name=v_name,
-                          metadata=metadata)
+                          params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('72aeca85-57a5-4c1f-9057-f320f9ea575b')
     def test_update_volume_with_empty_volume_id(self):
         v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
-        metadata = {'Type': 'work'}
+        params = {self.name_field: v_name}
         self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
-                          volume_id='', display_name=v_name,
-                          metadata=metadata)
+                          volume_id='', params=params)
 
     @test.attr(type=['negative'])
     @test.idempotent_id('30799cfd-7ee4-446c-b66c-45b383ed211b')
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 8303caf..865db39 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -26,14 +26,15 @@
 LOG = logging.getLogger(__name__)
 
 
+def _get_task_state(body):
+    return body.get('OS-EXT-STS:task_state', None)
+
+
 # NOTE(afazekas): This function needs to know a token and a subject.
 def wait_for_server_status(client, server_id, status, ready_wait=True,
                            extra_timeout=0, raise_on_error=True):
     """Waits for a server to reach a given status."""
 
-    def _get_task_state(body):
-        return body.get('OS-EXT-STS:task_state', None)
-
     # NOTE(afazekas): UNKNOWN status possible on ERROR
     # or in a very early stage.
     body = client.show_server(server_id)['server']
@@ -99,21 +100,33 @@
 
 def wait_for_server_termination(client, server_id, ignore_error=False):
     """Waits for server to reach termination."""
+    try:
+        body = client.show_server(server_id)['server']
+    except lib_exc.NotFound:
+        return
+    old_status = server_status = body['status']
+    old_task_state = task_state = _get_task_state(body)
     start_time = int(time.time())
     while True:
+        time.sleep(client.build_interval)
         try:
             body = client.show_server(server_id)['server']
         except lib_exc.NotFound:
             return
-
         server_status = body['status']
+        task_state = _get_task_state(body)
+        if (server_status != old_status) or (task_state != old_task_state):
+            LOG.info('State transition "%s" ==> "%s" after %d second wait',
+                     '/'.join((old_status, str(old_task_state))),
+                     '/'.join((server_status, str(task_state))),
+                     time.time() - start_time)
         if server_status == 'ERROR' and not ignore_error:
             raise exceptions.BuildErrorException(server_id=server_id)
 
         if int(time.time()) - start_time >= client.build_timeout:
             raise lib_exc.TimeoutException
-
-        time.sleep(client.build_interval)
+        old_status = server_status
+        old_task_state = task_state
 
 
 def wait_for_image_status(client, image_id, status):
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 2c8b618..9486b96 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -40,20 +40,23 @@
             self.__class__.__name__ + '-volume-origin')
         return self.create_volume(name=vol_name, imageRef=img_uuid)
 
-    def _get_bdm(self, vol_id, delete_on_termination=False):
+    def _get_bdm(self, source_id, source_type, delete_on_termination=False):
         # NOTE(gfidente): the syntax for block_device_mapping is
         # dev_name=id:type:size:delete_on_terminate
         # where type needs to be "snap" if the server is booted
         # from a snapshot, size instead can be safely left empty
+
         bd_map = [{
             'device_name': 'vda',
-            'volume_id': vol_id,
+            '{}_id'.format(source_type): source_id,
             'delete_on_termination': str(int(delete_on_termination))}]
         return {'block_device_mapping': bd_map}
 
-    def _boot_instance_from_volume(self, vol_id, keypair=None,
-                                   security_group=None,
-                                   delete_on_termination=False):
+    def _boot_instance_from_resource(self, source_id,
+                                     source_type,
+                                     keypair=None,
+                                     security_group=None,
+                                     delete_on_termination=False):
         create_kwargs = dict()
         if keypair:
             create_kwargs['key_name'] = keypair['name']
@@ -61,7 +64,10 @@
             create_kwargs['security_groups'] = [
                 {'name': security_group['name']}]
         create_kwargs.update(self._get_bdm(
-            vol_id, delete_on_termination=delete_on_termination))
+            source_id,
+            source_type,
+            delete_on_termination=delete_on_termination))
+
         return self.create_server(
             image_id='',
             wait_until='ACTIVE',
@@ -116,8 +122,11 @@
         # create an instance from volume
         LOG.info("Booting instance 1 from volume")
         volume_origin = self._create_volume_from_image()
-        instance_1st = self._boot_instance_from_volume(volume_origin['id'],
-                                                       keypair, security_group)
+        instance_1st = self._boot_instance_from_resource(
+            source_id=volume_origin['id'],
+            source_type='volume',
+            keypair=keypair,
+            security_group=security_group)
         LOG.info("Booted first instance: %s", instance_1st)
 
         # write content to volume on instance
@@ -131,8 +140,11 @@
         self._delete_server(instance_1st)
 
         # create a 2nd instance from volume
-        instance_2nd = self._boot_instance_from_volume(volume_origin['id'],
-                                                       keypair, security_group)
+        instance_2nd = self._boot_instance_from_resource(
+            source_id=volume_origin['id'],
+            source_type='volume',
+            keypair=keypair,
+            security_group=security_group)
         LOG.info("Booted second instance %s", instance_2nd)
 
         # check the content of written file
@@ -152,8 +164,10 @@
                                     size=snapshot['size'])
         LOG.info("Booting third instance from snapshot")
         server_from_snapshot = (
-            self._boot_instance_from_volume(volume['id'],
-                                            keypair, security_group))
+            self._boot_instance_from_resource(source_id=volume['id'],
+                                              source_type='volume',
+                                              keypair=keypair,
+                                              security_group=security_group))
         LOG.info("Booted third instance %s", server_from_snapshot)
 
         # check the content of written file
@@ -164,13 +178,49 @@
                                         private_key=keypair['private_key'])
         self.assertEqual(timestamp, timestamp3)
 
+    @test.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
+        boot_volume = self._create_volume_from_image()
+
+        # Create a snapshot
+        boot_snapshot = self._create_snapshot_from_volume(boot_volume['id'])
+
+        # Create a server from a volume snapshot
+        server = self._boot_instance_from_resource(
+            source_id=boot_snapshot['id'],
+            source_type='snapshot',
+            delete_on_termination=True)
+
+        server_info = self.servers_client.show_server(server['id'])['server']
+
+        # The created volume when creating a server from a snapshot
+        created_volume = server_info['os-extended-volumes:volumes_attached']
+
+        created_volume_info = self.volumes_client.show_volume(
+            created_volume[0]['id'])['volume']
+
+        # Verify the server was created from the snapshot
+        self.assertEqual(
+            boot_volume['volume_image_metadata']['image_id'],
+            created_volume_info['volume_image_metadata']['image_id'])
+        self.assertEqual(boot_snapshot['id'],
+                         created_volume_info['snapshot_id'])
+        self.assertEqual(server['id'],
+                         created_volume_info['attachments'][0]['server_id'])
+        self.assertEqual(created_volume[0]['id'],
+                         created_volume_info['attachments'][0]['volume_id'])
+
     @test.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
         volume_origin = self._create_volume_from_image()
-        instance = self._boot_instance_from_volume(volume_origin['id'],
-                                                   delete_on_termination=True)
+        instance = self._boot_instance_from_resource(
+            source_id=volume_origin['id'],
+            source_type='volume',
+            delete_on_termination=True)
         # create EBS image
         image = self.create_server_snapshot(instance)
 
@@ -187,10 +237,10 @@
 
 
 class TestVolumeBootPatternV2(TestVolumeBootPattern):
-    def _get_bdm(self, vol_id, delete_on_termination=False):
+    def _get_bdm(self, source_id, source_type, delete_on_termination=False):
         bd_map_v2 = [{
-            'uuid': vol_id,
-            'source_type': 'volume',
+            'uuid': source_id,
+            'source_type': source_type,
             'destination_type': 'volume',
             'boot_index': 0,
             'delete_on_termination': delete_on_termination}]