Merge "Prepare token clients for migration to tempest-lib"
diff --git a/tempest/api/baremetal/admin/test_api_discovery.py b/tempest/api/baremetal/admin/test_api_discovery.py
index 09788f2..f0b8b7f 100644
--- a/tempest/api/baremetal/admin/test_api_discovery.py
+++ b/tempest/api/baremetal/admin/test_api_discovery.py
@@ -18,6 +18,7 @@
     """Tests for API discovery features."""
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a3c27e94-f56c-42c4-8600-d6790650b9c5')
     def test_api_versions(self):
         _, descr = self.client.get_api_description()
         expected_versions = ('v1',)
@@ -27,12 +28,14 @@
             self.assertIn(v, versions)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('896283a6-488e-4f31-af78-6614286cbe0d')
     def test_default_version(self):
         _, descr = self.client.get_api_description()
         default_version = descr['default_version']
         self.assertEqual(default_version['id'], 'v1')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('abc0b34d-e684-4546-9728-ab7a9ad9f174')
     def test_version_1_resources(self):
         _, descr = self.client.get_version_description(version='v1')
         expected_resources = ('nodes', 'chassis',
diff --git a/tempest/api/baremetal/admin/test_chassis.py b/tempest/api/baremetal/admin/test_chassis.py
index 1cf22ae..da32f71 100644
--- a/tempest/api/baremetal/admin/test_chassis.py
+++ b/tempest/api/baremetal/admin/test_chassis.py
@@ -34,12 +34,14 @@
                 self.assertEqual(value, actual[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7c5a2e09-699c-44be-89ed-2bc189992d42')
     def test_create_chassis(self):
         descr = data_utils.rand_name('test-chassis-')
         _, chassis = self.create_chassis(description=descr)
         self.assertEqual(chassis['description'], descr)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cabe9c6f-dc16-41a7-b6b9-0a90c212edd5')
     def test_create_chassis_unicode_description(self):
         # Use a unicode string for testing:
         # 'We ♡ OpenStack in Ukraine'
@@ -48,17 +50,20 @@
         self.assertEqual(chassis['description'], descr)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c84644df-31c4-49db-a307-8942881f41c0')
     def test_show_chassis(self):
         _, chassis = self.client.show_chassis(self.chassis['uuid'])
         self._assertExpected(self.chassis, chassis)
 
     @test.attr(type="smoke")
+    @test.idempotent_id('29c9cd3f-19b5-417b-9864-99512c3b33b3')
     def test_list_chassis(self):
         _, body = self.client.list_chassis()
         self.assertIn(self.chassis['uuid'],
                       [i['uuid'] for i in body['chassis']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5ae649ad-22d1-4fe1-bbc6-97227d199fb3')
     def test_delete_chassis(self):
         _, body = self.create_chassis()
         uuid = body['uuid']
@@ -67,6 +72,7 @@
         self.assertRaises(lib_exc.NotFound, self.client.show_chassis, uuid)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cda8a41f-6be2-4cbf-840c-994b00a89b44')
     def test_update_chassis(self):
         _, body = self.create_chassis()
         uuid = body['uuid']
@@ -78,6 +84,7 @@
         self.assertEqual(chassis['description'], new_description)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('76305e22-a4e2-4ab3-855c-f4e2368b9335')
     def test_chassis_node_list(self):
         _, node = self.create_node(self.chassis['uuid'])
         _, body = self.client.list_chassis_nodes(self.chassis['uuid'])
diff --git a/tempest/api/baremetal/admin/test_drivers.py b/tempest/api/baremetal/admin/test_drivers.py
index 9d99295..de04562 100644
--- a/tempest/api/baremetal/admin/test_drivers.py
+++ b/tempest/api/baremetal/admin/test_drivers.py
@@ -27,12 +27,14 @@
         cls.driver_name = CONF.baremetal.driver
 
     @test.attr(type="smoke")
+    @test.idempotent_id('5aed2790-7592-4655-9b16-99abcc2e6ec5')
     def test_list_drivers(self):
         _, drivers = self.client.list_drivers()
         self.assertIn(self.driver_name,
                       [d['name'] for d in drivers['drivers']])
 
     @test.attr(type="smoke")
+    @test.idempotent_id('fb3287a3-c4d7-44bf-ae9d-1eef906d78ce')
     def test_show_driver(self):
         _, driver = self.client.show_driver(self.driver_name)
         self.assertEqual(self.driver_name, driver['name'])
diff --git a/tempest/api/baremetal/admin/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
index 1919223..f031614 100644
--- a/tempest/api/baremetal/admin/test_nodes.py
+++ b/tempest/api/baremetal/admin/test_nodes.py
@@ -47,6 +47,7 @@
         return instance_uuid
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4e939eb2-8a69-4e84-8652-6fffcbc9db8f')
     def test_create_node(self):
         params = {'cpu_arch': 'x86_64',
                   'cpus': '12',
@@ -57,6 +58,7 @@
         self._assertExpected(params, body['properties'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9ade60a4-505e-4259-9ec4-71352cbbaf47')
     def test_delete_node(self):
         _, node = self.create_node(self.chassis['uuid'])
 
@@ -66,17 +68,20 @@
                           node['uuid'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('55451300-057c-4ecf-8255-ba42a83d3a03')
     def test_show_node(self):
         _, loaded_node = self.client.show_node(self.node['uuid'])
         self._assertExpected(self.node, loaded_node)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4ca123c4-160d-4d8d-a3f7-15feda812263')
     def test_list_nodes(self):
         _, body = self.client.list_nodes()
         self.assertIn(self.node['uuid'],
                       [i['uuid'] for i in body['nodes']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('85b1f6e0-57fd-424c-aeff-c3422920556f')
     def test_list_nodes_association(self):
         _, body = self.client.list_nodes(associated=True)
         self.assertNotIn(self.node['uuid'],
@@ -91,6 +96,7 @@
         self.assertNotIn(self.node['uuid'], [n['uuid'] for n in body['nodes']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('18c4ebd8-f83a-4df7-9653-9fb33a329730')
     def test_node_port_list(self):
         _, port = self.create_port(self.node['uuid'],
                                    data_utils.rand_mac_address())
@@ -99,12 +105,14 @@
                       [p['uuid'] for p in body['ports']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('72591acb-f215-49db-8395-710d14eb86ab')
     def test_node_port_list_no_ports(self):
         _, node = self.create_node(self.chassis['uuid'])
         _, body = self.client.list_node_ports(node['uuid'])
         self.assertEmpty(body['ports'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4fed270a-677a-4d19-be87-fd38ae490320')
     def test_update_node(self):
         props = {'cpu_arch': 'x86_64',
                  'cpus': '12',
@@ -123,6 +131,7 @@
         self._assertExpected(new_p, node['properties'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cbf1f515-5f4b-4e49-945c-86bcaccfeb1d')
     def test_validate_driver_interface(self):
         _, body = self.client.validate_driver_interface(self.node['uuid'])
         core_interfaces = ['power', 'deploy']
@@ -130,10 +139,12 @@
             self.assertIn(interface, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5519371c-26a2-46e9-aa1a-f74226e9d71f')
     def test_set_node_boot_device(self):
         self.client.set_node_boot_device(self.node['uuid'], 'pxe')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9ea73775-f578-40b9-bc34-efc639c4f21f')
     def test_get_node_boot_device(self):
         body = self.client.get_node_boot_device(self.node['uuid'])
         self.assertIn('boot_device', body)
@@ -142,12 +153,14 @@
         self.assertTrue(isinstance(body['persistent'], bool))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3622bc6f-3589-4bc2-89f3-50419c66b133')
     def test_get_node_supported_boot_devices(self):
         body = self.client.get_node_supported_boot_devices(self.node['uuid'])
         self.assertIn('supported_boot_devices', body)
         self.assertTrue(isinstance(body['supported_boot_devices'], list))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f63b6288-1137-4426-8cfe-0d5b7eb87c06')
     def test_get_console(self):
         _, body = self.client.get_console(self.node['uuid'])
         con_info = ['console_enabled', 'console_info']
@@ -155,6 +168,7 @@
             self.assertIn(key, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('80504575-9b21-4670-92d1-143b948f9437')
     def test_set_console_mode(self):
         self.client.set_console_mode(self.node['uuid'], True)
 
@@ -162,6 +176,7 @@
         self.assertEqual(True, body['console_enabled'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b02a4f38-5e8b-44b2-aed2-a69a36ecfd69')
     def test_get_node_by_instance_uuid(self):
         instance_uuid = self._associate_node_with_instance()
         _, body = self.client.show_node_by_instance_uuid(instance_uuid)
diff --git a/tempest/api/baremetal/admin/test_nodestates.py b/tempest/api/baremetal/admin/test_nodestates.py
index f4f8054..bcb8b78 100644
--- a/tempest/api/baremetal/admin/test_nodestates.py
+++ b/tempest/api/baremetal/admin/test_nodestates.py
@@ -42,12 +42,14 @@
         raise exceptions.TimeoutException(message)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cd8afa5e-3f57-4e43-8185-beb83d3c9015')
     def test_list_nodestates(self):
         _, nodestates = self.client.list_nodestates(self.node['uuid'])
         for key in nodestates:
             self.assertEqual(nodestates[key], self.node[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fc5b9320-0c98-4e5a-8848-877fe5a0322c')
     def test_set_node_power_state(self):
         _, node = self.create_node(self.chassis['uuid'])
         states = ["power on", "rebooting", "power off"]
diff --git a/tempest/api/baremetal/admin/test_ports.py b/tempest/api/baremetal/admin/test_ports.py
index 0076dee..bbd2801 100644
--- a/tempest/api/baremetal/admin/test_ports.py
+++ b/tempest/api/baremetal/admin/test_ports.py
@@ -37,6 +37,7 @@
                 self.assertEqual(value, actual[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('83975898-2e50-42ed-b5f0-e510e36a0b56')
     def test_create_port(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -48,6 +49,7 @@
         self._assertExpected(port, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d1f6b249-4cf6-4fe6-9ed6-a6e84b1bf67b')
     def test_create_port_specifying_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -61,6 +63,7 @@
 
     @decorators.skip_because(bug='1398350')
     @test.attr(type='smoke')
+    @test.idempotent_id('4a02c4b0-6573-42a4-a513-2e36ad485b62')
     def test_create_port_with_extra(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -74,6 +77,7 @@
         self._assertExpected(port, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1bf257a9-aea3-494e-89c0-63f657ab4fdd')
     def test_delete_port(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -85,16 +89,19 @@
                           port['uuid'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9fa77ab5-ce59-4f05-baac-148904ba1597')
     def test_show_port(self):
         _, port = self.client.show_port(self.port['uuid'])
         self._assertExpected(self.port, port)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7c1114ff-fc3f-47bb-bc2f-68f61620ba8b')
     def test_show_port_by_address(self):
         _, port = self.client.show_port_by_address(self.port['address'])
         self._assertExpected(self.port, port['ports'][0])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bd773405-aea5-465d-b576-0ab1780069e5')
     def test_show_port_with_links(self):
         _, port = self.client.show_port(self.port['uuid'])
         self.assertIn('links', port.keys())
@@ -102,6 +109,7 @@
         self.assertIn(port['uuid'], port['links'][0]['href'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b5e91854-5cd7-4a8e-bb35-3e0a1314606d')
     def test_list_ports(self):
         _, body = self.client.list_ports()
         self.assertIn(self.port['uuid'],
@@ -112,12 +120,14 @@
                                     port['links'][0]['href'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('324a910e-2f80-4258-9087-062b5ae06240')
     def test_list_with_limit(self):
         _, body = self.client.list_ports(limit=3)
 
         next_marker = body['ports'][-1]['uuid']
         self.assertIn(next_marker, body['next'])
 
+    @test.idempotent_id('8a94b50f-9895-4a63-a574-7ecff86e5875')
     def test_list_ports_details(self):
         node_id = self.node['uuid']
 
@@ -142,6 +152,7 @@
             self.validate_self_link('ports', port['uuid'],
                                     port['links'][0]['href'])
 
+    @test.idempotent_id('8a03f688-7d75-4ecd-8cbc-e06b8f346738')
     def test_list_ports_details_with_address(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -155,6 +166,7 @@
         self.assertEqual(address, body['ports'][0]['address'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9c26298b-1bcb-47b7-9b9e-8bdd6e3c4aba')
     def test_update_port_replace(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -187,6 +199,7 @@
         self.assertEqual(new_extra, body['extra'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d7e7fece-6ed9-460a-9ebe-9267217e8580')
     def test_update_port_remove(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -214,6 +227,7 @@
         self.assertEqual(address, body['address'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('241288b3-e98a-400f-a4d7-d1f716146361')
     def test_update_port_add(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -236,6 +250,7 @@
 
     @decorators.skip_because(bug='1398350')
     @test.attr(type='smoke')
+    @test.idempotent_id('5309e897-0799-4649-a982-0179b04c3876')
     def test_update_port_mixed_ops(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
diff --git a/tempest/api/baremetal/admin/test_ports_negative.py b/tempest/api/baremetal/admin/test_ports_negative.py
index 8dbdedf..2e79883 100644
--- a/tempest/api/baremetal/admin/test_ports_negative.py
+++ b/tempest/api/baremetal/admin/test_ports_negative.py
@@ -27,6 +27,7 @@
         _, self.node = self.create_node(self.chassis['uuid'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('0a6ee1f7-d0d9-4069-8778-37f3aa07303a')
     def test_create_port_malformed_mac(self):
         node_id = self.node['uuid']
         address = 'malformed:mac'
@@ -35,6 +36,7 @@
                           self.create_port, node_id=node_id, address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('30277ee8-0c60-4f1d-b125-0e51c2f43369')
     def test_create_port_nonexsistent_node_id(self):
         node_id = str(data_utils.rand_uuid())
         address = data_utils.rand_mac_address()
@@ -42,21 +44,25 @@
                           node_id=node_id, address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('029190f6-43e1-40a3-b64a-65173ba653a3')
     def test_show_port_malformed_uuid(self):
         self.assertRaises(lib_exc.BadRequest, self.client.show_port,
                           'malformed:uuid')
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('0d00e13d-e2e0-45b1-bcbc-55a6d90ca793')
     def test_show_port_nonexistent_uuid(self):
         self.assertRaises(lib_exc.NotFound, self.client.show_port,
                           data_utils.rand_uuid())
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('4ad85266-31e9-4942-99ac-751897dc9e23')
     def test_show_port_by_mac_not_allowed(self):
         self.assertRaises(lib_exc.BadRequest, self.client.show_port,
                           data_utils.rand_mac_address())
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('89a34380-3c61-4c32-955c-2cd9ce94da21')
     def test_create_port_duplicated_port_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -67,6 +73,7 @@
                           address=address, uuid=uuid)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('65e84917-733c-40ae-ae4b-96a4adff931c')
     def test_create_port_no_mandatory_field_node_id(self):
         address = data_utils.rand_mac_address()
 
@@ -74,6 +81,7 @@
                           address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('bcea3476-7033-4183-acfe-e56a30809b46')
     def test_create_port_no_mandatory_field_mac(self):
         node_id = self.node['uuid']
 
@@ -81,6 +89,7 @@
                           node_id=node_id, address=None)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('2b51cd18-fb95-458b-9780-e6257787b649')
     def test_create_port_malformed_port_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -90,12 +99,14 @@
                           node_id=node_id, address=address, uuid=uuid)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('583a6856-6a30-4ac4-889f-14e2adff8105')
     def test_create_port_malformed_node_id(self):
         address = data_utils.rand_mac_address()
         self.assertRaises(lib_exc.BadRequest, self.create_port,
                           node_id='malformed:nodeid', address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('e27f8b2e-42c6-4a43-a3cd-accff716bc5c')
     def test_create_port_duplicated_mac(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -105,6 +116,7 @@
                           address=address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('8907082d-ac5e-4be3-b05f-d072ede82020')
     def test_update_port_by_mac_not_allowed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -121,6 +133,7 @@
                           patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('df1ac70c-db9f-41d9-90f1-78cd6b905718')
     def test_update_port_nonexistent(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -139,6 +152,7 @@
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('c701e315-aa52-41ea-817c-65c5ca8ca2a8')
     def test_update_port_malformed_port_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -152,6 +166,7 @@
                                   'value': new_address}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('f8f15803-34d6-45dc-b06f-e5e04bf1b38b')
     def test_update_port_add_nonexistent_property(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -164,6 +179,7 @@
                             'value': 'value'}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('898ec904-38b1-4fcb-9584-1187d4263a2a')
     def test_update_port_replace_node_id_with_malformed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -178,6 +194,7 @@
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('2949f30f-5f59-43fa-a6d9-4eac578afab4')
     def test_update_port_replace_mac_with_duplicated(self):
         node_id = self.node['uuid']
         address1 = data_utils.rand_mac_address()
@@ -195,6 +212,7 @@
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('97f6e048-6e4f-4eba-a09d-fbbc78b77a77')
     def test_update_port_replace_node_id_with_nonexistent(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -209,6 +227,7 @@
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('375022c5-9e9e-4b11-9ca4-656729c0c9b2')
     def test_update_port_replace_mac_with_malformed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -224,6 +243,7 @@
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('5722b853-03fc-4854-8308-2036a1b67d85')
     def test_update_port_replace_nonexistent_property(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -237,6 +257,7 @@
                           self.client.update_port, port_id, patch)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('ae2696ca-930a-4a7f-918f-30ae97c60f56')
     def test_update_port_remove_mandatory_field_mac(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -248,6 +269,7 @@
                           [{'path': '/address', 'op': 'remove'}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('5392c1f0-2071-4697-9064-ec2d63019018')
     def test_update_port_remove_mandatory_field_port_uuid(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -259,6 +281,7 @@
                           [{'path': '/uuid', 'op': 'remove'}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('06b50d82-802a-47ef-b079-0a3311cf85a2')
     def test_update_port_remove_nonexistent_property(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -270,6 +293,7 @@
                           [{'path': '/nonexistent', 'op': 'remove'}])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('03d42391-2145-4a6c-95bf-63fe55eb64fd')
     def test_delete_port_by_mac_not_allowed(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
@@ -278,6 +302,7 @@
         self.assertRaises(lib_exc.BadRequest, self.client.delete_port, address)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('0629e002-818e-4763-b25b-ae5e07b1cb23')
     def test_update_port_mixed_ops_integrity(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
diff --git a/tempest/api/compute/admin/test_agents.py b/tempest/api/compute/admin/test_agents.py
index b28b9e0..2bd15ac 100644
--- a/tempest/api/compute/admin/test_agents.py
+++ b/tempest/api/compute/admin/test_agents.py
@@ -61,6 +61,7 @@
         return kwargs
 
     @test.attr(type='gate')
+    @test.idempotent_id('1fc6bdc8-0b6d-4cc7-9f30-9b04fabe5b90')
     def test_create_agent(self):
         # Create an agent.
         params = self._param_helper(
@@ -73,6 +74,7 @@
             self.assertEqual(value, body[expected_item])
 
     @test.attr(type='gate')
+    @test.idempotent_id('dc9ffd51-1c50-4f0e-a820-ae6d2a568a9e')
     def test_update_agent(self):
         # Update an agent.
         params = self._param_helper(
@@ -83,6 +85,7 @@
             self.assertEqual(value, body[expected_item])
 
     @test.attr(type='gate')
+    @test.idempotent_id('470e0b89-386f-407b-91fd-819737d0b335')
     def test_delete_agent(self):
         # Delete an agent.
         self.client.delete_agent(self.agent_id)
@@ -92,6 +95,7 @@
         self.assertNotIn(self.agent_id, map(lambda x: x['agent_id'], agents))
 
     @test.attr(type='gate')
+    @test.idempotent_id('6a326c69-654b-438a-80a3-34bcc454e138')
     def test_list_agents(self):
         # List all agents.
         agents = self.client.list_agents()
@@ -99,6 +103,7 @@
         self.assertIn(self.agent_id, map(lambda x: x['agent_id'], agents))
 
     @test.attr(type='gate')
+    @test.idempotent_id('eabadde4-3cd7-4ec4-a4b5-5a936d2d4408')
     def test_list_agents_with_filter(self):
         # List the agent builds by the filter.
         params = self._param_helper(
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 2bf2b82..e3b0151 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -50,6 +50,7 @@
             pass
 
     @test.attr(type='gate')
+    @test.idempotent_id('0d148aa3-d54c-4317-aa8d-42040a475e20')
     def test_aggregate_create_delete(self):
         # Create and delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -62,6 +63,7 @@
         self.client.wait_for_resource_deletion(aggregate['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('5873a6f8-671a-43ff-8838-7ce430bb6d0b')
     def test_aggregate_create_delete_with_az(self):
         # Create and delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -76,6 +78,7 @@
         self.client.wait_for_resource_deletion(aggregate['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('68089c38-04b1-4758-bdf0-cf0daec4defd')
     def test_aggregate_create_verify_entry_in_list(self):
         # Create an aggregate and ensure it is listed.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -88,6 +91,7 @@
                           aggregates))
 
     @test.attr(type='gate')
+    @test.idempotent_id('36ec92ca-7a73-43bc-b920-7531809e8540')
     def test_aggregate_create_update_metadata_get_details(self):
         # Create an aggregate and ensure its details are returned.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -110,6 +114,7 @@
         self.assertEqual(meta, body["metadata"])
 
     @test.attr(type='gate')
+    @test.idempotent_id('4d2b2004-40fa-40a1-aab2-66f4dab81beb')
     def test_aggregate_create_update_with_az(self):
         # Update an aggregate and ensure properties are updated correctly
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -139,6 +144,7 @@
                           aggregates))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c8e85064-e79b-4906-9931-c11c24294d02')
     def test_aggregate_add_remove_host(self):
         # Add an host to the given aggregate and remove.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -159,6 +165,7 @@
         self.assertNotIn(self.host, body['hosts'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('7f6a1cc5-2446-4cdb-9baa-b6ae0a919b72')
     def test_aggregate_add_host_list(self):
         # Add an host to the given aggregate and list.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -177,6 +184,7 @@
         self.assertIn(self.host, agg['hosts'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('eeef473c-7c52-494d-9f09-2ed7fc8fc036')
     def test_aggregate_add_host_get_details(self):
         # Add an host to the given aggregate and get details.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -192,6 +200,7 @@
         self.assertIn(self.host, body['hosts'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('96be03c7-570d-409c-90f8-e4db3c646996')
     def test_aggregate_add_host_create_server_with_az(self):
         # Add an host to the given aggregate and create a server.
         self.useFixture(fixtures.LockFixture('availability_zone'))
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index fd44f7f..02e2b0b 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -41,6 +41,7 @@
         cls.host = hosts[0]
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('86a1cb14-da37-4a70-b056-903fd56dfe29')
     def test_aggregate_create_as_user(self):
         # Regular user is not allowed to create an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -49,6 +50,7 @@
                           name=aggregate_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3b8a1929-3793-4e92-bcb4-dfa572ee6c1d')
     def test_aggregate_create_aggregate_name_length_less_than_1(self):
         # the length of aggregate name should >= 1 and <=255
         self.assertRaises(lib_exc.BadRequest,
@@ -56,6 +58,7 @@
                           name='')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4c194563-543b-4e70-a719-557bbe947fac')
     def test_aggregate_create_aggregate_name_length_exceeds_255(self):
         # the length of aggregate name should >= 1 and <=255
         aggregate_name = 'a' * 256
@@ -64,6 +67,7 @@
                           name=aggregate_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c23a291-b0b1-487b-b464-132e061151b3')
     def test_aggregate_create_with_existent_aggregate_name(self):
         # creating an aggregate with existent aggregate name is forbidden
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -75,6 +79,7 @@
                           name=aggregate_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('cd6de795-c15d-45f1-8d9e-813c6bb72a3d')
     def test_aggregate_delete_as_user(self):
         # Regular user is not allowed to delete an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -86,12 +91,14 @@
                           aggregate['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b7d475a6-5dcd-4ff4-b70a-cd9de66a6672')
     def test_aggregate_list_as_user(self):
         # Regular user is not allowed to list aggregates.
         self.assertRaises(lib_exc.Unauthorized,
                           self.user_client.list_aggregates)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('557cad12-34c9-4ff4-95f0-22f0dfbaf7dc')
     def test_aggregate_get_details_as_user(self):
         # Regular user is not allowed to get aggregate details.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -103,18 +110,21 @@
                           aggregate['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c74f4bf1-4708-4ff2-95a0-f49eaca951bd')
     def test_aggregate_delete_with_invalid_id(self):
         # Delete an aggregate with invalid id should raise exceptions.
         self.assertRaises(lib_exc.NotFound,
                           self.client.delete_aggregate, -1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3c916244-2c46-49a4-9b55-b20bb0ae512c')
     def test_aggregate_get_details_with_invalid_id(self):
         # Get aggregate details with invalid id should raise exceptions.
         self.assertRaises(lib_exc.NotFound,
                           self.client.get_aggregate, -1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0ef07828-12b4-45ba-87cc-41425faf5711')
     def test_aggregate_add_non_exist_host(self):
         # Adding a non-exist host to an aggregate should raise exceptions.
         hosts_all = self.os_adm.hosts_client.list_hosts()
@@ -132,6 +142,7 @@
                           aggregate['id'], non_exist_host)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7324c334-bd13-4c93-8521-5877322c3d51')
     def test_aggregate_add_host_as_user(self):
         # Regular user is not allowed to add a host to an aggregate.
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -143,6 +154,7 @@
                           aggregate['id'], self.host)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('19dd44e1-c435-4ee1-a402-88c4f90b5950')
     def test_aggregate_add_existent_host(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -156,6 +168,7 @@
                           aggregate['id'], self.host)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7a53af20-137a-4e44-a4ae-e19260e626d9')
     def test_aggregate_remove_host_as_user(self):
         # Regular user is not allowed to remove a host from an aggregate.
         self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -170,6 +183,7 @@
                           aggregate['id'], self.host)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('95d6a6fa-8da9-4426-84d0-eec0329f2e4d')
     def test_aggregate_remove_nonexistent_host(self):
         non_exist_host = data_utils.rand_name('nonexist_host_')
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index 909f0a5..9d24b00 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -29,12 +29,14 @@
         cls.client = cls.availability_zone_admin_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('d3431479-8a09-4f76-aa2d-26dc580cb27c')
     def test_get_availability_zone_list(self):
         # List of availability zone
         availability_zone = self.client.get_availability_zone_list()
         self.assertTrue(len(availability_zone) > 0)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ef726c58-530f-44c2-968c-c7bed22d5b8c')
     def test_get_availability_zone_list_detail(self):
         # List of availability zones and available services
         availability_zone = self.client.get_availability_zone_list_detail()
diff --git a/tempest/api/compute/admin/test_availability_zone_negative.py b/tempest/api/compute/admin/test_availability_zone_negative.py
index 546aa3b..caecddc 100644
--- a/tempest/api/compute/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/admin/test_availability_zone_negative.py
@@ -30,6 +30,7 @@
         cls.non_adm_client = cls.availability_zone_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bf34dca2-fdc3-4073-9c02-7648d9eae0d7')
     def test_get_availability_zone_list_detail_with_non_admin_user(self):
         # List of availability zones and available services with
         # non-administrator user
diff --git a/tempest/api/compute/admin/test_baremetal_nodes.py b/tempest/api/compute/admin/test_baremetal_nodes.py
index d894de6..1381f80 100644
--- a/tempest/api/compute/admin/test_baremetal_nodes.py
+++ b/tempest/api/compute/admin/test_baremetal_nodes.py
@@ -33,6 +33,7 @@
         cls.client = cls.os_adm.baremetal_nodes_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e475aa6e-416d-4fa4-b3af-28d5e84250fb')
     def test_list_baremetal_nodes(self):
         # List all baremetal nodes.
         baremetal_nodes = self.client.list_baremetal_nodes()
diff --git a/tempest/api/compute/admin/test_fixed_ips.py b/tempest/api/compute/admin/test_fixed_ips.py
index 078fe08..820b9b0 100644
--- a/tempest/api/compute/admin/test_fixed_ips.py
+++ b/tempest/api/compute/admin/test_fixed_ips.py
@@ -40,18 +40,21 @@
                 break
 
     @test.attr(type='gate')
+    @test.idempotent_id('16b7d848-2f7c-4709-85a3-2dfb4576cc52')
     @test.services('network')
     def test_list_fixed_ip_details(self):
         fixed_ip = self.client.get_fixed_ip_details(self.ip)
         self.assertEqual(fixed_ip['address'], self.ip)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5485077b-7e46-4cec-b402-91dc3173433b')
     @test.services('network')
     def test_set_reserve(self):
         body = {"reserve": "None"}
         self.client.reserve_fixed_ip(self.ip, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7476e322-b9ff-4710-bf82-49d51bac6e2e')
     @test.services('network')
     def test_set_unreserve(self):
         body = {"unreserve": "None"}
diff --git a/tempest/api/compute/admin/test_fixed_ips_negative.py b/tempest/api/compute/admin/test_fixed_ips_negative.py
index f717291..df3c390 100644
--- a/tempest/api/compute/admin/test_fixed_ips_negative.py
+++ b/tempest/api/compute/admin/test_fixed_ips_negative.py
@@ -42,12 +42,14 @@
                 break
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9f17f47d-daad-4adc-986e-12370c93e407')
     @test.services('network')
     def test_list_fixed_ip_details_with_non_admin_user(self):
         self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.get_fixed_ip_details, self.ip)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ce60042c-fa60-4836-8d43-1c8e3359dc47')
     @test.services('network')
     def test_set_reserve_with_non_admin_user(self):
         body = {"reserve": "None"}
@@ -56,6 +58,7 @@
                           self.ip, body)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f1f7a35b-0390-48c5-9803-5f27461439db')
     @test.services('network')
     def test_set_unreserve_with_non_admin_user(self):
         body = {"unreserve": "None"}
@@ -64,6 +67,7 @@
                           self.ip, body)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f51cf464-7fc5-4352-bc3e-e75cfa2cb717')
     @test.services('network')
     def test_set_reserve_with_invalid_ip(self):
         # NOTE(maurosr): since this exercises the same code snippet, we do it
@@ -77,6 +81,7 @@
                           "my.invalid.ip", body)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fd26ef50-f135-4232-9d32-281aab3f9176')
     @test.services('network')
     def test_fixed_ip_with_invalid_action(self):
         body = {"invalid_action": "None"}
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 8d5c5e3..cd3a4f1 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -79,18 +79,21 @@
         return flavor['id']
 
     @test.attr(type='gate')
+    @test.idempotent_id('8b4330e1-12c4-4554-9390-e6639971f086')
     def test_create_flavor_with_int_id(self):
         flavor_id = data_utils.rand_int_id(start=1000)
         new_flavor_id = self._create_flavor(flavor_id)
         self.assertEqual(new_flavor_id, str(flavor_id))
 
     @test.attr(type='gate')
+    @test.idempotent_id('94c9bb4e-2c2a-4f3c-bb1f-5f0daf918e6d')
     def test_create_flavor_with_uuid_id(self):
         flavor_id = str(uuid.uuid4())
         new_flavor_id = self._create_flavor(flavor_id)
         self.assertEqual(new_flavor_id, flavor_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f83fe669-6758-448a-a85e-32d351f36fe0')
     def test_create_flavor_with_none_id(self):
         # If nova receives a request with None as flavor_id,
         # nova generates flavor_id of uuid.
@@ -99,6 +102,7 @@
         self.assertEqual(new_flavor_id, str(uuid.UUID(new_flavor_id)))
 
     @test.attr(type='gate')
+    @test.idempotent_id('8261d7b0-be58-43ec-a2e5-300573c3f6c5')
     def test_create_flavor_verify_entry_in_list_details(self):
         # Create a flavor and ensure it's details are listed
         # This operation requires the user to have 'admin' role
@@ -123,6 +127,7 @@
         self.assertTrue(flag)
 
     @test.attr(type='gate')
+    @test.idempotent_id('63dc64e6-2e79-4fdf-868f-85500d308d66')
     def test_create_list_flavor_without_extra_data(self):
         # Create a flavor and ensure it is listed
         # This operation requires the user to have 'admin' role
@@ -164,6 +169,7 @@
         self.assertTrue(flag)
 
     @test.attr(type='gate')
+    @test.idempotent_id('be6cc18c-7c5d-48c0-ac16-17eaf03c54eb')
     def test_list_non_public_flavor(self):
         # Create a flavor with os-flavor-access:is_public false.
         # The flavor should not be present in list_details as the
@@ -196,6 +202,7 @@
         self.assertFalse(flag)
 
     @test.attr(type='gate')
+    @test.idempotent_id('bcc418ef-799b-47cc-baa1-ce01368b8987')
     def test_create_server_with_non_public_flavor(self):
         # Create a flavor with os-flavor-access:is_public false
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -215,6 +222,7 @@
                           'test', self.image_ref, flavor['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('b345b196-bfbd-4231-8ac1-6d7fe15ff3a3')
     def test_list_public_flavor_with_other_user(self):
         # Create a Flavor with public access.
         # Try to List/Get flavor with another user
@@ -238,6 +246,7 @@
         self.assertTrue(flag)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fb9cbde6-3a0e-41f2-a983-bdb0a823c44e')
     def test_is_public_string_variations(self):
         flavor_id_not_public = data_utils.rand_int_id(start=1000)
         flavor_name_not_public = data_utils.rand_name(self.flavor_name_prefix)
@@ -280,6 +289,7 @@
                                 flavor_name_public)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3b541a2e-2ac2-4b42-8b8d-ba6e22fcd4da')
     def test_create_flavor_using_string_ram(self):
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 8a33ce7..aaa96ac 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -44,6 +44,7 @@
         cls.disk = 10
 
     @test.attr(type='gate')
+    @test.idempotent_id('ea2c2211-29fa-4db9-97c3-906d36fad3e0')
     def test_flavor_access_list_with_private_flavor(self):
         # Test to make sure that list flavor access on a newly created
         # private flavor will return an empty access list
@@ -59,6 +60,7 @@
         self.assertEqual(len(flavor_access), 0, str(flavor_access))
 
     @test.attr(type='gate')
+    @test.idempotent_id('59e622f6-bdf6-45e3-8ba8-fedad905a6b4')
     def test_flavor_access_add_remove(self):
         # Test to add and remove flavor access to a given tenant.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index 5031432..af53985 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -43,6 +43,7 @@
         cls.disk = 10
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0621c53e-d45d-40e7-951d-43e5e257b272')
     def test_flavor_access_list_with_public_flavor(self):
         # Test to list flavor access with exceptions by querying public flavor
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -58,6 +59,7 @@
                           new_flavor_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('41eaaade-6d37-4f28-9c74-f21b46ca67bd')
     def test_flavor_non_admin_add(self):
         # Test to add flavor access as a user without admin privileges.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -74,6 +76,7 @@
                           self.tenant_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('073e79a6-c311-4525-82dc-6083d919cb3a')
     def test_flavor_non_admin_remove(self):
         # Test to remove flavor access as a user without admin privileges.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -94,6 +97,7 @@
                           self.tenant_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f3592cc0-0306-483c-b210-9a7b5346eddc')
     def test_add_flavor_access_duplicate(self):
         # Create a new flavor.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -118,6 +122,7 @@
                           self.tenant_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1f710927-3bc7-4381-9f82-0ca6e42644b7')
     def test_remove_flavor_access_not_found(self):
         # Create a new flavor.
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index 55c3358..5847a64 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -57,6 +57,7 @@
         super(FlavorsExtraSpecsTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('0b2f9d4b-1ca2-4b99-bb40-165d4bb94208')
     def test_flavor_set_get_update_show_unset_keys(self):
         # Test to SET, GET, UPDATE, SHOW, UNSET flavor extra
         # spec as a user with admin privileges.
@@ -87,6 +88,7 @@
         self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
 
     @test.attr(type='gate')
+    @test.idempotent_id('a99dad88-ae1c-4fba-aeb4-32f898218bd0')
     def test_flavor_non_admin_get_all_keys(self):
         specs = {"key1": "value1", "key2": "value2"}
         self.client.set_flavor_extra_spec(self.flavor['id'], specs)
@@ -96,6 +98,7 @@
             self.assertEqual(body[key], specs[key])
 
     @test.attr(type='gate')
+    @test.idempotent_id('12805a7f-39a3-4042-b989-701d5cad9c90')
     def test_flavor_non_admin_get_specific_key(self):
         specs = {"key1": "value1", "key2": "value2"}
         body = self.client.set_flavor_extra_spec(self.flavor['id'], specs)
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
index c22602a..979fdd3 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
@@ -59,6 +59,7 @@
         super(FlavorsExtraSpecsNegativeTestJSON, cls).resource_cleanup()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a00a3b81-5641-45a8-ab2b-4a8ec41e1d7d')
     def test_flavor_non_admin_set_keys(self):
         # Test to SET flavor extra spec as a user without admin privileges.
         specs = {"key1": "value1", "key2": "value2"}
@@ -68,6 +69,7 @@
                           specs)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1ebf4ef8-759e-48fe-a801-d451d80476fb')
     def test_flavor_non_admin_update_specific_key(self):
         # non admin user is not allowed to update flavor extra spec
         specs = {"key1": "value1", "key2": "value2"}
@@ -82,6 +84,7 @@
                           key1='value1_new')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('28f12249-27c7-44c1-8810-1f382f316b11')
     def test_flavor_non_admin_unset_keys(self):
         specs = {"key1": "value1", "key2": "value2"}
         self.client.set_flavor_extra_spec(self.flavor['id'], specs)
@@ -92,6 +95,7 @@
                           'key1')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('440b9f3f-3c7f-4293-a106-0ceda350f8de')
     def test_flavor_unset_nonexistent_key(self):
         nonexistent_key = data_utils.rand_name('flavor_key')
         self.assertRaises(lib_exc.NotFound,
@@ -100,6 +104,7 @@
                           nonexistent_key)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('329a7be3-54b2-48be-8052-bf2ce4afd898')
     def test_flavor_get_nonexistent_key(self):
         self.assertRaises(lib_exc.NotFound,
                           self.flavors_client.get_flavor_extra_spec_with_key,
@@ -107,6 +112,7 @@
                           "nonexistent_key")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('25b822b8-9f49-44f6-80de-d99f0482e5cb')
     def test_flavor_update_mismatch_key(self):
         # the key will be updated should be match the key in the body
         self.assertRaises(lib_exc.BadRequest,
@@ -116,6 +122,7 @@
                           key1="value")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f5889590-bf66-41cc-b4b1-6e6370cfd93f')
     def test_flavor_update_more_key(self):
         # there should be just one item in the request body
         self.assertRaises(lib_exc.BadRequest,
diff --git a/tempest/api/compute/admin/test_flavors_negative.py b/tempest/api/compute/admin/test_flavors_negative.py
index d1060c5..042c270 100644
--- a/tempest/api/compute/admin/test_flavors_negative.py
+++ b/tempest/api/compute/admin/test_flavors_negative.py
@@ -53,6 +53,7 @@
         cls.rxtx = 2
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('404451c0-c1ae-4448-8d50-d74f26f93ec8')
     def test_get_flavor_details_for_deleted_flavor(self):
         # Delete a flavor and ensure it is not listed
         # Create a test flavor
@@ -84,6 +85,7 @@
         self.assertTrue(flag)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6f56e7b7-7500-4d0c-9913-880ca1efed87')
     def test_create_flavor_as_user(self):
         # only admin user can create a flavor
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -96,6 +98,7 @@
                           swap=self.swap, rxtx=self.rxtx)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a9a6dc02-8c14-4e05-a1ca-3468d4214882')
     def test_delete_flavor_as_user(self):
         # only admin user can delete a flavor
         self.assertRaises(lib_exc.Unauthorized,
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index e01245e..7ca081a 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -57,6 +57,7 @@
             pass
 
     @test.attr(type='gate')
+    @test.idempotent_id('2c8f145f-8012-4cb8-ac7e-95a587f0e4ab')
     @test.services('network')
     def test_create_list_delete_floating_ips_bulk(self):
         # Create, List  and delete the Floating IPs Bulk
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index b9d47bb..bef5d1f 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -29,11 +29,13 @@
         cls.client = cls.os_adm.hosts_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('9bfaf98d-e2cb-44b0-a07e-2558b2821e4f')
     def test_list_hosts(self):
         hosts = self.client.list_hosts()
         self.assertTrue(len(hosts) >= 2, str(hosts))
 
     @test.attr(type='gate')
+    @test.idempotent_id('5dc06f5b-d887-47a2-bb2a-67762ef3c6de')
     def test_list_hosts_with_zone(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
         hosts = self.client.list_hosts()
@@ -45,6 +47,7 @@
         self.assertIn(host, hosts)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9af3c171-fbf4-4150-a624-22109733c2a6')
     def test_list_hosts_with_a_blank_zone(self):
         # If send the request with a blank zone, the request will be successful
         # and it will return all the hosts list
@@ -53,6 +56,7 @@
         self.assertNotEqual(0, len(hosts))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c6ddbadb-c94e-4500-b12f-8ffc43843ff8')
     def test_list_hosts_with_nonexistent_zone(self):
         # If send the request with a nonexistent zone, the request will be
         # successful and no hosts will be retured
@@ -61,6 +65,7 @@
         self.assertEqual(0, len(hosts))
 
     @test.attr(type='gate')
+    @test.idempotent_id('38adbb12-aee2-4498-8aec-329c72423aa4')
     def test_show_host_detail(self):
         hosts = self.client.list_hosts()
 
diff --git a/tempest/api/compute/admin/test_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index 8d70c44..3c070ce 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -38,17 +38,20 @@
         return hostname
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dd032027-0210-4d9c-860e-69b1b8deed5f')
     def test_list_hosts_with_non_admin_user(self):
         self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_hosts)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e75b0a1a-041f-47a1-8b4a-b72a6ff36d3f')
     def test_show_host_detail_with_nonexistent_hostname(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
         self.assertRaises(lib_exc.NotFound,
                           self.client.show_host_detail, nonexitent_hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('19ebe09c-bfd4-4b7c-81a2-e2e0710f59cc')
     def test_show_host_detail_with_non_admin_user(self):
         hostname = self._get_host_name()
 
@@ -57,6 +60,7 @@
                           hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e40c72b1-0239-4ed6-ba21-81a184df1f7c')
     def test_update_host_with_non_admin_user(self):
         hostname = self._get_host_name()
 
@@ -67,6 +71,7 @@
                           maintenance_mode='enable')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('76e396fe-5418-4dd3-a186-5b301edc0721')
     def test_update_host_with_extra_param(self):
         # only 'status' and 'maintenance_mode' are the valid params.
         hostname = self._get_host_name()
@@ -79,6 +84,7 @@
                           param='XXX')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fbe2bf3e-3246-4a95-a59f-94e4e298ec77')
     def test_update_host_with_invalid_status(self):
         # 'status' can only be 'enable' or 'disable'
         hostname = self._get_host_name()
@@ -90,6 +96,7 @@
                           maintenance_mode='enable')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ab1e230e-5e22-41a9-8699-82b9947915d4')
     def test_update_host_with_invalid_maintenance_mode(self):
         # 'maintenance_mode' can only be 'enable' or 'disable'
         hostname = self._get_host_name()
@@ -101,6 +108,7 @@
                           maintenance_mode='invalid')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0cd85f75-6992-4a4a-b1bd-d11e37fd0eee')
     def test_update_host_without_param(self):
         # 'status' or 'maintenance_mode' needed for host update
         hostname = self._get_host_name()
@@ -110,6 +118,7 @@
                           hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('23c92146-2100-4d68-b2d6-c7ade970c9c1')
     def test_update_nonexistent_host(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
 
@@ -120,6 +129,7 @@
                           maintenance_mode='enable')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0d981ac3-4320-4898-b674-82b61fbb60e4')
     def test_startup_nonexistent_host(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
 
@@ -128,6 +138,7 @@
                           nonexitent_hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9f4ebb7e-b2ae-4e5b-a38f-0fd1bb0ddfca')
     def test_startup_host_with_non_admin_user(self):
         hostname = self._get_host_name()
 
@@ -136,6 +147,7 @@
                           hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9e637444-29cf-4244-88c8-831ae82c31b6')
     def test_shutdown_nonexistent_host(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
 
@@ -144,6 +156,7 @@
                           nonexitent_hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a803529c-7e3f-4d3c-a7d6-8e1c203d27f6')
     def test_shutdown_host_with_non_admin_user(self):
         hostname = self._get_host_name()
 
@@ -152,6 +165,7 @@
                           hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f86bfd7b-0b13-4849-ae29-0322e83ee58b')
     def test_reboot_nonexistent_host(self):
         nonexitent_hostname = data_utils.rand_name('rand_hostname')
 
@@ -160,6 +174,7 @@
                           nonexitent_hostname)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('02d79bb9-eb57-4612-abf6-2cb38897d2f8')
     def test_reboot_host_with_non_admin_user(self):
         hostname = self._get_host_name()
 
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index fbfef87..c65bded 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -37,18 +37,21 @@
         self.assertTrue(len(hypers) > 0, "No hypervisors found: %s" % hypers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7f0ceacd-c64d-4e96-b8ee-d02943142cc5')
     def test_get_hypervisor_list(self):
         # List of hypervisor and available hypervisors hostname
         hypers = self._list_hypervisors()
         self.assertHypervisors(hypers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('1e7fdac2-b672-4ad1-97a4-bad0e3030118')
     def test_get_hypervisor_list_details(self):
         # Display the details of the all hypervisor
         hypers = self.client.get_hypervisor_list_details()
         self.assertHypervisors(hypers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('94ff9eae-a183-428e-9cdb-79fde71211cc')
     def test_get_hypervisor_show_details(self):
         # Display the details of the specified hypervisor
         hypers = self._list_hypervisors()
@@ -60,6 +63,7 @@
                          hypers[0]['hypervisor_hostname'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('e81bba3f-6215-4e39-a286-d52d2f906862')
     def test_get_hypervisor_show_servers(self):
         # Show instances about the specific hypervisors
         hypers = self._list_hypervisors()
@@ -70,12 +74,14 @@
         self.assertTrue(len(hypervisors) > 0)
 
     @test.attr(type='gate')
+    @test.idempotent_id('797e4f28-b6e0-454d-a548-80cc77c00816')
     def test_get_hypervisor_stats(self):
         # Verify the stats of the all hypervisor
         stats = self.client.get_hypervisor_stats()
         self.assertTrue(len(stats) > 0)
 
     @test.attr(type='gate')
+    @test.idempotent_id('91a50d7d-1c2b-4f24-b55a-a1fe20efca70')
     def test_get_hypervisor_uptime(self):
         # Verify that GET shows the specified hypervisor uptime
         hypers = self._list_hypervisors()
@@ -113,6 +119,7 @@
             "None of the hypervisors had a valid uptime: %s" % hypers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('d7e1805b-3b14-4a3b-b6fd-50ec6d9f361f')
     def test_search_hypervisor(self):
         hypers = self._list_hypervisors()
         self.assertHypervisors(hypers)
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
index a9c1cb1..556424a 100644
--- a/tempest/api/compute/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -39,6 +39,7 @@
         return hypers
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c136086a-0f67-4b2b-bc61-8482bd68989f')
     def test_show_nonexistent_hypervisor(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
@@ -48,6 +49,7 @@
             nonexistent_hypervisor_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('51e663d0-6b89-4817-a465-20aca0667d03')
     def test_show_hypervisor_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
@@ -58,6 +60,7 @@
             hypers[0]['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('2a0a3938-832e-4859-95bf-1c57c236b924')
     def test_show_servers_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
@@ -68,6 +71,7 @@
             hypers[0]['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('02463d69-0ace-4d33-a4a8-93d7883a2bba')
     def test_show_servers_with_nonexistent_hypervisor(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
@@ -77,12 +81,14 @@
             nonexistent_hypervisor_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e2b061bb-13f9-40d8-9d6e-d5bf17595849')
     def test_get_hypervisor_stats_with_non_admin_user(self):
         self.assertRaises(
             lib_exc.Unauthorized,
             self.non_adm_client.get_hypervisor_stats)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f60aa680-9a3a-4c7d-90e1-fae3a4891303')
     def test_get_nonexistent_hypervisor_uptime(self):
         nonexistent_hypervisor_id = str(uuid.uuid4())
 
@@ -92,6 +98,7 @@
             nonexistent_hypervisor_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6c3461f9-c04c-4e2a-bebb-71dc9cb47df2')
     def test_get_hypervisor_uptime_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
@@ -102,6 +109,7 @@
             hypers[0]['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('51b3d536-9b14-409c-9bce-c6f7c794994e')
     def test_get_hypervisor_list_with_non_admin_user(self):
         # List of hypervisor and available services with non admin user
         self.assertRaises(
@@ -109,6 +117,7 @@
             self.non_adm_client.get_hypervisor_list)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dc02db05-e801-4c5f-bc8e-d915290ab345')
     def test_get_hypervisor_list_details_with_non_admin_user(self):
         # List of hypervisor details and available services with non admin user
         self.assertRaises(
@@ -116,6 +125,7 @@
             self.non_adm_client.get_hypervisor_list_details)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('19a45cc1-1000-4055-b6d2-28e8b2ec4faa')
     def test_search_nonexistent_hypervisor(self):
         nonexistent_hypervisor_name = data_utils.rand_name('test_hypervisor')
 
@@ -125,6 +135,7 @@
             nonexistent_hypervisor_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5b6a6c79-5dc1-4fa5-9c58-9c8085948e74')
     def test_search_hypervisor_with_non_admin_user(self):
         hypers = self._list_hypervisors()
         self.assertTrue(len(hypers) > 0)
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log.py b/tempest/api/compute/admin/test_instance_usage_audit_log.py
index 16ce93c..1a86b2d 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log.py
@@ -28,6 +28,7 @@
         cls.adm_client = cls.os_adm.instance_usages_audit_log_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('25319919-33d9-424f-9f99-2c203ee48b9d')
     def test_list_instance_usage_audit_logs(self):
         # list instance usage audit logs
         body = self.adm_client.list_instance_usage_audit_logs()
@@ -40,6 +41,7 @@
             self.assertIn(item, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6e40459d-7c5f-400b-9e83-449fbc8e7feb')
     def test_get_instance_usage_audit_log(self):
         # Get instance usage audit log before specified time
         now = datetime.datetime.now()
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py b/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
index 5453ff4..6b5a82f 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
@@ -30,6 +30,7 @@
         cls.adm_client = cls.os_adm.instance_usages_audit_log_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a9d33178-d2c9-4131-ad3b-f4ca8d0308a2')
     def test_instance_usage_audit_logs_with_nonadmin_user(self):
         # the instance_usage_audit_logs API just can be accessed by admin user
         self.assertRaises(lib_exc.Unauthorized,
@@ -42,6 +43,7 @@
                           urllib.quote(now.strftime("%Y-%m-%d %H:%M:%S")))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9b952047-3641-41c7-ba91-a809fc5974c8')
     def test_get_instance_usage_audit_logs_with_invalid_time(self):
         self.assertRaises(lib_exc.BadRequest,
                           self.adm_client.get_instance_usage_audit_log,
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index aaf7a78..67e4fe3 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -29,10 +29,12 @@
         cls.client = cls.os_adm.migrations_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('75c0b83d-72a0-4cf8-a153-631e83e7d53f')
     def test_list_migrations(self):
         # Admin can get the migrations list
         self.client.list_migrations()
 
+    @test.idempotent_id('1b512062-8093-438e-b47a-37d2f597cd64')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='gate')
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index 898d085..fa72c01 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -15,6 +15,7 @@
 
 from tempest.api.compute import base
 from tempest import config
+from tempest import test
 
 CONF = config.CONF
 
@@ -33,6 +34,7 @@
         super(NetworksTest, cls).resource_setup()
         cls.client = cls.os_adm.networks_client
 
+    @test.idempotent_id('d206d211-8912-486f-86e2-a9d090d1f416')
     def test_get_network(self):
         networks = self.client.list_networks()
         configured_network = [x for x in networks if x['label'] ==
@@ -45,6 +47,7 @@
         network = self.client.get_network(configured_network['id'])
         self.assertEqual(configured_network['label'], network['label'])
 
+    @test.idempotent_id('df3d1046-6fa5-4b2c-ad0c-cfa46a351cb9')
     def test_list_all_networks(self):
         networks = self.client.list_networks()
         # Check the configured network is in the list
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index b0fcf94..35e682e 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -51,6 +51,7 @@
                                      'cores', 'security_groups'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3b0a7c8f-cf58-46b8-a60c-715a32a8ba7d')
     def test_get_default_quotas(self):
         # Admin can get the default resource quota set for a tenant
         expected_quota_set = self.default_quota_set | set(['id'])
@@ -61,6 +62,7 @@
             self.assertIn(quota, quota_set.keys())
 
     @test.attr(type='gate')
+    @test.idempotent_id('55fbe2bf-21a9-435b-bbd2-4162b0ed799a')
     def test_update_all_quota_resources_for_tenant(self):
         # Admin can update all the resource quota limits for a tenant
         default_quota_set = self.adm_client.get_default_quota_set(
@@ -92,6 +94,7 @@
 
     # TODO(afazekas): merge these test cases
     @test.attr(type='gate')
+    @test.idempotent_id('ce9e0815-8091-4abd-8345-7fe5b85faa1d')
     def test_get_updated_quotas(self):
         # Verify that GET shows the updated quota set of tenant
         tenant_name = data_utils.rand_name('cpu_quota_tenant_')
@@ -125,6 +128,7 @@
         self.assertEqual(2048, quota_set['ram'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0')
     def test_delete_quota(self):
         # Admin can delete the resource quota set for a tenant
         tenant_name = data_utils.rand_name('ram_quota_tenant_')
@@ -169,6 +173,7 @@
     # global state, and possibly needs to be part of a set of
     # tests that get run all by themselves at the end under a
     # 'danger' flag.
+    @test.idempotent_id('7932ab0f-5136-4075-b201-c0e2338df51a')
     def test_update_default_quotas(self):
         LOG.debug("get the current 'default' quota class values")
         body = self.adm_client.get_quota_class_set('default')
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index 2fb7be6..73428df 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -38,6 +38,7 @@
         cls.demo_tenant_id = cls.client.tenant_id
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('733abfe8-166e-47bb-8363-23dbd7ff3476')
     def test_update_quota_normal_user(self):
         self.assertRaises(lib_exc.Unauthorized,
                           self.client.update_quota_set,
@@ -47,6 +48,7 @@
     # TODO(afazekas): Add dedicated tenant to the skiped quota tests
     # it can be moved into the setUpClass as well
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('91058876-9947-4807-9f22-f6eb17140d9b')
     def test_create_server_when_cpu_quota_is_full(self):
         # Disallow server creation when tenant's vcpu quota is full
         quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
@@ -63,6 +65,7 @@
                           self.create_test_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6fdd7012-584d-4327-a61c-49122e0d5864')
     def test_create_server_when_memory_quota_is_full(self):
         # Disallow server creation when tenant's memory quota is full
         quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
@@ -79,6 +82,7 @@
                           self.create_test_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7c6be468-0274-449a-81c3-ac1c32ee0161')
     def test_create_server_when_instances_quota_is_full(self):
         # Once instances quota limit is reached, disallow server creation
         quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
@@ -96,6 +100,7 @@
     @decorators.skip_because(bug="1186354",
                              condition=CONF.service_available.neutron)
     @test.attr(type='gate')
+    @test.idempotent_id('7c6c8f3b-2bf6-4918-b240-57b136a66aa0')
     @test.services('network')
     def test_security_groups_exceed_limit(self):
         # Negative test: Creation Security Groups over limit should FAIL
@@ -123,6 +128,7 @@
     @decorators.skip_because(bug="1186354",
                              condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6e9f436d-f1ed-4f8e-a493-7275dfaa4b4d')
     @test.services('network')
     def test_security_groups_rules_exceed_limit(self):
         # Negative test: Creation of Security Group Rules should FAIL
diff --git a/tempest/api/compute/admin/test_security_group_default_rules.py b/tempest/api/compute/admin/test_security_group_default_rules.py
index a0606cd..87c0008 100644
--- a/tempest/api/compute/admin/test_security_group_default_rules.py
+++ b/tempest/api/compute/admin/test_security_group_default_rules.py
@@ -56,6 +56,7 @@
         return rule
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6d880615-eec3-4d29-97c5-7a074dde239d')
     def test_create_delete_security_group_default_rules(self):
         # Create and delete Security Group default rule
         ip_protocols = ['tcp', 'udp', 'icmp']
@@ -68,6 +69,7 @@
                               rule['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4d752e0a-33a1-4c3a-b498-ff8667ca22e5')
     def test_create_security_group_default_rule_without_cidr(self):
         ip_protocol = 'udp'
         from_port = 80
@@ -82,6 +84,7 @@
         self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('29f2d218-69b0-4a95-8f3d-6bd0ef732b3a')
     def test_create_security_group_default_rule_with_blank_cidr(self):
         ip_protocol = 'icmp'
         from_port = 10
@@ -98,6 +101,7 @@
         self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6e6de55e-9146-4ae0-89f2-3569586e0b9b')
     def test_security_group_default_rules_list(self):
         ip_protocol = 'tcp'
         from_port = 22
@@ -114,6 +118,7 @@
         self.assertIn(rule, rules)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('15cbb349-86b4-4f71-a048-04b7ef3f150b')
     def test_default_security_group_default_rule_show(self):
         ip_protocol = 'tcp'
         from_port = 22
diff --git a/tempest/api/compute/admin/test_security_groups.py b/tempest/api/compute/admin/test_security_groups.py
index 82cb26e..19f5b8c 100644
--- a/tempest/api/compute/admin/test_security_groups.py
+++ b/tempest/api/compute/admin/test_security_groups.py
@@ -37,6 +37,7 @@
         else:
             self.client.delete_security_group(securitygroup_id)
 
+    @test.idempotent_id('49667619-5af9-4c63-ab5d-2cfdd1c8f7f1')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Skipped because neutron do not support all_tenants"
                       "search filter.")
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 84c38c1..adeb64b 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -45,6 +45,7 @@
         cls.s2_id = server['id']
 
     @test.attr(type='gate')
+    @test.idempotent_id('51717b38-bdc1-458b-b636-1cf82d99f62f')
     def test_list_servers_by_admin(self):
         # Listing servers by admin user returns empty list by default
         body = self.client.list_servers_with_detail()
@@ -52,6 +53,7 @@
         self.assertEqual([], servers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('06f960bb-15bb-48dc-873d-f96e89be7870')
     def test_list_servers_filter_by_error_status(self):
         # Filter the list of servers by server error status
         params = {'status': 'error'}
@@ -68,6 +70,7 @@
         self.assertNotIn(self.s2_id, map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('9f5579ae-19b4-4985-a091-2a5d56106580')
     def test_list_servers_by_admin_with_all_tenants(self):
         # Listing servers by admin user with all tenants parameter
         # Here should be listed all servers
@@ -80,6 +83,7 @@
         self.assertIn(self.s2_name, servers_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7e5d6b8f-454a-4ba1-8ae2-da857af8338b')
     def test_list_servers_by_admin_with_specified_tenant(self):
         # In nova v2, tenant_id is ignored unless all_tenants is specified
 
@@ -98,6 +102,7 @@
         self.assertEqual([], servers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('86c7a8f7-50cf-43a9-9bac-5b985317134f')
     def test_list_servers_filter_by_exist_host(self):
         # Filter the list of servers by existent host
         name = data_utils.rand_name('server')
@@ -120,6 +125,7 @@
                          map(lambda x: x['id'], nonexistent_servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ee8ae470-db70-474d-b752-690b7892cab1')
     def test_reset_state_server(self):
         # Reset server's state to 'error'
         self.client.reset_state(self.s1_id)
@@ -137,6 +143,7 @@
 
     @test.attr(type='gate')
     @decorators.skip_because(bug="1240043")
+    @test.idempotent_id('31ff3486-b8a0-4f56-a6c0-aab460531db3')
     def test_get_server_diagnostics_by_admin(self):
         # Retrieve server diagnostics by admin user
         diagnostic = self.client.get_server_diagnostics(self.s1_id)
@@ -147,6 +154,7 @@
             self.assertIn(key, str(diagnostic.keys()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('682cb127-e5bb-4f53-87ce-cb9003604442')
     def test_rebuild_server_in_error_state(self):
         # The server in error state should be rebuilt using the provided
         # image and changed to ACTIVE state
@@ -174,6 +182,7 @@
         self.assertEqual(self.image_ref_alt, rebuilt_image_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7a1323b4-a6a2-497a-96cb-76c07b945c71')
     def test_reset_network_inject_network_info(self):
         # Reset Network of a Server
         server = self.create_test_server(wait_until='ACTIVE')
@@ -182,6 +191,7 @@
         self.client.inject_network_info(server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('fdcd9b33-0903-4e00-a1f7-b5f6543068d6')
     def test_create_server_with_scheduling_hint(self):
         # Create a server with scheduler hints.
         hints = {
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index bbe289d..cafbf81 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -55,6 +55,7 @@
             flavor_id = data_utils.rand_int_id(start=1000)
         return flavor_id
 
+    @test.idempotent_id('28dcec23-f807-49da-822c-56a92ea3c687')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
@@ -76,6 +77,7 @@
                           self.servers[0]['id'],
                           flavor_ref['id'])
 
+    @test.idempotent_id('7368a427-2f26-4ad9-9ba9-911a0ec2b0db')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
@@ -98,23 +100,27 @@
                           flavor_ref['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b0b4d8af-1256-41ef-9ee7-25f1c19dde80')
     def test_reset_state_server_invalid_state(self):
         self.assertRaises(lib_exc.BadRequest,
                           self.client.reset_state, self.s1_id,
                           state='invalid')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4cdcc984-fab0-4577-9a9d-6d558527ee9d')
     def test_reset_state_server_invalid_type(self):
         self.assertRaises(lib_exc.BadRequest,
                           self.client.reset_state, self.s1_id,
                           state=1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e741298b-8df2-46f0-81cb-8f814ff2504c')
     def test_reset_state_server_nonexistent_server(self):
         self.assertRaises(lib_exc.NotFound,
                           self.client.reset_state, '999')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e84e2234-60d2-42fa-8b30-e2d3049724ac')
     def test_get_server_diagnostics_by_non_admin(self):
         # Non-admin user can not view server diagnostics according to policy
         self.assertRaises(lib_exc.Unauthorized,
@@ -122,12 +128,14 @@
                           self.s1_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('46a4e1ca-87ae-4d28-987a-1b6b136a0221')
     def test_migrate_non_existent_server(self):
         # migrate a non existent server
         self.assertRaises(lib_exc.NotFound,
                           self.client.migrate_server,
                           str(uuid.uuid4()))
 
+    @test.idempotent_id('b0b17f83-d14e-4fc4-8f31-bcc9f3cfa629')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index 5cf4a31..a6f79aa 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -30,11 +30,13 @@
         cls.client = cls.os_adm.services_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('5be41ef4-53d1-41cc-8839-5c2a48a1b283')
     def test_list_services(self):
         services = self.client.list_services()
         self.assertNotEqual(0, len(services))
 
     @test.attr(type='gate')
+    @test.idempotent_id('f345b1ec-bc6e-4c38-a527-3ca2bc00bef5')
     def test_get_service_by_service_binary_name(self):
         binary_name = 'nova-compute'
         params = {'binary': binary_name}
@@ -44,6 +46,7 @@
             self.assertEqual(binary_name, service['binary'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('affb42d5-5b4b-43c8-8b0b-6dca054abcca')
     def test_get_service_by_host_name(self):
         services = self.client.list_services()
         host_name = services[0]['host']
@@ -63,6 +66,7 @@
         self.assertEqual(sorted(s1), sorted(s2))
 
     @test.attr(type='gate')
+    @test.idempotent_id('39397f6f-37b8-4234-8671-281e44c74025')
     def test_get_service_by_service_and_host_name(self):
         services = self.client.list_services()
         host_name = services[0]['host']
diff --git a/tempest/api/compute/admin/test_services_negative.py b/tempest/api/compute/admin/test_services_negative.py
index 39d0ee1..b8974ca 100644
--- a/tempest/api/compute/admin/test_services_negative.py
+++ b/tempest/api/compute/admin/test_services_negative.py
@@ -31,11 +31,13 @@
         cls.non_admin_client = cls.services_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1126d1f8-266e-485f-a687-adc547492646')
     def test_list_services_with_non_admin_user(self):
         self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_services)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d0884a69-f693-4e79-a9af-232d15643bf7')
     def test_get_service_by_invalid_params(self):
         # return all services if send the request with invalid parameter
         services = self.client.list_services()
@@ -44,6 +46,7 @@
         self.assertEqual(len(services), len(services_xxx))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1e966d4a-226e-47c7-b601-0b18a27add54')
     def test_get_service_by_invalid_service_and_valid_host(self):
         services = self.client.list_services()
         host_name = services[0]['host']
@@ -52,6 +55,7 @@
         self.assertEqual(0, len(services))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('64e7e7fb-69e8-4cb6-a71d-8d5eb0c98655')
     def test_get_service_with_valid_service_and_invalid_host(self):
         services = self.client.list_services()
         binary_name = services[0]['binary']
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage.py b/tempest/api/compute/admin/test_simple_tenant_usage.py
index 6775d1f..be62b1d 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage.py
@@ -43,6 +43,7 @@
         return at.strftime('%Y-%m-%dT%H:%M:%S.%f')
 
     @test.attr(type='gate')
+    @test.idempotent_id('062c8ae9-9912-4249-8b51-e38d664e926e')
     def test_list_usage_all_tenants(self):
         # Get usage for all tenants
         params = {'start': self.start,
@@ -52,6 +53,7 @@
         self.assertEqual(len(tenant_usage), 8)
 
     @test.attr(type='gate')
+    @test.idempotent_id('94135049-a4c5-4934-ad39-08fa7da4f22e')
     def test_get_usage_tenant(self):
         # Get usage for a specific tenant
         params = {'start': self.start,
@@ -62,6 +64,7 @@
         self.assertEqual(len(tenant_usage), 8)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9d00a412-b40e-4fd9-8eba-97b496316116')
     def test_get_usage_tenant_with_non_admin_user(self):
         # Get usage for a specific tenant with non admin user
         params = {'start': self.start,
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
index 0d88f6c..8801e85 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
@@ -38,6 +38,7 @@
         return at.strftime('%Y-%m-%dT%H:%M:%S.%f')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8b21e135-d94b-4991-b6e9-87059609c8ed')
     def test_get_usage_tenant_with_empty_tenant_id(self):
         # Get usage for a specific tenant empty
         params = {'start': self.start,
@@ -47,6 +48,7 @@
                           '', params)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4079dd2a-9e8d-479f-869d-6fa985ce45b6')
     def test_get_usage_tenant_with_invalid_date(self):
         # Get usage for tenant with invalid date
         params = {'start': self.end,
@@ -56,6 +58,7 @@
                           self.client.tenant_id, params)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bbe6fe2c-15d8-404c-a0a2-44fad0ad5cc7')
     def test_list_usage_all_tenants_with_non_admin_user(self):
         # Get usage for all tenants with non admin user
         params = {'start': self.start,
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index 321a0a1..2be201a 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -22,6 +22,7 @@
     _api_version = 2
 
     @test.attr(type='gate')
+    @test.idempotent_id('c070a441-b08e-447e-a733-905909535b1b')
     def test_create_root_certificate(self):
         # create certificates
         body = self.certificates_client.create_certificate()
@@ -29,6 +30,7 @@
         self.assertIn('private_key', body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3ac273d0-92d2-4632-bdfc-afbc21d4606c')
     def test_get_root_certificate(self):
         # get the root certificate
         body = self.certificates_client.get_certificate('root')
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index c91ce17..b9056c7 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -29,6 +29,7 @@
         cls.client = cls.flavors_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e36c0eaa-dff5-4082-ad1f-3f9a80aa3f59')
     def test_list_flavors(self):
         # List of all flavors should contain the expected flavor
         flavors = self.client.list_flavors()
@@ -38,6 +39,7 @@
         self.assertIn(flavor_min_detail, flavors)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6e85fde4-b3cd-4137-ab72-ed5f418e8c24')
     def test_list_flavors_with_detail(self):
         # Detailed list of all flavors should contain the expected flavor
         flavors = self.client.list_flavors_with_detail()
@@ -45,12 +47,14 @@
         self.assertIn(flavor, flavors)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1f12046b-753d-40d2-abb6-d8eb8b30cb2f')
     def test_get_flavor(self):
         # The expected flavor details should be returned
         flavor = self.client.get_flavor_details(self.flavor_ref)
         self.assertEqual(self.flavor_ref, flavor['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('8d7691b3-6ed4-411a-abc9-2839a765adab')
     def test_list_flavors_limit_results(self):
         # Only the expected number of flavors should be returned
         params = {'limit': 1}
@@ -58,6 +62,7 @@
         self.assertEqual(1, len(flavors))
 
     @test.attr(type='gate')
+    @test.idempotent_id('b26f6327-2886-467a-82be-cef7a27709cb')
     def test_list_flavors_detailed_limit_results(self):
         # Only the expected number of flavors (detailed) should be returned
         params = {'limit': 1}
@@ -65,6 +70,7 @@
         self.assertEqual(1, len(flavors))
 
     @test.attr(type='gate')
+    @test.idempotent_id('e800f879-9828-4bd0-8eae-4f17189951fb')
     def test_list_flavors_using_marker(self):
         # The list of flavors should start from the provided marker
         flavor = self.client.get_flavor_details(self.flavor_ref)
@@ -76,6 +82,7 @@
                          'The list of flavors did not start after the marker.')
 
     @test.attr(type='gate')
+    @test.idempotent_id('6db2f0c0-ddee-4162-9c84-0703d3dd1107')
     def test_list_flavors_detailed_using_marker(self):
         # The list of flavors should start from the provided marker
         flavor = self.client.get_flavor_details(self.flavor_ref)
@@ -87,6 +94,7 @@
                          'The list of flavors did not start after the marker.')
 
     @test.attr(type='gate')
+    @test.idempotent_id('3df2743e-3034-4e57-a4cb-b6527f6eac79')
     def test_list_flavors_detailed_filter_by_min_disk(self):
         # The detailed list of flavors should be filtered by disk space
         flavor = self.client.get_flavor_details(self.flavor_ref)
@@ -97,6 +105,7 @@
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('09fe7509-b4ee-4b34-bf8b-39532dc47292')
     def test_list_flavors_detailed_filter_by_min_ram(self):
         # The detailed list of flavors should be filtered by RAM
         flavor = self.client.get_flavor_details(self.flavor_ref)
@@ -107,6 +116,7 @@
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('10645a4d-96f5-443f-831b-730711e11dd4')
     def test_list_flavors_filter_by_min_disk(self):
         # The list of flavors should be filtered by disk space
         flavor = self.client.get_flavor_details(self.flavor_ref)
@@ -117,6 +127,7 @@
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('935cf550-e7c8-4da6-8002-00f92d5edfaa')
     def test_list_flavors_filter_by_min_ram(self):
         # The list of flavors should be filtered by RAM
         flavor = self.client.get_flavor_details(self.flavor_ref)
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index 46a6ddb..f65223e 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -58,6 +58,7 @@
             pass
 
     @test.attr(type='gate')
+    @test.idempotent_id('f7bfb946-297e-41b8-9e8c-aba8e9bb5194')
     @test.services('network')
     def test_allocate_floating_ip(self):
         # Positive test:Allocation of a new floating IP to a project
@@ -73,6 +74,7 @@
         self.assertIn(floating_ip_details, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('de45e989-b5ca-4a9b-916b-04a52e7bbb8b')
     @test.services('network')
     def test_delete_floating_ip(self):
         # Positive test:Deletion of valid floating IP from project
@@ -86,6 +88,7 @@
         self.client.wait_for_resource_deletion(floating_ip_body['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('307efa27-dc6f-48a0-8cd2-162ce3ef0b52')
     @test.services('network')
     def test_associate_disassociate_floating_ip(self):
         # Positive test:Associate and disassociate the provided floating IP
@@ -106,6 +109,7 @@
             self.server_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6edef4b2-aaf1-4abc-bbe3-993e2561e0fe')
     @test.services('network')
     def test_associate_already_associated_floating_ip(self):
         # positive test:Association of an already associated floating IP
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index fa3fa16..2c08ae7 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -53,6 +53,7 @@
                 break
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6e0f059b-e4dd-48fb-8207-06e3bba5b074')
     @test.services('network')
     def test_allocate_floating_ip_from_nonexistent_pool(self):
         # Negative test:Allocation of a new floating IP from a nonexistent_pool
@@ -62,6 +63,7 @@
                           "non_exist_pool")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ae1c55a8-552b-44d4-bfb6-2a115a15d0ba')
     @test.services('network')
     def test_delete_nonexistent_floating_ip(self):
         # Negative test:Deletion of a nonexistent floating IP
@@ -72,6 +74,7 @@
                           self.non_exist_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('595fa616-1a71-4670-9614-46564ac49a4c')
     @test.services('network')
     def test_associate_nonexistent_floating_ip(self):
         # Negative test:Association of a non existent floating IP
@@ -82,6 +85,7 @@
                           "0.0.0.0", self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0a081a66-e568-4e6b-aa62-9587a876dca8')
     @test.services('network')
     def test_dissociate_nonexistent_floating_ip(self):
         # Negative test:Dissociation of a non existent floating IP should fail
@@ -91,6 +95,7 @@
                           "0.0.0.0", self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('804b4fcb-bbf5-412f-925d-896672b61eb3')
     @test.services('network')
     def test_associate_ip_to_server_without_passing_floating_ip(self):
         # Negative test:Association of empty floating IP to specific server
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 25f13fc..c18ecb7 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -41,6 +41,7 @@
         super(FloatingIPDetailsTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('16db31c3-fb85-40c9-bbe2-8cf7b67ff99f')
     @test.services('network')
     def test_list_floating_ips(self):
         # Positive test:Should return the list of floating IPs
@@ -52,6 +53,7 @@
             self.assertIn(self.floating_ip[i], floating_ips)
 
     @test.attr(type='gate')
+    @test.idempotent_id('eef497e0-8ff7-43c8-85ef-558440574f84')
     @test.services('network')
     def test_get_floating_ip_details(self):
         # Positive test:Should be able to GET the details of floatingIP
@@ -73,6 +75,7 @@
         self.assertEqual(floating_ip_id, body['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('df389fc8-56f5-43cc-b290-20eda39854d3')
     @test.services('network')
     def test_list_floating_ip_pools(self):
         # Positive test:Should return the list of floating IP Pools
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
index d1d3517..13d0719 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
@@ -33,6 +33,7 @@
         cls.client = cls.floating_ips_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7ab18834-4a4b-4f28-a2c5-440579866695')
     @test.services('network')
     def test_get_nonexistent_floating_ip_details(self):
         # Negative test:Should not be able to GET the details
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index c3b144d..8193a55 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -53,6 +53,7 @@
         self.client.set_image_metadata(self.image_id, meta)
 
     @test.attr(type='gate')
+    @test.idempotent_id('37ec6edd-cf30-4c53-bd45-ae74db6b0531')
     def test_list_image_metadata(self):
         # All metadata key/value pairs for an image should be returned
         resp_metadata = self.client.list_image_metadata(self.image_id)
@@ -60,6 +61,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ece7befc-d3ce-42a4-b4be-c3067a418c29')
     def test_set_image_metadata(self):
         # The metadata for the image should match the new values
         req_metadata = {'os_version': 'value2', 'architecture': 'value3'}
@@ -70,6 +72,7 @@
         self.assertEqual(req_metadata, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7b491c11-a9d5-40fe-a696-7f7e03d3fea2')
     def test_update_image_metadata(self):
         # The metadata for the image should match the updated values
         req_metadata = {'os_version': 'alt1', 'architecture': 'value3'}
@@ -83,6 +86,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4f5db52f-6685-4c75-b848-f4bb363f9aa6')
     def test_get_image_metadata_item(self):
         # The value for a specific metadata key should be returned
         meta = self.client.get_image_metadata_item(self.image_id,
@@ -90,6 +94,7 @@
         self.assertEqual('value2', meta['os_distro'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('f2de776a-4778-4d90-a5da-aae63aee64ae')
     def test_set_image_metadata_item(self):
         # The value provided for the given meta item should be set for
         # the image
@@ -101,6 +106,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a013796c-ba37-4bb5-8602-d944511def14')
     def test_delete_image_metadata_item(self):
         # The metadata value/key pair should be deleted from the image
         self.client.delete_image_metadata_item(self.image_id,
diff --git a/tempest/api/compute/images/test_image_metadata_negative.py b/tempest/api/compute/images/test_image_metadata_negative.py
index 0013714..d181ed9 100644
--- a/tempest/api/compute/images/test_image_metadata_negative.py
+++ b/tempest/api/compute/images/test_image_metadata_negative.py
@@ -28,6 +28,7 @@
         cls.client = cls.images_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('94069db2-792f-4fa8-8bd3-2271a6e0c095')
     def test_list_nonexistent_image_metadata(self):
         # Negative test: List on nonexistent image
         # metadata should not happen
@@ -35,6 +36,7 @@
                           data_utils.rand_uuid())
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a403ef9e-9f95-427c-b70a-3ce3388796f1')
     def test_update_nonexistent_image_metadata(self):
         # Negative test:An update should not happen for a non-existent image
         meta = {'os_distro': 'alt1', 'os_version': 'alt2'}
@@ -43,6 +45,7 @@
                           data_utils.rand_uuid(), meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('41ae052c-6ee6-405c-985e-5712393a620d')
     def test_get_nonexistent_image_metadata_item(self):
         # Negative test: Get on non-existent image should not happen
         self.assertRaises(lib_exc.NotFound,
@@ -50,6 +53,7 @@
                           data_utils.rand_uuid(), 'os_version')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dc64f2ce-77e8-45b0-88c8-e15041d08eaf')
     def test_set_nonexistent_image_metadata(self):
         # Negative test: Metadata should not be set to a non-existent image
         meta = {'os_distro': 'alt1', 'os_version': 'alt2'}
@@ -57,6 +61,7 @@
                           data_utils.rand_uuid(), meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('2154fd03-ab54-457c-8874-e6e3eb56e9cf')
     def test_set_nonexistent_image_metadata_item(self):
         # Negative test: Metadata item should not be set to a
         # nonexistent image
@@ -67,6 +72,7 @@
                           meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('848e157f-6bcf-4b2e-a5dd-5124025a8518')
     def test_delete_nonexistent_image_metadata_item(self):
         # Negative test: Shouldn't be able to delete metadata
         # item from non-existent image
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index 2508fe1..396d629 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -38,6 +38,7 @@
         cls.servers_client = cls.servers_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('aa06b52b-2db5-4807-b218-9441f75d74e3')
     def test_delete_saving_image(self):
         snapshot_name = data_utils.rand_name('test-snap-')
         server = self.create_test_server(wait_until='ACTIVE')
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 55184d9..ee52f37 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -40,6 +40,7 @@
         cls.servers_client = cls.servers_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6cd5a89d-5b47-46a7-93bc-3916f0d84973')
     def test_create_image_from_deleted_server(self):
         # An image should not be created if the server instance is removed
         server = self.create_test_server(wait_until='ACTIVE')
@@ -55,6 +56,7 @@
                           server['id'], name=name, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('82c5b0c4-9dbd-463c-872b-20c4755aae7f')
     def test_create_image_from_invalid_server(self):
         # An image should not be created with invalid server id
         # Create a new image with invalid server id
@@ -66,6 +68,7 @@
                           '!@#$%^&*()', name=name, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('aaacd1d0-55a2-4ce8-818a-b5439df8adc9')
     def test_create_image_from_stopped_server(self):
         server = self.create_test_server(wait_until='ACTIVE')
         self.servers_client.stop(server['id'])
@@ -81,6 +84,7 @@
         self.assertEqual(snapshot_name, image['name'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ec176029-73dc-4037-8d72-2e4ff60cf538')
     def test_create_image_specify_uuid_35_characters_or_less(self):
         # Return an error if Image ID passed is 35 characters or less
         snapshot_name = data_utils.rand_name('test-snap-')
@@ -89,6 +93,7 @@
                           test_uuid, snapshot_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('36741560-510e-4cc2-8641-55fe4dfb2437')
     def test_create_image_specify_uuid_37_characters_or_more(self):
         # Return an error if Image ID passed is 37 characters or more
         snapshot_name = data_utils.rand_name('test-snap-')
@@ -97,12 +102,14 @@
                           test_uuid, snapshot_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('381acb65-785a-4942-94ce-d8f8c84f1f0f')
     def test_delete_image_with_invalid_image_id(self):
         # An image should not be deleted with invalid image id
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           '!@$%^&*()')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('137aef61-39f7-44a1-8ddf-0adf82511701')
     def test_delete_non_existent_image(self):
         # Return an error while trying to delete a non-existent image
 
@@ -111,11 +118,13 @@
                           non_existent_image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e6e41425-af5c-4fe6-a4b5-7b7b963ffda5')
     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', 'gate'])
+    @test.idempotent_id('924540c3-f1f1-444c-8f58-718958b6724e')
     def test_delete_image_non_hex_string_id(self):
         # Return an error while trying to delete an image with non hex id
         image_id = '11a22b9-120q-5555-cc11-00ab112223gj'
@@ -123,11 +132,13 @@
                           image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('68e2c175-bd26-4407-ac0f-4ea9ce2139ea')
     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', 'gate'])
+    @test.idempotent_id('b340030d-82cd-4066-a314-c72fb7c59277')
     def test_delete_image_id_is_over_35_character_limit(self):
         # Return an error while trying to delete image with id over limit
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 12aa886..abdeb18 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -67,6 +67,7 @@
         return flavor['disk']
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3731d080-d4c5-4872-b41a-64d0d0021314')
     def test_create_delete_image(self):
 
         # Create a new image
@@ -96,6 +97,7 @@
         self.client.wait_for_resource_deletion(image_id)
 
     @test.attr(type=['gate'])
+    @test.idempotent_id('3b7c6fe4-dfe7-477c-9243-b06359db51e6')
     def test_create_image_specify_multibyte_character_image_name(self):
         # prefix character is:
         # http://www.fileformat.info/info/unicode/char/1F4A9/index.htm
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 7f15ad1..f6a4aec 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -74,6 +74,7 @@
         cls.image_ids = []
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('55d1d38c-dd66-4933-9c8e-7d92aeb60ddc')
     def test_create_image_specify_invalid_metadata(self):
         # Return an error when creating image with invalid metadata
         snapshot_name = data_utils.rand_name('test-snap-')
@@ -82,6 +83,7 @@
                           self.server_id, snapshot_name, meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3d24d11f-5366-4536-bd28-cff32b748eca')
     def test_create_image_specify_metadata_over_limits(self):
         # Return an error when creating image with meta data over 256 chars
         snapshot_name = data_utils.rand_name('test-snap-')
@@ -90,6 +92,7 @@
                           self.server_id, snapshot_name, meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0460efcf-ee88-4f94-acef-1bf658695456')
     def test_create_second_image_when_first_image_is_being_saved(self):
         # Disallow creating another image when first image is being saved
 
@@ -107,6 +110,7 @@
                           self.server_id, alt_snapshot_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('084f0cbc-500a-4963-8a4e-312905862581')
     def test_create_image_specify_name_over_256_chars(self):
         # Return an error if snapshot name over 256 characters is passed
 
@@ -115,6 +119,7 @@
                           self.server_id, snapshot_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0894954d-2db2-4195-a45b-ffec0bc0187e')
     def test_delete_image_that_is_not_yet_active(self):
         # Return an error while trying to delete an image what is creating
 
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index a2e5f56..6176d85 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -93,6 +93,7 @@
         cls.snapshot2_id = cls.snapshot2['id']
 
     @test.attr(type='gate')
+    @test.idempotent_id('a3f5b513-aeb3-42a9-b18e-f091ef73254d')
     def test_list_images_filter_by_status(self):
         # The list of images should contain only images with the
         # provided status
@@ -104,6 +105,7 @@
         self.assertTrue(any([i for i in images if i['id'] == self.image3_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('33163b73-79f5-4d07-a7ea-9213bcc468ff')
     def test_list_images_filter_by_name(self):
         # List of all images should contain the expected images filtered
         # by name
@@ -114,6 +116,7 @@
         self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
         self.assertFalse(any([i for i in images if i['id'] == self.image3_id]))
 
+    @test.idempotent_id('9f238683-c763-45aa-b848-232ec3ce3105')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -131,6 +134,7 @@
         self.assertFalse(any([i for i in images
                               if i['id'] == self.snapshot3_id]))
 
+    @test.idempotent_id('05a377b8-28cf-4734-a1e6-2ab5c38bf606')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -150,6 +154,7 @@
             self.assertTrue(any([i for i in images
                                  if i['id'] == self.snapshot3_id]))
 
+    @test.idempotent_id('e3356918-4d3e-4756-81d5-abc4524ba29f')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -168,6 +173,7 @@
                               if i['id'] == self.image_ref]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('3a484ca9-67ba-451e-b494-7fcf28d32d62')
     def test_list_images_limit_results(self):
         # Verify only the expected number of results are returned
         params = {'limit': '1'}
@@ -175,6 +181,7 @@
         self.assertEqual(1, len([x for x in images if 'id' in x]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('18bac3ae-da27-436c-92a9-b22474d13aab')
     def test_list_images_filter_by_changes_since(self):
         # Verify only updated images are returned in the detailed list
 
@@ -186,6 +193,7 @@
         self.assertTrue(found)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9b0ea018-6185-4f71-948a-a123a107988e')
     def test_list_images_with_detail_filter_by_status(self):
         # Detailed list of all images should only contain images
         # with the provided status
@@ -197,6 +205,7 @@
         self.assertTrue(any([i for i in images if i['id'] == self.image3_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('644ea267-9bd9-4f3b-af9f-dffa02396a17')
     def test_list_images_with_detail_filter_by_name(self):
         # Detailed list of all images should contain the expected
         # images filtered by name
@@ -208,6 +217,7 @@
         self.assertFalse(any([i for i in images if i['id'] == self.image3_id]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ba2fa9a9-b672-47cc-b354-3b4c0600e2cb')
     def test_list_images_with_detail_limit_results(self):
         # Verify only the expected number of results (with full details)
         # are returned
@@ -215,6 +225,7 @@
         images = self.client.list_images_with_detail(params)
         self.assertEqual(1, len(images))
 
+    @test.idempotent_id('8c78f822-203b-4bf6-8bba-56ebd551cf84')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -234,6 +245,7 @@
             self.assertTrue(any([i for i in images
                                  if i['id'] == self.snapshot3_id]))
 
+    @test.idempotent_id('888c0cc0-7223-43c5-9db0-b125fd0a393b')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.attr(type='gate')
@@ -253,6 +265,7 @@
                               if i['id'] == self.image_ref]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('7d439e18-ac2e-4827-b049-7e18004712c4')
     def test_list_images_with_detail_filter_by_changes_since(self):
         # Verify an update image is returned
 
diff --git a/tempest/api/compute/images/test_list_image_filters_negative.py b/tempest/api/compute/images/test_list_image_filters_negative.py
index 77c9459..e5418ad 100644
--- a/tempest/api/compute/images/test_list_image_filters_negative.py
+++ b/tempest/api/compute/images/test_list_image_filters_negative.py
@@ -33,6 +33,7 @@
         cls.client = cls.images_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('391b0440-432c-4d4b-b5da-c5096aa247eb')
     def test_get_nonexistent_image(self):
         # Check raises a NotFound
         nonexistent_image = data_utils.rand_uuid()
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index cd01147..36451ec 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -31,12 +31,14 @@
         cls.client = cls.images_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
     def test_get_image(self):
         # Returns the correct details for a single image
         image = self.client.get_image(self.image_ref)
         self.assertEqual(self.image_ref, image['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fd51b7f4-d4a3-4331-9885-866658112a6f')
     def test_list_images(self):
         # The list of all images should contain the image
         images = self.client.list_images()
@@ -44,6 +46,7 @@
         self.assertTrue(found)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9f94cb6b-7f10-48c5-b911-a0b84d7d4cd6')
     def test_list_images_with_detail(self):
         # Detailed list of all images should contain the expected images
         images = self.client.list_images_with_detail()
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index d7884ab..972f0de 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -36,6 +36,7 @@
         return body
 
     @test.attr(type='gate')
+    @test.idempotent_id('1d1dbedb-d7a0-432a-9d09-83f543c3c19b')
     def test_keypairs_create_list_delete(self):
         # Keypairs created should be available in the response list
         # Create 3 keypairs
@@ -64,6 +65,7 @@
                          % ', '.join(m_key['name'] for m_key in missing_kps))
 
     @test.attr(type='gate')
+    @test.idempotent_id('6c1d3123-4519-4742-9194-622cb1714b7d')
     def test_keypair_create_delete(self):
         # Keypair should be created, verified and deleted
         k_name = data_utils.rand_name('keypair-')
@@ -77,6 +79,7 @@
                         "Field private_key is empty or not found.")
 
     @test.attr(type='gate')
+    @test.idempotent_id('a4233d5d-52d8-47cc-9a25-e1864527e3df')
     def test_get_keypair_detail(self):
         # Keypair should be created, Got details by name and deleted
         k_name = data_utils.rand_name('keypair-')
@@ -92,6 +95,7 @@
                         "Field public_key is empty or not found.")
 
     @test.attr(type='gate')
+    @test.idempotent_id('39c90c6a-304a-49dd-95ec-2366129def05')
     def test_keypair_create_with_pub_key(self):
         # Keypair should be created with a given public key
         k_name = data_utils.rand_name('keypair-')
diff --git a/tempest/api/compute/keypairs/test_keypairs_negative.py b/tempest/api/compute/keypairs/test_keypairs_negative.py
index ea25527..e63f3c7 100644
--- a/tempest/api/compute/keypairs/test_keypairs_negative.py
+++ b/tempest/api/compute/keypairs/test_keypairs_negative.py
@@ -33,6 +33,7 @@
         self.addCleanup(self.client.delete_keypair, keypair_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('29cca892-46ae-4d48-bc32-8fe7e731eb81')
     def test_keypair_create_with_invalid_pub_key(self):
         # Keypair should not be created with a non RSA public key
         k_name = data_utils.rand_name('keypair-')
@@ -41,6 +42,7 @@
                           self._create_keypair, k_name, pub_key)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7cc32e47-4c42-489d-9623-c5e2cb5a2fa5')
     def test_keypair_delete_nonexistent_key(self):
         # Non-existent key deletion should throw a proper error
         k_name = data_utils.rand_name("keypair-non-existent-")
@@ -48,6 +50,7 @@
                           k_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dade320e-69ca-42a9-ba4a-345300f127e0')
     def test_create_keypair_with_empty_public_key(self):
         # Keypair should not be created with an empty public key
         k_name = data_utils.rand_name("keypair-")
@@ -56,6 +59,7 @@
                           k_name, pub_key)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fc100c19-2926-4b9c-8fdc-d0589ee2f9ff')
     def test_create_keypair_when_public_key_bits_exceeds_maximum(self):
         # Keypair should not be created when public key bits are too long
         k_name = data_utils.rand_name("keypair-")
@@ -64,6 +68,7 @@
                           k_name, pub_key)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0359a7f1-f002-4682-8073-0c91e4011b7c')
     def test_create_keypair_with_duplicate_name(self):
         # Keypairs with duplicate names should not be created
         k_name = data_utils.rand_name('keypair-')
@@ -74,12 +79,14 @@
         self.client.delete_keypair(k_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1398abe1-4a84-45fb-9294-89f514daff00')
     def test_create_keypair_with_empty_name_string(self):
         # Keypairs with name being an empty string should not be created
         self.assertRaises(lib_exc.BadRequest, self._create_keypair,
                           '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3faa916f-779f-4103-aca7-dc3538eee1b7')
     def test_create_keypair_with_long_keynames(self):
         # Keypairs with name longer than 255 chars should not be created
         k_name = 'keypair-'.ljust(260, '0')
@@ -87,6 +94,7 @@
                           k_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('45fbe5e0-acb5-49aa-837a-ff8d0719db91')
     def test_create_keypair_invalid_name(self):
         # Keypairs with name being an invalid name should not be created
         k_name = 'key_/.\@:'
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index de6eecb..39ed2a1 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -25,6 +25,7 @@
         cls.client = cls.limits_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('b54c66af-6ab6-4cf0-a9e5-a0cb58d75e0b')
     def test_absLimits_get(self):
         # To check if all limits are present in the response
         absolute_limits = self.client.get_absolute_limits()
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index d82a2e5..507f24e 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -34,6 +34,7 @@
         cls.server_client = cls.servers_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('215cd465-d8ae-49c9-bf33-9c911913a5c8')
     def test_max_image_meta_exceed_limit(self):
         # We should not create vm with image meta over maxImageMeta limit
         # Get max limit value
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 1871c73..70394d8 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -60,6 +60,7 @@
                              "Miss-matched key is %s" % key)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('850795d7-d4d3-4e55-b527-a774c0123d3a')
     @test.services('network')
     def test_security_group_rules_create(self):
         # Positive test: Creation of Security Group rule
@@ -78,6 +79,7 @@
         self._check_expected_response(rule)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7a01873e-3c38-4f30-80be-31a043cfe2fd')
     @test.services('network')
     def test_security_group_rules_create_with_optional_cidr(self):
         # Positive test: Creation of Security Group rule
@@ -101,6 +103,7 @@
         self._check_expected_response(rule)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7f5d2899-7705-4d4b-8458-4505188ffab6')
     @test.services('network')
     def test_security_group_rules_create_with_optional_group_id(self):
         # Positive test: Creation of Security Group rule
@@ -129,6 +132,7 @@
         self._check_expected_response(rule)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a6154130-5a55-4850-8be4-5e9e796dbf17')
     @test.services('network')
     def test_security_group_rules_list(self):
         # Positive test: Created Security Group rules should be
@@ -164,6 +168,7 @@
         self.assertTrue(any([i for i in rules if i['id'] == rule2_id]))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fc5c5acf-2091-43a6-a6ae-e42760e9ffaf')
     @test.services('network')
     def test_security_group_rules_delete_when_peer_group_deleted(self):
         # Positive test:rule will delete when peer group deleting
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index bd48cbe..f6a50ee 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -38,6 +38,7 @@
         cls.client = cls.security_groups_client
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('1d507e98-7951-469b-82c3-23f1e6b8c254')
     @test.services('network')
     def test_create_security_group_rule_with_non_existent_id(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -52,6 +53,7 @@
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('2244d7e4-adb7-4ecb-9930-2d77e123ce4f')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_id(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -66,6 +68,7 @@
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('8bd56d02-3ffa-4d67-9933-b6b9a01d6089')
     @test.services('network')
     def test_create_security_group_rule_duplicate(self):
         # Negative test: Create Security Group rule duplicate should fail
@@ -89,6 +92,7 @@
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('84c81249-9f6e-439c-9bbf-cbb0d2cddbdf')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_ip_protocol(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -106,6 +110,7 @@
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('12bbc875-1045-4f7a-be46-751277baedb9')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_from_port(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -122,6 +127,7 @@
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('ff88804d-144f-45d1-bf59-dd155838a43a')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_to_port(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -138,6 +144,7 @@
                           parent_group_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('00296fa9-0576-496a-ae15-fbab843189e0')
     @test.services('network')
     def test_create_security_group_rule_with_invalid_port_range(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -154,6 +161,7 @@
                           secgroup_id, ip_protocol, from_port, to_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('56fddcca-dbb8-4494-a0db-96e9f869527c')
     @test.services('network')
     def test_delete_security_group_rule_with_non_existent_id(self):
         # Negative test: Deletion of Security Group rule should be FAIL
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 743a4e7..5a11854 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -28,6 +28,7 @@
         cls.client = cls.security_groups_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('eb2b087d-633d-4d0d-a7bd-9e6ba35b32de')
     @test.services('network')
     def test_security_groups_create_list_delete(self):
         # Positive test:Should return the list of Security Groups
@@ -60,6 +61,7 @@
                                             for m_group in deleted_sgs))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ecc0da4a-2117-48af-91af-993cca39a615')
     @test.services('network')
     def test_security_group_create_get_delete(self):
         # Security Group should be created, fetched and deleted
@@ -82,6 +84,7 @@
         self.client.wait_for_resource_deletion(securitygroup['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fe4abc0d-83f5-4c50-ad11-57a1127297a2')
     @test.services('network')
     def test_server_security_groups(self):
         # Checks that security groups may be added and linked to a server
@@ -125,6 +128,7 @@
         self.client.delete_security_group(sg2['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7d4e1d3c-3209-4d6d-b020-986304ebad1f')
     @test.services('network')
     def test_update_security_groups(self):
         # Update security group name and description
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index 2cbea1a..0127dc7 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -52,6 +52,7 @@
         return non_exist_id
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('673eaec1-9b3e-48ed-bdf1-2786c1b9661c')
     @test.services('network')
     def test_security_group_get_nonexistent_group(self):
         # Negative test:Should not be able to GET the details
@@ -63,6 +64,7 @@
     @decorators.skip_because(bug="1161411",
                              condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('1759c3cb-b0fc-44b7-86ce-c99236be911d')
     @test.services('network')
     def test_security_group_create_with_invalid_group_name(self):
         # Negative test: Security Group should not be created with group name
@@ -84,6 +86,7 @@
     @decorators.skip_because(bug="1161411",
                              condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('777b6f14-aca9-4758-9e84-38783cfa58bc')
     @test.services('network')
     def test_security_group_create_with_invalid_group_description(self):
         # Negative test:Security Group should not be created with description
@@ -101,6 +104,7 @@
                           self.client.create_security_group, s_name,
                           s_description)
 
+    @test.idempotent_id('9fdb4abc-6b66-4b27-b89c-eb215a956168')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron allows duplicate names for security groups")
     @test.attr(type=['negative', 'smoke'])
@@ -117,6 +121,7 @@
                           s_description)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('36a1629f-c6da-4a26-b8b8-55e7e5d5cd58')
     @test.services('network')
     def test_delete_the_default_security_group(self):
         # Negative test:Deletion of the "default" Security Group should Fail
@@ -132,6 +137,7 @@
                           default_security_group_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('6727c00b-214c-4f9e-9a52-017ac3e98411')
     @test.services('network')
     def test_delete_nonexistent_security_group(self):
         # Negative test:Deletion of a non-existent Security Group should fail
@@ -140,6 +146,7 @@
                           self.client.delete_security_group, non_exist_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('1438f330-8fa4-4aeb-8a94-37c250106d7f')
     @test.services('network')
     def test_delete_security_group_without_passing_id(self):
         # Negative test:Deletion of a Security Group with out passing ID
@@ -147,6 +154,7 @@
         self.assertRaises(lib_exc.NotFound,
                           self.client.delete_security_group, '')
 
+    @test.idempotent_id('00579617-fe04-4e1c-9d08-ca7467d2e34b')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_id")
     @test.attr(type=['negative', 'smoke'])
@@ -161,6 +169,7 @@
                           self.client.update_security_group, sg_id_invalid,
                           name=s_name, description=s_description)
 
+    @test.idempotent_id('cda8d8b4-59f8-4087-821d-20cf5a03b3b1')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_name")
     @test.attr(type=['negative', 'smoke'])
@@ -176,6 +185,7 @@
                           self.client.update_security_group,
                           securitygroup_id, name=s_new_name)
 
+    @test.idempotent_id('97d12b1c-a610-4194-93f1-ba859e718b45')
     @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_description")
     @test.attr(type=['negative', 'smoke'])
@@ -192,6 +202,7 @@
                           securitygroup_id, description=s_new_des)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('27edee9c-873d-4da6-a68a-3c256efebe8f')
     @test.services('network')
     def test_update_non_existent_security_group(self):
         # Update a non-existent Security Group should Fail
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 6422215..0702f3f 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -117,6 +117,7 @@
         self.assertEqual(sorted(list1), sorted(list2))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
     @test.services('network')
     def test_create_list_show_delete_interfaces(self):
         server, ifs = self._create_server_get_interfaces()
@@ -139,6 +140,7 @@
         self.assertEqual(len(ifs) - 1, len(_ifs))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9')
     @test.services('network')
     def test_add_remove_fixed_ip(self):
         # Add and Remove the fixed IP to server.
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index dfff014..5962042 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -29,6 +29,7 @@
         cls.client = cls.availability_zone_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('a8333aa2-205c-449f-a828-d38c2489bf25')
     def test_get_availability_zone_list_with_non_admin_user(self):
         # List of availability zone with non-administrator user
         availability_zone = self.client.get_availability_zone_list()
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 6711fa9..14eb536 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -55,6 +55,7 @@
         cls.server = cls.client.get_server(cls.server_initial['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5de47127-9977-400a-936f-abcfbec1218f')
     def test_verify_server_details(self):
         # Verify the specified server attributes are set correctly
         self.assertEqual(self.accessIPv4, self.server['accessIPv4'])
@@ -68,6 +69,7 @@
         self.assertEqual(self.meta, self.server['metadata'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9a438d88-10c6-4bcd-8b5b-5b6e25e1346f')
     def test_list_servers(self):
         # The created server should be in the list of all servers
         body = self.client.list_servers()
@@ -76,6 +78,7 @@
         self.assertTrue(found)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
     def test_list_servers_with_detail(self):
         # The created server should be in the detailed list of all servers
         body = self.client.list_servers_with_detail()
@@ -83,6 +86,7 @@
         found = any([i for i in servers if i['id'] == self.server['id']])
         self.assertTrue(found)
 
+    @test.idempotent_id('cbc0f52f-05aa-492b-bdc1-84b575ca294b')
     @testtools.skipUnless(CONF.compute.run_ssh,
                           'Instance validation tests are disabled.')
     @test.attr(type='gate')
@@ -94,6 +98,7 @@
                                                   self.password)
         self.assertEqual(flavor['vcpus'], linux_client.get_number_of_vcpus())
 
+    @test.idempotent_id('ac1ad47f-984b-4441-9274-c9079b7a0666')
     @testtools.skipUnless(CONF.compute.run_ssh,
                           'Instance validation tests are disabled.')
     @test.attr(type='gate')
@@ -104,6 +109,7 @@
         self.assertTrue(linux_client.hostname_equals_servername(self.name))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ed20d3fb-9d1f-4329-b160-543fbd5d9811')
     def test_create_server_with_scheduler_hint_group(self):
         # Create a server with the scheduler hint "group".
         name = data_utils.rand_name('server_group')
@@ -121,6 +127,7 @@
         server_group = self.client.get_server_group(group_id)
         self.assertIn(server['id'], server_group['members'])
 
+    @test.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2')
     @testtools.skipUnless(CONF.service_available.neutron,
                           'Neutron service must be available.')
     def test_verify_multiple_nics_order(self):
@@ -193,6 +200,7 @@
         cls.flavor_client = cls.os_adm.flavors_client
         cls.client = cls.servers_client
 
+    @test.idempotent_id('b3c7bcfc-bb5b-4e22-b517-c7f686b802ca')
     @testtools.skipUnless(CONF.compute.run_ssh,
                           'Instance validation tests are disabled.')
     @test.attr(type='gate')
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index ba20229..8842899 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -33,6 +33,7 @@
         cls.client = cls.servers_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('9e6e0c87-3352-42f7-9faf-5d6210dbd159')
     def test_delete_server_while_in_building_state(self):
         # Delete a server while it's VM state is Building
         server = self.create_test_server(wait_until='BUILD')
@@ -40,6 +41,7 @@
         self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('925fdfb4-5b13-47ea-ac8a-c36ae6fddb05')
     def test_delete_active_server(self):
         # Delete a server while it's VM state is Active
         server = self.create_test_server(wait_until='ACTIVE')
@@ -47,6 +49,7 @@
         self.client.wait_for_server_termination(server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('546d368c-bb6c-4645-979a-83ed16f3a6be')
     def test_delete_server_while_in_shutoff_state(self):
         # Delete a server while it's VM state is Shutoff
         server = self.create_test_server(wait_until='ACTIVE')
@@ -55,6 +58,7 @@
         self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('943bd6e8-4d7a-4904-be83-7a6cc2d4213b')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type='gate')
@@ -66,6 +70,7 @@
         self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('1f82ebd3-8253-4f4e-b93f-de9b7df56d8b')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type='gate')
@@ -77,6 +82,7 @@
         self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('bb0cb402-09dd-4947-b6e5-5e7e1cfa61ad')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type='gate')
@@ -96,6 +102,7 @@
         self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('ab0c38b4-cdd8-49d3-9b92-0cb898723c01')
     @testtools.skipIf(not CONF.compute_feature_enabled.resize,
                       'Resize not available.')
     @test.attr(type='gate')
@@ -107,6 +114,7 @@
         self.client.delete_server(server['id'])
         self.client.wait_for_server_termination(server['id'])
 
+    @test.idempotent_id('d0f3f0d6-d9b6-4a32-8da4-23015dcab23c')
     @test.services('volume')
     @test.attr(type='gate')
     def test_delete_server_while_in_attached_volume(self):
@@ -139,6 +147,7 @@
         cls.admin_client = cls.os_adm.servers_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('99774678-e072-49d1-9d2a-49a59bc56063')
     def test_delete_server_while_in_error_state(self):
         # Delete a server while it's VM state is error
         server = self.create_test_server(wait_until='ACTIVE')
@@ -151,6 +160,7 @@
                                                         ignore_error=True)
 
     @test.attr(type='gate')
+    @test.idempotent_id('73177903-6737-4f27-a60c-379e8ae8cf48')
     def test_admin_delete_servers_of_others(self):
         # Administrator can delete servers of others
         server = self.create_test_server(wait_until='ACTIVE')
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 76e6128..a15a9b7 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -44,6 +44,7 @@
             self.assertEqual(disk_config, server['OS-DCF:diskConfig'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('bef56b09-2e8c-4883-a370-4950812f430e')
     def test_rebuild_server_with_manual_disk_config(self):
         # A server should be rebuilt using the manual disk config option
         self._update_server_with_disk_config(disk_config='AUTO')
@@ -60,6 +61,7 @@
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('9c9fae77-4feb-402f-8450-bf1c8b609713')
     def test_rebuild_server_with_auto_disk_config(self):
         # A server should be rebuilt using the auto disk config option
         self._update_server_with_disk_config(disk_config='MANUAL')
@@ -83,6 +85,7 @@
         else:
             return self.flavor_ref
 
+    @test.idempotent_id('414e7e93-45b5-44bc-8e03-55159c6bfc97')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='gate')
@@ -100,6 +103,7 @@
         server = self.client.get_server(self.server_id)
         self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
 
+    @test.idempotent_id('693d16f3-556c-489a-8bac-3d0ca2490bad')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='gate')
@@ -118,6 +122,7 @@
         self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('5ef18867-358d-4de9-b3c9-94d4ba35742f')
     def test_update_server_from_auto_to_manual(self):
         # A server should be updated from auto to manual disk config
         self._update_server_with_disk_config(disk_config='AUTO')
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index e02c41b..b00221c 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -28,6 +28,7 @@
         cls.server_id = server['id']
 
     @test.attr(type='gate')
+    @test.idempotent_id('77ca5cc5-9990-45e0-ab98-1de8fead201a')
     def test_list_instance_actions(self):
         # List actions of the provided server
         self.client.reboot(self.server_id, 'HARD')
@@ -39,6 +40,7 @@
         self.assertTrue(any([i for i in body if i['action'] == 'reboot']))
 
     @test.attr(type='gate')
+    @test.idempotent_id('aacc71ca-1d70-4aa5-bbf6-0ff71470e43c')
     def test_get_instance_action(self):
         # Get the action details of the provided server
         body = self.client.get_instance_action(self.server_id,
diff --git a/tempest/api/compute/servers/test_instance_actions_negative.py b/tempest/api/compute/servers/test_instance_actions_negative.py
index 2f9216f..a0064b2 100644
--- a/tempest/api/compute/servers/test_instance_actions_negative.py
+++ b/tempest/api/compute/servers/test_instance_actions_negative.py
@@ -30,6 +30,7 @@
         cls.server_id = server['id']
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('67e1fce6-7ec2-45c6-92d4-0a8f1a632910')
     def test_list_instance_actions_non_existent_server(self):
         # List actions of the non-existent server id
         non_existent_server_id = data_utils.rand_uuid()
@@ -38,6 +39,7 @@
                           non_existent_server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0269f40a-6f18-456c-b336-c03623c897f1')
     def test_get_instance_action_invalid_request(self):
         # Get the action details of the provided server with invalid request
         self.assertRaises(lib_exc.NotFound, self.client.get_instance_action,
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 8cc7c80..bfba105 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -86,6 +86,7 @@
                 network = cls.isolated_creds.get_primary_network()
                 cls.fixed_network_name = network['name']
 
+    @test.idempotent_id('05e8a8e7-9659-459a-989d-92c2f501f4ba')
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @test.attr(type='gate')
     def test_list_servers_filter_by_image(self):
@@ -99,6 +100,7 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('573637f5-7325-47bb-9144-3476d0416908')
     def test_list_servers_filter_by_flavor(self):
         # Filter the list of servers by flavor
         params = {'flavor': self.flavor_ref_alt}
@@ -110,6 +112,7 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('9b067a7b-7fee-4f6a-b29c-be43fe18fc5a')
     def test_list_servers_filter_by_server_name(self):
         # Filter the list of servers by server name
         params = {'name': self.s1_name}
@@ -121,6 +124,7 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e')
     def test_list_servers_filter_by_server_status(self):
         # Filter the list of servers by server status
         params = {'status': 'active'}
@@ -132,6 +136,7 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('451dbbb2-f330-4a9f-b0e1-5f5d2cb0f34c')
     def test_list_servers_filter_by_shutoff_status(self):
         # Filter the list of servers by server shutoff status
         params = {'status': 'shutoff'}
@@ -149,6 +154,7 @@
         self.assertNotIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('614cdfc1-d557-4bac-915b-3e67b48eee76')
     def test_list_servers_filter_by_limit(self):
         # Verify only the expected number of servers are returned
         params = {'limit': 1}
@@ -156,6 +162,7 @@
         self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
 
     @test.attr(type='gate')
+    @test.idempotent_id('b1495414-2d93-414c-8019-849afe8d319e')
     def test_list_servers_filter_by_zero_limit(self):
         # Verify only the expected number of servers are returned
         params = {'limit': 0}
@@ -163,6 +170,7 @@
         self.assertEqual(0, len(servers['servers']))
 
     @test.attr(type='gate')
+    @test.idempotent_id('37791bbd-90c0-4de0-831e-5f38cba9c6b3')
     def test_list_servers_filter_by_exceed_limit(self):
         # Verify only the expected number of servers are returned
         params = {'limit': 100000}
@@ -171,6 +179,7 @@
         self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
                          len([x for x in servers['servers'] if 'id' in x]))
 
+    @test.idempotent_id('b3304c3b-97df-46d2-8cd3-e2b6659724e7')
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @test.attr(type='gate')
     def test_list_servers_detailed_filter_by_image(self):
@@ -184,6 +193,7 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('80c574cc-0925-44ba-8602-299028357dd9')
     def test_list_servers_detailed_filter_by_flavor(self):
         # Filter the detailed list of servers by flavor
         params = {'flavor': self.flavor_ref_alt}
@@ -195,6 +205,7 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('f9eb2b70-735f-416c-b260-9914ac6181e4')
     def test_list_servers_detailed_filter_by_server_name(self):
         # Filter the detailed list of servers by server name
         params = {'name': self.s1_name}
@@ -206,6 +217,7 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('de2612ab-b7dd-4044-b0b1-d2539601911f')
     def test_list_servers_detailed_filter_by_server_status(self):
         # Filter the detailed list of servers by server status
         params = {'status': 'active'}
@@ -220,6 +232,7 @@
                                           if x['id'] in test_ids])
 
     @test.attr(type='gate')
+    @test.idempotent_id('e9f624ee-92af-4562-8bec-437945a18dcb')
     def test_list_servers_filtered_by_name_wildcard(self):
         # List all servers that contains '-instance' in name
         params = {'name': '-instance'}
@@ -242,6 +255,7 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('24a89b0c-0d55-4a28-847f-45075f19b27b')
     def test_list_servers_filtered_by_name_regex(self):
         # list of regex that should match s1, s2 and s3
         regexes = ['^.*\-instance\-[0-9]+$', '^.*\-instance\-.*$']
@@ -266,6 +280,7 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('43a1242e-7b31-48d1-88f2-3f72aa9f2077')
     def test_list_servers_filtered_by_ip(self):
         # Filter servers by ip
         # Here should be listed 1 server
@@ -282,6 +297,7 @@
     @decorators.skip_because(bug="1182883",
                              condition=CONF.service_available.neutron)
     @test.attr(type='gate')
+    @test.idempotent_id('a905e287-c35e-42f2-b132-d02b09f3654a')
     def test_list_servers_filtered_by_ip_regex(self):
         # Filter servers by regex ip
         # List all servers filtered by part of ip address.
@@ -297,6 +313,7 @@
         self.assertIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @test.attr(type='gate')
+    @test.idempotent_id('67aec2d0-35fe-4503-9f92-f13272b867ed')
     def test_list_servers_detailed_limit_results(self):
         # Verify only the expected number of detailed results are returned
         params = {'limit': 1}
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 7ede69c..7837ac1 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -49,6 +49,7 @@
         cls.deleted_fixtures.append(srv)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f')
     def test_list_servers_with_a_deleted_server(self):
         # Verify deleted servers do not show by default in list servers
         # List servers and verify server not returned
@@ -60,6 +61,7 @@
         self.assertEqual([], actual)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ff01387d-c7ad-47b4-ae9e-64fa214638fe')
     def test_list_servers_by_non_existing_image(self):
         # Listing servers for a non existing image returns empty list
         non_existing_image = '1234abcd-zzz0-aaa9-ppp3-0987654abcde'
@@ -68,6 +70,7 @@
         self.assertEqual([], servers)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5913660b-223b-44d4-a651-a0fbfd44ca75')
     def test_list_servers_by_non_existing_flavor(self):
         # Listing servers by non existing flavor returns empty list
         non_existing_flavor = 1234
@@ -76,6 +79,7 @@
         self.assertEqual([], servers)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e2c77c4a-000a-4af3-a0bd-629a328bde7c')
     def test_list_servers_by_non_existing_server_name(self):
         # Listing servers for a non existent server name returns empty list
         non_existing_name = 'junk_server_1234'
@@ -84,6 +88,7 @@
         self.assertEqual([], servers)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fcdf192d-0f74-4d89-911f-1ec002b822c4')
     def test_list_servers_status_non_existing(self):
         # Return an empty list when invalid status is specified
         non_existing_status = 'BALONEY'
@@ -92,36 +97,42 @@
         self.assertEqual([], servers)
 
     @test.attr(type='gate')
+    @test.idempotent_id('12c80a9f-2dec-480e-882b-98ba15757659')
     def test_list_servers_by_limits(self):
         # List servers by specifying limits
         body = self.client.list_servers({'limit': 1})
         self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d47c17fb-eebd-4287-8e95-f20a7e627b18')
     def test_list_servers_by_limits_greater_than_actual_count(self):
         # List servers by specifying a greater value for limit
         body = self.client.list_servers({'limit': 100})
         self.assertEqual(len(self.existing_fixtures), len(body['servers']))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('679bc053-5e70-4514-9800-3dfab1a380a6')
     def test_list_servers_by_limits_pass_string(self):
         # Return an error if a string value is passed for limit
         self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
                           {'limit': 'testing'})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('62610dd9-4713-4ee0-8beb-fd2c1aa7f950')
     def test_list_servers_by_limits_pass_negative_value(self):
         # Return an error if a negative value for limit is passed
         self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
                           {'limit': -1})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('87d12517-e20a-4c9c-97b6-dd1628d6d6c9')
     def test_list_servers_by_changes_since_invalid_date(self):
         # Return an error when invalid date format is passed
         self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
                           {'changes-since': '2011/01/01'})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('74745ad8-b346-45b5-b9b8-509d7447fc1f')
     def test_list_servers_by_changes_since_future_date(self):
         # Return an empty list when a date in the future is passed
         changes_since = {'changes-since': '2051-01-01T12:34:00Z'}
@@ -129,6 +140,7 @@
         self.assertEqual(0, len(body['servers']))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('93055106-2d34-46fe-af68-d9ddbf7ee570')
     def test_list_servers_detail_server_is_deleted(self):
         # Server details are not listed for a deleted server
         deleted_ids = [s['id'] for s in self.deleted_fixtures]
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index cffda95..69c056e 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -35,6 +35,7 @@
         return body
 
     @test.attr(type='gate')
+    @test.idempotent_id('61e03386-89c3-449c-9bb1-a06f423fd9d1')
     def test_multiple_create(self):
         body = self._create_multiple_servers(wait_until='ACTIVE',
                                              min_count=1,
@@ -45,6 +46,7 @@
         self.assertNotIn('reservation_id', body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('864777fb-2f1e-44e3-b5b9-3eb6fa84f2f7')
     def test_multiple_create_with_reservation_return(self):
         body = self._create_multiple_servers(wait_until='ACTIVE',
                                              min_count=1,
diff --git a/tempest/api/compute/servers/test_multiple_create_negative.py b/tempest/api/compute/servers/test_multiple_create_negative.py
index eca97c1..caf1ae5 100644
--- a/tempest/api/compute/servers/test_multiple_create_negative.py
+++ b/tempest/api/compute/servers/test_multiple_create_negative.py
@@ -37,30 +37,35 @@
         return body
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('daf29d8d-e928-4a01-9a8c-b129603f3fc0')
     def test_min_count_less_than_one(self):
         invalid_min_count = 0
         self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           min_count=invalid_min_count)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('999aa722-d624-4423-b813-0d1ac9884d7a')
     def test_min_count_non_integer(self):
         invalid_min_count = 2.5
         self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           min_count=invalid_min_count)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a6f9c2ab-e060-4b82-b23c-4532cb9390ff')
     def test_max_count_less_than_one(self):
         invalid_max_count = 0
         self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           max_count=invalid_max_count)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c5698d1-d7af-4c80-b971-9d403135eea2')
     def test_max_count_non_integer(self):
         invalid_max_count = 2.5
         self.assertRaises(lib_exc.BadRequest, self._create_multiple_servers,
                           max_count=invalid_max_count)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('476da616-f1ef-4271-a9b1-b9fc87727cdf')
     def test_max_count_less_than_min_count(self):
         min_count = 3
         max_count = 2
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index a2a71ae..ce3772f 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -59,6 +59,7 @@
         cls.client = cls.servers_client
         cls.server_id = cls.rebuild_server(None)
 
+    @test.idempotent_id('6158df09-4b82-4ab3-af6d-29cf36af858d')
     @testtools.skipUnless(CONF.compute_feature_enabled.change_password,
                           'Change password not available.')
     @test.attr(type='gate')
@@ -95,17 +96,20 @@
                             '%s > %s' % (new_boot_time, boot_time))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32')
     def test_reboot_server_hard(self):
         # The server should be power cycled
         self._test_reboot_server('HARD')
 
     @decorators.skip_because(bug="1014647")
     @test.attr(type='smoke')
+    @test.idempotent_id('4640e3ef-a5df-482e-95a1-ceeeb0faa84d')
     def test_reboot_server_soft(self):
         # The server should be signaled to reboot gracefully
         self._test_reboot_server('SOFT')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aaa6cdf3-55a7-461a-add9-1c8596b9a07c')
     def test_rebuild_server(self):
         # The server should be rebuilt using the provided image and data
         meta = {'rebuild': 'server'}
@@ -143,6 +147,7 @@
             self.client.rebuild(self.server_id, self.image_ref)
 
     @test.attr(type='gate')
+    @test.idempotent_id('30449a88-5aff-4f9b-9866-6ee9b17f906d')
     def test_rebuild_server_in_stop_state(self):
         # The server in stop state  should be rebuilt using the provided
         # image and remain in SHUTOFF state
@@ -206,18 +211,21 @@
             # NOTE(mriedem): tearDown requires the server to be started.
             self.client.start(self.server_id)
 
+    @test.idempotent_id('1499262a-9328-4eda-9068-db1ac57498d2')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='smoke')
     def test_resize_server_confirm(self):
         self._test_resize_server_confirm(stop=False)
 
+    @test.idempotent_id('138b131d-66df-48c9-a171-64f45eb92962')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='smoke')
     def test_resize_server_confirm_from_stopped(self):
         self._test_resize_server_confirm(stop=True)
 
+    @test.idempotent_id('c03aab19-adb1-44f5-917d-c419577e9e68')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type='gate')
@@ -237,6 +245,7 @@
         server = self.client.get_server(self.server_id)
         self.assertEqual(previous_flavor_ref, server['flavor']['id'])
 
+    @test.idempotent_id('b963d4f1-94b3-4c40-9e97-7b583f46e470')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting not available, backup not possible.')
     @test.attr(type='gate')
@@ -326,6 +335,7 @@
         lines = len(output.split('\n'))
         self.assertEqual(lines, 10)
 
+    @test.idempotent_id('4b8867e6-fffa-4d54-b1d1-6fdda57be2f3')
     @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
                           'Console output not supported.')
     @test.attr(type='gate')
@@ -343,6 +353,7 @@
 
         self.wait_for(self._get_output)
 
+    @test.idempotent_id('89104062-69d8-4b19-a71b-f47b7af093d7')
     @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
                           'Console output not supported.')
     @test.attr(type='gate')
@@ -362,6 +373,7 @@
 
         self.wait_for(_check_full_length_console_log)
 
+    @test.idempotent_id('5b65d4e7-4ecd-437c-83c0-d6b79d927568')
     @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
                           'Console output not supported.')
     @test.attr(type='gate')
@@ -380,6 +392,7 @@
 
         self.wait_for(self._get_output)
 
+    @test.idempotent_id('bd61a9fd-062f-4670-972b-2d6c3e3b9e73')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type='gate')
@@ -389,6 +402,7 @@
         self.client.unpause_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @test.idempotent_id('0d8ee21e-b749-462d-83da-b85b41c86c7f')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type='gate')
@@ -398,6 +412,7 @@
         self.client.resume_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @test.idempotent_id('77eba8e0-036e-4635-944b-f7a8f3b78dc9')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type='gate')
@@ -428,6 +443,7 @@
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
     def test_stop_start_server(self):
         self.servers_client.stop(self.server_id)
         self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
@@ -435,6 +451,7 @@
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('80a8094c-211e-440a-ab88-9e59d556c7ee')
     def test_lock_unlock_server(self):
         # Lock the server,try server stop(exceptions throw),unlock it and retry
         self.servers_client.lock_server(self.server_id)
@@ -456,6 +473,7 @@
         self.assertNotEqual('None', parsed_url.hostname)
         self.assertIn(parsed_url.scheme, valid_scheme)
 
+    @test.idempotent_id('c6bc11bf-592e-4015-9319-1c98dc64daf5')
     @testtools.skipUnless(CONF.compute_feature_enabled.vnc_console,
                           'VNC Console feature is disabled.')
     @test.attr(type='gate')
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 1c7915a..d0dfc87 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -37,6 +37,7 @@
         cls.server = cls.create_test_server(wait_until='ACTIVE')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6eb718c0-02d9-4d5e-acd1-4e0c269cef39')
     @test.services('network')
     def test_list_server_addresses(self):
         # All public and private addresses for
@@ -54,6 +55,7 @@
                 self.assertTrue(address['version'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('87bbc374-5538-4f64-b673-2b0e4443cc30')
     @test.services('network')
     def test_list_server_addresses_by_network(self):
         # Providing a network type should filter
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index b32231a..dac5637 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -37,6 +37,7 @@
         cls.server = cls.create_test_server(wait_until='ACTIVE')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('02c3f645-2d2e-4417-8525-68c0407d001b')
     @test.services('network')
     def test_list_server_addresses_invalid_server_id(self):
         # List addresses request should fail if server id not in system
@@ -44,6 +45,7 @@
                           '999')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a2ab5144-78c0-4942-a0ed-cc8edccfd9ba')
     @test.services('network')
     def test_list_server_addresses_by_network_neg(self):
         # List addresses by network should fail if network name not valid
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index 58ff460..ac04feb 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -63,11 +63,13 @@
         self._delete_server_group(server_group)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5dc57eda-35b7-4af7-9e5f-3c2be3d2d68b')
     def test_create_delete_server_group_with_affinity_policy(self):
         # Create and Delete the server-group with affinity policy
         self._create_delete_server_group(self.policy)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3645a102-372f-4140-afad-13698d850d23')
     def test_create_delete_server_group_with_anti_affinity_policy(self):
         # Create and Delete the server-group with anti-affinity policy
         policy = ['anti-affinity']
@@ -75,12 +77,14 @@
 
     @decorators.skip_because(bug="1324348")
     @test.attr(type='gate')
+    @test.idempotent_id('6d9bae05-eb32-425d-a673-e14e1b1c6306')
     def test_create_delete_server_group_with_multiple_policies(self):
         # Create and Delete the server-group with multiple policies
         policies = ['affinity', 'affinity']
         self._create_delete_server_group(policies)
 
     @test.attr(type='gate')
+    @test.idempotent_id('154dc5a4-a2fe-44b5-b99e-f15806a4a113')
     def test_create_delete_multiple_server_groups_with_same_name_policy(self):
         # Create and Delete the server-groups with same name and same policy
         server_groups = []
@@ -96,6 +100,7 @@
             self._delete_server_group(server_groups[i])
 
     @test.attr(type='gate')
+    @test.idempotent_id('b3545034-dd78-48f0-bdc2-a4adfa6d0ead')
     def test_get_server_group(self):
         # Get the server-group
         body = self.client.get_server_group(
@@ -103,6 +108,7 @@
         self.assertEqual(self.created_server_group, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('d4874179-27b4-4d7d-80e4-6c560cdfe321')
     def test_list_server_groups(self):
         # List the server-group
         body = self.client.list_server_groups()
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index c7c74f7..4a14228 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -33,6 +33,7 @@
         self.client.set_server_metadata(self.server_id, meta)
 
     @test.attr(type='gate')
+    @test.idempotent_id('479da087-92b3-4dcf-aeb3-fd293b2d14ce')
     def test_list_server_metadata(self):
         # All metadata key/value pairs for a server should be returned
         resp_metadata = self.client.list_server_metadata(self.server_id)
@@ -42,6 +43,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('211021f6-21de-4657-a68f-908878cfe251')
     def test_set_server_metadata(self):
         # The server's metadata should be replaced with the provided values
         # Create a new set of metadata for the server
@@ -54,6 +56,7 @@
         self.assertEqual(resp_metadata, req_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('344d981e-0c33-4997-8a5d-6c1d803e4134')
     def test_update_server_metadata(self):
         # The server's metadata values should be updated to the
         # provided values
@@ -66,6 +69,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('0f58d402-e34a-481d-8af8-b392b17426d9')
     def test_update_metadata_empty_body(self):
         # The original metadata should not be lost if empty metadata body is
         # passed
@@ -76,12 +80,14 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3043c57d-7e0e-49a6-9a96-ad569c265e6a')
     def test_get_server_metadata_item(self):
         # The value for a specific metadata key should be returned
         meta = self.client.get_server_metadata_item(self.server_id, 'key2')
         self.assertEqual('value2', meta['key2'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('58c02d4f-5c67-40be-8744-d3fa5982eb1c')
     def test_set_server_metadata_item(self):
         # The item's value should be updated to the provided value
         # Update the metadata value
@@ -94,6 +100,7 @@
         self.assertEqual(expected, resp_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('127642d6-4c7b-4486-b7cd-07265a378658')
     def test_delete_server_metadata_item(self):
         # The metadata value/key pair should be deleted from the server
         self.client.delete_server_metadata_item(self.server_id, 'key1')
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index 441c965..0eb3800 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -33,6 +33,7 @@
         cls.server_id = server['id']
 
     @test.attr(type=['gate', 'negative'])
+    @test.idempotent_id('fe114a8f-3a57-4eff-9ee2-4e14628df049')
     def test_server_create_metadata_key_too_long(self):
         # Attempt to start a server with a meta-data key that is > 255
         # characters
@@ -48,6 +49,7 @@
         # no teardown - all creates should fail
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('92431555-4d8b-467c-b95b-b17daa5e57ff')
     def test_create_server_metadata_blank_key(self):
         # Blank key should trigger an error.
         meta = {'': 'data1'}
@@ -56,6 +58,7 @@
                           meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4d9cd7a3-2010-4b41-b8fe-3bbf0b169466')
     def test_server_metadata_non_existent_server(self):
         # GET on a non-existent server should not succeed
         non_existent_server_id = data_utils.rand_uuid()
@@ -65,6 +68,7 @@
                           'test2')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f408e78e-3066-4097-9299-3b0182da812e')
     def test_list_server_metadata_non_existent_server(self):
         # List metadata on a non-existent server should not succeed
         non_existent_server_id = data_utils.rand_uuid()
@@ -73,6 +77,7 @@
                           non_existent_server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0025fbd6-a4ba-4cde-b8c2-96805dcfdabc')
     def test_wrong_key_passed_in_body(self):
         # Raise BadRequest if key in uri does not match
         # the key passed in body.
@@ -82,6 +87,7 @@
                           self.server_id, 'key', meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0df38c2a-3d4e-4db5-98d8-d4d9fa843a12')
     def test_set_metadata_non_existent_server(self):
         # Set metadata on a non-existent server should not succeed
         non_existent_server_id = data_utils.rand_uuid()
@@ -92,6 +98,7 @@
                           meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('904b13dc-0ef2-4e4c-91cd-3b4a0f2f49d8')
     def test_update_metadata_non_existent_server(self):
         # An update should not happen for a non-existent server
         non_existent_server_id = data_utils.rand_uuid()
@@ -102,6 +109,7 @@
                           meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a452f38c-05c2-4b47-bd44-a4f0bf5a5e48')
     def test_update_metadata_with_blank_key(self):
         # Blank key should trigger an error
         meta = {'': 'data1'}
@@ -110,6 +118,7 @@
                           self.server_id, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6bbd88e1-f8b3-424d-ba10-ae21c45ada8d')
     def test_delete_metadata_non_existent_server(self):
         # Should not be able to delete metadata item from a non-existent server
         non_existent_server_id = data_utils.rand_uuid()
@@ -119,6 +128,7 @@
                           'd')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d8c0a210-a5c3-4664-be04-69d96746b547')
     def test_metadata_items_limit(self):
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised while exceeding metadata items limit for
@@ -143,6 +153,7 @@
                           self.server_id, req_metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('96100343-7fa9-40d8-80fa-d29ef588ce1c')
     def test_set_server_metadata_blank_key(self):
         # Raise a bad request error for blank key.
         # set_server_metadata will replace all metadata with new value
@@ -152,6 +163,7 @@
                           self.server_id, meta=meta)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('64a91aee-9723-4863-be44-4c9d9f1e7d0e')
     def test_set_server_metadata_missing_metadata(self):
         # Raise a bad request error for a missing metadata field
         # set_server_metadata will replace all metadata with new value
diff --git a/tempest/api/compute/servers/test_server_password.py b/tempest/api/compute/servers/test_server_password.py
index a814359..57fa408 100644
--- a/tempest/api/compute/servers/test_server_password.py
+++ b/tempest/api/compute/servers/test_server_password.py
@@ -27,9 +27,11 @@
         cls.server = cls.create_test_server(wait_until="ACTIVE")
 
     @test.attr(type='gate')
+    @test.idempotent_id('f83b582f-62a8-4f22-85b0-0dee50ff783a')
     def test_get_server_password(self):
         self.client.get_password(self.server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('f8229e8b-b625-4493-800a-bde86ac611ea')
     def test_delete_server_password(self):
         self.client.delete_password(self.server['id'])
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index ca6e28c..4a28dfb 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -29,6 +29,7 @@
         cls.user_client = cls.limits_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('176cd8c9-b9e8-48ee-a480-180beab292bf')
     def test_personality_files_exceed_limit(self):
         # Server creation should fail if greater than the maximum allowed
         # number of files are injected into the server.
@@ -48,6 +49,7 @@
                           self.create_test_server, personality=personality)
 
     @test.attr(type='gate')
+    @test.idempotent_id('52f12ee8-5180-40cc-b417-31572ea3d555')
     def test_can_create_server_with_max_number_personality_files(self):
         # Server should be created successfully if maximum allowed number of
         # files is injected into the server during creation.
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index a096fd8..a1a99a1 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -77,6 +77,7 @@
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fd032140-714c-42e4-a8fd-adcd8df06be6')
     def test_rescue_unrescue_instance(self):
         self.servers_client.rescue_server(
             self.server_id, adminPass=self.password)
@@ -85,6 +86,7 @@
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
     def test_rescued_vm_associate_dissociate_floating_ip(self):
         # Rescue the server
         self.servers_client.rescue_server(
@@ -102,6 +104,7 @@
                                                     self.server_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('affca41f-7195-492d-8065-e09eee245404')
     def test_rescued_vm_add_remove_security_group(self):
         # Rescue the server
         self.servers_client.rescue_server(
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 904e42b..6e23334 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -78,6 +78,7 @@
         self.servers_client.unpause_server(server_id)
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
 
+    @test.idempotent_id('cc3a883f-43c0-4fb6-a9bb-5579d64984ed')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -91,11 +92,13 @@
                           self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('db22b618-f157-4566-a317-1b6d467a8094')
     def test_rescued_vm_reboot(self):
         self.assertRaises(lib_exc.Conflict, self.servers_client.reboot,
                           self.rescue_id, 'HARD')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6dfc0a55-3a77-4564-a144-1587b7971dde')
     def test_rescue_non_existent_server(self):
         # Rescue a non-existing server
         non_existent_server = data_utils.rand_uuid()
@@ -104,12 +107,14 @@
                           non_existent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('70cdb8a1-89f8-437d-9448-8844fd82bf46')
     def test_rescued_vm_rebuild(self):
         self.assertRaises(lib_exc.Conflict,
                           self.servers_client.rebuild,
                           self.rescue_id,
                           self.image_ref_alt)
 
+    @test.idempotent_id('d0ccac79-0091-4cf4-a1ce-26162d0cc55f')
     @test.services('volume')
     @test.attr(type=['negative', 'gate'])
     def test_rescued_vm_attach_volume(self):
@@ -128,6 +133,7 @@
                           volume['id'],
                           device='/dev/%s' % self.device)
 
+    @test.idempotent_id('f56e465b-fe10-48bf-b75d-646cda3a8bc9')
     @test.services('volume')
     @test.attr(type=['negative', 'gate'])
     def test_rescued_vm_detach_volume(self):
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index 1375039..624d9c2 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -30,6 +30,7 @@
         super(ServersTestJSON, self).tearDown()
 
     @test.attr(type='gate')
+    @test.idempotent_id('b92d5ec7-b1dd-44a2-87e4-45e888c46ef0')
     def test_create_server_with_admin_password(self):
         # If an admin password is provided on server creation, the server's
         # root password should be set to that password.
@@ -39,6 +40,7 @@
         self.assertEqual('testpassword', server['adminPass'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('8fea6be7-065e-47cf-89b8-496e6f96c699')
     def test_create_with_existing_server_name(self):
         # Creating a server with a name that already exists is allowed
 
@@ -58,6 +60,7 @@
         self.assertEqual(name1, name2)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f9e15296-d7f9-4e62-b53f-a04e89160833')
     def test_create_specify_keypair(self):
         # Specify a keypair while creating a server
 
@@ -83,6 +86,7 @@
         return server
 
     @test.attr(type='gate')
+    @test.idempotent_id('5e6ccff8-349d-4852-a8b3-055df7988dd2')
     def test_update_server_name(self):
         # The server name should be changed to the the provided value
         server = self.create_test_server(wait_until='ACTIVE')
@@ -90,6 +94,7 @@
         self._update_server_name(server['id'], 'ACTIVE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('6ac19cb1-27a3-40ec-b350-810bdc04c08e')
     def test_update_server_name_in_stop_state(self):
         # The server name should be changed to the the provided value
         server = self.create_test_server(wait_until='ACTIVE')
@@ -99,6 +104,7 @@
         self.assertNotIn('progress', updated_server)
 
     @test.attr(type='gate')
+    @test.idempotent_id('89b90870-bc13-4b73-96af-f9d4f2b70077')
     def test_update_access_server_address(self):
         # The server's access addresses should reflect the provided values
         server = self.create_test_server(wait_until='ACTIVE')
@@ -115,6 +121,7 @@
         self.assertEqual('::babe:202:202', server['accessIPv6'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('38fb1d02-c3c5-41de-91d3-9bc2025a75eb')
     def test_create_server_with_ipv6_addr_only(self):
         # Create a server without an IPv4 address(only IPv6 address).
         server = self.create_test_server(accessIPv6='2001:2001::3')
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index d973242..dd82893 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -50,6 +50,7 @@
         cls.server_id = server['id']
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf')
     def test_server_name_blank(self):
         # Create a server with name parameter empty
 
@@ -58,6 +59,7 @@
                           name='')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b8a7235e-5246-4a8f-a08e-b34877c6586f')
     def test_personality_file_contents_not_encoded(self):
         # Use an unencoded file when creating a server with personality
 
@@ -70,6 +72,7 @@
                           personality=person)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fcba1052-0a50-4cf3-b1ac-fae241edf02f')
     def test_create_with_invalid_image(self):
         # Create a server with an unknown image
 
@@ -78,6 +81,7 @@
                           image_id=-1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('18f5227f-d155-4429-807c-ccb103887537')
     def test_create_with_invalid_flavor(self):
         # Create a server with an unknown flavor
 
@@ -86,6 +90,7 @@
                           flavor=-1,)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7f70a4d1-608f-4794-9e56-cb182765972c')
     def test_invalid_access_ip_v4_address(self):
         # An access IPv4 address must match a valid address pattern
 
@@ -94,6 +99,7 @@
                           self.create_test_server, accessIPv4=IPv4)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0')
     def test_invalid_ip_v6_address(self):
         # An access IPv6 address must match a valid address pattern
 
@@ -102,6 +108,7 @@
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server, accessIPv6=IPv6)
 
+    @test.idempotent_id('7ea45b3e-e770-46fa-bfcc-9daaf6d987c0')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
@@ -112,6 +119,7 @@
                           self.client.resize,
                           nonexistent_server, self.flavor_ref)
 
+    @test.idempotent_id('ced1a1d7-2ab6-45c9-b90f-b27d87b30efd')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
@@ -121,6 +129,7 @@
         self.assertRaises(lib_exc.BadRequest, self.client.resize,
                           self.server_id, flavor_ref=nonexistent_flavor)
 
+    @test.idempotent_id('45436a7d-a388-4a35-a9d8-3adc5d0d940b')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     @test.attr(type=['negative', 'gate'])
@@ -130,12 +139,14 @@
                           self.server_id, flavor_ref="")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d4c023a0-9c55-4747-9dd5-413b820143c7')
     def test_reboot_non_existent_server(self):
         # Reboot a non existent server
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.reboot,
                           nonexistent_server, 'SOFT')
 
+    @test.idempotent_id('d1417e7f-a509-41b5-a102-d5eed8613369')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -149,6 +160,7 @@
         self.client.unpause_server(self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('98fa0458-1485-440f-873b-fe7f0d714930')
     def test_rebuild_reboot_deleted_server(self):
         # Rebuild and Reboot a deleted server
         server = self.create_test_server()
@@ -162,6 +174,7 @@
                           server['id'], 'SOFT')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d86141a7-906e-4731-b187-d64a2ea61422')
     def test_rebuild_non_existent_server(self):
         # Rebuild a non existent server
         nonexistent_server = data_utils.rand_uuid()
@@ -171,6 +184,7 @@
                           self.image_ref_alt)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('fd57f159-68d6-4c2a-902b-03070828a87e')
     def test_create_numeric_server_name(self):
         server_name = 12345
         self.assertRaises(lib_exc.BadRequest,
@@ -178,6 +192,7 @@
                           name=server_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c3e0fb12-07fc-4d76-a22e-37409887afe8')
     def test_create_server_name_length_exceeds_256(self):
         # Create a server with name length exceeding 256 characters
 
@@ -187,6 +202,7 @@
                           name=server_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4e72dc2d-44c5-4336-9667-f7972e95c402')
     def test_create_with_invalid_network_uuid(self):
         # Pass invalid network uuid while creating a server
 
@@ -197,6 +213,7 @@
                           networks=networks)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7a2efc39-530c-47de-b875-2dd01c8d39bd')
     def test_create_with_non_existent_keypair(self):
         # Pass a non-existent keypair while creating a server
 
@@ -206,6 +223,7 @@
                           key_name=key_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7fc74810-0bd2-4cd7-8244-4f33a9db865a')
     def test_create_server_metadata_exceeds_length_limit(self):
         # Pass really long metadata while creating a server
 
@@ -215,6 +233,7 @@
                           meta=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('aa8eed43-e2cb-4ebf-930b-da14f6a21d81')
     def test_update_name_of_non_existent_server(self):
         # Update name of a non-existent server
 
@@ -225,6 +244,7 @@
                           server_name, name=new_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('38204696-17c6-44da-9590-40f87fb5a899')
     def test_update_server_set_empty_name(self):
         # Update name of the server to an empty string
 
@@ -235,6 +255,7 @@
                           server_name, name=new_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
     def test_update_server_of_another_tenant(self):
         # Update name of a server that belongs to another tenant
 
@@ -244,6 +265,7 @@
                           name=new_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5c8e244c-dada-4590-9944-749c455b431f')
     def test_update_server_name_length_exceeds_256(self):
         # Update name of server exceed the name length limit
 
@@ -254,6 +276,7 @@
                           name=new_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1041b4e6-514b-4855-96a5-e974b60870a3')
     def test_delete_non_existent_server(self):
         # Delete a non existent server
 
@@ -262,6 +285,7 @@
                           nonexistent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
     def test_delete_a_server_of_another_tenant(self):
         # Delete a server that belongs to another tenant
         self.assertRaises(lib_exc.NotFound,
@@ -269,12 +293,14 @@
                           self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('75f79124-277c-45e6-a373-a1d6803f4cc4')
     def test_delete_server_pass_negative_id(self):
         # Pass an invalid string parameter to delete server
 
         self.assertRaises(lib_exc.NotFound, self.client.delete_server, -1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5')
     def test_delete_server_pass_id_exceeding_length_limit(self):
         # Pass a server ID that exceeds length limit to delete server
 
@@ -282,6 +308,7 @@
                           sys.maxint + 1)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c5fa6041-80cd-483b-aa6d-4e45f19d093c')
     def test_create_with_nonexistent_security_group(self):
         # Create a server with a nonexistent security group
 
@@ -291,6 +318,7 @@
                           security_groups=security_groups)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3436b02f-1b1e-4f03-881e-c6a602327439')
     def test_get_non_existent_server(self):
         # Get a non existent server details
         nonexistent_server = data_utils.rand_uuid()
@@ -298,12 +326,14 @@
                           nonexistent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a31460a9-49e1-42aa-82ee-06e0bb7c2d03')
     def test_stop_non_existent_server(self):
         # Stop a non existent server
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.servers_client.stop,
                           nonexistent_server)
 
+    @test.idempotent_id('6a8dc0c6-6cd4-4c0a-9f32-413881828091')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -313,6 +343,7 @@
         self.assertRaises(lib_exc.NotFound, self.client.pause_server,
                           nonexistent_server)
 
+    @test.idempotent_id('705b8e3a-e8a7-477c-a19b-6868fc24ac75')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -322,6 +353,7 @@
         self.assertRaises(lib_exc.NotFound, self.client.unpause_server,
                           nonexistent_server)
 
+    @test.idempotent_id('c8e639a7-ece8-42dd-a2e0-49615917ba4f')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -331,6 +363,7 @@
                           self.client.unpause_server,
                           self.server_id)
 
+    @test.idempotent_id('d1f032d5-7b6e-48aa-b252-d5f16dd994ca')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -340,6 +373,7 @@
         self.assertRaises(lib_exc.NotFound, self.client.suspend_server,
                           nonexistent_server)
 
+    @test.idempotent_id('7f323206-05a9-4bf8-996b-dd5b2036501b')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -352,6 +386,7 @@
                           self.server_id)
         self.client.resume_server(self.server_id)
 
+    @test.idempotent_id('221cd282-bddb-4837-a683-89c2487389b6')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -361,6 +396,7 @@
         self.assertRaises(lib_exc.NotFound, self.client.resume_server,
                           nonexistent_server)
 
+    @test.idempotent_id('ccb6294d-c4c9-498f-8a43-554c098bfadb')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -371,6 +407,7 @@
                           self.server_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7dd919e7-413f-4198-bebb-35e2a01b13e9')
     def test_get_console_output_of_non_existent_server(self):
         # get the console output for a non existent server
         nonexistent_server = data_utils.rand_uuid()
@@ -379,6 +416,7 @@
                           nonexistent_server, 10)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6f47992b-5144-4250-9f8b-f00aa33950f3')
     def test_force_delete_nonexistent_server_id(self):
         # force-delete a non existent server
         nonexistent_server = data_utils.rand_uuid()
@@ -387,6 +425,7 @@
                           nonexistent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c6d38cc-fcfb-437a-85b9-7b788af8bf01')
     def test_restore_nonexistent_server_id(self):
         # restore-delete a non existent server
         nonexistent_server = data_utils.rand_uuid()
@@ -395,12 +434,14 @@
                           nonexistent_server)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7fcadfab-bd6a-4753-8db7-4a51e51aade9')
     def test_restore_server_invalid_state(self):
         # we can only restore-delete a server in 'soft-delete' state
         self.assertRaises(lib_exc.Conflict,
                           self.client.restore_soft_deleted_server,
                           self.server_id)
 
+    @test.idempotent_id('abca56e2-a892-48ea-b5e5-e07e69774816')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -410,6 +451,7 @@
         self.assertRaises(lib_exc.NotFound, self.client.shelve_server,
                           nonexistent_server)
 
+    @test.idempotent_id('443e4f9b-e6bf-4389-b601-3a710f15fddd')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -439,6 +481,7 @@
 
         self.client.unshelve_server(self.server_id)
 
+    @test.idempotent_id('23d23b37-afaf-40d7-aa5d-5726f82d8821')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
@@ -448,6 +491,7 @@
         self.assertRaises(lib_exc.NotFound, self.client.unshelve_server,
                           nonexistent_server)
 
+    @test.idempotent_id('8f198ded-1cca-4228-9e65-c6b449c54880')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 564704e..0b2f4c6 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -45,6 +45,7 @@
     @decorators.skip_because(bug="1183436",
                              condition=CONF.service_available.neutron)
     @test.attr(type='gate')
+    @test.idempotent_id('96c4e2ef-5e4d-4d7f-87f5-fed6dca18016')
     @test.services('network')
     def test_list_virtual_interfaces(self):
         # Positive test:Should be able to GET the virtual interfaces list
diff --git a/tempest/api/compute/servers/test_virtual_interfaces_negative.py b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
index 58c4fcd..e5cb744 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces_negative.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
@@ -35,6 +35,7 @@
         cls.client = cls.servers_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('64ebd03c-1089-4306-93fa-60f5eb5c803c')
     @test.services('network')
     def test_list_virtual_interfaces_invalid_server_id(self):
         # Negative test: Should not be able to GET virtual interfaces
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index b64981f..2dbe123 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -104,30 +104,35 @@
         super(AuthorizationTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('56816e4a-bd34-47b5-aee9-268c3efeb5d4')
     def test_get_server_for_alt_account_fails(self):
         # A GET request for a server on another user's account should fail
         self.assertRaises(lib_exc.NotFound, self.alt_client.get_server,
                           self.server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('fb8a4870-6d9d-44ad-8375-95d52e98d9f6')
     def test_delete_server_for_alt_account_fails(self):
         # A DELETE request for another user's server should fail
         self.assertRaises(lib_exc.NotFound, self.alt_client.delete_server,
                           self.server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d792f91f-1d49-4eb5-b1ff-b229c4b9dc64')
     def test_update_server_for_alt_account_fails(self):
         # An update server request for another user's server should fail
         self.assertRaises(lib_exc.NotFound, self.alt_client.update_server,
                           self.server['id'], name='test')
 
     @test.attr(type='gate')
+    @test.idempotent_id('488f24df-d7f7-4207-949a-f17fcb8e8769')
     def test_list_server_addresses_for_alt_account_fails(self):
         # A list addresses request for another user's server should fail
         self.assertRaises(lib_exc.NotFound, self.alt_client.list_addresses,
                           self.server['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('00b442d0-2e72-40e7-9b1f-31772e36da01')
     def test_list_server_addresses_by_network_for_alt_account_fails(self):
         # A list address/network request for another user's server should fail
         server_id = self.server['id']
@@ -136,6 +141,7 @@
                           'public')
 
     @test.attr(type='gate')
+    @test.idempotent_id('cc90b35a-19f0-45d2-b680-2aabf934aa22')
     def test_list_servers_with_alternate_tenant(self):
         # A list on servers from one tenant should not
         # show on alternate tenant
@@ -146,30 +152,35 @@
         self.assertNotIn(self.server['id'], alt_server_ids)
 
     @test.attr(type='gate')
+    @test.idempotent_id('376dbc16-0779-4384-a723-752774799641')
     def test_change_password_for_alt_account_fails(self):
         # A change password request for another user's server should fail
         self.assertRaises(lib_exc.NotFound, self.alt_client.change_password,
                           self.server['id'], 'newpass')
 
     @test.attr(type='gate')
+    @test.idempotent_id('14cb5ff5-f646-45ca-8f51-09081d6c0c24')
     def test_reboot_server_for_alt_account_fails(self):
         # A reboot request for another user's server should fail
         self.assertRaises(lib_exc.NotFound, self.alt_client.reboot,
                           self.server['id'], 'HARD')
 
     @test.attr(type='gate')
+    @test.idempotent_id('8a0bce51-cd00-480b-88ba-dbc7d8408a37')
     def test_rebuild_server_for_alt_account_fails(self):
         # A rebuild request for another user's server should fail
         self.assertRaises(lib_exc.NotFound, self.alt_client.rebuild,
                           self.server['id'], self.image_ref_alt)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e4da647e-f982-4e61-9dad-1d1abebfb933')
     def test_resize_server_for_alt_account_fails(self):
         # A resize request for another user's server should fail
         self.assertRaises(lib_exc.NotFound, self.alt_client.resize,
                           self.server['id'], self.flavor_ref_alt)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a9fe8112-0ffa-4902-b061-f892bd5fe0d3')
     def test_create_image_for_alt_account_fails(self):
         # A create image request for another user's server should fail
         self.assertRaises(lib_exc.NotFound,
@@ -177,12 +188,14 @@
                           self.server['id'], 'testImage')
 
     @test.attr(type='gate')
+    @test.idempotent_id('95d445f6-babc-4f2e-aea3-aa24ec5e7f0d')
     def test_create_server_with_unauthorized_image(self):
         # Server creation with another user's image should fail
         self.assertRaises(lib_exc.BadRequest, self.alt_client.create_server,
                           'test', self.image['id'], self.flavor_ref)
 
     @test.attr(type='gate')
+    @test.idempotent_id('acf8724b-142b-4044-82c3-78d31a533f24')
     def test_create_server_fails_when_tenant_incorrect(self):
         # A create server request should fail if the tenant id does not match
         # the current user
@@ -196,6 +209,7 @@
                           self.image['id'], self.flavor_ref)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f03d1ded-7fd4-4d29-bc13-e2391f29c625')
     def test_create_keypair_in_analt_user_tenant(self):
         # A create keypair request should fail if the tenant id does not match
         # the current user
@@ -219,6 +233,7 @@
                           "if the tenant id does not match the current user")
 
     @test.attr(type='gate')
+    @test.idempotent_id('85bcdd8f-56b4-4868-ae56-63fbf6f7e405')
     def test_get_keypair_of_alt_account_fails(self):
         # A GET request for another user's keypair should fail
         self.assertRaises(lib_exc.NotFound,
@@ -226,6 +241,7 @@
                           self.keypairname)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6d841683-a8e0-43da-a1b8-b339f7692b61')
     def test_delete_keypair_of_alt_account_fails(self):
         # A DELETE request for another user's keypair should fail
         self.assertRaises(lib_exc.NotFound,
@@ -233,12 +249,14 @@
                           self.keypairname)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fcb2e144-36e3-4dfb-9f9f-e72fcdec5656')
     def test_get_image_for_alt_account_fails(self):
         # A GET request for an image on another user's account should fail
         self.assertRaises(lib_exc.NotFound,
                           self.alt_images_client.get_image, self.image['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('9facb962-f043-4a9d-b9ee-166a32dea098')
     def test_delete_image_for_alt_account_fails(self):
         # A DELETE request for another user's image should fail
         self.assertRaises(lib_exc.NotFound,
@@ -246,6 +264,7 @@
                           self.image['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('752c917e-83be-499d-a422-3559127f7d3c')
     def test_create_security_group_in_analt_user_tenant(self):
         # A create security group request should fail if the tenant id does not
         # match the current user
@@ -271,6 +290,7 @@
                           "the tenant id does not match the current user")
 
     @test.attr(type='gate')
+    @test.idempotent_id('9db3590f-4d15-4e5f-985e-b28514919a6f')
     def test_get_security_group_of_alt_account_fails(self):
         # A GET request for another user's security group should fail
         self.assertRaises(lib_exc.NotFound,
@@ -278,6 +298,7 @@
                           self.security_group['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('155387a5-2bbc-4acf-ab06-698dae537ea5')
     def test_delete_security_group_of_alt_account_fails(self):
         # A DELETE request for another user's security group should fail
         self.assertRaises(lib_exc.NotFound,
@@ -285,6 +306,7 @@
                           self.security_group['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('b2b76de0-210a-4089-b921-591c9ec552f6')
     def test_create_security_group_rule_in_analt_user_tenant(self):
         # A create security group rule request should fail if the tenant id
         # does not match the current user
@@ -315,6 +337,7 @@
                           " current user")
 
     @test.attr(type='gate')
+    @test.idempotent_id('c6044177-37ef-4ce4-b12c-270ddf26d7da')
     def test_delete_security_group_rule_of_alt_account_fails(self):
         # A DELETE request for another user's security group rule
         # should fail
@@ -323,6 +346,7 @@
                           self.rule['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('c5f52351-53d9-4fc9-83e5-917f7f5e3d71')
     def test_set_metadata_of_alt_account_server_fails(self):
         # A set metadata for another user's server should fail
         req_metadata = {'meta1': 'data1', 'meta2': 'data2'}
@@ -332,6 +356,7 @@
                           req_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fb6f51e9-df15-4939-898d-1aca38c258f0')
     def test_set_metadata_of_alt_account_image_fails(self):
         # A set metadata for another user's image should fail
         req_metadata = {'meta1': 'value1', 'meta2': 'value2'}
@@ -340,6 +365,7 @@
                           self.image['id'], req_metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('dea1936a-473d-49f2-92ad-97bb7aded22e')
     def test_get_metadata_of_alt_account_server_fails(self):
         # A get metadata for another user's server should fail
         req_metadata = {'meta1': 'data1'}
@@ -351,6 +377,7 @@
                           self.server['id'], 'meta1')
 
     @test.attr(type='gate')
+    @test.idempotent_id('16b2d724-0d3b-4216-a9fa-97bd4d9cf670')
     def test_get_metadata_of_alt_account_image_fails(self):
         # A get metadata for another user's image should fail
         req_metadata = {'meta1': 'value1'}
@@ -363,6 +390,7 @@
                           self.image['id'], 'meta1')
 
     @test.attr(type='gate')
+    @test.idempotent_id('79531e2e-e721-493c-8b30-a35db36fdaa6')
     def test_delete_metadata_of_alt_account_server_fails(self):
         # A delete metadata for another user's server should fail
         req_metadata = {'meta1': 'data1'}
@@ -374,6 +402,7 @@
                           self.server['id'], 'meta1')
 
     @test.attr(type='gate')
+    @test.idempotent_id('a5175dcf-cef8-43d6-9b77-3cb707d62e94')
     def test_delete_metadata_of_alt_account_image_fails(self):
         # A delete metadata for another user's image should fail
         req_metadata = {'meta1': 'data1'}
@@ -386,6 +415,7 @@
                           self.image['id'], 'meta1')
 
     @test.attr(type='gate')
+    @test.idempotent_id('b0c1e7a0-8853-40fd-8384-01f93d116cae')
     def test_get_console_output_of_alt_account_server_fails(self):
         # A Get Console Output for another user's server should fail
         self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index f40ae9f..1063f90 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -28,6 +28,7 @@
 class ExtensionsTestJSON(base.BaseV2ComputeTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('3bb27738-b759-4e0d-a5fa-37d7a6df07d1')
     def test_list_extensions(self):
         # List of all extensions
         if len(CONF.compute_feature_enabled.api_extensions) == 0:
@@ -44,6 +45,7 @@
         extension_list = map(lambda x: x['alias'], extensions)
         LOG.debug("Nova extensions: %s" % ','.join(extension_list))
 
+    @test.idempotent_id('05762f39-bdfa-4cdb-9b46-b78f8e78e2fd')
     @test.requires_ext(extension='os-consoles', service='compute')
     @test.attr(type='gate')
     def test_get_extension(self):
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index 235b058..a933f81 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -81,6 +81,7 @@
             self.volumes_client.wait_for_volume_status(volume_id, 'available')
         self.volumes_client.delete_volume(volume_id)
 
+    @test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
     @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
                       'Live migration not available')
     @test.attr(type='gate')
@@ -96,6 +97,7 @@
         self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
         self.assertEqual(target_host, self._get_host_for_server(server_id))
 
+    @test.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
     @testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
                       CONF.compute_feature_enabled.
                       block_migration_for_live_migration,
diff --git a/tempest/api/compute/test_live_block_migration_negative.py b/tempest/api/compute/test_live_block_migration_negative.py
index 34c75d5..bed53d6 100644
--- a/tempest/api/compute/test_live_block_migration_negative.py
+++ b/tempest/api/compute/test_live_block_migration_negative.py
@@ -42,6 +42,7 @@
         return body
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7fb7856e-ae92-44c9-861a-af62d7830bcb')
     def test_invalid_host_for_migration(self):
         # Migrating to an invalid host should not change the status
         target_host = data_utils.rand_name('host-')
diff --git a/tempest/api/compute/test_networks.py b/tempest/api/compute/test_networks.py
index 033f4a5..c30beb7 100644
--- a/tempest/api/compute/test_networks.py
+++ b/tempest/api/compute/test_networks.py
@@ -28,6 +28,7 @@
         cls.client = cls.os.networks_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('3fe07175-312e-49a5-a623-5f52eeada4c2')
     def test_list_networks(self):
         networks = self.client.list_networks()
         self.assertNotEmpty(networks, "No networks found.")
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index db2e281..1df67d9 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -40,6 +40,7 @@
                                      'cores', 'security_groups'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107')
     def test_get_quotas(self):
         # User can get the quota set for it's tenant
         expected_quota_set = self.default_quota_set | set(['id'])
@@ -56,6 +57,7 @@
             self.assertIn(quota, quota_set.keys())
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9bfecac7-b966-4f47-913f-1a9e2c12134a')
     def test_get_default_quotas(self):
         # User can get the default quota set for it's tenant
         expected_quota_set = self.default_quota_set | set(['id'])
@@ -65,6 +67,7 @@
             self.assertIn(quota, quota_set.keys())
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cd65d997-f7e4-4966-a7e9-d5001b674fdc')
     def test_compare_tenant_quotas_with_default_quotas(self):
         # Tenants are created with the default quota values
         defualt_quota_set = \
diff --git a/tempest/api/compute/test_tenant_networks.py b/tempest/api/compute/test_tenant_networks.py
index 0591acc..3a712dd 100644
--- a/tempest/api/compute/test_tenant_networks.py
+++ b/tempest/api/compute/test_tenant_networks.py
@@ -24,6 +24,7 @@
         cls.client = cls.os.tenant_networks_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('edfea98e-bbe3-4c7a-9739-87b986baff26')
     def test_list_show_tenant_networks(self):
         tenant_networks = self.client.list_tenant_networks()
         self.assertNotEmpty(tenant_networks, "No tenant networks found.")
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 424b0fa..43d2302 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -84,6 +84,7 @@
 
         self.addCleanup(self._detach, self.server['id'], self.volume['id'])
 
+    @test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
     @testtools.skipUnless(CONF.compute.run_ssh, 'SSH required for this test')
     @test.attr(type='gate')
     def test_attach_detach_volume(self):
@@ -120,6 +121,7 @@
         self.assertNotIn(self.device, partitions)
 
     @test.attr(type='gate')
+    @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
     def test_list_get_volume_attachments(self):
         # Create Server, Volume and attach that Volume to Server
         self._create_and_attach()
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index aa4fb52..207476d 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -39,6 +39,7 @@
         cls.client = cls.volumes_extensions_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f10f25eb-9775-4d9d-9cbe-1cf54dae9d5f')
     def test_volume_create_get_delete(self):
         # CREATE, GET, DELETE Volume
         volume = None
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index cb74876..501e9ed 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -84,6 +84,7 @@
         super(VolumesTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('bc2dd1a0-15af-48e5-9990-f2e75a48325d')
     def test_volume_list(self):
         # Should return the list of Volumes
         # Fetch all Volumes
@@ -99,6 +100,7 @@
                                    for m_vol in missing_volumes))
 
     @test.attr(type='gate')
+    @test.idempotent_id('bad0567a-5a4f-420b-851e-780b55bb867c')
     def test_volume_list_with_details(self):
         # Should return the list of Volumes with details
         # Fetch all Volumes
@@ -114,6 +116,7 @@
                                    for m_vol in missing_volumes))
 
     @test.attr(type='gate')
+    @test.idempotent_id('1048ed81-2baf-487a-b284-c0622b86e7b8')
     def test_volume_list_param_limit(self):
         # Return the list of volumes based on limit set
         params = {'limit': 2}
@@ -123,6 +126,7 @@
                          "Failed to list volumes by limit set")
 
     @test.attr(type='gate')
+    @test.idempotent_id('33985568-4965-49d5-9bcc-0aa007ca5b7a')
     def test_volume_list_with_detail_param_limit(self):
         # Return the list of volumes with details based on limit set.
         params = {'limit': 2}
@@ -132,6 +136,7 @@
                          "Failed to list volume details by limit set")
 
     @test.attr(type='gate')
+    @test.idempotent_id('51c22651-a074-4ea7-af0b-094f9331303e')
     def test_volume_list_param_offset_and_limit(self):
         # Return the list of volumes based on offset and limit set.
         # get all volumes list
@@ -149,6 +154,7 @@
                              "Failed to list volumes by offset and limit")
 
     @test.attr(type='gate')
+    @test.idempotent_id('06b6abc4-3f10-48e9-a7a1-3facc98f03e5')
     def test_volume_list_with_detail_param_offset_and_limit(self):
         # Return the list of volumes details based on offset and limit set.
         # get all volumes list
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index 53217c9..89f6817 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -40,6 +40,7 @@
         cls.client = cls.volumes_extensions_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c03ea686-905b-41a2-8748-9635154b7c57')
     def test_volume_get_nonexistent_volume_id(self):
         # Negative: Should not be able to get details of nonexistent volume
         # Creating a nonexistent volume id
@@ -48,6 +49,7 @@
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('54a34226-d910-4b00-9ef8-8683e6c55846')
     def test_volume_delete_nonexistent_volume_id(self):
         # Negative: Should not be able to delete nonexistent Volume
         # Creating nonexistent volume id
@@ -56,6 +58,7 @@
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5125ae14-152b-40a7-b3c5-eae15e9022ef')
     def test_create_volume_with_invalid_size(self):
         # Negative: Should not be able to create volume with invalid size
         # in request
@@ -65,6 +68,7 @@
                           size='#$%', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('131cb3a1-75cc-4d40-b4c3-1317f64719b0')
     def test_create_volume_with_out_passing_size(self):
         # Negative: Should not be able to create volume without passing size
         # in request
@@ -74,6 +78,7 @@
                           size='', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8cce995e-0a83-479a-b94d-e1e40b8a09d1')
     def test_create_volume_with_size_zero(self):
         # Negative: Should not be able to create volume with size zero
         v_name = data_utils.rand_name('Volume-')
@@ -82,17 +87,20 @@
                           size='0', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f01904f2-e975-4915-98ce-cb5fa27bde4f')
     def test_get_invalid_volume_id(self):
         # Negative: Should not be able to get volume with invalid id
         self.assertRaises(lib_exc.NotFound,
                           self.client.get_volume, '#$%%&^&^')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('62bab09a-4c03-4617-8cca-8572bc94af9b')
     def test_get_volume_without_passing_volume_id(self):
         # Negative: Should not be able to get volume when empty ID is passed
         self.assertRaises(lib_exc.NotFound, self.client.get_volume, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('62972737-124b-4513-b6cf-2f019f178494')
     def test_delete_invalid_volume_id(self):
         # Negative: Should not be able to delete volume when invalid ID is
         # passed
@@ -100,6 +108,7 @@
                           self.client.delete_volume, '!@#$%^&*()')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0d1417c5-4ae8-4c2c-adc5-5f0b864253e5')
     def test_delete_volume_without_passing_volume_id(self):
         # Negative: Should not be able to delete volume when empty ID is passed
         self.assertRaises(lib_exc.NotFound, self.client.delete_volume, '')
diff --git a/tempest/api/data_processing/test_cluster_templates.py b/tempest/api/data_processing/test_cluster_templates.py
index 422ea5b..af7cbaf 100644
--- a/tempest/api/data_processing/test_cluster_templates.py
+++ b/tempest/api/data_processing/test_cluster_templates.py
@@ -112,10 +112,12 @@
         return resp_body['id'], template_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3525f1f1-3f9c-407d-891a-a996237e728b')
     def test_cluster_template_create(self):
         self._create_cluster_template()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7a161882-e430-4840-a1c6-1d928201fab2')
     def test_cluster_template_list(self):
         template_info = self._create_cluster_template()
 
@@ -126,6 +128,7 @@
         self.assertIn(template_info, templates_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2b75fe22-f731-4b0f-84f1-89ab25f86637')
     def test_cluster_template_get(self):
         template_id, template_name = self._create_cluster_template()
 
@@ -135,6 +138,7 @@
         self.assertDictContainsSubset(self.cluster_template, template)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ff1fd989-171c-4dd7-91fd-9fbc71b09675')
     def test_cluster_template_delete(self):
         template_id, _ = self._create_cluster_template()
 
diff --git a/tempest/api/data_processing/test_data_sources.py b/tempest/api/data_processing/test_data_sources.py
index a50f44b..dd16b2f 100644
--- a/tempest/api/data_processing/test_data_sources.py
+++ b/tempest/api/data_processing/test_data_sources.py
@@ -79,22 +79,26 @@
         self.assertDictContainsSubset(source_body, source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9e0e836d-c372-4fca-91b7-b66c3e9646c8')
     def test_swift_data_source_create(self):
         self._create_data_source(self.swift_data_source_with_creds)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3cb87a4a-0534-4b97-9edc-8bbc822b68a0')
     def test_swift_data_source_list(self):
         source_info = (
             self._create_data_source(self.swift_data_source_with_creds))
         self._list_data_sources(source_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fc07409b-6477-4cb3-9168-e633c46b227f')
     def test_swift_data_source_get(self):
         source_id, source_name = (
             self._create_data_source(self.swift_data_source_with_creds))
         self._get_data_source(source_id, source_name, self.swift_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('df53669c-0cd1-4cf7-b408-4cf215d8beb8')
     def test_swift_data_source_delete(self):
         source_id, _ = (
             self._create_data_source(self.swift_data_source_with_creds))
@@ -103,15 +107,18 @@
         self.client.delete_data_source(source_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('88505d52-db01-4229-8f1d-a1137da5fe2d')
     def test_local_hdfs_data_source_create(self):
         self._create_data_source(self.local_hdfs_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('81d7d42a-d7f6-4d9b-b38c-0801a4dfe3c2')
     def test_local_hdfs_data_source_list(self):
         source_info = self._create_data_source(self.local_hdfs_data_source)
         self._list_data_sources(source_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ec0144c6-db1e-4169-bb06-7abae14a8443')
     def test_local_hdfs_data_source_get(self):
         source_id, source_name = (
             self._create_data_source(self.local_hdfs_data_source))
@@ -119,6 +126,7 @@
             source_id, source_name, self.local_hdfs_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e398308b-4230-4f86-ba10-9b0b60a59c8d')
     def test_local_hdfs_data_source_delete(self):
         source_id, _ = self._create_data_source(self.local_hdfs_data_source)
 
@@ -126,15 +134,18 @@
         self.client.delete_data_source(source_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bfd91128-e642-4d95-a973-3e536962180c')
     def test_external_hdfs_data_source_create(self):
         self._create_data_source(self.external_hdfs_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('92e2be72-f7ab-499d-ae01-fb9943c90d8e')
     def test_external_hdfs_data_source_list(self):
         source_info = self._create_data_source(self.external_hdfs_data_source)
         self._list_data_sources(source_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a31edb1b-6bc6-4f42-871f-70cd243184ac')
     def test_external_hdfs_data_source_get(self):
         source_id, source_name = (
             self._create_data_source(self.external_hdfs_data_source))
@@ -142,6 +153,7 @@
             source_id, source_name, self.external_hdfs_data_source)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('295924cd-a085-4b45-aea8-0707cdb2da7e')
     def test_external_hdfs_data_source_delete(self):
         source_id, _ = self._create_data_source(self.external_hdfs_data_source)
 
diff --git a/tempest/api/data_processing/test_job_binaries.py b/tempest/api/data_processing/test_job_binaries.py
index 2f6d998..fb21270 100644
--- a/tempest/api/data_processing/test_job_binaries.py
+++ b/tempest/api/data_processing/test_job_binaries.py
@@ -70,10 +70,12 @@
         return resp_body['id'], binary_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c00d43f8-4360-45f8-b280-af1a201b12d3')
     def test_swift_job_binary_create(self):
         self._create_job_binary(self.swift_job_binary_with_extra)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f8809352-e79d-4748-9359-ce1efce89f2a')
     def test_swift_job_binary_list(self):
         binary_info = self._create_job_binary(self.swift_job_binary_with_extra)
 
@@ -83,6 +85,7 @@
         self.assertIn(binary_info, binaries_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2d4a670f-e8f1-413c-b5ac-50c1bfe9e1b1')
     def test_swift_job_binary_get(self):
         binary_id, binary_name = (
             self._create_job_binary(self.swift_job_binary_with_extra))
@@ -93,6 +96,7 @@
         self.assertDictContainsSubset(self.swift_job_binary, binary)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9b0e8f38-04f3-4616-b399-cfa7eb2677ed')
     def test_swift_job_binary_delete(self):
         binary_id, _ = (
             self._create_job_binary(self.swift_job_binary_with_extra))
@@ -101,10 +105,12 @@
         self.client.delete_job_binary(binary_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('63662f6d-8291-407e-a6fc-f654522ebab6')
     def test_internal_db_job_binary_create(self):
         self._create_job_binary(self.internal_db_job_binary)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('38731e7b-6d9d-4ffa-8fd1-193c453e88b1')
     def test_internal_db_job_binary_list(self):
         binary_info = self._create_job_binary(self.internal_db_job_binary)
 
@@ -114,6 +120,7 @@
         self.assertIn(binary_info, binaries_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1b32199b-c3f5-43e1-a37a-3797e57b7066')
     def test_internal_db_job_binary_get(self):
         binary_id, binary_name = (
             self._create_job_binary(self.internal_db_job_binary))
@@ -124,6 +131,7 @@
         self.assertDictContainsSubset(self.internal_db_job_binary, binary)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3c42b0c3-3e03-46a5-adf0-df0650271a4e')
     def test_internal_db_job_binary_delete(self):
         binary_id, _ = self._create_job_binary(self.internal_db_job_binary)
 
@@ -131,6 +139,7 @@
         self.client.delete_job_binary(binary_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d5d47659-7e2c-4ea7-b292-5b3e559e8587')
     def test_job_binary_get_data(self):
         binary_id, _ = self._create_job_binary(self.internal_db_job_binary)
 
diff --git a/tempest/api/data_processing/test_job_binary_internals.py b/tempest/api/data_processing/test_job_binary_internals.py
index b8121a0..3d76ebe 100644
--- a/tempest/api/data_processing/test_job_binary_internals.py
+++ b/tempest/api/data_processing/test_job_binary_internals.py
@@ -47,10 +47,12 @@
         return resp_body['id'], binary_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('249c4dc2-946f-4939-83e6-212ddb6ea0be')
     def test_job_binary_internal_create(self):
         self._create_job_binary_internal()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1e3c2ecd-5673-499d-babe-4fe2fcdf64ee')
     def test_job_binary_internal_list(self):
         binary_info = self._create_job_binary_internal()
 
@@ -60,6 +62,7 @@
         self.assertIn(binary_info, binaries_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a2046a53-386c-43ab-be35-df54b19db776')
     def test_job_binary_internal_get(self):
         binary_id, binary_name = self._create_job_binary_internal()
 
@@ -68,6 +71,7 @@
         self.assertEqual(binary_name, binary['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b3568c33-4eed-40d5-aae4-6ff3b2ac58f5')
     def test_job_binary_internal_delete(self):
         binary_id, _ = self._create_job_binary_internal()
 
@@ -75,6 +79,7 @@
         self.client.delete_job_binary_internal(binary_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8871f2b0-5782-4d66-9bb9-6f95bcb839ea')
     def test_job_binary_internal_get_data(self):
         binary_id, _ = self._create_job_binary_internal()
 
diff --git a/tempest/api/data_processing/test_jobs.py b/tempest/api/data_processing/test_jobs.py
index a7beb0e..83eb54d 100644
--- a/tempest/api/data_processing/test_jobs.py
+++ b/tempest/api/data_processing/test_jobs.py
@@ -61,10 +61,12 @@
         return resp_body['id'], job_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8cf785ca-adf4-473d-8281-fb9a5efa3073')
     def test_job_create(self):
         self._create_job()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('41e253fe-b02a-41a0-b186-5ff1f0463ba3')
     def test_job_list(self):
         job_info = self._create_job()
 
@@ -74,6 +76,7 @@
         self.assertIn(job_info, jobs_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3faf17fa-bc94-4a60-b1c3-79e53674c16c')
     def test_job_get(self):
         job_id, job_name = self._create_job()
 
@@ -82,6 +85,7 @@
         self.assertEqual(job_name, job['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('dff85e62-7dda-4ad8-b1ee-850adecb0c6e')
     def test_job_delete(self):
         job_id, _ = self._create_job()
 
diff --git a/tempest/api/data_processing/test_node_group_templates.py b/tempest/api/data_processing/test_node_group_templates.py
index d37e910..9d84218 100644
--- a/tempest/api/data_processing/test_node_group_templates.py
+++ b/tempest/api/data_processing/test_node_group_templates.py
@@ -61,10 +61,12 @@
         return resp_body['id'], template_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('63164051-e46d-4387-9741-302ef4791cbd')
     def test_node_group_template_create(self):
         self._create_node_group_template()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('eb39801d-2612-45e5-88b1-b5d70b329185')
     def test_node_group_template_list(self):
         template_info = self._create_node_group_template()
 
@@ -75,6 +77,7 @@
         self.assertIn(template_info, templates_info)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6ee31539-a708-466f-9c26-4093ce09a836')
     def test_node_group_template_get(self):
         template_id, template_name = self._create_node_group_template()
 
@@ -84,6 +87,7 @@
         self.assertDictContainsSubset(self.node_group_template, template)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f4f5cb82-708d-4031-81c4-b0618a706a2f')
     def test_node_group_template_delete(self):
         template_id, _ = self._create_node_group_template()
 
diff --git a/tempest/api/data_processing/test_plugins.py b/tempest/api/data_processing/test_plugins.py
index 8c9b720..92a5bd0 100644
--- a/tempest/api/data_processing/test_plugins.py
+++ b/tempest/api/data_processing/test_plugins.py
@@ -33,10 +33,12 @@
         return plugins_names
 
     @test.attr(type='smoke')
+    @test.idempotent_id('01a005a3-426c-4c0b-9617-d09475403e09')
     def test_plugin_list(self):
         self._list_all_plugin_names()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('53cf6487-2cfb-4a6f-8671-97c542c6e901')
     def test_plugin_get(self):
         for plugin_name in self._list_all_plugin_names():
             plugin = self.client.get_plugin(plugin_name)
diff --git a/tempest/api/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
index db8939e..eeb472c 100644
--- a/tempest/api/database/flavors/test_flavors.py
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -25,6 +25,7 @@
         cls.client = cls.database_flavors_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c94b825e-0132-4686-8049-8a4a2bc09525')
     def test_get_db_flavor(self):
         # The expected flavor details should be returned
         flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
@@ -34,6 +35,7 @@
         self.assertIn('name', flavor)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('685025d6-0cec-4673-8a8d-995cb8e0d3bb')
     def test_list_db_flavors(self):
         flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
         # List of all flavors should contain the expected flavor
@@ -52,6 +54,7 @@
                 self.assertNotIn(name, db_flavor)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('afb2667f-4ec2-4925-bcb7-313fdcffb80d')
     @test.services('compute')
     def test_compare_db_flavors_with_os(self):
         db_flavors = self.client.list_db_flavors()
diff --git a/tempest/api/database/flavors/test_flavors_negative.py b/tempest/api/database/flavors/test_flavors_negative.py
index bb9c05d..1b2c88c 100644
--- a/tempest/api/database/flavors/test_flavors_negative.py
+++ b/tempest/api/database/flavors/test_flavors_negative.py
@@ -27,6 +27,7 @@
         cls.client = cls.database_flavors_client
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f8e7b721-373f-4a64-8e9c-5327e975af3e')
     def test_get_non_existent_db_flavor(self):
         # flavor details are not returned for non-existent flavors
         self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/database/limits/test_limits.py b/tempest/api/database/limits/test_limits.py
index d1c9baf..7d2fbac 100644
--- a/tempest/api/database/limits/test_limits.py
+++ b/tempest/api/database/limits/test_limits.py
@@ -25,6 +25,7 @@
         cls.client = cls.database_limits_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('73024538-f316-4829-b3e9-b459290e137a')
     def test_absolute_limits(self):
         # Test to verify if all absolute limit paramaters are
         # present when verb is ABSOLUTE
diff --git a/tempest/api/database/versions/test_versions.py b/tempest/api/database/versions/test_versions.py
index 8960437..55d8246 100644
--- a/tempest/api/database/versions/test_versions.py
+++ b/tempest/api/database/versions/test_versions.py
@@ -25,6 +25,7 @@
         cls.client = cls.database_versions_client
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6952cd77-90cd-4dca-bb60-8e2c797940cf')
     def test_list_db_versions(self):
         versions = self.client.list_db_versions()
         self.assertTrue(len(versions) > 0, "No database versions found")
diff --git a/tempest/api/identity/admin/test_roles.py b/tempest/api/identity/admin/test_roles.py
index 80ad6db..3eb6c08 100644
--- a/tempest/api/identity/admin/test_roles.py
+++ b/tempest/api/identity/admin/test_roles.py
@@ -46,6 +46,7 @@
         self.assertTrue(found, "assigned role was not in list")
 
     @test.attr(type='gate')
+    @test.idempotent_id('75d9593f-50b7-4fcf-bd64-e3fb4a278e23')
     def test_list_roles(self):
         """Return a list of all roles."""
         body = self.client.list_roles()
@@ -54,6 +55,7 @@
         self.assertEqual(len(found), len(self.data.roles))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c62d909d-6c21-48c0-ae40-0a0760e6db5e')
     def test_role_create_delete(self):
         """Role should be created, verified, and deleted."""
         role_name = data_utils.rand_name(name='role-test-')
@@ -71,6 +73,7 @@
         self.assertFalse(any(found))
 
     @test.attr(type='gate')
+    @test.idempotent_id('db6870bd-a6ed-43be-a9b1-2f10a5c9994f')
     def test_get_role_by_id(self):
         """Get a role by its id."""
         self.data.setup_test_role()
@@ -81,6 +84,7 @@
         self.assertEqual(role_name, body['name'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('0146f675-ffbd-4208-b3a4-60eb628dbc5e')
     def test_assign_user_role(self):
         """Assign a role to a user on a tenant."""
         (user, tenant, role) = self._get_role_params()
@@ -89,6 +93,7 @@
         self.assert_role_in_role_list(role, roles)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f0b9292c-d3ba-4082-aa6c-440489beef69')
     def test_remove_user_role(self):
         """Remove a role assigned to a user on a tenant."""
         (user, tenant, role) = self._get_role_params()
@@ -98,6 +103,7 @@
                                      user_role['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('262e1e3e-ed71-4edd-a0e5-d64e83d66d05')
     def test_list_user_roles(self):
         """List roles assigned to a user on tenant."""
         (user, tenant, role) = self._get_role_params()
diff --git a/tempest/api/identity/admin/test_roles_negative.py b/tempest/api/identity/admin/test_roles_negative.py
index c38e6e0..be9fb52 100644
--- a/tempest/api/identity/admin/test_roles_negative.py
+++ b/tempest/api/identity/admin/test_roles_negative.py
@@ -32,12 +32,14 @@
         return (user, tenant, role)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d5d5f1df-f8ca-4de0-b2ef-259c1cc67025')
     def test_list_roles_by_unauthorized_user(self):
         # Non-administrator user should not be able to list roles
         self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_roles)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('11a3c7da-df6c-40c2-abc2-badd682edf9f')
     def test_list_roles_request_without_token(self):
         # Request to list roles without a valid token should fail
         token = self.client.auth_provider.get_token()
@@ -46,11 +48,13 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c0b89e56-accc-4c73-85f8-9c0f866104c1')
     def test_role_create_blank_name(self):
         # Should not be able to create a role with a blank name
         self.assertRaises(lib_exc.BadRequest, self.client.create_role, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('585c8998-a8a4-4641-a5dd-abef7a8ced00')
     def test_create_role_by_unauthorized_user(self):
         # Non-administrator user should not be able to create role
         role_name = data_utils.rand_name(name='role-')
@@ -58,6 +62,7 @@
                           self.non_admin_client.create_role, role_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a7edd17a-e34a-4aab-8bb7-fa6f498645b8')
     def test_create_role_request_without_token(self):
         # Request to create role without a valid token should fail
         token = self.client.auth_provider.get_token()
@@ -68,6 +73,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c0cde2c8-81c1-4bb0-8fe2-cf615a3547a8')
     def test_role_create_duplicate(self):
         # Role names should be unique
         role_name = data_utils.rand_name(name='role-dup-')
@@ -78,6 +84,7 @@
                           role_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('15347635-b5b1-4a87-a280-deb2bd6d865e')
     def test_delete_role_by_unauthorized_user(self):
         # Non-administrator user should not be able to delete role
         role_name = data_utils.rand_name(name='role-')
@@ -88,6 +95,7 @@
                           self.non_admin_client.delete_role, role_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('44b60b20-70de-4dac-beaf-a3fc2650a16b')
     def test_delete_role_request_without_token(self):
         # Request to delete role without a valid token should fail
         role_name = data_utils.rand_name(name='role-')
@@ -102,6 +110,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('38373691-8551-453a-b074-4260ad8298ef')
     def test_delete_role_non_existent(self):
         # Attempt to delete a non existent role should fail
         non_existent_role = str(uuid.uuid4().hex)
@@ -109,6 +118,7 @@
                           non_existent_role)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('391df5cf-3ec3-46c9-bbe5-5cb58dd4dc41')
     def test_assign_user_role_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to
         # assign a role to user
@@ -118,6 +128,7 @@
                           tenant['id'], user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f0d2683c-5603-4aee-95d7-21420e87cfd8')
     def test_assign_user_role_request_without_token(self):
         # Request to assign a role to a user without a valid token
         (user, tenant, role) = self._get_role_params()
@@ -129,6 +140,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('99b297f6-2b5d-47c7-97a9-8b6bb4f91042')
     def test_assign_user_role_for_non_existent_role(self):
         # Attempt to assign a non existent role to user should fail
         (user, tenant, role) = self._get_role_params()
@@ -137,6 +149,7 @@
                           tenant['id'], user['id'], non_existent_role)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b2285aaa-9e76-4704-93a9-7a8acd0a6c8f')
     def test_assign_user_role_for_non_existent_tenant(self):
         # Attempt to assign a role on a non existent tenant should fail
         (user, tenant, role) = self._get_role_params()
@@ -145,6 +158,7 @@
                           non_existent_tenant, user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5c3132cd-c4c8-4402-b5ea-71eb44e97793')
     def test_assign_duplicate_user_role(self):
         # Duplicate user role should not get assigned
         (user, tenant, role) = self._get_role_params()
@@ -153,6 +167,7 @@
                           tenant['id'], user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d0537987-0977-448f-a435-904c15de7298')
     def test_remove_user_role_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to
         # remove a user's role
@@ -165,6 +180,7 @@
                           tenant['id'], user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('cac81cf4-c1d2-47dc-90d3-f2b7eb572286')
     def test_remove_user_role_request_without_token(self):
         # Request to remove a user's role without a valid token
         (user, tenant, role) = self._get_role_params()
@@ -179,6 +195,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ab32d759-cd16-41f1-a86e-44405fa9f6d2')
     def test_remove_user_role_non_existent_role(self):
         # Attempt to delete a non existent role from a user should fail
         (user, tenant, role) = self._get_role_params()
@@ -190,6 +207,7 @@
                           tenant['id'], user['id'], non_existent_role)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('67a679ec-03dd-4551-bbfc-d1c93284f023')
     def test_remove_user_role_non_existent_tenant(self):
         # Attempt to remove a role from a non existent tenant should fail
         (user, tenant, role) = self._get_role_params()
@@ -201,6 +219,7 @@
                           non_existent_tenant, user['id'], role['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7391ab4c-06f3-477a-a64a-c8e55ce89837')
     def test_list_user_roles_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to list
         # a user's roles
@@ -211,6 +230,7 @@
                           user['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('682adfb2-fd5f-4b0a-a9ca-322e9bebb907')
     def test_list_user_roles_request_without_token(self):
         # Request to list user's roles without a valid token should fail
         (user, tenant, role) = self._get_role_params()
diff --git a/tempest/api/identity/admin/test_services.py b/tempest/api/identity/admin/test_services.py
index af38afc..035f5f8 100644
--- a/tempest/api/identity/admin/test_services.py
+++ b/tempest/api/identity/admin/test_services.py
@@ -31,6 +31,7 @@
                           service_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('84521085-c6e6-491c-9a08-ec9f70f90110')
     def test_create_get_delete_service(self):
         # GET Service
         # Creating a Service
@@ -63,6 +64,7 @@
                          service_data['description'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('5d3252c8-e555-494b-a6c8-e11d7335da42')
     def test_create_service_without_description(self):
         # Create a service only with name and type
         name = data_utils.rand_name('service-')
@@ -76,6 +78,7 @@
         self.assertEqual(type, service['type'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('34ea6489-012d-4a86-9038-1287cadd5eca')
     def test_list_services(self):
         # Create, List, Verify and Delete Services
         services = []
diff --git a/tempest/api/identity/admin/test_tenant_negative.py b/tempest/api/identity/admin/test_tenant_negative.py
index db51f14..8346a3d 100644
--- a/tempest/api/identity/admin/test_tenant_negative.py
+++ b/tempest/api/identity/admin/test_tenant_negative.py
@@ -24,12 +24,14 @@
 class TenantsNegativeTestJSON(base.BaseIdentityV2AdminTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ca9bb202-63dd-4240-8a07-8ef9c19c04bb')
     def test_list_tenants_by_unauthorized_user(self):
         # Non-administrator user should not be able to list tenants
         self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_tenants)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('df33926c-1c96-4d8d-a762-79cc6b0c3cf4')
     def test_list_tenant_request_without_token(self):
         # Request to list tenants without a valid token should fail
         token = self.client.auth_provider.get_token()
@@ -38,6 +40,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('162ba316-f18b-4987-8c0c-fd9140cd63ed')
     def test_tenant_delete_by_unauthorized_user(self):
         # Non-administrator user should not be able to delete a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -47,6 +50,7 @@
                           self.non_admin_client.delete_tenant, tenant['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e450db62-2e9d-418f-893a-54772d6386b1')
     def test_tenant_delete_request_without_token(self):
         # Request to delete a tenant without a valid token should fail
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -59,12 +63,14 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c9a2aed-6e3c-467a-8f5c-89da9d1b516b')
     def test_delete_non_existent_tenant(self):
         # Attempt to delete a non existent tenant should fail
         self.assertRaises(lib_exc.NotFound, self.client.delete_tenant,
                           str(uuid.uuid4().hex))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('af16f44b-a849-46cb-9f13-a751c388f739')
     def test_tenant_create_duplicate(self):
         # Tenant names should be unique
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -79,6 +85,7 @@
                           tenant_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d26b278a-6389-4702-8d6e-5980d80137e0')
     def test_create_tenant_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to create a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -86,6 +93,7 @@
                           self.non_admin_client.create_tenant, tenant_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a3ee9d7e-6920-4dd5-9321-d4b2b7f0a638')
     def test_create_tenant_request_without_token(self):
         # Create tenant request without a token should not be authorized
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -96,12 +104,14 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5a2e4ca9-b0c0-486c-9c48-64a94fba2395')
     def test_create_tenant_with_empty_name(self):
         # Tenant name should not be empty
         self.assertRaises(lib_exc.BadRequest, self.client.create_tenant,
                           name='')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('2ff18d1e-dfe3-4359-9dc3-abf582c196b9')
     def test_create_tenants_name_length_over_64(self):
         # Tenant name length should not be greater than 64 characters
         tenant_name = 'a' * 65
@@ -109,12 +119,14 @@
                           tenant_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bd20dc2a-9557-4db7-b755-f48d952ad706')
     def test_update_non_existent_tenant(self):
         # Attempt to update a non existent tenant should fail
         self.assertRaises(lib_exc.NotFound, self.client.update_tenant,
                           str(uuid.uuid4().hex))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('41704dc5-c5f7-4f79-abfa-76e6fedc570b')
     def test_tenant_update_by_unauthorized_user(self):
         # Non-administrator user should not be able to update a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -124,6 +136,7 @@
                           self.non_admin_client.update_tenant, tenant['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7a421573-72c7-4c22-a98e-ce539219c657')
     def test_tenant_update_request_without_token(self):
         # Request to update a tenant without a valid token should fail
         tenant_name = data_utils.rand_name(name='tenant-')
diff --git a/tempest/api/identity/admin/test_tenants.py b/tempest/api/identity/admin/test_tenants.py
index cfae3a1..3f1c3cd 100644
--- a/tempest/api/identity/admin/test_tenants.py
+++ b/tempest/api/identity/admin/test_tenants.py
@@ -23,6 +23,7 @@
 class TenantsTestJSON(base.BaseIdentityV2AdminTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('16c6e05c-6112-4b0e-b83f-5e43f221b6b0')
     def test_tenant_list_delete(self):
         # Create several tenants and delete them
         tenants = []
@@ -45,6 +46,7 @@
         self.assertFalse(any(found), 'Tenants failed to delete')
 
     @test.attr(type='gate')
+    @test.idempotent_id('d25e9f24-1310-4d29-b61b-d91299c21d6d')
     def test_tenant_create_with_description(self):
         # Create tenant with a description
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -65,6 +67,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('670bdddc-1cd7-41c7-b8e2-751cfb67df50')
     def test_tenant_create_enabled(self):
         # Create a tenant that is enabled
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -81,6 +84,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3be22093-b30f-499d-b772-38340e5e16fb')
     def test_tenant_create_not_enabled(self):
         # Create a tenant that is not enabled
         tenant_name = data_utils.rand_name(name='tenant-')
@@ -99,6 +103,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('781f2266-d128-47f3-8bdb-f70970add238')
     def test_tenant_update_name(self):
         # Update name attribute of a tenant
         t_name1 = data_utils.rand_name(name='tenant-')
@@ -125,6 +130,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('859fcfe1-3a03-41ef-86f9-b19a47d1cd87')
     def test_tenant_update_desc(self):
         # Update description attribute of a tenant
         t_name = data_utils.rand_name(name='tenant-')
@@ -152,6 +158,7 @@
         self.data.tenants.remove(tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('8fc8981f-f12d-4c66-9972-2bdcf2bc2e1a')
     def test_tenant_update_enable(self):
         # Update the enabled attribute of a tenant
         t_name = data_utils.rand_name(name='tenant-')
diff --git a/tempest/api/identity/admin/test_tokens.py b/tempest/api/identity/admin/test_tokens.py
index 5323fde..751f5fd 100644
--- a/tempest/api/identity/admin/test_tokens.py
+++ b/tempest/api/identity/admin/test_tokens.py
@@ -21,6 +21,7 @@
 class TokensTestJSON(base.BaseIdentityV2AdminTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('453ad4d5-e486-4b2f-be72-cffc8149e586')
     def test_create_get_delete_token(self):
         # get a token by username and password
         user_name = data_utils.rand_name(name='user-')
@@ -51,6 +52,7 @@
         self.client.delete_token(token_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('25ba82ee-8a32-4ceb-8f50-8b8c71e8765e')
     def test_rescope_token(self):
         """An unscoped token can be requested, that token can be used to
            request a scoped token.
diff --git a/tempest/api/identity/admin/test_users.py b/tempest/api/identity/admin/test_users.py
index 9159468..fc64f67 100644
--- a/tempest/api/identity/admin/test_users.py
+++ b/tempest/api/identity/admin/test_users.py
@@ -30,6 +30,7 @@
         cls.alt_email = cls.alt_user + '@testmail.tm'
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2d55a71e-da1d-4b43-9c03-d269fd93d905')
     def test_create_user(self):
         # Create a user
         self.data.setup_test_tenant()
@@ -40,6 +41,7 @@
         self.assertEqual(self.alt_user, user['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('89d9fdb8-15c2-4304-a429-48715d0af33d')
     def test_create_user_with_enabled(self):
         # Create a user with enabled : False
         self.data.setup_test_tenant()
@@ -53,6 +55,7 @@
         self.assertEqual(self.alt_email, user['email'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('39d05857-e8a5-4ed4-ba83-0b52d3ab97ee')
     def test_update_user(self):
         # Test case to check if updating of user attributes is successful.
         test_user = data_utils.rand_name('test_user_')
@@ -79,6 +82,7 @@
         self.assertEqual('false', str(updated_user['enabled']).lower())
 
     @test.attr(type='smoke')
+    @test.idempotent_id('29ed26f4-a74e-4425-9a85-fdb49fa269d2')
     def test_delete_user(self):
         # Delete a user
         test_user = data_utils.rand_name('test_user_')
@@ -89,6 +93,7 @@
         self.client.delete_user(user['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aca696c3-d645-4f45-b728-63646045beb1')
     def test_user_authentication(self):
         # Valid user's token is authenticated
         self.data.setup_test_user()
@@ -101,6 +106,7 @@
                                self.data.test_tenant)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5d1fa498-4c2d-4732-a8fe-2b054598cfdd')
     def test_authentication_request_without_token(self):
         # Request for token authentication with a valid token in header
         self.data.setup_test_user()
@@ -117,6 +123,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a149c02e-e5e0-4b89-809e-7e8faf33ccda')
     def test_get_users(self):
         # Get a list of users and find the test user
         self.data.setup_test_user()
@@ -126,6 +133,7 @@
                         "Could not find %s" % self.data.test_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6e317209-383a-4bed-9f10-075b7c82c79a')
     def test_list_users_for_tenant(self):
         # Return a list of all users for a tenant
         self.data.setup_test_tenant()
@@ -156,6 +164,7 @@
                          ', '.join(m_user for m_user in missing_users))
 
     @test.attr(type='gate')
+    @test.idempotent_id('a8b54974-40e1-41c0-b812-50fc90827971')
     def test_list_users_with_roles_for_tenant(self):
         # Return list of users on tenant when roles are assigned to users
         self.data.setup_test_user()
@@ -191,6 +200,7 @@
                          ', '.join(m_user for m_user in missing_users))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1aeb25ac-6ec5-4d8b-97cb-7ac3567a989f')
     def test_update_user_password(self):
         # Test case to check if updating of user password is successful.
         self.data.setup_test_user()
diff --git a/tempest/api/identity/admin/test_users_negative.py b/tempest/api/identity/admin/test_users_negative.py
index 99993b9..f40621b 100644
--- a/tempest/api/identity/admin/test_users_negative.py
+++ b/tempest/api/identity/admin/test_users_negative.py
@@ -31,6 +31,7 @@
         cls.alt_email = cls.alt_user + '@testmail.tm'
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('60a1f5fa-5744-4cdf-82bf-60b7de2d29a4')
     def test_create_user_by_unauthorized_user(self):
         # Non-administrator should not be authorized to create a user
         self.data.setup_test_tenant()
@@ -40,6 +41,7 @@
                           self.alt_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d80d0c2f-4514-4d1e-806d-0930dfc5a187')
     def test_create_user_with_empty_name(self):
         # User with an empty name should not be created
         self.data.setup_test_tenant()
@@ -48,6 +50,7 @@
                           self.alt_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7704b4f3-3b75-4b82-87cc-931d41c8f780')
     def test_create_user_with_name_length_over_255(self):
         # Length of user name filed should be restricted to 255 characters
         self.data.setup_test_tenant()
@@ -56,6 +59,7 @@
                           self.data.tenant['id'], self.alt_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('57ae8558-120c-4723-9308-3751474e7ecf')
     def test_create_user_with_duplicate_name(self):
         # Duplicate user should not be created
         self.data.setup_test_user()
@@ -64,6 +68,7 @@
                           self.data.tenant['id'], self.data.test_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0132cc22-7c4f-42e1-9e50-ac6aad31d59a')
     def test_create_user_for_non_existent_tenant(self):
         # Attempt to create a user in a non-existent tenant should fail
         self.assertRaises(lib_exc.NotFound, self.client.create_user,
@@ -71,6 +76,7 @@
                           self.alt_email)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('55bbb103-d1ae-437b-989b-bcdf8175c1f4')
     def test_create_user_request_without_a_token(self):
         # Request to create a user without a valid token should fail
         self.data.setup_test_tenant()
@@ -86,6 +92,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('23a2f3da-4a1a-41da-abdd-632328a861ad')
     def test_create_user_with_enabled_non_bool(self):
         # Attempt to create a user with valid enabled para should fail
         self.data.setup_test_tenant()
@@ -96,6 +103,7 @@
                           self.alt_email, enabled=3)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3d07e294-27a0-4144-b780-a2a1bf6fee19')
     def test_update_user_for_non_existent_user(self):
         # Attempt to update a user non-existent user should fail
         user_name = data_utils.rand_name('user-')
@@ -104,6 +112,7 @@
                           non_existent_id, name=user_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('3cc2a64b-83aa-4b02-88f0-d6ab737c4466')
     def test_update_user_request_without_a_token(self):
         # Request to update a user without a valid token should fail
 
@@ -118,6 +127,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('424868d5-18a7-43e1-8903-a64f95ee3aac')
     def test_update_user_by_unauthorized_user(self):
         # Non-administrator should not be authorized to update user
         self.data.setup_test_tenant()
@@ -125,6 +135,7 @@
                           self.non_admin_client.update_user, self.alt_user)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d45195d5-33ed-41b9-a452-7d0d6a00f6e9')
     def test_delete_users_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to delete a user
         self.data.setup_test_user()
@@ -133,12 +144,14 @@
                           self.data.user['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7cc82f7e-9998-4f89-abae-23df36495867')
     def test_delete_non_existent_user(self):
         # Attempt to delete a non-existent user should fail
         self.assertRaises(lib_exc.NotFound, self.client.delete_user,
                           'junk12345123')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('57fe1df8-0aa7-46c0-ae9f-c2e785c7504a')
     def test_delete_user_request_without_a_token(self):
         # Request to delete a user without a valid token should fail
 
@@ -153,6 +166,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('593a4981-f6d4-460a-99a1-57a78bf20829')
     def test_authentication_for_disabled_user(self):
         # Disabled user's token should not get authenticated
         self.data.setup_test_user()
@@ -163,6 +177,7 @@
                           self.data.test_tenant)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('440a7a8d-9328-4b7b-83e0-d717010495e4')
     def test_authentication_when_tenant_is_disabled(self):
         # User's token for a disabled tenant should not be authenticated
         self.data.setup_test_user()
@@ -173,6 +188,7 @@
                           self.data.test_tenant)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('921f1ad6-7907-40b8-853f-637e7ee52178')
     def test_authentication_with_invalid_tenant(self):
         # User's token for an invalid tenant should not be authenticated
         self.data.setup_test_user()
@@ -182,6 +198,7 @@
                           'junktenant1234')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bde9aecd-3b1c-4079-858f-beb5deaa5b5e')
     def test_authentication_with_invalid_username(self):
         # Non-existent user's token should not get authenticated
         self.data.setup_test_user()
@@ -190,6 +207,7 @@
                           self.data.test_tenant)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('d5308b33-3574-43c3-8d87-1c090c5e1eca')
     def test_authentication_with_invalid_password(self):
         # User's token with invalid password should not be authenticated
         self.data.setup_test_user()
@@ -198,6 +216,7 @@
                           self.data.test_tenant)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('284192ce-fb7c-4909-a63b-9a502e0ddd11')
     def test_get_users_by_unauthorized_user(self):
         # Non-administrator user should not be authorized to get user list
         self.data.setup_test_user()
@@ -205,6 +224,7 @@
                           self.non_admin_client.get_users)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('a73591ec-1903-4ffe-be42-282b39fefc9d')
     def test_get_users_request_without_token(self):
         # Request to get list of users without a valid token should fail
         token = self.client.auth_provider.get_token()
@@ -213,6 +233,7 @@
         self.client.auth_provider.clear_auth()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f5d39046-fc5f-425c-b29e-bac2632da28e')
     def test_list_users_with_invalid_tenant(self):
         # Should not be able to return a list of all
         # users for a non-existent tenant
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index f22ceec..6fbd544 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -51,6 +51,7 @@
         self.creds_client.delete_credential(cred_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7cd59bf9-bda4-4c72-9467-d21cab278355')
     def test_credentials_create_get_update_delete(self):
         keys = [data_utils.rand_name('Access-'),
                 data_utils.rand_name('Secret-')]
@@ -83,6 +84,7 @@
                              get_body['blob'][value2])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('13202c00-0021-42a1-88d4-81b44d448aab')
     def test_credentials_list_delete(self):
         created_cred_ids = list()
         fetched_cred_ids = list()
diff --git a/tempest/api/identity/admin/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index b7b78da..f74b30d 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -35,6 +35,7 @@
         self.client.delete_domain(domain_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d6110661-6a71-49a7-a453-b5e26640ff6d')
     def test_default_project_id(self):
         # create a domain
         dom_name = data_utils.rand_name('dom')
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 0914674..6c634b8 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -28,6 +28,7 @@
         self.client.delete_domain(domain_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8cf516ef-2114-48f1-907b-d32726c734d4')
     def test_list_domains(self):
         # Test to list domains
         domain_ids = list()
@@ -47,6 +48,7 @@
         self.assertEqual(0, len(missing_doms))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f2f5b44a-82e8-4dad-8084-0661ea3b18cf')
     def test_create_update_delete_domain(self):
         d_name = data_utils.rand_name('domain-')
         d_desc = data_utils.rand_name('domain-desc-')
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 75cb6bd..4a11c95 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -57,6 +57,7 @@
         super(EndPointsTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('c19ecf90-240e-4e23-9966-21cee3f6a618')
     def test_list_endpoints(self):
         # Get a list of endpoints
         fetched_endpoints = self.client.list_endpoints()
@@ -68,6 +69,7 @@
                          ', '.join(str(e) for e in missing_endpoints))
 
     @test.attr(type='gate')
+    @test.idempotent_id('0e2446d2-c1fd-461b-a729-b9e73e3e3b37')
     def test_create_list_delete_endpoint(self):
         region = data_utils.rand_name('region')
         url = data_utils.rand_url()
@@ -91,6 +93,7 @@
         self.assertNotIn(endpoint['id'], fetched_endpoints_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('37e8f15e-ee7c-4657-a1e7-f6b61e375eff')
     def test_update_endpoint(self):
         # Creating an endpoint so as to check update endpoint
         # with new values
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index ff450e1..06c8e77 100644
--- a/tempest/api/identity/admin/v3/test_endpoints_negative.py
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -49,6 +49,7 @@
         super(EndpointsNegativeTestJSON, cls).resource_cleanup()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ac6c137e-4d3d-448f-8c83-4f13d0942651')
     def test_create_with_enabled_False(self):
         # Enabled should be a boolean, not a string like 'False'
         interface = 'public'
@@ -59,6 +60,7 @@
                           force_enabled='False')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9c43181e-0627-484a-8c79-923e8a59598b')
     def test_create_with_enabled_True(self):
         # Enabled should be a boolean, not a string like 'True'
         interface = 'public'
@@ -83,11 +85,13 @@
                           endpoint_for_update['id'], force_enabled=enabled)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('65e41f32-5eb7-498f-a92a-a6ccacf7439a')
     def test_update_with_enabled_False(self):
         # Enabled should be a boolean, not a string like 'False'
         self._assert_update_raises_bad_request('False')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('faba3587-f066-4757-a48e-b4a3f01803bb')
     def test_update_with_enabled_True(self):
         # Enabled should be a boolean, not a string like 'True'
         self._assert_update_raises_bad_request('True')
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index d4a83e2..2c70a7c 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -21,6 +21,7 @@
 class GroupsV3TestJSON(base.BaseIdentityV3AdminTest):
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2e80343b-6c81-4ac3-88c7-452f3e9d5129')
     def test_group_create_update_get(self):
         name = data_utils.rand_name('Group')
         description = data_utils.rand_name('Description')
@@ -44,6 +45,7 @@
         self.assertEqual(new_desc, new_group['description'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1598521a-2f36-4606-8df9-30772bd51339')
     def test_group_users_add_list_delete(self):
         name = data_utils.rand_name('Group')
         group = self.client.create_group(name)
@@ -68,6 +70,7 @@
         self.assertEqual(len(group_users), 0)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('64573281-d26a-4a52-b899-503cb0f4e4ec')
     def test_list_user_groups(self):
         # create a user
         user = self.client.create_user(
@@ -88,6 +91,7 @@
         self.assertEqual(2, len(user_groups))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cc9a57a5-a9ed-4f2d-a29f-4f979a06ec71')
     def test_list_groups(self):
         # Test to list groups
         group_ids = list()
diff --git a/tempest/api/identity/admin/v3/test_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
index 24b130c..ca30b6e 100644
--- a/tempest/api/identity/admin/v3/test_list_projects.py
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -38,6 +38,7 @@
         cls.project_ids.append(cls.p2['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('1d830662-22ad-427c-8c3e-4ec854b0af44')
     def test_projects_list(self):
         # List projects
         list_projects = self.client.list_projects()
@@ -47,17 +48,20 @@
             self.assertIn(get_project, list_projects)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fab13f3c-f6a6-4b9f-829b-d32fd44fdf10')
     def test_list_projects_with_domains(self):
         # List projects with domain
         self._list_projects_with_params(
             {'domain_id': self.data.domain['id']}, 'domain_id')
 
     @test.attr(type='gate')
+    @test.idempotent_id('0fe7a334-675a-4509-b00e-1c4b95d5dae8')
     def test_list_projects_with_enabled(self):
         # List the projects with enabled
         self._list_projects_with_params({'enabled': False}, 'enabled')
 
     @test.attr(type='gate')
+    @test.idempotent_id('fa178524-4e6d-4925-907c-7ab9f42c7e26')
     def test_list_projects_with_name(self):
         # List projects with name
         self._list_projects_with_params({'name': self.p1_name}, 'name')
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index a6c3309..1407f38 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -51,6 +51,7 @@
         cls.data.v3_users.append(cls.non_domain_enabled_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('08f9aabb-dcfe-41d0-8172-82b5fa0bd73d')
     def test_list_user_domains(self):
         # List users with domain
         params = {'domain_id': self.data.domain['id']}
@@ -59,6 +60,7 @@
                                      self.non_domain_enabled_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('bff8bf2f-9408-4ef5-b63a-753c8c2124eb')
     def test_list_users_with_not_enabled(self):
         # List the users with not enabled
         params = {'enabled': False}
@@ -67,6 +69,7 @@
                                      self.domain_enabled_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('c285bb37-7325-4c02-bff3-3da5d946d683')
     def test_list_users_with_name(self):
         # List users with name
         params = {'name': self.domain_enabled_user['name']}
@@ -75,6 +78,7 @@
                                      self.non_domain_enabled_user)
 
     @test.attr(type='gate')
+    @test.idempotent_id('b30d4651-a2ea-4666-8551-0c0e49692635')
     def test_list_users(self):
         # List users
         body = self.client.get_users()
@@ -86,6 +90,7 @@
                          ', '.join(m_user for m_user in missing_users))
 
     @test.attr(type='gate')
+    @test.idempotent_id('b4baa3ae-ac00-4b4e-9e27-80deaad7771f')
     def test_get_user(self):
         # Get a user detail
         user = self.client.get_user(self.data.v3_users[0]['id'])
diff --git a/tempest/api/identity/admin/v3/test_policies.py b/tempest/api/identity/admin/v3/test_policies.py
index 0d5dc47..900c26e 100644
--- a/tempest/api/identity/admin/v3/test_policies.py
+++ b/tempest/api/identity/admin/v3/test_policies.py
@@ -24,6 +24,7 @@
         self.policy_client.delete_policy(policy_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1a0ad286-2d06-4123-ab0d-728893a76201')
     def test_list_policies(self):
         # Test to list policies
         policy_ids = list()
@@ -44,6 +45,7 @@
         self.assertEqual(0, len(missing_pols))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e544703a-2f03-4cf2-9b0f-350782fdb0d3')
     def test_create_update_delete_policy(self):
         # Test to update policy
         blob = data_utils.rand_name('BlobName-')
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index d879c7a..052cf0e 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -21,6 +21,7 @@
 class ProjectsTestJSON(base.BaseIdentityV3AdminTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('0ecf465c-0dc4-4532-ab53-91ffeb74d12d')
     def test_project_create_with_description(self):
         # Create project with a description
         project_name = data_utils.rand_name('project-')
@@ -38,6 +39,7 @@
                          'to be set')
 
     @test.attr(type='gate')
+    @test.idempotent_id('5f50fe07-8166-430b-a882-3b2ee0abe26f')
     def test_project_create_with_domain(self):
         # Create project with a domain
         self.data.setup_test_domain()
@@ -53,6 +55,7 @@
         self.assertEqual(self.data.domain['id'], body['domain_id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('1f66dc76-50cc-4741-a200-af984509e480')
     def test_project_create_enabled(self):
         # Create a project that is enabled
         project_name = data_utils.rand_name('project-')
@@ -67,6 +70,7 @@
         self.assertTrue(en2, 'Enable should be True in lookup')
 
     @test.attr(type='gate')
+    @test.idempotent_id('78f96a9c-e0e0-4ee6-a3ba-fbf6dfd03207')
     def test_project_create_not_enabled(self):
         # Create a project that is not enabled
         project_name = data_utils.rand_name('project-')
@@ -82,6 +86,7 @@
                          'Enable should be False in lookup')
 
     @test.attr(type='gate')
+    @test.idempotent_id('f608f368-048c-496b-ad63-d286c26dab6b')
     def test_project_update_name(self):
         # Update name attribute of a project
         p_name1 = data_utils.rand_name('project-')
@@ -103,6 +108,7 @@
         self.assertEqual(resp2_name, resp3_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f138b715-255e-4a7d-871d-351e1ef2e153')
     def test_project_update_desc(self):
         # Update description attribute of a project
         p_name = data_utils.rand_name('project-')
@@ -126,6 +132,7 @@
         self.assertEqual(resp2_desc, resp3_desc)
 
     @test.attr(type='gate')
+    @test.idempotent_id('b6b25683-c97f-474d-a595-55d410b68100')
     def test_project_update_enable(self):
         # Update the enabled attribute of a project
         p_name = data_utils.rand_name('project-')
@@ -149,6 +156,7 @@
         self.assertEqual(resp2_en, resp3_en)
 
     @test.attr(type='gate')
+    @test.idempotent_id('59398d4a-5dc5-4f86-9a4c-c26cc804d6c6')
     def test_associate_user_to_project(self):
         # Associate a user to a project
         # Create a Project
diff --git a/tempest/api/identity/admin/v3/test_projects_negative.py b/tempest/api/identity/admin/v3/test_projects_negative.py
index a194198..bc92900 100644
--- a/tempest/api/identity/admin/v3/test_projects_negative.py
+++ b/tempest/api/identity/admin/v3/test_projects_negative.py
@@ -23,12 +23,14 @@
 class ProjectsNegativeTestJSON(base.BaseIdentityV3AdminTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('24c49279-45dd-4155-887a-cb738c2385aa')
     def test_list_projects_by_unauthorized_user(self):
         # Non-admin user should not be able to list projects
         self.assertRaises(lib_exc.Unauthorized,
                           self.non_admin_client.list_projects)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('874c3e84-d174-4348-a16b-8c01f599561b')
     def test_project_create_duplicate(self):
         # Project names should be unique
         project_name = data_utils.rand_name('project-dup-')
@@ -39,6 +41,7 @@
             lib_exc.Conflict, self.client.create_project, project_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8fba9de2-3e1f-4e77-812a-60cb68f8df13')
     def test_create_project_by_unauthorized_user(self):
         # Non-admin user should not be authorized to create a project
         project_name = data_utils.rand_name('project-')
@@ -47,12 +50,14 @@
             project_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7828db17-95e5-475b-9432-9a51b4aa79a9')
     def test_create_project_with_empty_name(self):
         # Project name should not be empty
         self.assertRaises(lib_exc.BadRequest, self.client.create_project,
                           name='')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('502b6ceb-b0c8-4422-bf53-f08fdb21e2f0')
     def test_create_projects_name_length_over_64(self):
         # Project name length should not be greater than 64 characters
         project_name = 'a' * 65
@@ -60,6 +65,7 @@
                           project_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8d68c012-89e0-4394-8d6b-ccd7196def97')
     def test_project_delete_by_unauthorized_user(self):
         # Non-admin user should not be able to delete a project
         project_name = data_utils.rand_name('project-')
@@ -70,6 +76,7 @@
             project['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7965b581-60c1-43b7-8169-95d4ab7fc6fb')
     def test_delete_non_existent_project(self):
         # Attempt to delete a non existent project should fail
         self.assertRaises(lib_exc.NotFound, self.client.delete_project,
diff --git a/tempest/api/identity/admin/v3/test_regions.py b/tempest/api/identity/admin/v3/test_regions.py
index 2ea7107..bf3c12e 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -48,6 +48,7 @@
                           self.client.get_region, region_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('56186092-82e4-43f2-b954-91013218ba42')
     def test_create_update_get_delete_region(self):
         r_description = data_utils.rand_name('description-')
         region = self.client.create_region(
@@ -72,6 +73,7 @@
                          region['parent_region_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2c12c5b5-efcf-4aa5-90c5-bff1ab0cdbe2')
     def test_create_region_with_specific_id(self):
         # Create a region with a specific id
         r_region_id = data_utils.rand_uuid()
@@ -84,6 +86,7 @@
         self.assertEqual(r_description, region['description'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d180bf99-544a-445c-ad0d-0c0d27663796')
     def test_list_regions(self):
         # Get a list of regions
         fetched_regions = self.client.list_regions()
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 747911b..24da22a 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -66,6 +66,7 @@
         self.assertIn(role_id, fetched_role_ids)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('18afc6c0-46cf-4911-824e-9989cc056c3a')
     def test_role_create_update_get_list(self):
         r_name = data_utils.rand_name('Role-')
         role = self.client.create_role(r_name)
@@ -88,6 +89,7 @@
         self.assertIn(role['id'], [r['id'] for r in roles])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c6b80012-fe4a-498b-9ce8-eb391c05169f')
     def test_grant_list_revoke_role_to_user_on_project(self):
         self.client.assign_user_role_on_project(
             self.project['id'], self.user_body['id'], self.role['id'])
@@ -105,6 +107,7 @@
             self.project['id'], self.user_body['id'], self.role['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6c9a2940-3625-43a3-ac02-5dcec62ef3bd')
     def test_grant_list_revoke_role_to_user_on_domain(self):
         self.client.assign_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
@@ -122,6 +125,7 @@
             self.domain['id'], self.user_body['id'], self.role['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cbf11737-1904-4690-9613-97bcbb3df1c4')
     def test_grant_list_revoke_role_to_group_on_project(self):
         # Grant role to group on project
         self.client.assign_group_role_on_project(
@@ -152,6 +156,7 @@
             self.project['id'], self.group_body['id'], self.role['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4bf8a70b-e785-413a-ad53-9f91ce02faa7')
     def test_grant_list_revoke_role_to_group_on_domain(self):
         self.client.assign_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
@@ -169,6 +174,7 @@
             self.domain['id'], self.group_body['id'], self.role['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('f5654bcc-08c4-4f71-88fe-05d64e06de94')
     def test_list_roles(self):
         # Return a list of all roles
         body = self.client.list_roles()
diff --git a/tempest/api/identity/admin/v3/test_services.py b/tempest/api/identity/admin/v3/test_services.py
index 13e6d66..bf5cc3e 100644
--- a/tempest/api/identity/admin/v3/test_services.py
+++ b/tempest/api/identity/admin/v3/test_services.py
@@ -30,6 +30,7 @@
                           service_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5193aad5-bcb7-411d-85b0-b3b61b96ef06')
     def test_create_update_get_service(self):
         # Creating a Service
         name = data_utils.rand_name('service')
@@ -62,6 +63,7 @@
         self.assertDictContainsSubset(update_service, fetched_service)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d1dcb1a1-2b6b-4da8-bbb8-5532ef6e8269')
     def test_create_service_without_description(self):
         # Create a service only with name and type
         name = data_utils.rand_name('service')
@@ -74,6 +76,7 @@
         self.assertDictContainsSubset(expected_data, service)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e55908e8-360e-439e-8719-c3230a3e179e')
     def test_list_services(self):
         # Create, List, Verify and Delete Services
         service_ids = list()
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 919eab9..47f9dbd 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -23,6 +23,7 @@
 class TokensV3TestJSON(base.BaseIdentityV3AdminTest):
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0f9f5a5f-d5cd-4a86-8a5b-c5ded151f212')
     def test_tokens(self):
         # Valid user's token is authenticated
         # Create a User
@@ -48,6 +49,7 @@
                           subject_token)
 
     @test.attr(type='gate')
+    @test.idempotent_id('565fa210-1da1-4563-999b-f7b5b67cf112')
     def test_rescope_token(self):
         """Rescope a token.
 
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index e73ad1d..4b5075c 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -188,6 +188,7 @@
         self.addCleanup(self.cleanup_user_and_roles)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5a0a91a4-baef-4a14-baba-59bf4d7fcace')
     def test_trust_impersonate(self):
         # Test case to check we can create, get and delete a trust
         # updates are not supported for trusts
@@ -200,6 +201,7 @@
         self.check_trust_roles()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ed2a8779-a7ac-49dc-afd7-30f32f936ed2')
     def test_trust_noimpersonate(self):
         # Test case to check we can create, get and delete a trust
         # with impersonation=False
@@ -212,6 +214,7 @@
         self.check_trust_roles()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0ed14b66-cefd-4b5c-a964-65759453e292')
     def test_trust_expire(self):
         # Test case to check we can create, get and delete a trust
         # with an expiry specified
@@ -234,6 +237,7 @@
         self.check_trust_roles()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3e48f95d-e660-4fa9-85e0-5a3d85594384')
     def test_trust_expire_invalid(self):
         # Test case to check we can check an invlaid expiry time
         # is rejected with the correct error
@@ -244,6 +248,7 @@
                           expires=expires_str)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6268b345-87ca-47c0-9ce3-37792b43403a')
     def test_get_trusts_query(self):
         self.create_trust()
         trusts_get = self.trustor_client.get_trusts(
@@ -252,6 +257,7 @@
         self.validate_trust(trusts_get[0], summary=True)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4773ebd5-ecbf-4255-b8d8-b63e6f72b65d')
     def test_get_trusts_all(self):
         self.create_trust()
         trusts_get = self.client.get_trusts()
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 2481d9d..8120fa7 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -21,6 +21,7 @@
 class UsersV3TestJSON(base.BaseIdentityV3AdminTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('b537d090-afb9-4519-b95d-270b0708e87e')
     def test_user_update(self):
         # Test case to check if updating of user attributes is successful.
         # Creating first user
@@ -64,6 +65,7 @@
         self.assertEqual('false', str(new_user_get['enabled']).lower())
 
     @test.attr(type='gate')
+    @test.idempotent_id('2d223a0e-e457-4a70-9fb1-febe027a0ff9')
     def test_update_user_password(self):
         # Creating User to check password updation
         u_name = data_utils.rand_name('user')
@@ -85,6 +87,7 @@
         self.assertEqual(token_details['user']['name'], u_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a831e70c-e35b-430b-92ed-81ebbc5437b8')
     def test_list_user_projects(self):
         # List the projects that a user has access upon
         assigned_project_ids = list()
@@ -138,6 +141,7 @@
                                    in missing_projects))
 
     @test.attr(type='gate')
+    @test.idempotent_id('c10dcd90-461d-4b16-8e23-4eb836c00644')
     def test_get_user(self):
         # Get a user detail
         self.data.setup_test_v3_user()
diff --git a/tempest/api/identity/test_extension.py b/tempest/api/identity/test_extension.py
index bbc4c13..f4a5c86 100644
--- a/tempest/api/identity/test_extension.py
+++ b/tempest/api/identity/test_extension.py
@@ -20,6 +20,7 @@
 class ExtensionTestJSON(base.BaseIdentityV2AdminTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('85f3f661-f54c-4d48-b563-72ae952b9383')
     def test_list_extensions(self):
         # List all the extensions
         body = self.non_admin_client.list_extensions()
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index d18a274..07a0df8 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -20,6 +20,7 @@
 class ImageMembersTest(base.BaseV1ImageMembersTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('1d6ef640-3a20-4c84-8710-d95828fdb6ad')
     def test_add_image_member(self):
         image = self._create_image()
         self.client.add_member(self.alt_tenant_id, image)
@@ -31,6 +32,7 @@
         self.alt_img_cli.get_image(image)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6a5328a5-80e8-4b82-bd32-6c061f128da9')
     def test_get_shared_images(self):
         image = self._create_image()
         self.client.add_member(self.alt_tenant_id, image)
@@ -43,6 +45,7 @@
         self.assertIn(image, images)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a76a3191-8948-4b44-a9d6-4053e5f2b138')
     def test_remove_member(self):
         image_id = self._create_image()
         self.client.add_member(self.alt_tenant_id, 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 1622791..c276d25 100644
--- a/tempest/api/image/v1/test_image_members_negative.py
+++ b/tempest/api/image/v1/test_image_members_negative.py
@@ -22,6 +22,7 @@
 class ImageMembersNegativeTest(base.BaseV1ImageMembersTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.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()
@@ -29,6 +30,7 @@
                           self.alt_tenant_id, non_exist_image)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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()
@@ -36,6 +38,7 @@
                           self.alt_tenant_id, non_exist_image)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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()
@@ -44,6 +47,7 @@
                           non_exist_tenant, image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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 b9f12e6..a268128 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -27,6 +27,7 @@
     """Here we test the registration and creation of images."""
 
     @test.attr(type='gate')
+    @test.idempotent_id('3027f8e6-3492-4a11-8575-c3293017af4d')
     def test_register_then_upload(self):
         # Register, then upload an image
         properties = {'prop1': 'val1'}
@@ -50,6 +51,7 @@
         self.assertEqual(1024, body.get('size'))
 
     @test.attr(type='gate')
+    @test.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
     def test_register_remote_image(self):
         # Register a new remote image
         body = self.create_image(name='New Remote Image',
@@ -67,6 +69,7 @@
         self.assertEqual(properties['key2'], 'value2')
 
     @test.attr(type='gate')
+    @test.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
     def test_register_http_image(self):
         body = self.create_image(name='New Http Image',
                                  container_format='bare',
@@ -80,6 +83,7 @@
         self.client.get_image(image_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
     def test_register_image_with_min_ram(self):
         # Register an image with min ram
         properties = {'prop1': 'val1'}
@@ -166,6 +170,7 @@
         return image_id
 
     @test.attr(type='gate')
+    @test.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.image_list()
@@ -174,6 +179,7 @@
             self.assertIn(image_id, image_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
     def test_index_disk_format(self):
         images_list = self.client.image_list(disk_format='ami')
         for image in images_list:
@@ -183,6 +189,7 @@
         self.assertFalse(self.created_set - self.ami_set <= result_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
     def test_index_container_format(self):
         images_list = self.client.image_list(container_format='bare')
         for image in images_list:
@@ -192,6 +199,7 @@
         self.assertFalse(self.created_set - self.bare_set <= result_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
     def test_index_max_size(self):
         images_list = self.client.image_list(size_max=42)
         for image in images_list:
@@ -201,6 +209,7 @@
         self.assertFalse(self.created_set - self.size42_set <= result_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('6ffc16d0-4cbf-4401-95c8-4ac63eac34d8')
     def test_index_min_size(self):
         images_list = self.client.image_list(size_min=142)
         for image in images_list:
@@ -210,6 +219,7 @@
         self.assertFalse(self.size42_set <= result_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e5dc26d9-9aa2-48dd-bda5-748e1445da98')
     def test_index_status_active_detail(self):
         images_list = self.client.image_list_detail(status='active',
                                                     sort_key='size',
@@ -222,6 +232,7 @@
             self.assertEqual(image['status'], 'active')
 
     @test.attr(type='gate')
+    @test.idempotent_id('097af10a-bae8-4342-bff4-edf89969ed2a')
     def test_index_name(self):
         images_list = self.client.image_list_detail(
             name='New Remote Image dup')
@@ -256,6 +267,7 @@
         return image_id
 
     @test.attr(type='gate')
+    @test.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_metadata = self.client.get_image_meta(self.image_id)
@@ -263,6 +275,7 @@
         self.assertEqual(expected, resp_metadata['properties'])
 
     @test.attr(type='gate')
+    @test.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 698bac0..85b9435 100644
--- a/tempest/api/image/v1/test_images_negative.py
+++ b/tempest/api/image/v1/test_images_negative.py
@@ -23,23 +23,27 @@
     """Here are negative tests for the deletion and creation of images."""
 
     @test.attr(type=['negative', 'gate'])
+    @test.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,
                           'test', 'wrong', 'vhd')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('993face5-921d-4e84-aabf-c1bba4234a67')
     def test_register_with_invalid_disk_format(self):
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           'test', 'bare', 'wrong')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bb016f15-0820-4f27-a92d-09b2f67d2488')
     def test_delete_image_with_invalid_image_id(self):
         # An image should not be deleted with invalid image id
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           '!@$%^&*()')
 
     @test.attr(type=['negative', 'gate'])
+    @test.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
 
@@ -48,11 +52,13 @@
                           non_existent_image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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', 'gate'])
+    @test.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
         image_id = '11a22b9-120q-5555-cc11-00ab112223gj'
@@ -60,11 +66,13 @@
                           image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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', 'gate'])
+    @test.idempotent_id('a4a448ab-3db2-4d2d-b9b2-6a1271241dfe')
     def test_delete_image_id_is_over_35_character_limit(self):
         # Return an error while trying to delete image with id over limit
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 6b654ca..a4f5ae3 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -28,6 +28,7 @@
     """
 
     @test.attr(type='gate')
+    @test.idempotent_id('139b765e-7f3d-4b3d-8b37-3ca3876ee318')
     def test_register_upload_get_image_file(self):
 
         """
@@ -69,6 +70,7 @@
         self.assertEqual(file_content, body.data)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f848bb94-1c6e-45a4-8726-39e3a5b23535')
     def test_delete_image(self):
         # Deletes an image by image_id
 
@@ -90,6 +92,7 @@
         self.assertNotIn(image_id, images_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('f66891a7-a35c-41a8-b590-a065c2a1caa6')
     def test_update_image(self):
         # Updates an image by image_id
 
@@ -168,6 +171,7 @@
                 self.assertEqual(params[key], image[key], msg)
 
     @test.attr(type='gate')
+    @test.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
     def test_index_no_params(self):
         # Simple test to see all fixture images returned
         images_list = self.client.image_list()
@@ -177,24 +181,28 @@
             self.assertIn(image, image_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e')
     def test_list_images_param_container_format(self):
         # Test to get all images with container_format='bare'
         params = {"container_format": "bare"}
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.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.attr(type='gate')
+    @test.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.attr(type='gate')
+    @test.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[1]
@@ -205,6 +213,7 @@
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.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[1]
@@ -222,12 +231,14 @@
                             "Failed to get images by size_min and size_max")
 
     @test.attr(type='gate')
+    @test.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.attr(type='gate')
+    @test.idempotent_id('e914a891-3cc8-4b40-ad32-e0a39ffbddbb')
     def test_list_images_param_limit(self):
         # Test to get images by limit
         params = {"limit": 2}
@@ -237,6 +248,7 @@
                          "Failed to get images by limit")
 
     @test.attr(type='gate')
+    @test.idempotent_id('622b925c-479f-4736-860d-adeaf13bc371')
     def test_get_image_schema(self):
         # Test to get image schema
         schema = "image"
@@ -244,6 +256,7 @@
         self.assertEqual("image", body['name'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('25c8d7b2-df21-460f-87ac-93130bcdc684')
     def test_get_images_schema(self):
         # Test to get images schema
         schema = "images"
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index 956829e..bbe4ce8 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -17,6 +17,7 @@
 class ImagesMemberTest(base.BaseV2MemberImageTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('5934c6ea-27dc-4d6e-9421-eeb5e045494a')
     def test_image_share_accept(self):
         image_id = self._create_image()
         member = self.os_img_client.add_member(image_id,
@@ -38,6 +39,7 @@
         self.assertEqual(member['status'], 'accepted')
 
     @test.attr(type='gate')
+    @test.idempotent_id('d9e83e5f-3524-4b38-a900-22abcb26e90e')
     def test_image_share_reject(self):
         image_id = self._create_image()
         member = self.os_img_client.add_member(image_id,
@@ -52,6 +54,7 @@
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
 
     @test.attr(type='gate')
+    @test.idempotent_id('a6ee18b9-4378-465e-9ad9-9a6de58a3287')
     def test_get_image_member(self):
         image_id = self._create_image()
         self.os_img_client.add_member(image_id,
@@ -68,6 +71,7 @@
         self.assertEqual('accepted', member['status'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('72989bc7-2268-48ed-af22-8821e835c914')
     def test_remove_image_member(self):
         image_id = self._create_image()
         self.os_img_client.add_member(image_id,
@@ -81,11 +85,13 @@
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
 
     @test.attr(type='gate')
+    @test.idempotent_id('634dcc3f-f6e2-4409-b8fd-354a0bb25d83')
     def test_get_image_member_schema(self):
         body = self.os_img_client.get_schema("member")
         self.assertEqual("member", body['name'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('6ae916ef-1052-4e11-8d36-b3ae14853cbb')
     def test_get_image_members_schema(self):
         body = self.os_img_client.get_schema("members")
         self.assertEqual("members", body['name'])
diff --git a/tempest/api/image/v2/test_images_member_negative.py b/tempest/api/image/v2/test_images_member_negative.py
index 068a6e5..a0c59ff 100644
--- a/tempest/api/image/v2/test_images_member_negative.py
+++ b/tempest/api/image/v2/test_images_member_negative.py
@@ -19,6 +19,7 @@
 class ImagesMemberNegativeTest(base.BaseV2MemberImageTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('b79efb37-820d-4cf0-b54c-308b00cf842c')
     def test_image_share_invalid_status(self):
         image_id = self._create_image()
         member = self.os_img_client.add_member(image_id,
@@ -29,6 +30,7 @@
                           image_id, self.alt_tenant_id, 'notavalidstatus')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('27002f74-109e-4a37-acd0-f91cd4597967')
     def test_image_share_owner_cannot_accept(self):
         image_id = self._create_image()
         member = self.os_img_client.add_member(image_id,
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index 9f0ad2d..23d32f4 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -37,6 +37,7 @@
      """
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('668743d5-08ad-4480-b2b8-15da34f81d9f')
     def test_get_non_existent_image(self):
         # get the non-existent image
         non_existent_id = str(uuid.uuid4())
@@ -44,12 +45,14 @@
                           non_existent_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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.get_image, image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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,6 +71,7 @@
                           image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('6fe40f1c-57bd-4918-89cc-8500f850f3de')
     def test_delete_non_existing_image(self):
         # delete non-existent image
         non_existent_image_id = str(uuid.uuid4())
@@ -75,6 +79,7 @@
                           non_existent_image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('32248db1-ab88-4821-9604-c7c369f1f88c')
     def test_delete_image_null_id(self):
         # delete image with image_id=NULL
         image_id = ""
@@ -82,12 +87,14 @@
                           image_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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,
                           'test', 'wrong', 'vhd')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('70c6040c-5a97-4111-9e13-e73665264ce1')
     def test_register_with_invalid_disk_format(self):
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           'test', 'bare', 'wrong')
diff --git a/tempest/api/image/v2/test_images_tags.py b/tempest/api/image/v2/test_images_tags.py
index 4686de2..350ede3 100644
--- a/tempest/api/image/v2/test_images_tags.py
+++ b/tempest/api/image/v2/test_images_tags.py
@@ -20,6 +20,7 @@
 class ImagesTagsTest(base.BaseV2ImageTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('10407036-6059-4f95-a2cd-cbbbee7ed329')
     def test_update_delete_tags_for_image(self):
         body = 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 5b18862..bbe0431 100644
--- a/tempest/api/image/v2/test_images_tags_negative.py
+++ b/tempest/api/image/v2/test_images_tags_negative.py
@@ -24,6 +24,7 @@
 class ImagesTagsNegativeTest(base.BaseV2ImageTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.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-')
@@ -32,6 +33,7 @@
                           non_exist_image, tag)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('39c023a2-325a-433a-9eea-649bf1414b19')
     def test_delete_non_existing_tag(self):
         # Delete non existing tag.
         body = self.create_image(container_format='bare',
diff --git a/tempest/api/messaging/test_claims.py b/tempest/api/messaging/test_claims.py
index c9064b0..ebaa283 100644
--- a/tempest/api/messaging/test_claims.py
+++ b/tempest/api/messaging/test_claims.py
@@ -55,6 +55,7 @@
         return resp, body
 
     @test.attr(type='smoke')
+    @test.idempotent_id('936cb1ca-b7af-44dd-a752-805e8c98156f')
     def test_post_claim(self):
         _, body = self._post_and_claim_messages(queue_name=self.queue_name)
         claimed_message_uri = body[0]['href']
@@ -68,6 +69,7 @@
 
     @decorators.skip_because(bug="1331517")
     @test.attr(type='smoke')
+    @test.idempotent_id('84e491f4-68c6-451f-9846-b8f868eb27c5')
     def test_query_claim(self):
         # Post a Claim
         resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
@@ -82,6 +84,7 @@
 
     @decorators.skip_because(bug="1328111")
     @test.attr(type='smoke')
+    @test.idempotent_id('420ef0c5-9bd6-4b82-b06d-d9da330fefd3')
     def test_update_claim(self):
         # Post a Claim
         resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
@@ -105,6 +108,7 @@
         self.client.delete_messages(claimed_message_uri)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fd4c7921-cb3f-4ed8-9ac8-e8f1e74c44aa')
     def test_release_claim(self):
         # Post a Claim
         resp, body = self._post_and_claim_messages(queue_name=self.queue_name)
diff --git a/tempest/api/messaging/test_messages.py b/tempest/api/messaging/test_messages.py
index dca95fc..12a3df5 100644
--- a/tempest/api/messaging/test_messages.py
+++ b/tempest/api/messaging/test_messages.py
@@ -41,6 +41,7 @@
         return resp, body
 
     @test.attr(type='smoke')
+    @test.idempotent_id('93867172-a414-4eb3-a639-96e943c516b4')
     def test_post_messages(self):
         # Post Messages
         resp, _ = self._post_messages()
@@ -53,6 +54,7 @@
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c967d59a-e919-41cb-994b-1c4300452c80')
     def test_list_messages(self):
         # Post Messages
         self._post_messages()
@@ -64,6 +66,7 @@
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2a68e3de-24df-47c3-9039-ec4156656bf8')
     def test_get_message(self):
         # Post Messages
         _, body = self._post_messages()
@@ -76,6 +79,7 @@
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c4b0a30b-efda-4b87-a395-0c43140df74d')
     def test_get_multiple_messages(self):
         # Post Messages
         resp, _ = self._post_messages()
@@ -88,6 +92,7 @@
         self.assertEqual('200', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fc0fca47-dd8b-4ecc-8522-d9c191f9bc9f')
     def test_delete_single_message(self):
         # Post Messages
         _, body = self._post_messages()
@@ -103,6 +108,7 @@
         self.assertEqual('204', resp['status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('00cca069-5c8f-4b42-bff1-c577da2a4546')
     def test_delete_multiple_messages(self):
         # Post Messages
         resp, _ = self._post_messages()
diff --git a/tempest/api/messaging/test_queues.py b/tempest/api/messaging/test_queues.py
index 24656bf..5d9a7c7 100644
--- a/tempest/api/messaging/test_queues.py
+++ b/tempest/api/messaging/test_queues.py
@@ -30,6 +30,7 @@
 class TestQueues(base.BaseMessagingTest):
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9f1c4c72-80c5-4dac-acf3-188cef42e36c')
     def test_create_delete_queue(self):
         # Create & Delete Queue
         queue_name = data_utils.rand_name('test-')
@@ -60,18 +61,21 @@
             cls.client.create_queue(queue_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ccd3d69e-f156-4c5f-8a12-b4f24bee44e1')
     def test_check_queue_existence(self):
         # Checking Queue Existence
         for queue_name in self.queues:
             self.check_queue_exists(queue_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e27634d8-9c8f-47d8-a677-655c47658d3e')
     def test_check_queue_head(self):
         # Checking Queue Existence by calling HEAD
         for queue_name in self.queues:
             self.check_queue_exists_head(queue_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0a0feeca-7768-4303-806d-82bbbb796ad3')
     def test_list_queues(self):
         # Listing queues
         _, body = self.list_queues()
@@ -80,6 +84,7 @@
             self.assertIn(item['name'], self.queues)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8fb66602-077d-49d6-ae1a-5f2091739178')
     def test_get_queue_stats(self):
         # Retrieve random queue
         queue_name = self.queues[data_utils.rand_int_id(0,
@@ -93,6 +98,7 @@
             self.assertNotIn(element, msgs)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0e2441e6-6593-4bdb-a3c0-20e66eeb3fff')
     def test_set_and_get_queue_metadata(self):
         # Retrieve random queue
         queue_name = self.queues[data_utils.rand_int_id(0,
diff --git a/tempest/api/network/admin/test_agent_management.py b/tempest/api/network/admin/test_agent_management.py
index 20948cc..d5454ec 100644
--- a/tempest/api/network/admin/test_agent_management.py
+++ b/tempest/api/network/admin/test_agent_management.py
@@ -30,6 +30,7 @@
         cls.agent = agents[0]
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9c80f04d-11f3-44a4-8738-ed2f879b0ff4')
     def test_list_agent(self):
         body = self.admin_client.list_agents()
         agents = body['agents']
@@ -42,17 +43,20 @@
         self.assertIn(self.agent, agents)
 
     @test.attr(type=['smoke'])
+    @test.idempotent_id('e335be47-b9a1-46fd-be30-0874c0b751e6')
     def test_list_agents_non_admin(self):
         body = self.client.list_agents()
         self.assertEqual(len(body["agents"]), 0)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('869bc8e8-0fda-4a30-9b71-f8a7cf58ca9f')
     def test_show_agent(self):
         body = self.admin_client.show_agent(self.agent['id'])
         agent = body['agent']
         self.assertEqual(agent['id'], self.agent['id'])
 
     @test.attr(type='smoke')
+    @test.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
@@ -64,6 +68,7 @@
         self.assertEqual(origin_status, updated_status)
 
     @test.attr(type='smoke')
+    @test.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 4eb6b87..26f5e7a 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -32,11 +32,13 @@
         cls.port = cls.create_port(cls.network)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
     def test_list_dhcp_agent_hosting_network(self):
         self.admin_client.list_dhcp_agent_hosting_network(
             self.network['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('30c48f98-e45d-4ffb-841c-b8aad57c7587')
     def test_list_networks_hosted_by_one_dhcp(self):
         body = self.admin_client.list_dhcp_agent_hosting_network(
             self.network['id'])
@@ -56,6 +58,7 @@
         return network_id in network_ids
 
     @test.attr(type='smoke')
+    @test.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.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 6e24f8e..20b4e31 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -12,6 +12,7 @@
 
 from tempest.api.network import base
 from tempest.common.utils import data_utils
+from tempest import test
 
 
 class ExternalNetworksTestJSON(base.BaseAdminNetworkTest):
@@ -30,6 +31,7 @@
         self.addCleanup(self.admin_client.delete_network, network['id'])
         return network
 
+    @test.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
@@ -38,6 +40,7 @@
         self.assertIsNotNone(ext_network['id'])
         self.assertTrue(ext_network['router:external'])
 
+    @test.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
@@ -50,6 +53,7 @@
         # Verify that router:external parameter was updated
         self.assertTrue(updated_network['router:external'])
 
+    @test.idempotent_id('39be4c9b-a57e-4ff9-b7c7-b218e209dfcc')
     def test_list_external_networks(self):
         # Create external_net
         external_network = self._create_network()
@@ -66,6 +70,7 @@
             elif net['id'] == external_network['id']:
                 self.assertTrue(net['router:external'])
 
+    @test.idempotent_id('2ac50ab2-7ebd-4e27-b3ce-a9e399faaea2')
     def test_show_external_networks_attribute(self):
         # Create external_net
         external_network = self._create_network()
@@ -83,6 +88,7 @@
         self.assertEqual(self.network['id'], show_net['id'])
         self.assertFalse(show_net['router:external'])
 
+    @test.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 aa8dd9a..c2fa0dd 100644
--- a/tempest/api/network/admin/test_external_networks_negative.py
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -25,6 +25,7 @@
 class ExternalNetworksAdminNegativeTestJSON(base.BaseAdminNetworkTest):
 
     @test.attr(type=['negative'])
+    @test.idempotent_id('d402ae6c-0be0-4d8e-833b-a738895d98d0')
     def test_create_port_with_precreated_floatingip_as_fixed_ip(self):
         """
         External networks can be used to create both floating-ip as well
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 e7d4c06..a3a9977 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -41,6 +41,7 @@
         cls.port = cls.create_port(cls.network)
 
     @test.attr(type='smoke')
+    @test.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_client.create_floatingip(
@@ -72,6 +73,7 @@
         self.assertNotIn(floating_ip_alt['id'], floating_ip_ids)
 
     @test.attr(type='smoke')
+    @test.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_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 05a8e35..e6fa0a6 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -50,10 +50,12 @@
             raise cls.skipException(msg)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b7ce6e89-e837-4ded-9b78-9ed3c9c6a45a')
     def test_list_routers_on_l3_agent(self):
         self.admin_client.list_routers_on_l3_agent(self.agent['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9464e5e7-8625-49c3-8fd1-89c52be59d66')
     def test_add_list_remove_router_on_l3_agent(self):
         l3_agent_ids = list()
         name = data_utils.rand_name('router1-')
diff --git a/tempest/api/network/admin/test_lbaas_agent_scheduler.py b/tempest/api/network/admin/test_lbaas_agent_scheduler.py
index 8cfd5c2..c178fc0 100644
--- a/tempest/api/network/admin/test_lbaas_agent_scheduler.py
+++ b/tempest/api/network/admin/test_lbaas_agent_scheduler.py
@@ -46,6 +46,7 @@
                                    "HTTP", cls.subnet)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e5ea8b15-4f44-4350-963c-e0fcb533ee79')
     def test_list_pools_on_lbaas_agent(self):
         found = False
         body = self.admin_client.list_agents(
@@ -64,6 +65,7 @@
         self.assertTrue(found, msg)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e2745593-fd79-4b98-a262-575fd7865796')
     def test_show_lbaas_agent_hosting_pool(self):
         body = self.admin_client.show_lbaas_agent_hosting_pool(
             self.pool['id'])
diff --git a/tempest/api/network/admin/test_load_balancer_admin_actions.py b/tempest/api/network/admin/test_load_balancer_admin_actions.py
index 2537b28..931f079 100644
--- a/tempest/api/network/admin/test_load_balancer_admin_actions.py
+++ b/tempest/api/network/admin/test_load_balancer_admin_actions.py
@@ -43,6 +43,7 @@
                                    "ROUND_ROBIN", "HTTP", cls.subnet)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6b0a20d8-4fcd-455e-b54f-ec4db5199518')
     def test_create_vip_as_admin_for_another_tenant(self):
         name = data_utils.rand_name('vip-')
         body = self.admin_client.create_pool(
@@ -69,6 +70,7 @@
         self.assertEqual(vip['name'], show_vip['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('74552cfc-ab78-4fb6-825b-f67bca379921')
     def test_create_health_monitor_as_admin_for_another_tenant(self):
         body = (
             self.admin_client.create_health_monitor(delay=4,
@@ -86,6 +88,7 @@
         self.assertEqual(health_monitor['id'], show_health_monitor['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('266a192d-3c22-46c4-a8fb-802450301e82')
     def test_create_pool_from_admin_user_other_tenant(self):
         body = self.admin_client.create_pool(
             name=data_utils.rand_name('pool-'),
@@ -99,6 +102,7 @@
         self.assertEqual(self.tenant_id, pool['tenant_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('158bb272-b9ed-4cfc-803c-661dac46f783')
     def test_create_member_from_admin_user_other_tenant(self):
         body = self.admin_client.create_member(address="10.0.9.47",
                                                protocol_port=80,
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 39850f5..1ea24fe 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -83,10 +83,12 @@
             self.assertNotEqual(tenant_id, q['tenant_id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
     def test_quotas(self):
         new_quotas = {'network': 0, 'security_group': 0}
         self._check_quotas(new_quotas)
 
+    @test.idempotent_id('a7add2b1-691e-44d6-875f-697d9685f091')
     @test.requires_ext(extension='lbaas', service='network')
     @test.attr(type='gate')
     def test_lbaas_quotas(self):
diff --git a/tempest/api/network/admin/test_routers_dvr.py b/tempest/api/network/admin/test_routers_dvr.py
index c6d8165..d1833dd 100644
--- a/tempest/api/network/admin/test_routers_dvr.py
+++ b/tempest/api/network/admin/test_routers_dvr.py
@@ -41,6 +41,7 @@
         cls.admin_client.delete_router(router['router']['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('08a2a0a8-f1e4-4b34-8e30-e522e836c44e')
     def test_distributed_router_creation(self):
         """
         Test uses administrative credentials to creates a
@@ -58,6 +59,7 @@
         self.assertTrue(router['router']['distributed'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8a0a72b4-7290-4677-afeb-b4ffe37bc352')
     def test_centralized_router_creation(self):
         """
         Test uses administrative credentials to creates a
@@ -76,6 +78,7 @@
         self.assertFalse(router['router']['distributed'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('acd43596-c1fb-439d-ada8-31ad48ae3c2e')
     def test_centralized_router_update_to_dvr(self):
         """
         Test uses administrative credentials to creates a
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index a4954af..99bd82c 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -53,6 +53,7 @@
         cls.mac_address = port['mac_address']
 
     @test.attr(type='smoke')
+    @test.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,
@@ -91,17 +92,20 @@
         self.assertEqual(allowed_address_pair, allowed_address_pairs)
 
     @test.attr(type='smoke')
+    @test.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.attr(type='smoke')
+    @test.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.tenant_network_cidr))
         self._update_port_with_address(cidr)
 
     @test.attr(type='smoke')
+    @test.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.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 1b28bac..5168219 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -21,6 +21,7 @@
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import test
 
 CONF = config.CONF
 
@@ -94,6 +95,7 @@
                                                    port_mac).format()
         return real_ip, eui_ip
 
+    @test.idempotent_id('e5517e62-6f16-430d-a672-f80875493d4c')
     def test_dhcpv6_stateless_eui64(self):
         """When subnets configured with RAs SLAAC (AOM=100) and DHCP stateless
         (AOM=110) both for radvd and dnsmasq, port shall receive IP address
@@ -112,6 +114,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')
     def test_dhcpv6_stateless_no_ra(self):
         """When subnets configured with dnsmasq SLAAC and DHCP stateless
         and there is no radvd, port shall receive IP address calculated
@@ -133,6 +136,7 @@
                                  ra_mode if ra_mode else "Off",
                                  add_mode if add_mode else "Off"))
 
+    @test.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 (
@@ -150,6 +154,7 @@
                               self.network,
                               **kwargs)
 
+    @test.idempotent_id('21635b6f-165a-4d42-bf49-7d195e47342f')
     def test_dhcpv6_stateless_no_ra_no_dhcp(self):
         """If no radvd option and no dnsmasq option is configured
         port shall receive IP from fixed IPs list of subnet.
@@ -162,6 +167,7 @@
                              'but shall be taken from fixed IPs') % (
                                 real_ip, eui_ip))
 
+    @test.idempotent_id('4544adf7-bb5f-4bdc-b769-b3e77026cef2')
     def test_dhcpv6_two_subnets(self):
         """When one IPv6 subnet configured with dnsmasq SLAAC or DHCP stateless
         and other IPv6 is with DHCP stateful, port shall receive EUI-64 IP
@@ -215,6 +221,7 @@
                         real_dhcp_ip,
                         str(dhcp_ip)))
 
+    @test.idempotent_id('4256c61d-c538-41ea-9147-3c450c36669e')
     def test_dhcpv6_64_subnets(self):
         """When one IPv6 subnet configured with dnsmasq SLAAC or DHCP stateless
         and other IPv4 is with DHCP of IPv4, port shall receive EUI-64 IP
@@ -264,6 +271,7 @@
                         real_dhcp_ip,
                         str(dhcp_ip)))
 
+    @test.idempotent_id('4ab211a0-276f-4552-9070-51e27f58fecf')
     def test_dhcp_stateful(self):
         """With all options below, DHCPv6 shall allocate first
         address from subnet pool to port.
@@ -289,6 +297,7 @@
                     port_ip,
                     str(dhcp_ip)))
 
+    @test.idempotent_id('51a5e97f-f02e-4e4e-9a17-a69811d300e3')
     def test_dhcp_stateful_fixedips(self):
         """With all options below, port shall be able to get
         requested IP from fixed IP range not depending on
@@ -317,6 +326,7 @@
                               "port create request: %s") % (
                                  port_ip, ip))
 
+    @test.idempotent_id('98244d88-d990-4570-91d4-6b25d70d08af')
     def test_dhcp_stateful_fixedips_outrange(self):
         """When port gets IP address from fixed IP range it
         shall be checked if it's from subnets range.
@@ -334,6 +344,7 @@
                           fixed_ips=[{'subnet_id': subnet['id'],
                                       'ip_address': ip}])
 
+    @test.idempotent_id('57b8302b-cba9-4fbb-8835-9168df029051')
     def test_dhcp_stateful_fixedips_duplicate(self):
         """When port gets IP address from fixed IP range it
         shall be checked if it's not duplicate.
@@ -366,6 +377,7 @@
         body = self.client.show_port(port['port_id'])
         return subnet, body['port']
 
+    @test.idempotent_id('e98f65db-68f4-4330-9fea-abd8c5192d4d')
     def test_dhcp_stateful_router(self):
         """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 2b4ccaf..bce8efe 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -36,6 +36,7 @@
         super(ExtensionsTestJSON, cls).resource_setup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
     def test_list_show_extensions(self):
         # List available extensions for the tenant
         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 1faac58..612c20a 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -54,6 +54,7 @@
         ]
 
     @test.attr(type='smoke')
+    @test.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.client.create_port(
@@ -70,6 +71,7 @@
         self._confirm_extra_dhcp_options(port[0], self.extra_dhcp_opts)
 
     @test.attr(type='smoke')
+    @test.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 43b296c..cc88852 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -64,6 +64,7 @@
             cls.create_port(cls.network)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
     def test_create_list_show_update_delete_floating_ip(self):
         # Creates a floating IP
         body = self.client.create_floatingip(
@@ -118,6 +119,7 @@
         self.assertIsNone(updated_floating_ip['router_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
     def test_floating_ip_delete_port(self):
         # Create a floating IP
         body = self.client.create_floatingip(
@@ -143,6 +145,7 @@
         self.assertIsNone(shown_floating_ip['router_id'])
 
     @test.attr(type='smoke')
+    @test.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.client.create_floatingip(
@@ -169,6 +172,7 @@
         self.assertIsNotNone(updated_floating_ip['fixed_ip_address'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5')
     def test_create_floating_ip_specifying_a_fixed_ip_address(self):
         body = self.client.create_floatingip(
             floating_network_id=self.ext_net_id,
@@ -186,6 +190,7 @@
         self.assertIsNone(floating_ip['floatingip']['port_id'])
 
     @test.attr(type='smoke')
+    @test.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
         ips = list(netaddr.IPNetwork(self.subnet['cidr']))
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index 7d70976..c4c547c 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -49,6 +49,7 @@
         cls.port = cls.create_port(cls.network)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('22996ea8-4a81-4b27-b6e1-fa5df92fa5e8')
     def test_create_floatingip_with_port_ext_net_unreachable(self):
         self.assertRaises(lib_exc.NotFound, self.client.create_floatingip,
                           floating_network_id=self.ext_net_id,
@@ -57,6 +58,7 @@
                                                     ['ip_address'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('50b9aeb4-9f0b-48ee-aa31-fa955a48ff54')
     def test_create_floatingip_in_private_network(self):
         self.assertRaises(lib_exc.BadRequest,
                           self.client.create_floatingip,
@@ -66,6 +68,7 @@
                                                     ['ip_address'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('6b3b8797-6d43-4191-985c-c48b773eb429')
     def test_associate_floatingip_port_ext_net_unreachable(self):
         # Create floating ip
         body = self.client.create_floatingip(
diff --git a/tempest/api/network/test_fwaas_extensions.py b/tempest/api/network/test_fwaas_extensions.py
index 280c5bb..d97a60c 100644
--- a/tempest/api/network/test_fwaas_extensions.py
+++ b/tempest/api/network/test_fwaas_extensions.py
@@ -99,6 +99,7 @@
                  (fw_id, target_states))
             raise exceptions.TimeoutException(m)
 
+    @test.idempotent_id('1b84cf01-9c09-4ce7-bc72-b15e39076468')
     def test_list_firewall_rules(self):
         # List firewall rules
         fw_rules = self.client.list_firewall_rules()
@@ -116,6 +117,7 @@
                         m['ip_version'],
                         m['enabled']) for m in fw_rules])
 
+    @test.idempotent_id('563564f7-7077-4f5e-8cdc-51f37ae5a2b9')
     def test_create_update_delete_firewall_rule(self):
         # Create firewall rule
         body = self.client.create_firewall_rule(
@@ -136,12 +138,14 @@
         self.assertNotIn(fw_rule_id,
                          [m['id'] for m in fw_rules['firewall_rules']])
 
+    @test.idempotent_id('3ff8c08e-26ff-4034-ae48-810ed213a998')
     def test_show_firewall_rule(self):
         # show a created firewall rule
         fw_rule = self.client.show_firewall_rule(self.fw_rule['id'])
         for key, value in fw_rule['firewall_rule'].iteritems():
             self.assertEqual(self.fw_rule[key], value)
 
+    @test.idempotent_id('1086dd93-a4c0-4bbb-a1bd-6d4bc62c199f')
     def test_list_firewall_policies(self):
         fw_policies = self.client.list_firewall_policies()
         fw_policies = fw_policies['firewall_policies']
@@ -152,6 +156,7 @@
                         m['name'],
                         m['firewall_rules']) for m in fw_policies])
 
+    @test.idempotent_id('bbf37b6c-498c-421e-9c95-45897d3ed775')
     def test_create_update_delete_firewall_policy(self):
         # Create firewall policy
         body = self.client.create_firewall_policy(
@@ -174,6 +179,7 @@
         fw_policies = fw_policies['firewall_policies']
         self.assertNotIn(fw_policy_id, [m['id'] for m in fw_policies])
 
+    @test.idempotent_id('1df59b3a-517e-41d4-96f6-fc31cf4ecff2')
     def test_show_firewall_policy(self):
         # show a created firewall policy
         fw_policy = self.client.show_firewall_policy(self.fw_policy['id'])
@@ -181,6 +187,7 @@
         for key, value in fw_policy.iteritems():
             self.assertEqual(self.fw_policy[key], value)
 
+    @test.idempotent_id('02082a03-3cdd-4789-986a-1327dd80bfb7')
     def test_create_show_delete_firewall(self):
         # Create tenant network resources required for an ACTIVE firewall
         network = self.create_network()
@@ -225,6 +232,7 @@
         self.client.delete_firewall(firewall_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('53305b4b-9897-4e01-87c0-2ae386083180')
     def test_firewall_rule_insertion_position_removal_rule_from_policy(self):
         # Create firewall rule
         body = self.client.create_firewall_rule(
@@ -291,6 +299,7 @@
         return [ruleid for ruleid in fw_policy['firewall_policy']
                 ['firewall_rules']]
 
+    @test.idempotent_id('8515ca8a-0d2f-4298-b5ff-6f924e4587ca')
     def test_update_firewall_policy_audited_attribute(self):
         # Create firewall rule
         body = self.client.create_firewall_rule(
diff --git a/tempest/api/network/test_load_balancer.py b/tempest/api/network/test_load_balancer.py
index 107d8cd..6872dfa 100644
--- a/tempest/api/network/test_load_balancer.py
+++ b/tempest/api/network/test_load_balancer.py
@@ -81,6 +81,7 @@
                 self.assertIn(value, objs)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c96dbfab-4a80-4e74-a535-e950b5bedd47')
     def test_list_vips(self):
         # Verify the vIP exists in the list of all vIPs
         body = self.client.list_vips()
@@ -88,6 +89,7 @@
         self.assertIn(self.vip['id'], [v['id'] for v in vips])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b8853f65-5089-4e69-befd-041a143427ff')
     def test_list_vips_with_filter(self):
         name = data_utils.rand_name('vip-')
         body = self.client.create_pool(name=data_utils.rand_name("pool-"),
@@ -105,6 +107,7 @@
             admin_state_up=False)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('27f56083-9af9-4a48-abe9-ca1bcc6c9035')
     def test_create_update_delete_pool_vip(self):
         # Creates a vip
         name = data_utils.rand_name('vip-')
@@ -161,6 +164,7 @@
         self.client.delete_pool(pool['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0435a95e-1d19-4d90-9e9f-3b979e9ad089')
     def test_show_vip(self):
         # Verifies the details of a vip
         body = self.client.show_vip(self.vip['id'])
@@ -171,6 +175,7 @@
                 self.assertEqual(self.vip[key], value)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6e7a7d31-8451-456d-b24a-e50479ce42a7')
     def test_show_pool(self):
         # Here we need to new pool without any dependence with vips
         body = self.client.create_pool(name=data_utils.rand_name("pool-"),
@@ -188,6 +193,7 @@
                 self.assertEqual(value, shown_pool[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d1ab1ffa-e06a-487f-911f-56418cb27727')
     def test_list_pools(self):
         # Verify the pool exists in the list of all pools
         body = self.client.list_pools()
@@ -195,6 +201,7 @@
         self.assertIn(self.pool['id'], [p['id'] for p in pools])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('27cc4c1a-caac-4273-b983-2acb4afaad4f')
     def test_list_pools_with_filters(self):
         attr_exceptions = ['status', 'vip_id', 'members', 'provider',
                            'status_description']
@@ -206,6 +213,7 @@
             admin_state_up=False)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('282d0dfd-5c3a-4c9b-b39c-c99782f39193')
     def test_list_members(self):
         # Verify the member exists in the list of all members
         body = self.client.list_members()
@@ -213,6 +221,7 @@
         self.assertIn(self.member['id'], [m['id'] for m in members])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('243b5126-24c6-4879-953e-7c7e32d8a57f')
     def test_list_members_with_filters(self):
         attr_exceptions = ['status', 'status_description']
         self._check_list_with_filter('member', attr_exceptions,
@@ -221,6 +230,7 @@
                                      pool_id=self.pool['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fb833ee8-9e69-489f-b540-a409762b78b2')
     def test_create_update_delete_member(self):
         # Creates a member
         body = self.client.create_member(address=self.member_address,
@@ -236,6 +246,7 @@
         self.client.delete_member(member['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('893cd71f-a7dd-4485-b162-f6ab9a534914')
     def test_show_member(self):
         # Verifies the details of a member
         body = self.client.show_member(self.member['id'])
@@ -246,6 +257,7 @@
                 self.assertEqual(self.member[key], value)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8e5822c5-68a4-4224-8d6c-a617741ebc2d')
     def test_list_health_monitors(self):
         # Verify the health monitor exists in the list of all health monitors
         body = self.client.list_health_monitors()
@@ -254,6 +266,7 @@
                       [h['id'] for h in health_monitors])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('49bac58a-511c-4875-b794-366698211d25')
     def test_list_health_monitors_with_filters(self):
         attr_exceptions = ['status', 'status_description', 'pools']
         self._check_list_with_filter('health_monitor', attr_exceptions,
@@ -261,6 +274,7 @@
                                      timeout=2)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e8ce05c4-d554-4d1e-a257-ad32ce134bb5')
     def test_create_update_delete_health_monitor(self):
         # Creates a health_monitor
         body = self.client.create_health_monitor(delay=4,
@@ -278,6 +292,7 @@
         body = self.client.delete_health_monitor(health_monitor['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d3e1aebc-06c2-49b3-9816-942af54012eb')
     def test_create_health_monitor_http_type(self):
         hm_type = "HTTP"
         body = self.client.create_health_monitor(delay=4,
@@ -290,6 +305,7 @@
         self.assertEqual(hm_type, health_monitor['type'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0eff9f67-90fb-4bb1-b4ed-c5fda99fff0c')
     def test_update_health_monitor_http_method(self):
         body = self.client.create_health_monitor(delay=4,
                                                  max_retries=3,
@@ -309,6 +325,7 @@
         self.assertEqual("290", updated_health_monitor['expected_codes'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('08e126ab-1407-483f-a22e-b11cc032ca7c')
     def test_show_health_monitor(self):
         # Verifies the details of a health_monitor
         body = self.client.show_health_monitor(self.health_monitor['id'])
@@ -319,6 +336,7 @@
                 self.assertEqual(self.health_monitor[key], value)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('87f7628e-8918-493d-af50-0602845dbb5b')
     def test_associate_disassociate_health_monitor_with_pool(self):
         # Verify that a health monitor can be associated with a pool
         self.client.associate_health_monitor_with_pool(
@@ -344,6 +362,7 @@
                          [p['pool_id'] for p in health_monitor['pools']])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('525fc7dc-be24-408d-938d-822e9783e027')
     def test_get_lb_pool_stats(self):
         # Verify the details of pool stats
         body = self.client.list_lb_pool_stats(self.pool['id'])
@@ -354,6 +373,7 @@
         self.assertIn("bytes_out", stats)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('66236be2-5121-4047-8cde-db4b83b110a5')
     def test_update_list_of_health_monitors_associated_with_pool(self):
         (self.client.associate_health_monitor_with_pool
             (self.health_monitor['id'], self.pool['id']))
@@ -368,6 +388,7 @@
                 (self.health_monitor['id'], self.pool['id']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('44ec9b40-b501-41e2-951f-4fc673b15ac0')
     def test_update_admin_state_up_of_pool(self):
         self.client.update_pool(self.pool['id'],
                                 admin_state_up=False)
@@ -376,6 +397,7 @@
         self.assertFalse(pool['admin_state_up'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('466a9d4c-37c6-4ea2-b807-133437beb48c')
     def test_show_vip_associated_with_pool(self):
         body = self.client.show_pool(self.pool['id'])
         pool = body['pool']
@@ -385,6 +407,7 @@
         self.assertEqual(self.vip['id'], vip['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7b97694e-69d0-4151-b265-e1052a465aa8')
     def test_show_members_associated_with_pool(self):
         body = self.client.show_pool(self.pool['id'])
         members = body['pool']['members']
@@ -395,6 +418,7 @@
             self.assertIsNotNone(body['member']['admin_state_up'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('73ed6f27-595b-4b2c-969c-dbdda6b8ab34')
     def test_update_pool_related_to_member(self):
         # Create new pool
         body = self.client.create_pool(name=data_utils.rand_name("pool-"),
@@ -415,6 +439,7 @@
                                          pool_id=self.pool['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cf63f071-bbe3-40ba-97a0-a33e11923162')
     def test_update_member_weight(self):
         self.client.update_member(self.member['id'],
                                   weight=2)
diff --git a/tempest/api/network/test_metering_extensions.py b/tempest/api/network/test_metering_extensions.py
index c80d0e9..f794f5a 100644
--- a/tempest/api/network/test_metering_extensions.py
+++ b/tempest/api/network/test_metering_extensions.py
@@ -66,6 +66,7 @@
         self.assertEqual(len(rules['metering_label_rules']), 0)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e2fb2f8c-45bf-429a-9f17-171c70444612')
     def test_list_metering_labels(self):
         # Verify label filtering
         body = self.admin_client.list_metering_labels(id=33)
@@ -73,6 +74,7 @@
         self.assertEqual(0, len(metering_labels))
 
     @test.attr(type='smoke')
+    @test.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-')
@@ -89,6 +91,7 @@
         self.assertEqual(len(labels['metering_labels']), 1)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('30abb445-0eea-472e-bd02-8649f54a5968')
     def test_show_metering_label(self):
         # Verifies the details of a label
         body = self.admin_client.show_metering_label(self.metering_label['id'])
@@ -101,6 +104,7 @@
                          metering_label['description'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cc832399-6681-493b-9d79-0202831a1281')
     def test_list_metering_label_rules(self):
         # Verify rule filtering
         body = self.admin_client.list_metering_label_rules(id=33)
@@ -108,6 +112,7 @@
         self.assertEqual(0, len(metering_label_rules))
 
     @test.attr(type='smoke')
+    @test.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
@@ -126,6 +131,7 @@
         self.assertEqual(len(rules['metering_label_rules']), 1)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b7354489-96ea-41f3-9452-bace120fb4a7')
     def test_show_metering_label_rule(self):
         # Verifies the details of a rule
         body = (self.admin_client.show_metering_label_rule(
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 0df455e..0801045 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -177,6 +177,7 @@
         self.subnets.pop()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
     def test_create_update_delete_network_subnet(self):
         # Create a network
         name = data_utils.rand_name('network-')
@@ -199,6 +200,7 @@
         self.assertEqual(updated_subnet['name'], new_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
     def test_show_network(self):
         # Verify the details of a network
         body = self.client.show_network(self.network['id'])
@@ -207,6 +209,7 @@
             self.assertEqual(network[key], self.network[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
     def test_show_network_fields(self):
         # Verify specific fields of a network
         fields = ['id', 'name']
@@ -218,6 +221,7 @@
             self.assertEqual(network[field_name], self.network[field_name])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
     def test_list_networks(self):
         # Verify the network exists in the list of all networks
         body = self.client.list_networks()
@@ -226,6 +230,7 @@
         self.assertNotEmpty(networks, "Created network not found in the list")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
     def test_list_networks_fields(self):
         # Verify specific fields of the networks
         fields = ['id', 'name']
@@ -236,6 +241,7 @@
             self.assertEqual(sorted(network.keys()), sorted(fields))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
     def test_show_subnet(self):
         # Verify the details of a subnet
         body = self.client.show_subnet(self.subnet['id'])
@@ -246,6 +252,7 @@
             self.assertEqual(subnet[key], self.subnet[key])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
     def test_show_subnet_fields(self):
         # Verify specific fields of a subnet
         fields = ['id', 'network_id']
@@ -257,6 +264,7 @@
             self.assertEqual(subnet[field_name], self.subnet[field_name])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
     def test_list_subnets(self):
         # Verify the subnet exists in the list of all subnets
         body = self.client.list_subnets()
@@ -265,6 +273,7 @@
         self.assertNotEmpty(subnets, "Created subnet not found in the list")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
     def test_list_subnets_fields(self):
         # Verify specific fields of subnets
         fields = ['id', 'network_id']
@@ -283,6 +292,7 @@
             pass
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
     def test_delete_network_with_subnet(self):
         # Creates a network
         name = data_utils.rand_name('network-')
@@ -308,34 +318,41 @@
         self.subnets.pop()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
     def test_create_delete_subnet_without_gateway(self):
         self._create_verify_delete_subnet()
 
     @test.attr(type='smoke')
+    @test.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.attr(type='smoke')
+    @test.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.attr(type='smoke')
+    @test.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.attr(type='smoke')
+    @test.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.attr(type='smoke')
+    @test.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.attr(type='smoke')
+    @test.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)
@@ -369,12 +386,14 @@
         self._compare_resource_attrs(updated_subnet, kwargs)
 
     @test.attr(type='smoke')
+    @test.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')
     def test_external_network_visibility(self):
         """Verifies user can see external networks but not subnets."""
         body = self.client.list_networks(**{'router:external': True})
@@ -446,6 +465,7 @@
             self.assertNotIn(n['id'], ports_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
     def test_bulk_create_delete_network(self):
         # Creates 2 networks in one request
         network_names = [data_utils.rand_name('network-'),
@@ -461,23 +481,27 @@
             self.assertIn(n['id'], networks_list)
 
     @test.attr(type='smoke')
+    @test.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
-        cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-        mask_bits = CONF.network.tenant_network_mask_bits
+        if self._ip_version == 4:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+            mask_bits = CONF.network.tenant_network_mask_bits
+        else:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+            mask_bits = CONF.network.tenant_network_v6_mask_bits
+
         cidrs = [subnet_cidr for subnet_cidr in cidr.subnet(mask_bits)]
+
         names = [data_utils.rand_name('subnet-') for i in range(len(networks))]
         subnets_list = []
-        # TODO(raies): "for IPv6, version list [4, 6] will be used.
-        # and cidr for IPv6 will be of IPv6"
-        ip_version = [4, 4]
         for i in range(len(names)):
             p1 = {
                 'network_id': networks[i]['id'],
                 'cidr': str(cidrs[(i)]),
                 'name': names[i],
-                'ip_version': ip_version[i]
+                'ip_version': self._ip_version
             }
             subnets_list.append(p1)
         del subnets_list[1]['name']
@@ -492,6 +516,7 @@
             self.assertIn(n['id'], subnets_list)
 
     @test.attr(type='smoke')
+    @test.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
@@ -517,10 +542,15 @@
             self.assertIn(n['id'], ports_list)
 
 
+class BulkNetworkOpsIpV6TestJSON(BulkNetworkOpsTestJSON):
+    _ip_version = 6
+
+
 class NetworksIpV6TestJSON(NetworksTestJSON):
     _ip_version = 6
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
     def test_create_delete_subnet_with_gw(self):
         net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
         gateway = str(netaddr.IPAddress(net.first + 2))
@@ -531,6 +561,7 @@
         self.assertEqual(subnet['gateway_ip'], gateway)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
     def test_create_delete_subnet_with_default_gw(self):
         net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
         gateway_ip = str(netaddr.IPAddress(net.first + 1))
@@ -541,6 +572,7 @@
         self.assertEqual(subnet['gateway_ip'], gateway_ip)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
     def test_create_list_subnet_with_no_gw64_one_network(self):
         name = data_utils.rand_name('network-')
         network = self.create_network(name)
@@ -579,6 +611,7 @@
         super(NetworksIpV6TestAttrs, cls).resource_setup()
 
     @test.attr(type='smoke')
+    @test.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'],
@@ -586,12 +619,14 @@
             ipv6_address_mode='dhcpv6-stateful')
 
     @test.attr(type='smoke')
+    @test.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.attr(type='smoke')
+    @test.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',
@@ -618,6 +653,7 @@
             slaac_network['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
     def test_create_delete_slaac_subnet_with_ports(self):
         """Test deleting subnet with SLAAC ports
 
@@ -628,6 +664,7 @@
         self._test_delete_subnet_with_ports("slaac")
 
     @test.attr(type='smoke')
+    @test.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 09bd9c3..1002295 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -24,30 +24,35 @@
 class NetworksNegativeTestJSON(base.BaseNetworkTest):
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
     def test_show_non_existent_network(self):
         non_exist_id = data_utils.rand_name('network')
         self.assertRaises(lib_exc.NotFound, self.client.show_network,
                           non_exist_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
     def test_show_non_existent_subnet(self):
         non_exist_id = data_utils.rand_name('subnet')
         self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
                           non_exist_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('a954861d-cbfd-44e8-b0a9-7fab111f235d')
     def test_show_non_existent_port(self):
         non_exist_id = data_utils.rand_name('port')
         self.assertRaises(lib_exc.NotFound, self.client.show_port,
                           non_exist_id)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('98bfe4e3-574e-4012-8b17-b2647063de87')
     def test_update_non_existent_network(self):
         non_exist_id = data_utils.rand_name('network')
         self.assertRaises(lib_exc.NotFound, self.client.update_network,
                           non_exist_id, name="new_name")
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('03795047-4a94-4120-a0a1-bd376e36fd4e')
     def test_delete_non_existent_network(self):
         non_exist_id = data_utils.rand_name('network')
         self.assertRaises(lib_exc.NotFound, self.client.delete_network,
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 2460092..33211fc 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -51,6 +51,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')
     def test_create_update_delete_port(self):
         # Verify port creation
         body = self.client.create_port(network_id=self.network['id'])
@@ -67,6 +68,7 @@
         self.assertEqual(updated_port['name'], new_name)
         self.assertFalse(updated_port['admin_state_up'])
 
+    @test.idempotent_id('67f1b811-f8db-43e2-86bd-72c074d4a42c')
     def test_create_bulk_port(self):
         network1 = self.network
         name = data_utils.rand_name('network-')
@@ -96,6 +98,7 @@
         return netaddr.IPAddress(cidr)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0435f278-40ae-48cb-a404-b8a087bc09b1')
     def test_create_port_in_allowed_allocation_pools(self):
         network = self.create_network()
         net_id = network['id']
@@ -114,6 +117,7 @@
         self.assertIn(ip_address, ip_range)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
     def test_show_port(self):
         # Verify the details of port
         body = self.client.show_port(self.port['id'])
@@ -127,6 +131,7 @@
                         (port, excluded_keys=['extra_dhcp_opts']))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd')
     def test_show_port_fields(self):
         # Verify specific fields of a port
         fields = ['id', 'mac_address']
@@ -138,6 +143,7 @@
             self.assertEqual(port[field_name], self.port[field_name])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cf95b358-3e92-4a29-a148-52445e1ac50e')
     def test_list_ports(self):
         # Verify the port exists in the list of all ports
         body = self.client.list_ports()
@@ -146,6 +152,7 @@
         self.assertNotEmpty(ports, "Created port not found in the list")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5ad01ed0-0e6e-4c5d-8194-232801b15c72')
     def test_port_list_filter_by_router_id(self):
         # Create a router
         network = self.create_network()
@@ -168,6 +175,7 @@
         self.assertEqual(ports[0]['device_id'], router['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ff7f117f-f034-4e0e-abff-ccef05c454b4')
     def test_list_ports_fields(self):
         # Verify specific fields of ports
         fields = ['id', 'mac_address']
@@ -179,6 +187,7 @@
             self.assertEqual(sorted(fields), sorted(port.keys()))
 
     @test.attr(type='smoke')
+    @test.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()
@@ -259,17 +268,20 @@
             self.assertIn(security_group, port_show['security_groups'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('58091b66-4ff4-4cc1-a549-05d60c7acd1a')
     def test_update_port_with_security_group_and_extra_attributes(self):
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup')])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('edf6766d-3d40-4621-bc6e-2521a44c257d')
     def test_update_port_with_two_security_groups_and_extra_attributes(self):
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup'),
              data_utils.rand_name('secgroup')])
 
     @test.attr(type='smoke')
+    @test.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.client.create_port(network_id=self.network['id'])
@@ -287,6 +299,7 @@
                          show_port['mac_address'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4179dcb9-1382-4ced-84fe-1b91c54f5735')
     def test_create_port_with_no_securitygroups(self):
         network = self.create_network()
         self.addCleanup(self.client.delete_network, network['id'])
@@ -310,6 +323,7 @@
         cls.host_id = socket.gethostname()
 
     @test.attr(type='smoke')
+    @test.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}
@@ -321,6 +335,7 @@
         self.assertEqual(self.host_id, host_id)
 
     @test.attr(type='smoke')
+    @test.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_client.create_port(**post_body)
@@ -334,6 +349,7 @@
         self.assertEqual(self.host_id, host_id)
 
     @test.attr(type='smoke')
+    @test.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']}
@@ -359,6 +375,7 @@
         self.assertEqual(self.host_id, listed_port[0]['binding:host_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b54ac0ff-35fc-4c79-9ca3-c7dbd4ea4f13')
     def test_show_port_binding_ext_attr(self):
         body = self.admin_client.create_port(network_id=self.network['id'])
         port = body['port']
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index b0ee00d..1388b3b 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -51,6 +51,7 @@
         return router
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f64403e2-8483-4b34-8ccd-b09a87bcc68c')
     def test_create_show_list_update_delete_router(self):
         # Create a router
         # NOTE(salv-orlando): Do not invoke self.create_router
@@ -89,6 +90,7 @@
         self.assertEqual(show_body['router']['name'], updated_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e54dd3a3-4352-4921-b09d-44369ae17397')
     def test_create_router_setting_tenant_id(self):
         # Test creating router from admin user setting tenant_id.
         test_tenant = data_utils.rand_name('test_tenant_')
@@ -105,6 +107,7 @@
                         create_body['router']['id'])
         self.assertEqual(tenant_id, create_body['router']['tenant_id'])
 
+    @test.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_create_router_with_default_snat_value(self):
@@ -116,6 +119,7 @@
             router['id'], {'network_id': CONF.network.public_network_id,
                            'enable_snat': True})
 
+    @test.idempotent_id('ea74068d-09e9-4fd7-8995-9b6a1ace920f')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_create_router_with_snat_explicit(self):
@@ -135,6 +139,7 @@
                                         exp_ext_gw_info=external_gateway_info)
 
     @test.attr(type='smoke')
+    @test.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)
@@ -153,6 +158,7 @@
                          router['id'])
 
     @test.attr(type='smoke')
+    @test.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)
@@ -197,6 +203,7 @@
                       map(lambda x: x['subnet_id'], fixed_ips))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6cc285d8-46bf-4f36-9b1a-783e3008ba79')
     def test_update_router_set_gateway(self):
         router = self._create_router(data_utils.rand_name('router-'))
         self.client.update_router(
@@ -209,6 +216,7 @@
             {'network_id': CONF.network.public_network_id})
         self._verify_gateway_port(router['id'])
 
+    @test.idempotent_id('b386c111-3b21-466d-880c-5e72b01e1a33')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_update_router_set_gateway_with_snat_explicit(self):
@@ -224,6 +232,7 @@
              'enable_snat': True})
         self._verify_gateway_port(router['id'])
 
+    @test.idempotent_id('96536bc7-8262-4fb2-9967-5c46940fa279')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_update_router_set_gateway_without_snat(self):
@@ -240,6 +249,7 @@
         self._verify_gateway_port(router['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ad81b7ee-4f81-407b-a19c-17e623f763e8')
     def test_update_router_unset_gateway(self):
         router = self._create_router(
             data_utils.rand_name('router-'),
@@ -252,6 +262,7 @@
             device_id=router['id'])
         self.assertFalse(list_body['ports'])
 
+    @test.idempotent_id('f2faf994-97f4-410b-a831-9bc977b64374')
     @test.requires_ext(extension='ext-gw-mode', service='network')
     @test.attr(type='smoke')
     def test_update_router_reset_gateway_without_snat(self):
@@ -269,6 +280,7 @@
              'enable_snat': False})
         self._verify_gateway_port(router['id'])
 
+    @test.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
     @test.requires_ext(extension='extraroute', service='network')
     @test.attr(type='smoke')
     def test_update_extra_route(self):
@@ -304,6 +316,7 @@
         self.client.delete_extra_routes(router_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a8902683-c788-4246-95c7-ad9c6d63a4d9')
     def test_update_router_admin_state(self):
         self.router = self._create_router(data_utils.rand_name('router-'))
         self.assertFalse(self.router['admin_state_up'])
@@ -315,6 +328,7 @@
         self.assertTrue(show_body['router']['admin_state_up'])
 
     @test.attr(type='smoke')
+    @test.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-'))
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 67a6c94..9f76dd2 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -40,6 +40,7 @@
                            CONF.network.tenant_network_v6_cidr)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('37a94fc0-a834-45b9-bd23-9a81d2fd1e22')
     def test_router_add_gateway_invalid_network_returns_404(self):
         self.assertRaises(lib_exc.NotFound,
                           self.client.update_router,
@@ -48,6 +49,7 @@
                               'network_id': self.router['id']})
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('11836a18-0b15-4327-a50b-f0d9dc66bddd')
     def test_router_add_gateway_net_not_external_returns_400(self):
         alt_network = self.create_network(
             network_name=data_utils.rand_name('router-negative-'))
@@ -60,6 +62,7 @@
                               'network_id': alt_network['id']})
 
     @test.attr(type=['negative', 'smoke'])
+    @test.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-'))
@@ -75,6 +78,7 @@
                           subnet02['id'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
     def test_router_remove_interface_in_use_returns_409(self):
         self.client.add_router_interface_with_subnet_id(
             self.router['id'], self.subnet['id'])
@@ -83,18 +87,21 @@
                           self.router['id'])
 
     @test.attr(type=['negative', 'smoke'])
+    @test.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.client.show_router,
                           router)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.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.client.update_router,
                           router, name="new_name")
 
     @test.attr(type=['negative', 'smoke'])
+    @test.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.client.delete_router,
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index f9af3cc..8479013 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -69,6 +69,7 @@
                              (key, value))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e30abd17-fef9-4739-8617-dc26da88e686')
     def test_list_security_groups(self):
         # Verify the that security group belonging to tenant exist in list
         body = self.client.list_security_groups()
@@ -81,6 +82,7 @@
         self.assertIsNotNone(found, msg)
 
     @test.attr(type='smoke')
+    @test.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,6 +111,7 @@
                          new_description)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cfb99e0e-7410-4a3d-8a0c-959a63ee77e9')
     def test_create_show_delete_security_group_rule(self):
         group_create_body, _ = self._create_security_group()
 
@@ -140,6 +143,7 @@
                           rule_list)
 
     @test.attr(type='smoke')
+    @test.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.
 
@@ -158,6 +162,7 @@
                                                 port_range_max)
 
     @test.attr(type='smoke')
+    @test.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.
 
@@ -178,6 +183,7 @@
                                                     icmp_type, icmp_code)
 
     @test.attr(type='smoke')
+    @test.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()
@@ -196,6 +202,7 @@
                                                 remote_group_id=remote_id)
 
     @test.attr(type='smoke')
+    @test.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()
@@ -213,6 +220,7 @@
                                                 remote_ip_prefix=ip_prefix)
 
     @test.attr(type='smoke')
+    @test.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 0da1aac..97c0592 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -36,12 +36,14 @@
             raise cls.skipException(msg)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('424fd5c3-9ddc-486a-b45f-39bf0c820fc6')
     def test_show_non_existent_security_group(self):
         non_exist_id = str(uuid.uuid4())
         self.assertRaises(lib_exc.NotFound, self.client.show_security_group,
                           non_exist_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('4c094c09-000b-4e41-8100-9617600c02a6')
     def test_show_non_existent_security_group_rule(self):
         non_exist_id = str(uuid.uuid4())
         self.assertRaises(lib_exc.NotFound,
@@ -49,6 +51,7 @@
                           non_exist_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1f1bb89d-5664-4956-9fcd-83ee0fa603df')
     def test_delete_non_existent_security_group(self):
         non_exist_id = str(uuid.uuid4())
         self.assertRaises(lib_exc.NotFound,
@@ -57,6 +60,7 @@
                           )
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('981bdc22-ce48-41ed-900a-73148b583958')
     def test_create_security_group_rule_with_bad_protocol(self):
         group_create_body, _ = self._create_security_group()
 
@@ -68,6 +72,7 @@
             protocol=pname, direction='ingress', ethertype=self.ethertype)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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()
 
@@ -81,6 +86,7 @@
                 remote_ip_prefix=remote_ip_prefix)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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 = str(uuid.uuid4())
@@ -95,6 +101,7 @@
                 remote_group_id=remote_group_id)
 
     @test.attr(type=['negative', 'gate'])
+    @test.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()
@@ -109,6 +116,7 @@
             remote_group_id=sg2_body['security_group']['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5666968c-fff3-40d6-9efc-df1c8bd01abb')
     def test_create_security_group_rule_with_bad_ethertype(self):
         group_create_body, _ = self._create_security_group()
 
@@ -120,6 +128,7 @@
             protocol='udp', direction='ingress', ethertype=ethertype)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d')
     def test_create_security_group_rule_with_invalid_ports(self):
         group_create_body, _ = self._create_security_group()
 
@@ -150,6 +159,7 @@
             self.assertIn(msg, str(ex))
 
     @test.attr(type=['negative', 'smoke'])
+    @test.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'
@@ -158,6 +168,7 @@
                           name=name)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.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()
@@ -182,6 +193,7 @@
             port_range_min=min_port, port_range_max=max_port)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.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 = str(uuid.uuid4())
@@ -196,6 +208,7 @@
     _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
 
     @test.attr(type=['negative', 'gate'])
+    @test.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_type_management.py b/tempest/api/network/test_service_type_management.py
index e620ae6..a1e4136 100644
--- a/tempest/api/network/test_service_type_management.py
+++ b/tempest/api/network/test_service_type_management.py
@@ -27,6 +27,7 @@
 
     @decorators.skip_because(bug="1400370")
     @test.attr(type='smoke')
+    @test.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
     def test_service_provider_list(self):
         body = self.client.list_service_providers()
         self.assertIsInstance(body['service_providers'], list)
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
index d869b55..ebf31d3 100644
--- a/tempest/api/network/test_vpnaas_extensions.py
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -101,6 +101,7 @@
         return body['network']['tenant_id']
 
     @test.attr(type='smoke')
+    @test.idempotent_id('14311574-0737-4e53-ac05-f7ae27742eed')
     def test_admin_create_ipsec_policy_for_tenant(self):
         tenant_id = self._get_tenant_id()
         # Create IPSec policy for the newly created tenant
@@ -118,6 +119,7 @@
         self.assertIn(ipsecpolicy['id'], ipsecpolicies)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b62acdc6-0c53-4d84-84aa-859b22b79799')
     def test_admin_create_vpn_service_for_tenant(self):
         tenant_id = self._get_tenant_id()
 
@@ -143,6 +145,7 @@
         self.assertIn(vpnservice['id'], vpn_services)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('58cc4a1c-443b-4f39-8fb6-c19d39f343ab')
     def test_admin_create_ike_policy_for_tenant(self):
         tenant_id = self._get_tenant_id()
 
@@ -163,6 +166,7 @@
         self.assertIn(ikepolicy['id'], ikepolicies)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('de5bb04c-3a1f-46b1-b329-7a8abba5c7f1')
     def test_list_vpn_services(self):
         # Verify the VPN service exists in the list of all VPN services
         body = self.client.list_vpnservices()
@@ -170,6 +174,7 @@
         self.assertIn(self.vpnservice['id'], [v['id'] for v in vpnservices])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aacb13b1-fdc7-41fd-bab2-32621aee1878')
     def test_create_update_delete_vpn_service(self):
         # Creates a VPN service and sets up deletion
         network1 = self.create_network()
@@ -196,6 +201,7 @@
         # should be "ACTIVE" not "PENDING*"
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0dedfc1d-f8ee-4e2a-bfd4-7997b9dc17ff')
     def test_show_vpn_service(self):
         # Verifies the details of a vpn service
         body = self.client.show_vpnservice(self.vpnservice['id'])
@@ -212,6 +218,7 @@
         self.assertIn(vpnservice['status'], valid_status)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e0fb6200-da3d-4869-8340-a8c1956ca618')
     def test_list_ike_policies(self):
         # Verify the ike policy exists in the list of all IKE policies
         body = self.client.list_ikepolicies()
@@ -219,6 +226,7 @@
         self.assertIn(self.ikepolicy['id'], [i['id'] for i in ikepolicies])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d61f29a5-160c-487d-bc0d-22e32e731b44')
     def test_create_update_delete_ike_policy(self):
         # Creates a IKE policy
         name = data_utils.rand_name('ike-policy')
@@ -253,6 +261,7 @@
         self.assertNotIn(ike_policy['id'], ikepolicies)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b5fcf3a3-9407-452d-b8a8-e7c6c32baea8')
     def test_show_ike_policy(self):
         # Verifies the details of a ike policy
         body = self.client.show_ikepolicy(self.ikepolicy['id'])
@@ -275,6 +284,7 @@
                          ikepolicy['ike_version'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('19ea0a2f-add9-44be-b732-ffd8a7b42f37')
     def test_list_ipsec_policies(self):
         # Verify the ipsec policy exists in the list of all ipsec policies
         body = self.client.list_ipsecpolicies()
@@ -282,6 +292,7 @@
         self.assertIn(self.ipsecpolicy['id'], [i['id'] for i in ipsecpolicies])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9c1701c9-329a-4e5d-930a-1ead1b3f86ad')
     def test_create_update_delete_ipsec_policy(self):
         # Creates an ipsec policy
         ipsec_policy_body = {'name': data_utils.rand_name('ipsec-policy'),
@@ -308,6 +319,7 @@
                           self.client.delete_ipsecpolicy, ipsecpolicy['id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('601f8a05-9d3c-4539-a400-1c4b3a21b03b')
     def test_show_ipsec_policy(self):
         # Verifies the details of an ipsec policy
         body = self.client.show_ipsecpolicy(self.ipsecpolicy['id'])
diff --git a/tempest/api/object_storage/test_account_bulk.py b/tempest/api/object_storage/test_account_bulk.py
index 31a80cf..54c87d7 100644
--- a/tempest/api/object_storage/test_account_bulk.py
+++ b/tempest/api/object_storage/test_account_bulk.py
@@ -66,6 +66,7 @@
         self.assertNotIn(container_name, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a407de51-1983-47cc-9f14-47c2b059413c')
     @test.requires_ext(extension='bulk', service='object')
     def test_extract_archive(self):
         # Test bulk operation of file upload with an archived file
@@ -102,6 +103,7 @@
         self.assertIn(object_name, [c['name'] for c in contents_list])
 
     @test.attr(type='gate')
+    @test.idempotent_id('c075e682-0d2a-43b2-808d-4116200d736d')
     @test.requires_ext(extension='bulk', service='object')
     def test_bulk_delete(self):
         # Test bulk operation of deleting multiple files
@@ -129,6 +131,7 @@
         self._check_contents_deleted(container_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('dbea2bcb-efbb-4674-ac8a-a5a0e33d1d79')
     @test.requires_ext(extension='bulk', service='object')
     def test_bulk_delete_by_POST(self):
         # Test bulk operation of deleting multiple files
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index e3f5f3d..29f314d 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -78,6 +78,7 @@
         super(AccountQuotasTest, cls).resource_cleanup()
 
     @test.attr(type="smoke")
+    @test.idempotent_id('a22ef352-a342-4587-8f47-3bbdb5b039c4')
     @test.requires_ext(extension='account_quotas', service='object')
     def test_upload_valid_object(self):
         object_name = data_utils.rand_name(name="TestObject")
@@ -88,6 +89,7 @@
         self.assertHeaders(resp, 'Object', 'PUT')
 
     @test.attr(type=["smoke"])
+    @test.idempotent_id('63f51f9f-5f1d-4fc6-b5be-d454d70949d6')
     @test.requires_ext(extension='account_quotas', service='object')
     def test_admin_modify_quota(self):
         """Test that the ResellerAdmin is able to modify and remove the quota
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index 783bf1a..548c619 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -80,6 +80,7 @@
         super(AccountQuotasNegativeTest, cls).resource_cleanup()
 
     @test.attr(type=["negative", "smoke"])
+    @test.idempotent_id('d1dc5076-555e-4e6d-9697-28f1fe976324')
     @test.requires_ext(extension='account_quotas', service='object')
     def test_user_modify_quota(self):
         """Test that a user is not able to modify or remove a quota on
@@ -98,6 +99,7 @@
 
     @test.attr(type=["negative", "smoke"])
     @decorators.skip_because(bug="1310597")
+    @test.idempotent_id('cf9e21f5-3aa4-41b1-9462-28ac550d8d3f')
     @test.requires_ext(extension='account_quotas', service='object')
     def test_upload_large_object(self):
         object_name = data_utils.rand_name(name="TestObject")
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 2bc4f59..63d0425 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -46,6 +46,7 @@
         super(AccountTest, cls).resource_cleanup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3499406a-ae53-4f8c-b43a-133d4dc6fe3f')
     def test_list_containers(self):
         # list of all containers should not be empty
         resp, container_list = self.account_client.list_account_containers()
@@ -56,6 +57,7 @@
             self.assertIn(container_name, container_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('884ec421-fbad-4fcc-916b-0580f2699565')
     def test_list_no_containers(self):
         # List request to empty account
 
@@ -87,6 +89,7 @@
         self.assertEqual(len(container_list), 0)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1c7efa35-e8a2-4b0b-b5ff-862c7fd83704')
     def test_list_containers_with_format_json(self):
         # list containers setting format parameter to 'json'
         params = {'format': 'json'}
@@ -99,6 +102,7 @@
         self.assertTrue([c['bytes'] for c in container_list])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4477b609-1ca6-4d4b-b25d-ad3f01086089')
     def test_list_containers_with_format_xml(self):
         # list containers setting format parameter to 'xml'
         params = {'format': 'xml'}
@@ -114,6 +118,7 @@
         self.assertEqual(container_list.find(".//bytes").tag, 'bytes')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('6eb04a6a-4860-4e31-ba91-ea3347d76b58')
     @testtools.skipIf(
         not CONF.object_storage_feature_enabled.discoverability,
         'Discoverability function is disabled')
@@ -123,6 +128,7 @@
         self.assertThat(resp, custom_matchers.AreAllWellFormatted())
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5cfa4ab2-4373-48dd-a41f-a532b12b08b2')
     def test_list_containers_with_limit(self):
         # list containers one of them, half of them then all of them
         for limit in (1, self.containers_count / 2, self.containers_count):
@@ -134,6 +140,7 @@
             self.assertEqual(len(container_list), limit)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('638f876d-6a43-482a-bbb3-0840bca101c6')
     def test_list_containers_with_marker(self):
         # list containers using marker param
         # first expect to get 0 container as we specified last
@@ -154,6 +161,7 @@
         self.assertEqual(len(container_list), self.containers_count / 2 - 1)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
     def test_list_containers_with_end_marker(self):
         # list containers using end_marker param
         # first expect to get 0 container as we specified first container as
@@ -172,6 +180,7 @@
         self.assertEqual(len(container_list), self.containers_count / 2)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
     def test_list_containers_with_marker_and_end_marker(self):
         # list containers combining marker and end_marker param
         params = {'marker': self.containers[0],
@@ -182,6 +191,7 @@
         self.assertEqual(len(container_list), self.containers_count - 2)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f7064ae8-dbcc-48da-b594-82feef6ea5af')
     def test_list_containers_with_limit_and_marker(self):
         # list containers combining marker and limit param
         # result are always limitated by the limit whatever the marker
@@ -196,6 +206,7 @@
             self.assertTrue(len(container_list) <= limit, str(container_list))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('888a3f0e-7214-4806-8e50-5e0c9a69bb5e')
     def test_list_containers_with_limit_and_end_marker(self):
         # list containers combining limit and end_marker param
         limit = random.randint(1, self.containers_count)
@@ -208,6 +219,7 @@
                          min(limit, self.containers_count / 2))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
     def test_list_containers_with_limit_and_marker_and_end_marker(self):
         # list containers combining limit, marker and end_marker param
         limit = random.randint(1, self.containers_count)
@@ -221,6 +233,7 @@
                          min(limit, self.containers_count - 2))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4894c312-6056-4587-8d6f-86ffbf861f80')
     def test_list_account_metadata(self):
         # list all account metadata
 
@@ -236,6 +249,7 @@
         self.account_client.delete_account_metadata(metadata)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b904c2e3-24c2-4dba-ad7d-04e90a761be5')
     def test_list_no_account_metadata(self):
         # list no account metadata
         resp, _ = self.account_client.list_account_metadata()
@@ -243,6 +257,7 @@
         self.assertNotIn('x-account-meta-', str(resp))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e2a08b5f-3115-4768-a3ee-d4287acd6c08')
     def test_update_account_metadata_with_create_metadata(self):
         # add metadata to account
         metadata = {'test-account-meta1': 'Meta1'}
@@ -257,6 +272,7 @@
         self.account_client.delete_account_metadata(metadata)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9f60348d-c46f-4465-ae06-d51dbd470953')
     def test_update_account_metadata_with_delete_matadata(self):
         # delete metadata from account
         metadata = {'test-account-meta1': 'Meta1'}
@@ -268,6 +284,7 @@
         self.assertNotIn('x-account-meta-test-account-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('64fd53f3-adbd-4639-af54-436e4982dbfb')
     def test_update_account_metadata_with_create_matadata_key(self):
         # if the value of metadata is not set, the metadata is not
         # registered at a server
@@ -279,6 +296,7 @@
         self.assertNotIn('x-account-meta-test-account-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d4d884d3-4696-4b85-bc98-4f57c4dd2bf1')
     def test_update_account_metadata_with_delete_matadata_key(self):
         # Although the value of metadata is not set, the feature of
         # deleting metadata is valid
@@ -292,6 +310,7 @@
         self.assertNotIn('x-account-meta-test-account-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8e5fc073-59b9-42ee-984a-29ed11b2c749')
     def test_update_account_metadata_with_create_and_delete_metadata(self):
         # Send a request adding and deleting metadata requests simultaneously
         metadata_1 = {'test-account-meta1': 'Meta1'}
diff --git a/tempest/api/object_storage/test_account_services_negative.py b/tempest/api/object_storage/test_account_services_negative.py
index 9acf668..a913bd7 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -24,6 +24,7 @@
 class AccountNegativeTest(base.BaseObjectTest):
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('070e6aca-6152-4867-868d-1118d68fb38c')
     def test_list_containers_with_non_authorized_user(self):
         # list containers using non-authorized user
 
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index 44763a1..6368bec 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -42,6 +42,7 @@
         super(ObjectTestACLs, self).tearDown()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a3270f3f-7640-4944-8448-c7ea783ea5b6')
     def test_read_object_with_rights(self):
         # attempt to read object using authorized user
         # update X-Container-Read metadata ACL
@@ -66,6 +67,7 @@
         self.assertHeaders(resp, 'Object', 'GET')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aa58bfa5-40d9-4bc3-82b4-d07f4a9e392a')
     def test_write_object_with_rights(self):
         # attempt to write object using authorized user
         # update X-Container-Write metadata ACL
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index edc052e..644c3b1 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -45,6 +45,7 @@
         super(ObjectACLsNegativeTest, self).tearDown()
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('af587587-0c24-4e15-9822-8352ce711013')
     def test_write_object_without_using_creds(self):
         # trying to create object with empty headers
         # X-Auth-Token is not provided
@@ -58,6 +59,7 @@
                           self.container_name, object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('af85af0b-a025-4e72-a90e-121babf55720')
     def test_delete_object_without_using_creds(self):
         # create object
         object_name = data_utils.rand_name(name='Object')
@@ -74,6 +76,7 @@
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('63d84e37-55a6-42e2-9e5f-276e60e26a00')
     def test_write_object_with_non_authorized_user(self):
         # attempt to upload another file using non-authorized user
         # User provided token is forbidden. ACL are not set
@@ -88,6 +91,7 @@
                           self.container_name, object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('abf63359-be52-4feb-87dd-447689fc77fd')
     def test_read_object_with_non_authorized_user(self):
         # attempt to read object using non-authorized user
         # User provided token is forbidden. ACL are not set
@@ -105,6 +109,7 @@
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('7343ac3d-cfed-4198-9bb0-00149741a492')
     def test_delete_object_with_non_authorized_user(self):
         # attempt to delete object using non-authorized user
         # User provided token is forbidden. ACL are not set
@@ -122,6 +127,7 @@
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('9ed01334-01e9-41ea-87ea-e6f465582823')
     def test_read_object_without_rights(self):
         # attempt to read object using non-authorized user
         # update X-Container-Read metadata ACL
@@ -145,6 +151,7 @@
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('a3a585a7-d8cf-4b65-a1a0-edc2b1204f85')
     def test_write_object_without_rights(self):
         # attempt to write object using non-authorized user
         # update X-Container-Write metadata ACL
@@ -165,6 +172,7 @@
                           object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('8ba512ad-aa6e-444e-b882-2906a0ea2052')
     def test_write_object_without_write_rights(self):
         # attempt to write object using non-authorized user
         # update X-Container-Read and X-Container-Write metadata ACL
@@ -187,6 +195,7 @@
                           object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'smoke'])
+    @test.idempotent_id('b4e366f8-f185-47ab-b789-df4416f9ecdb')
     def test_delete_object_without_write_rights(self):
         # attempt to delete object using non-authorized user
         # update X-Container-Read and X-Container-Write metadata ACL
diff --git a/tempest/api/object_storage/test_container_quotas.py b/tempest/api/object_storage/test_container_quotas.py
index 12ec6d2..c78b4c3 100644
--- a/tempest/api/object_storage/test_container_quotas.py
+++ b/tempest/api/object_storage/test_container_quotas.py
@@ -51,6 +51,7 @@
         self.delete_containers([self.container_name])
         super(ContainerQuotasTest, self).tearDown()
 
+    @test.idempotent_id('9a0fb034-86af-4df0-86fa-f8bd7db21ae0')
     @test.requires_ext(extension='container_quotas', service='object')
     @test.attr(type="smoke")
     def test_upload_valid_object(self):
@@ -67,6 +68,7 @@
         nafter = self._get_bytes_used()
         self.assertEqual(nbefore + len(data), nafter)
 
+    @test.idempotent_id('22eeeb2b-3668-4160-baef-44790f65a5a0')
     @test.requires_ext(extension='container_quotas', service='object')
     @test.attr(type="smoke")
     def test_upload_large_object(self):
@@ -83,6 +85,7 @@
         nafter = self._get_bytes_used()
         self.assertEqual(nbefore, nafter)
 
+    @test.idempotent_id('3a387039-697a-44fc-a9c0-935de31f426b')
     @test.requires_ext(extension='container_quotas', service='object')
     @test.attr(type="smoke")
     def test_upload_too_many_objects(self):
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index fe06fd0..54da0d1 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -47,6 +47,7 @@
         return object_name
 
     @test.attr(type='smoke')
+    @test.idempotent_id('92139d73-7819-4db1-85f8-3f2f22a8d91f')
     def test_create_container(self):
         container_name = data_utils.rand_name(name='TestContainer')
         resp, body = self.container_client.create_container(container_name)
@@ -54,6 +55,7 @@
         self.assertHeaders(resp, 'Container', 'PUT')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('49f866ed-d6af-4395-93e7-4187eb56d322')
     def test_create_container_overwrite(self):
         # overwrite container with the same name
         container_name = data_utils.rand_name(name='TestContainer')
@@ -64,6 +66,7 @@
         self.assertHeaders(resp, 'Container', 'PUT')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c2ac4d59-d0f5-40d5-ba19-0635056d48cd')
     def test_create_container_with_metadata_key(self):
         # create container with the blank value of metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -81,6 +84,7 @@
         self.assertNotIn('x-container-meta-test-container-meta', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e1e8df32-7b22-44e1-aa08-ccfd8d446b58')
     def test_create_container_with_metadata_value(self):
         # create container with metadata value
         container_name = data_utils.rand_name(name='TestContainer')
@@ -99,6 +103,7 @@
                          metadata['test-container-meta'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('24d16451-1c0c-4e4f-b59c-9840a3aba40e')
     def test_create_container_with_remove_metadata_key(self):
         # create container with the blank value of remove metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -119,6 +124,7 @@
         self.assertNotIn('x-container-meta-test-container-meta', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8a21ebad-a5c7-4e29-b428-384edc8cd156')
     def test_create_container_with_remove_metadata_value(self):
         # create container with remove metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -137,6 +143,7 @@
         self.assertNotIn('x-container-meta-test-container-meta', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('95d3a249-b702-4082-a2c4-14bb860cf06a')
     def test_delete_container(self):
         # create a container
         container_name = self._create_container()
@@ -146,6 +153,7 @@
         self.containers.remove(container_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('312ff6bd-5290-497f-bda1-7c5fec6697ab')
     def test_list_container_contents(self):
         # get container contents list
         container_name = self._create_container()
@@ -157,6 +165,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4646ac2d-9bfb-4c7d-a3c5-0f527402b3df')
     def test_list_container_contents_with_no_object(self):
         # get empty container contents list
         container_name = self._create_container()
@@ -167,6 +176,7 @@
         self.assertEqual('', object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fe323a32-57b9-4704-a996-2e68f83b09bc')
     def test_list_container_contents_with_delimiter(self):
         # get container contents list using delimiter param
         container_name = self._create_container()
@@ -181,6 +191,7 @@
         self.assertEqual(object_name.split('/')[0], object_list.strip('/\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('55b4fa5c-e12e-4ca9-8fcf-a79afe118522')
     def test_list_container_contents_with_end_marker(self):
         # get container contents list using end_marker param
         container_name = self._create_container()
@@ -194,6 +205,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('196f5034-6ab0-4032-9da9-a937bbb9fba9')
     def test_list_container_contents_with_format_json(self):
         # get container contents list using format_json param
         container_name = self._create_container()
@@ -213,6 +225,7 @@
         self.assertTrue([c['last_modified'] for c in object_list])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('655a53ca-4d15-408c-a377-f4c6dbd0a1fa')
     def test_list_container_contents_with_format_xml(self):
         # get container contents list using format_xml param
         container_name = self._create_container()
@@ -237,6 +250,7 @@
                          'last_modified')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('297ec38b-2b61-4ff4-bcd1-7fa055e97b61')
     def test_list_container_contents_with_limit(self):
         # get container contents list using limit param
         container_name = self._create_container()
@@ -250,6 +264,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c31ddc63-2a58-4f6b-b25c-94d2937e6867')
     def test_list_container_contents_with_marker(self):
         # get container contents list using marker param
         container_name = self._create_container()
@@ -263,6 +278,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('58ca6cc9-6af0-408d-aaec-2a6a7b2f0df9')
     def test_list_container_contents_with_path(self):
         # get container contents list using path param
         container_name = self._create_container()
@@ -277,6 +293,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('77e742c7-caf2-4ec9-8aa4-f7d509a3344c')
     def test_list_container_contents_with_prefix(self):
         # get container contents list using prefix param
         container_name = self._create_container()
@@ -291,6 +308,7 @@
         self.assertEqual(object_name, object_list.strip('\n'))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('96e68f0e-19ec-4aa2-86f3-adc6a45e14dd')
     def test_list_container_metadata(self):
         # List container metadata
         container_name = self._create_container()
@@ -307,6 +325,7 @@
         self.assertEqual(resp['x-container-meta-name'], metadata['name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a2faf936-6b13-4f8d-92a2-c2278355821e')
     def test_list_no_container_metadata(self):
         # HEAD container without metadata
         container_name = self._create_container()
@@ -317,6 +336,7 @@
         self.assertNotIn('x-container-meta-', str(resp))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('cf19bc0b-7e16-4a5a-aaed-cb0c2fe8deef')
     def test_update_container_metadata_with_create_and_delete_matadata(self):
         # Send one request of adding and deleting metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -340,6 +360,7 @@
                          metadata_2['test-container-meta2'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2ae5f295-4bf1-4e04-bfad-21e54b62cec5')
     def test_update_container_metadata_with_create_metadata(self):
         # update container metadata using add metadata
         container_name = self._create_container()
@@ -357,6 +378,7 @@
                          metadata['test-container-meta1'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3a5ce7d4-6e4b-47d0-9d87-7cd42c325094')
     def test_update_container_metadata_with_delete_metadata(self):
         # update container metadata using delete metadata
         container_name = data_utils.rand_name(name='TestContainer')
@@ -375,6 +397,7 @@
         self.assertNotIn('x-container-meta-test-container-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('31f40a5f-6a52-4314-8794-cd89baed3040')
     def test_update_container_metadata_with_create_matadata_key(self):
         # update container metadata with a blenk value of metadata
         container_name = self._create_container()
@@ -390,6 +413,7 @@
         self.assertNotIn('x-container-meta-test-container-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a2e36378-6f1f-43f4-840a-ffd9cfd61914')
     def test_update_container_metadata_with_delete_metadata_key(self):
         # update container metadata with a blank value of matadata
         container_name = data_utils.rand_name(name='TestContainer')
diff --git a/tempest/api/object_storage/test_container_staticweb.py b/tempest/api/object_storage/test_container_staticweb.py
index 8a61911..102c9cd 100644
--- a/tempest/api/object_storage/test_container_staticweb.py
+++ b/tempest/api/object_storage/test_container_staticweb.py
@@ -51,6 +51,7 @@
             cls.delete_containers([cls.container_name])
         super(StaticWebTest, cls).resource_cleanup()
 
+    @test.idempotent_id('c1f055ab-621d-4a6a-831f-846fcb578b8b')
     @test.requires_ext(extension='staticweb', service='object')
     @test.attr('gate')
     def test_web_index(self):
@@ -82,6 +83,7 @@
             self.container_name)
         self.assertNotIn('x-container-meta-web-index', body)
 
+    @test.idempotent_id('941814cf-db9e-4b21-8112-2b6d0af10ee5')
     @test.requires_ext(extension='staticweb', service='object')
     @test.attr('gate')
     def test_web_listing(self):
@@ -114,6 +116,7 @@
             self.container_name)
         self.assertNotIn('x-container-meta-web-listings', body)
 
+    @test.idempotent_id('bc37ec94-43c8-4990-842e-0e5e02fc8926')
     @test.requires_ext(extension='staticweb', service='object')
     @test.attr('gate')
     def test_web_listing_css(self):
@@ -138,6 +141,7 @@
         css = '<link rel="stylesheet" type="text/css" href="listings.css" />'
         self.assertIn(css, body)
 
+    @test.idempotent_id('f18b4bef-212e-45e7-b3ca-59af3a465f82')
     @test.requires_ext(extension='staticweb', service='object')
     @test.attr('gate')
     def test_web_error(self):
diff --git a/tempest/api/object_storage/test_container_sync.py b/tempest/api/object_storage/test_container_sync.py
index 09b0ce0..71f1275 100644
--- a/tempest/api/object_storage/test_container_sync.py
+++ b/tempest/api/object_storage/test_container_sync.py
@@ -114,6 +114,7 @@
 
     @test.attr(type='slow')
     @decorators.skip_because(bug='1317133')
+    @test.idempotent_id('be008325-1bba-4925-b7dd-93b58f22ce9b')
     @testtools.skipIf(
         not CONF.object_storage_feature_enabled.container_sync,
         'Old-style container sync function is disabled')
diff --git a/tempest/api/object_storage/test_container_sync_middleware.py b/tempest/api/object_storage/test_container_sync_middleware.py
index 41509a0..4491a84 100644
--- a/tempest/api/object_storage/test_container_sync_middleware.py
+++ b/tempest/api/object_storage/test_container_sync_middleware.py
@@ -37,6 +37,7 @@
         cls.cluster_name = CONF.object_storage.cluster_name
 
     @test.attr(type='slow')
+    @test.idempotent_id('ea4645a1-d147-4976-82f7-e5a7a3065f80')
     @test.requires_ext(extension='container_sync', service='object')
     def test_container_synchronization(self):
         def make_headers(cont, cont_client):
diff --git a/tempest/api/object_storage/test_crossdomain.py b/tempest/api/object_storage/test_crossdomain.py
index 66e8176..16ff95e 100644
--- a/tempest/api/object_storage/test_crossdomain.py
+++ b/tempest/api/object_storage/test_crossdomain.py
@@ -39,6 +39,7 @@
         self.account_client.skip_path()
 
     @test.attr('gate')
+    @test.idempotent_id('d1b8b031-b622-4010-82f9-ff78a9e915c7')
     @test.requires_ext(extension='crossdomain', service='object')
     def test_get_crossdomain_policy(self):
         resp, body = self.account_client.get("crossdomain.xml", {})
diff --git a/tempest/api/object_storage/test_healthcheck.py b/tempest/api/object_storage/test_healthcheck.py
index 6fbd77b..a2a4497 100644
--- a/tempest/api/object_storage/test_healthcheck.py
+++ b/tempest/api/object_storage/test_healthcheck.py
@@ -28,6 +28,7 @@
         self.account_client.skip_path()
 
     @test.attr('gate')
+    @test.idempotent_id('db5723b1-f25c-49a9-bfeb-7b5640caf337')
     def test_get_healthcheck(self):
 
         resp, _ = self.account_client.get("healthcheck", {})
diff --git a/tempest/api/object_storage/test_object_expiry.py b/tempest/api/object_storage/test_object_expiry.py
index be5d50e..ac6f49a 100644
--- a/tempest/api/object_storage/test_object_expiry.py
+++ b/tempest/api/object_storage/test_object_expiry.py
@@ -70,6 +70,7 @@
                           self.container_name, self.object_name)
 
     @test.attr(type='gate')
+    @test.idempotent_id('fb024a42-37f3-4ba5-9684-4f40a7910b41')
     def test_get_object_after_expiry_time(self):
         # the 10s is important, because the get calls can take 3s each
         # some times
@@ -77,6 +78,7 @@
         self._test_object_expiry(metadata)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e592f18d-679c-48fe-9e36-4be5f47102c5')
     def test_get_object_at_expiry_time(self):
         metadata = {'X-Delete-At': str(int(time.time()) + 10)}
         self._test_object_expiry(metadata)
diff --git a/tempest/api/object_storage/test_object_formpost.py b/tempest/api/object_storage/test_object_formpost.py
index 7a9fcf6..5425eaa 100644
--- a/tempest/api/object_storage/test_object_formpost.py
+++ b/tempest/api/object_storage/test_object_formpost.py
@@ -106,6 +106,7 @@
         content_type = 'multipart/form-data; boundary=%s' % boundary
         return body, content_type
 
+    @test.idempotent_id('80fac02b-6e54-4f7b-be0d-a965b5cbef76')
     @test.requires_ext(extension='formpost', service='object')
     @test.attr(type='gate')
     def test_post_object_using_form(self):
diff --git a/tempest/api/object_storage/test_object_formpost_negative.py b/tempest/api/object_storage/test_object_formpost_negative.py
index cdd9d2c..d8fc077 100644
--- a/tempest/api/object_storage/test_object_formpost_negative.py
+++ b/tempest/api/object_storage/test_object_formpost_negative.py
@@ -107,6 +107,7 @@
         content_type = 'multipart/form-data; boundary=%s' % boundary
         return body, content_type
 
+    @test.idempotent_id('d3fb3c4d-e627-48ce-9379-a1631f21336d')
     @test.requires_ext(extension='formpost', service='object')
     @test.attr(type=['gate', 'negative'])
     def test_post_object_using_form_expired(self):
@@ -123,6 +124,7 @@
             url, body, headers=headers)
         self.assertIn('FormPost: Form Expired', str(exc))
 
+    @test.idempotent_id('b277257f-113c-4499-b8d1-5fead79f7360')
     @test.requires_ext(extension='formpost', service='object')
     @test.attr(type='gate')
     def test_post_object_using_form_invalid_signature(self):
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index cbca5e8..a4d0377 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -85,6 +85,7 @@
                 self.assertNotIn('x-object-meta-' + meta_key, resp)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5b4ce26f-3545-46c9-a2ba-5754358a4c62')
     def test_create_object(self):
         # create object
         object_name = data_utils.rand_name(name='TestObject')
@@ -104,6 +105,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('5daebb1d-f0d5-4dc9-b541-69672eff00b0')
     def test_create_object_with_content_disposition(self):
         # create object with content_disposition
         object_name = data_utils.rand_name(name='TestObject')
@@ -126,6 +128,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='gate')
+    @test.idempotent_id('605f8317-f945-4bee-ae91-013f1da8f0a0')
     def test_create_object_with_content_encoding(self):
         # create object with content_encoding
         object_name = data_utils.rand_name(name='TestObject')
@@ -153,6 +156,7 @@
         self.assertEqual(body, data_before)
 
     @test.attr(type='gate')
+    @test.idempotent_id('73820093-0503-40b1-a478-edf0e69c7d1f')
     def test_create_object_with_etag(self):
         # create object with etag
         object_name = data_utils.rand_name(name='TestObject')
@@ -172,6 +176,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('84dafe57-9666-4f6d-84c8-0814d37923b8')
     def test_create_object_with_expect_continue(self):
         # create object with expect_continue
         object_name = data_utils.rand_name(name='TestObject')
@@ -198,6 +203,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4f84422a-e2f2-4403-b601-726a4220b54e')
     def test_create_object_with_transfer_encoding(self):
         # create object with transfer_encoding
         object_name = data_utils.rand_name(name='TestObject')
@@ -215,6 +221,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('0f3d62a6-47e3-4554-b0e5-1a5dc372d501')
     def test_create_object_with_x_fresh_metadata(self):
         # create object with x_fresh_metadata
         object_name_base = data_utils.rand_name(name='TestObject')
@@ -241,6 +248,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('1c7ed3e4-2099-406b-b843-5301d4811baf')
     def test_create_object_with_x_object_meta(self):
         # create object with object_meta
         object_name = data_utils.rand_name(name='TestObject')
@@ -260,6 +268,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e4183917-33db-4153-85cc-4dacbb938865')
     def test_create_object_with_x_object_metakey(self):
         # create object with the blank value of metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -279,6 +288,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ce798afc-b278-45de-a5ce-2ea124b98b99')
     def test_create_object_with_x_remove_object_meta(self):
         # create object with x_remove_object_meta
         object_name = data_utils.rand_name(name='TestObject')
@@ -302,6 +312,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('ad21e342-7916-4f9e-ab62-a1f885f2aaf9')
     def test_create_object_with_x_remove_object_metakey(self):
         # create object with the blank value of remove metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -325,6 +336,7 @@
         self.assertEqual(data, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('17738d45-03bd-4d45-9e0b-7b2f58f98687')
     def test_delete_object(self):
         # create object
         object_name = data_utils.rand_name(name='TestObject')
@@ -337,6 +349,7 @@
         self.assertHeaders(resp, 'Object', 'DELETE')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7a94c25d-66e6-434c-9c38-97d4e2c29945')
     def test_update_object_metadata(self):
         # update object metadata
         object_name, data = self._create_object()
@@ -355,6 +368,7 @@
         self.assertIn('x-object-meta-test-meta', resp)
         self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
 
+    @test.idempotent_id('48650ed0-c189-4e1e-ad6b-1d4770c6e134')
     def test_update_object_metadata_with_remove_metadata(self):
         # update object metadata with remove metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -379,6 +393,7 @@
         self.assertNotIn('x-object-meta-test-meta1', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f726174b-2ded-4708-bff7-729d12ce1f84')
     def test_update_object_metadata_with_create_and_remove_metadata(self):
         # creation and deletion of metadata with one request
         object_name = data_utils.rand_name(name='TestObject')
@@ -406,6 +421,7 @@
         self.assertEqual(resp['x-object-meta-test-meta2'], 'Meta2')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('08854588-6449-4bb7-8cca-f2e1040f5e6f')
     def test_update_object_metadata_with_x_object_manifest(self):
         # update object metadata with x_object_manifest
 
@@ -432,6 +448,7 @@
         self.assertIn('x-object-manifest', resp)
         self.assertNotEqual(len(resp['x-object-manifest']), 0)
 
+    @test.idempotent_id('0dbbe89c-6811-4d84-a2df-eca2bdd40c0e')
     def test_update_object_metadata_with_x_object_metakey(self):
         # update object metadata with a blenk value of metadata
         object_name, data = self._create_object()
@@ -451,6 +468,7 @@
         self.assertEqual(resp['x-object-meta-test-meta'], '')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9a88dca4-b684-425b-806f-306cd0e57e42')
     def test_update_object_metadata_with_x_remove_object_metakey(self):
         # update object metadata with a blank value of remove metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -475,6 +493,7 @@
         self.assertNotIn('x-object-meta-test-meta', resp)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9a447cf6-de06-48de-8226-a8c6ed31caf2')
     def test_list_object_metadata(self):
         # get object metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -493,6 +512,7 @@
         self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('170fb90e-f5c3-4b1f-ae1b-a18810821172')
     def test_list_no_object_metadata(self):
         # get empty list of object metadata
         object_name, data = self._create_object()
@@ -504,6 +524,7 @@
         self.assertNotIn('x-object-meta-', str(resp))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('23a3674c-d6de-46c3-86af-ff92bfc8a3da')
     def test_list_object_metadata_with_x_object_manifest(self):
         # get object metadata with x_object_manifest
 
@@ -544,6 +565,7 @@
                          '%s/%s' % (self.container_name, object_name))
 
     @test.attr(type='smoke')
+    @test.idempotent_id('02610ba7-86b7-4272-9ed8-aa8d417cb3cd')
     def test_get_object(self):
         # retrieve object's data (in response body)
 
@@ -557,6 +579,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('005f9bf6-e06d-41ec-968e-96c78e0b1d82')
     def test_get_object_with_metadata(self):
         # get object with metadata
         object_name = data_utils.rand_name(name='TestObject')
@@ -576,6 +599,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('05a1890e-7db9-4a6c-90a8-ce998a2bddfa')
     def test_get_object_with_range(self):
         # get object with range
         object_name = data_utils.rand_name(name='TestObject')
@@ -594,6 +618,7 @@
         self.assertEqual(body, data[rand_num - 3: rand_num])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('11b4515b-7ba7-4ca8-8838-357ded86fc10')
     def test_get_object_with_x_object_manifest(self):
         # get object with x_object_manifest
 
@@ -637,6 +662,7 @@
         self.assertEqual(''.join(data_segments), body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c05b4013-e4de-47af-be84-e598062b16fc')
     def test_get_object_with_if_match(self):
         # get object with if_match
         object_name = data_utils.rand_name(name='TestObject')
@@ -657,6 +683,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('be133639-e5d2-4313-9b1f-2d59fc054a16')
     def test_get_object_with_if_modified_since(self):
         # get object with if_modified_since
         object_name = data_utils.rand_name(name='TestObject')
@@ -676,6 +703,7 @@
         self.assertHeaders(resp, 'Object', 'GET')
         self.assertEqual(body, data)
 
+    @test.idempotent_id('641500d5-1612-4042-a04d-01fc4528bc30')
     def test_get_object_with_if_none_match(self):
         # get object with if_none_match
         object_name = data_utils.rand_name(name='TestObject')
@@ -698,6 +726,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0aa1201c-10aa-467a-bee7-63cbdd463152')
     def test_get_object_with_if_unmodified_since(self):
         # get object with if_unmodified_since
         object_name, data = self._create_object()
@@ -713,6 +742,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('94587078-475f-48f9-a40f-389c246e31cd')
     def test_get_object_with_x_newest(self):
         # get object with x_newest
         object_name, data = self._create_object()
@@ -726,6 +756,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1a9ab572-1b66-4981-8c21-416e2a5e6011')
     def test_copy_object_in_same_container(self):
         # create source object
         src_object_name = data_utils.rand_name(name='SrcObject')
@@ -752,6 +783,7 @@
         self.assertEqual(body, src_data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2248abba-415d-410b-9c30-22dff9cd6e67')
     def test_copy_object_to_itself(self):
         # change the content type of an existing object
 
@@ -773,6 +805,7 @@
         self.assertEqual(resp['content-type'], metadata['content-type'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('06f90388-2d0e-40aa-934c-e9a8833e958a')
     def test_copy_object_2d_way(self):
         # create source object
         src_object_name = data_utils.rand_name(name='SrcObject')
@@ -799,6 +832,7 @@
         self._check_copied_obj(dst_object_name, src_data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('aa467252-44f3-472a-b5ae-5b57c3c9c147')
     def test_copy_object_across_containers(self):
         # create a container to use as  asource container
         src_container_name = data_utils.rand_name(name='TestSourceContainer')
@@ -839,6 +873,7 @@
         self.assertEqual(resp[actual_meta_key], meta_value)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('5a9e2cc6-85b6-46fc-916d-0cbb7a88e5fd')
     def test_copy_object_with_x_fresh_metadata(self):
         # create source object
         metadata = {'x-object-meta-src': 'src_value'}
@@ -859,6 +894,7 @@
         self._check_copied_obj(dst_object_name, data, not_in_meta=["src"])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a28a8b99-e701-4d7e-9d84-3b66f121460b')
     def test_copy_object_with_x_object_metakey(self):
         # create source object
         metadata = {'x-object-meta-src': 'src_value'}
@@ -881,6 +917,7 @@
         self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('edabedca-24c3-4322-9b70-d6d9f942a074')
     def test_copy_object_with_x_object_meta(self):
         # create source object
         metadata = {'x-object-meta-src': 'src_value'}
@@ -903,6 +940,7 @@
         self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
 
     @test.attr(type='gate')
+    @test.idempotent_id('e3e6a64a-9f50-4955-b987-6ce6767c97fb')
     def test_object_upload_in_segments(self):
         # create object
         object_name = data_utils.rand_name(name='LObject')
@@ -945,6 +983,7 @@
         self.assertEqual(''.join(data_segments), body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('50d01f12-526f-4360-9ac2-75dd508d7b68')
     def test_get_object_if_different(self):
         # http://en.wikipedia.org/wiki/HTTP_ETag
         # Make a conditional request for an object using the If-None-Match
@@ -987,6 +1026,7 @@
         super(PublicObjectTest, self).tearDown()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('07c9cf95-c0d4-4b49-b9c8-0ef2c9b27193')
     def test_access_public_container_object_without_using_creds(self):
         # make container public-readable and access an object in it object
         # anonymously, without using credentials
@@ -1025,6 +1065,7 @@
         self.assertEqual(body, data)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('54e2a2fe-42dc-491b-8270-8e4217dd4cdc')
     def test_access_public_object_with_another_user_creds(self):
         # make container public-readable and access an object in it using
         # another user's credentials
diff --git a/tempest/api/object_storage/test_object_slo.py b/tempest/api/object_storage/test_object_slo.py
index 7b85201..b013752 100644
--- a/tempest/api/object_storage/test_object_slo.py
+++ b/tempest/api/object_storage/test_object_slo.py
@@ -110,6 +110,7 @@
         self.assertHeaders(resp, 'Object', method)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2c3f24a6-36e8-4711-9aa2-800ee1fc7b5b')
     def test_upload_manifest(self):
         # create static large object from multipart manifest
         manifest = self._create_manifest()
@@ -124,6 +125,7 @@
         self._assertHeadersSLO(resp, 'PUT')
 
     @test.attr(type='gate')
+    @test.idempotent_id('e69ad766-e1aa-44a2-bdd2-bf62c09c1456')
     def test_list_large_object_metadata(self):
         # list static large object metadata using multipart manifest
         object_name = self._create_large_object()
@@ -135,6 +137,7 @@
         self._assertHeadersSLO(resp, 'HEAD')
 
     @test.attr(type='gate')
+    @test.idempotent_id('49bc49bc-dd1b-4c0f-904e-d9f10b830ee8')
     def test_retrieve_large_object(self):
         # list static large object using multipart manifest
         object_name = self._create_large_object()
@@ -149,6 +152,7 @@
         self.assertEqual(body, sum_data)
 
     @test.attr(type='gate')
+    @test.idempotent_id('87b6dfa1-abe9-404d-8bf0-6c3751e6aa77')
     def test_delete_large_object(self):
         # delete static large object using multipart manifest
         object_name = self._create_large_object()
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index dd4fd17..4563bfd 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -94,6 +94,7 @@
         return url
 
     @test.attr(type='gate')
+    @test.idempotent_id('f91c96d4-1230-4bba-8eb9-84476d18d991')
     @test.requires_ext(extension='tempurl', service='object')
     def test_get_object_using_temp_url(self):
         expires = self._get_expiry_date()
@@ -113,6 +114,7 @@
         self.assertHeaders(resp, 'Object', 'HEAD')
 
     @test.attr(type='gate')
+    @test.idempotent_id('671f9583-86bd-4128-a034-be282a68c5d8')
     @test.requires_ext(extension='tempurl', service='object')
     def test_get_object_using_temp_url_key_2(self):
         key2 = 'Meta2-'
@@ -137,6 +139,7 @@
         self.assertEqual(body, self.content)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9b08dade-3571-4152-8a4f-a4f2a873a735')
     @test.requires_ext(extension='tempurl', service='object')
     def test_put_object_using_temp_url(self):
         new_data = data_utils.arbitrary_string(
@@ -165,6 +168,7 @@
         self.assertEqual(body, new_data)
 
     @test.attr(type='gate')
+    @test.idempotent_id('249a0111-5ad3-4534-86a7-1993d55f9185')
     @test.requires_ext(extension='tempurl', service='object')
     def test_head_object_using_temp_url(self):
         expires = self._get_expiry_date()
@@ -179,6 +183,7 @@
         self.assertHeaders(resp, 'Object', 'HEAD')
 
     @test.attr(type='gate')
+    @test.idempotent_id('9d9cfd90-708b-465d-802c-e4a8090b823d')
     @test.requires_ext(extension='tempurl', service='object')
     def test_get_object_using_temp_url_with_inline_query_parameter(self):
         expires = self._get_expiry_date()
diff --git a/tempest/api/object_storage/test_object_temp_url_negative.py b/tempest/api/object_storage/test_object_temp_url_negative.py
index ca34293..af927a8 100644
--- a/tempest/api/object_storage/test_object_temp_url_negative.py
+++ b/tempest/api/object_storage/test_object_temp_url_negative.py
@@ -93,6 +93,7 @@
         return url
 
     @test.attr(type=['gate', 'negative'])
+    @test.idempotent_id('5a583aca-c804-41ba-9d9a-e7be132bdf0b')
     @test.requires_ext(extension='tempurl', service='object')
     def test_get_object_after_expiration_time(self):
 
diff --git a/tempest/api/object_storage/test_object_version.py b/tempest/api/object_storage/test_object_version.py
index da40e5a..225159f 100644
--- a/tempest/api/object_storage/test_object_version.py
+++ b/tempest/api/object_storage/test_object_version.py
@@ -45,6 +45,7 @@
         self.assertEqual(header_value, versioned)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a151e158-dcbf-4a1f-a1e7-46cd65895a6f')
     @testtools.skipIf(
         not CONF.object_storage_feature_enabled.object_versioning,
         'Object-versioning is disabled')
diff --git a/tempest/api/orchestration/stacks/test_environment.py b/tempest/api/orchestration/stacks/test_environment.py
index 96e1c50..2989709 100644
--- a/tempest/api/orchestration/stacks/test_environment.py
+++ b/tempest/api/orchestration/stacks/test_environment.py
@@ -25,6 +25,7 @@
 class StackEnvironmentTest(base.BaseOrchestrationTest):
 
     @test.attr(type='gate')
+    @test.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')
@@ -42,6 +43,7 @@
         self.assertEqual(20, len(random_value))
 
     @test.attr(type='gate')
+    @test.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')
@@ -71,6 +73,7 @@
         self.assertEqual(expected_length, len(random_value))
 
     @test.attr(type='gate')
+    @test.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 5f7f954..833fb28 100644
--- a/tempest/api/orchestration/stacks/test_limits.py
+++ b/tempest/api/orchestration/stacks/test_limits.py
@@ -26,6 +26,7 @@
 class TestServerStackLimits(base.BaseOrchestrationTest):
 
     @test.attr(type='gate')
+    @test.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
@@ -39,6 +40,7 @@
         self.assertIn('Template exceeds maximum allowed size', str(ex))
 
     @test.attr(type='gate')
+    @test.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 b8a93f0..253d197 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -97,6 +97,7 @@
             cls.test_resources[resource['logical_resource_id']] = resource
 
     @test.attr(type='slow')
+    @test.idempotent_id('f9e2664c-bc44-4eef-98b6-495e4f9d74b3')
     def test_created_resources(self):
         """Verifies created neutron resources."""
         resources = [('Network', self.neutron_basic_template['resources'][
@@ -115,6 +116,7 @@
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
     @test.attr(type='slow')
+    @test.idempotent_id('c572b915-edb1-4e90-b196-c7199a6848c0')
     @test.services('network')
     def test_created_network(self):
         """Verifies created network."""
@@ -127,6 +129,7 @@
             'Network']['properties']['name'], network['name'])
 
     @test.attr(type='slow')
+    @test.idempotent_id('e8f84b96-f9d7-4684-ad5f-340203e9f2c2')
     @test.services('network')
     def test_created_subnet(self):
         """Verifies created subnet."""
@@ -145,6 +148,7 @@
         self.assertEqual(str(self.subnet_cidr), subnet['cidr'])
 
     @test.attr(type='slow')
+    @test.idempotent_id('96af4c7f-5069-44bc-bdcf-c0390f8a67d1')
     @test.services('network')
     def test_created_router(self):
         """Verifies created router."""
@@ -158,6 +162,7 @@
         self.assertEqual(True, router['admin_state_up'])
 
     @test.attr(type='slow')
+    @test.idempotent_id('89f605bd-153e-43ee-a0ed-9919b63423c5')
     @test.services('network')
     def test_created_router_interface(self):
         """Verifies created router interface."""
@@ -181,6 +186,7 @@
                          router_interface_ip)
 
     @test.attr(type='slow')
+    @test.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 db1ac9a..e8f3522 100644
--- a/tempest/api/orchestration/stacks/test_non_empty_stack.py
+++ b/tempest/api/orchestration/stacks/test_non_empty_stack.py
@@ -54,6 +54,7 @@
         return stacks
 
     @test.attr(type='gate')
+    @test.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()
@@ -61,6 +62,7 @@
         self.assertIn(self.stack_name, stacks_names)
 
     @test.attr(type='gate')
+    @test.idempotent_id('992f96e3-41ee-4ff6-91c7-bcfb670c0919')
     def test_stack_show(self):
         """Getting details about created stack should be possible."""
         stack = self.client.get_stack(self.stack_name)
@@ -80,6 +82,7 @@
         self.assertEqual('fluffy', stack['outputs'][0]['output_key'])
 
     @test.attr(type='gate')
+    @test.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)
@@ -90,6 +93,7 @@
                                           'RESUME_COMPLETE')
 
     @test.attr(type='gate')
+    @test.idempotent_id('c951d55e-7cce-4c1f-83a0-bad735437fa6')
     def test_list_resources(self):
         """Getting list of created resources for the stack should be possible.
         """
@@ -97,6 +101,7 @@
         self.assertEqual({self.resource_name: self.resource_type}, resources)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2aba03b3-392f-4237-900b-1f5a5e9bd962')
     def test_show_resource(self):
         """Getting details about created resource should be possible."""
         resource = self.client.get_resource(self.stack_identifier,
@@ -111,6 +116,7 @@
         self.assertEqual(self.resource_type, resource['resource_type'])
 
     @test.attr(type='gate')
+    @test.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(
@@ -120,6 +126,7 @@
         self.assertEqual(['Tom', 'Stinky'], metadata.get('kittens', None))
 
     @test.attr(type='gate')
+    @test.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)
@@ -135,6 +142,7 @@
         self.assertIn('CREATE_COMPLETE', resource_statuses)
 
     @test.attr(type='gate')
+    @test.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 772bab3..6d2dcc7 100644
--- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -49,6 +49,7 @@
             cls.test_resources[resource['logical_resource_id']] = resource
 
     @test.attr(type='gate')
+    @test.idempotent_id('b476eac2-a302-4815-961f-18c410a2a537')
     def test_created_resources(self):
         """Verifies created keypair resource."""
 
@@ -69,6 +70,7 @@
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('8d77dec7-91fd-45a6-943d-5abd45e338a4')
     def test_stack_keypairs_output(self):
         stack = self.client.get_stack(self.stack_name)
         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 e204894..33d2f9e 100644
--- a/tempest/api/orchestration/stacks/test_resource_types.py
+++ b/tempest/api/orchestration/stacks/test_resource_types.py
@@ -17,6 +17,7 @@
 class ResourceTypesTest(base.BaseOrchestrationTest):
 
     @test.attr(type='smoke')
+    @test.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()
@@ -24,6 +25,7 @@
         self.assertIn('OS::Nova::Server', resource_types)
 
     @test.attr(type='smoke')
+    @test.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()
@@ -36,6 +38,7 @@
             self.assertEqual(resource_type, type_schema['resource_type'])
 
     @test.attr(type='smoke')
+    @test.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.get_resource_type_template(
diff --git a/tempest/api/orchestration/stacks/test_soft_conf.py b/tempest/api/orchestration/stacks/test_soft_conf.py
index 220054e..7387c62 100644
--- a/tempest/api/orchestration/stacks/test_soft_conf.py
+++ b/tempest/api/orchestration/stacks/test_soft_conf.py
@@ -81,6 +81,7 @@
             lib_exc.NotFound, self.client.get_software_config, config_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('136162ed-9445-4b9c-b7fc-306af8b5da99')
     def test_get_software_config(self):
         """Testing software config get."""
         for conf in self.configs:
@@ -88,6 +89,7 @@
             self._validate_config(conf, api_config)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1275c835-c967-4a2c-8d5d-ad533447ed91')
     def test_get_deployment_list(self):
         """Getting a list of all deployments"""
         deploy_list = self.client.get_software_deploy_list()
@@ -96,6 +98,7 @@
         self.assertIn(self.deployment_id, deploy_ids)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('fe7cd9f9-54b1-429c-a3b7-7df8451db913')
     def test_get_deployment_metadata(self):
         """Testing deployment metadata get"""
         metadata = self.client.get_software_deploy_meta(self.server_id)
@@ -112,6 +115,7 @@
                          deployment['software_deployment']['config_id'])
 
     @test.attr(type='smoke')
+    @test.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
@@ -124,6 +128,7 @@
                                   self.status_reason, self.configs[0]['id'])
 
     @test.attr(type='smoke')
+    @test.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.get_software_deploy_meta(self.server_id)
@@ -147,6 +152,7 @@
                 test_metadata['metadata'][0][key])
 
     @test.attr(type='smoke')
+    @test.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.get_software_deploy_meta(self.server_id)
diff --git a/tempest/api/orchestration/stacks/test_stacks.py b/tempest/api/orchestration/stacks/test_stacks.py
index 5cdd8b4..a9b3a6b 100644
--- a/tempest/api/orchestration/stacks/test_stacks.py
+++ b/tempest/api/orchestration/stacks/test_stacks.py
@@ -27,11 +27,13 @@
         super(StacksTestJSON, cls).resource_setup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d35d628c-07f6-4674-85a1-74db9919e986')
     def test_stack_list_responds(self):
         stacks = self.client.list_stacks()
         self.assertIsInstance(stacks, list)
 
     @test.attr(type='smoke')
+    @test.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 83abc91..efbf695 100644
--- a/tempest/api/orchestration/stacks/test_swift_resources.py
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -58,6 +58,7 @@
         for resource in resources:
             cls.test_resources[resource['logical_resource_id']] = resource
 
+    @test.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')
@@ -72,6 +73,7 @@
             self.assertEqual(resource_name, resource['logical_resource_id'])
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
+    @test.idempotent_id('bd438b18-5494-4d5a-9ce6-d2a942ec5060')
     @test.services('object_storage')
     def test_created_containers(self):
         params = {'format': 'json'}
@@ -81,6 +83,7 @@
                               if cont['name'].startswith(self.stack_name)]
         self.assertEqual(2, len(created_containers))
 
+    @test.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')
@@ -98,6 +101,7 @@
         for h in acl_headers:
             self.assertIn(h, headers)
 
+    @test.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 6113cab..d0fc1cf 100644
--- a/tempest/api/orchestration/stacks/test_templates.py
+++ b/tempest/api/orchestration/stacks/test_templates.py
@@ -36,11 +36,13 @@
         cls.parameters = {}
 
     @test.attr(type='gate')
+    @test.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.attr(type='gate')
+    @test.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 9a5bc68..ebba694 100644
--- a/tempest/api/orchestration/stacks/test_templates_negative.py
+++ b/tempest/api/orchestration/stacks/test_templates_negative.py
@@ -36,6 +36,7 @@
         cls.parameters = {}
 
     @test.attr(type=['gate', 'negative'])
+    @test.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 8356497..5a1a6d7 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -55,6 +55,7 @@
             'name'], self.get_stack_output(stack_identifier, 'display_name'))
 
     @test.attr(type='gate')
+    @test.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."""
@@ -84,6 +85,7 @@
         self.volumes_client.wait_for_resource_deletion(volume_id)
 
     @test.attr(type='gate')
+    @test.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/telemetry/test_telemetry_alarming_api.py b/tempest/api/telemetry/test_telemetry_alarming_api.py
index cb2d2bd..768b6ea 100644
--- a/tempest/api/telemetry/test_telemetry_alarming_api.py
+++ b/tempest/api/telemetry/test_telemetry_alarming_api.py
@@ -30,6 +30,7 @@
             cls.create_alarm(threshold_rule=cls.rule)
 
     @test.attr(type="gate")
+    @test.idempotent_id('1c918e06-210b-41eb-bd45-14676dd77cd6')
     def test_alarm_list(self):
         # List alarms
         alarm_list = self.telemetry_client.list_alarms()
@@ -43,6 +44,7 @@
                          ', '.join(str(a) for a in missing_alarms))
 
     @test.attr(type="gate")
+    @test.idempotent_id('1297b095-39c1-4e74-8a1f-4ae998cedd67')
     def test_create_update_get_delete_alarm(self):
         # Create an alarm
         alarm_name = data_utils.rand_name('telemetry_alarm')
@@ -74,6 +76,7 @@
                           self.telemetry_client.get_alarm, alarm_id)
 
     @test.attr(type="gate")
+    @test.idempotent_id('aca49486-70bb-4016-87e0-f6131374f741')
     def test_set_get_alarm_state(self):
         alarm_states = ['ok', 'alarm', 'insufficient data']
         alarm = self.create_alarm(threshold_rule=self.rule)
@@ -88,6 +91,7 @@
         self.assertEqual(new_state, state.data)
 
     @test.attr(type="gate")
+    @test.idempotent_id('08d7e45a-1344-4e5c-ba6f-f6cbb77f55b9')
     def test_create_delete_alarm_with_combination_rule(self):
         rule = {"alarm_ids": self.alarm_ids,
                 "operator": "or"}
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index a0256af..6862401 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -30,6 +30,7 @@
                                     "is disabled")
 
     @test.attr(type="gate")
+    @test.idempotent_id('d7f8c1c8-d470-4731-8604-315d3956caad')
     @testtools.skipIf(not CONF.service_available.nova,
                       "Nova is not available.")
     def test_check_nova_notification(self):
@@ -42,6 +43,7 @@
             self.await_samples(metric, query)
 
     @test.attr(type="smoke")
+    @test.idempotent_id('04b10bfe-a5dc-47af-b22f-0460426bf498')
     @test.services("image")
     @testtools.skipIf(not CONF.image_feature_enabled.api_v1,
                       "Glance api v1 is disabled")
@@ -58,6 +60,7 @@
             self.await_samples(metric, query)
 
     @test.attr(type="smoke")
+    @test.idempotent_id('c240457d-d943-439b-8aea-85e26d64fe8e')
     @test.services("image")
     @testtools.skipIf(not CONF.image_feature_enabled.api_v2,
                       "Glance api v2 is disabled")
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 32cdb01..97dd104 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -101,18 +101,21 @@
         super(VolumeMultiBackendV2Test, cls).resource_cleanup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c1a41f3f-9dad-493e-9f09-3ff197d477cc')
     def test_backend_name_reporting(self):
         # get volume id which created by type without prefix
         volume_id = self.volume_id_list_without_prefix[0]
         self._test_backend_name_reporting_by_volume_id(volume_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f38e647f-ab42-4a31-a2e7-ca86a6485215')
     def test_backend_name_reporting_with_prefix(self):
         # get volume id which created by type with prefix
         volume_id = self.volume_id_list_with_prefix[0]
         self._test_backend_name_reporting_by_volume_id(volume_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('46435ab1-a0af-4401-8373-f14e66b0dd58')
     def test_backend_name_distinction(self):
         if self.backend1_name == self.backend2_name:
             raise self.skipException("backends configured with same name")
@@ -122,6 +125,7 @@
         self._test_backend_name_distinction(volume1_id, volume2_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4236305b-b65a-4bfc-a9d2-69cb5b2bf2ed')
     def test_backend_name_distinction_with_prefix(self):
         if self.backend1_name == self.backend2_name:
             raise self.skipException("backends configured with same name")
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index a4b4e3e..469f13e 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -81,6 +81,7 @@
         return 'os-extended-snapshot-attributes:progress'
 
     @test.attr(type='gate')
+    @test.idempotent_id('3e13ca2f-48ea-49f3-ae1a-488e9180d535')
     def test_reset_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
@@ -91,6 +92,7 @@
         self.assertEqual(status, snapshot_get['status'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('41288afd-d463-485e-8f6e-4eea159413eb')
     def test_update_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
@@ -109,21 +111,25 @@
         self.assertEqual(progress, snapshot_get[progress_alias])
 
     @test.attr(type='gate')
+    @test.idempotent_id('05f711b6-e629-4895-8103-7ca069f2073a')
     def test_snapshot_force_delete_when_snapshot_is_creating(self):
         # test force delete when status of snapshot is creating
         self._create_reset_and_force_delete_temp_snapshot('creating')
 
     @test.attr(type='gate')
+    @test.idempotent_id('92ce8597-b992-43a1-8868-6316b22a969e')
     def test_snapshot_force_delete_when_snapshot_is_deleting(self):
         # test force delete when status of snapshot is deleting
         self._create_reset_and_force_delete_temp_snapshot('deleting')
 
     @test.attr(type='gate')
+    @test.idempotent_id('645a4a67-a1eb-4e8e-a547-600abac1525d')
     def test_snapshot_force_delete_when_snapshot_is_error(self):
         # test force delete when status of snapshot is error
         self._create_reset_and_force_delete_temp_snapshot('error')
 
     @test.attr(type='gate')
+    @test.idempotent_id('bf89080f-8129-465e-9327-b2f922666ba5')
     def test_snapshot_force_delete_when_snapshot_is_error_deleting(self):
         # test force delete when status of snapshot is error_deleting
         self._create_reset_and_force_delete_temp_snapshot('error_deleting')
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index 8189aab..551dc6f 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -20,6 +20,7 @@
 class VolumeHostsAdminV2TestsJSON(base.BaseVolumeAdminTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('d5f3efa2-6684-4190-9ced-1c2f526352ad')
     def test_list_hosts(self):
         hosts = self.hosts_client.list_hosts()
         self.assertTrue(len(hosts) >= 2, "No. of hosts are < 2,"
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index f41a97e..9b436aa 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -31,12 +31,14 @@
         cls.demo_tenant_id = cls.isolated_creds.get_primary_creds().tenant_id
 
     @test.attr(type='gate')
+    @test.idempotent_id('59eada70-403c-4cef-a2a3-a8ce2f1b07a0')
     def test_list_quotas(self):
         quotas = self.quotas_client.get_quota_set(self.demo_tenant_id)
         for key in QUOTA_KEYS:
             self.assertIn(key, quotas)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2be020a2-5fdd-423d-8d35-a7ffbc36e9f7')
     def test_list_default_quotas(self):
         quotas = self.quotas_client.get_default_quota_set(
             self.demo_tenant_id)
@@ -44,6 +46,7 @@
             self.assertIn(key, quotas)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3d45c99e-cc42-4424-a56e-5cbd212b63a6')
     def test_update_all_quota_resources_for_tenant(self):
         # Admin can update all the resource quota limits for a tenant
         default_quota_set = self.quotas_client.get_default_quota_set(
@@ -68,6 +71,7 @@
         self.assertDictContainsSubset(new_quota_set, quota_set)
 
     @test.attr(type='gate')
+    @test.idempotent_id('18c51ae9-cb03-48fc-b234-14a19374dbed')
     def test_show_quota_usage(self):
         quota_usage = self.quotas_client.get_quota_usage(
             self.os_adm.credentials.tenant_id)
@@ -77,6 +81,7 @@
                 self.assertIn(usage_key, quota_usage[key])
 
     @test.attr(type='gate')
+    @test.idempotent_id('ae8b6091-48ad-4bfa-a188-bbf5cc02115f')
     def test_quota_usage(self):
         quota_usage = self.quotas_client.get_quota_usage(
             self.demo_tenant_id)
@@ -95,6 +100,7 @@
                          new_quota_usage['gigabytes']['in_use'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('874b35a9-51f1-4258-bec5-cd561b6690d3')
     def test_delete_quota(self):
         # Admin can delete the resource quota set for a tenant
         tenant_name = data_utils.rand_name('quota_tenant_')
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index e37d8f2..67edd09 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -45,18 +45,21 @@
         cls.snapshot = cls.create_snapshot(cls.volume['id'])
 
     @test.attr(type='negative')
+    @test.idempotent_id('bf544854-d62a-47f2-a681-90f7a47d86b6')
     def test_quota_volumes(self):
         self.assertRaises(lib_exc.OverLimit,
                           self.volumes_client.create_volume,
                           size=1)
 
     @test.attr(type='negative')
+    @test.idempotent_id('02bbf63f-6c05-4357-9d98-2926a94064ff')
     def test_quota_volume_snapshots(self):
         self.assertRaises(lib_exc.OverLimit,
                           self.snapshots_client.create_snapshot,
                           self.volume['id'])
 
     @test.attr(type='negative')
+    @test.idempotent_id('2dc27eee-8659-4298-b900-169d71a91374')
     def test_quota_volume_gigabytes(self):
         # NOTE(gfidente): quota set needs to be changed for this test
         # or we may be limited by the volumes or snaps quota number, not by
diff --git a/tempest/api/volume/admin/test_volume_services.py b/tempest/api/volume/admin/test_volume_services.py
index 3bab185..cc4f1a0 100644
--- a/tempest/api/volume/admin/test_volume_services.py
+++ b/tempest/api/volume/admin/test_volume_services.py
@@ -31,11 +31,13 @@
         cls.binary_name = cls.services[0]['binary']
 
     @test.attr(type='gate')
+    @test.idempotent_id('e0218299-0a59-4f43-8b2b-f1c035b3d26d')
     def test_list_services(self):
         services = self.admin_volume_services_client.list_services()
         self.assertNotEqual(0, len(services))
 
     @test.attr(type='gate')
+    @test.idempotent_id('63a3e1ca-37ee-4983-826d-83276a370d25')
     def test_get_service_by_service_binary_name(self):
         params = {'binary': self.binary_name}
         services = self.admin_volume_services_client.list_services(params)
@@ -44,6 +46,7 @@
             self.assertEqual(self.binary_name, service['binary'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('178710e4-7596-4e08-9333-745cb8bc4f8d')
     def test_get_service_by_host_name(self):
         services_on_host = [service for service in self.services if
                             service['host'] == self.host_name]
@@ -60,6 +63,7 @@
         self.assertEqual(sorted(s1), sorted(s2))
 
     @test.attr(type='gate')
+    @test.idempotent_id('ffa6167c-4497-4944-a464-226bbdb53908')
     def test_get_service_by_service_and_host_name(self):
         params = {'host': self.host_name, 'binary': self.binary_name}
 
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index d4062cc..8705f6f 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -31,12 +31,14 @@
         self.volume_types_client.delete_volume_type(volume_type_id)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('9d9b28e3-1b2e-4483-a2cc-24aa0ea1de54')
     def test_volume_type_list(self):
         # List Volume types.
         body = self.volume_types_client.list_volume_types()
         self.assertIsInstance(body, list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c03cc62c-f4e9-4623-91ec-64ce2f9c1260')
     def test_volume_crud_with_volume_type_and_extra_specs(self):
         # Create/update/get/delete volume with volume_type and extra spec.
         volume_types = list()
@@ -87,6 +89,7 @@
                          'from the created Volume')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('4e955c3b-49db-4515-9590-0c99f8e471ad')
     def test_volume_type_create_get_delete(self):
         # Create/get volume type.
         body = {}
@@ -119,6 +122,7 @@
                          'from the created Volume_type')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7830abd0-ff99-4793-a265-405684a54d46')
     def test_volume_type_encryption_create_get_delete(self):
         # Create/get/delete encryption type.
         provider = "LuksEncryptor"
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 1ce1402..5ca838e 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -33,6 +33,7 @@
         super(VolumeTypesExtraSpecsV2Test, cls).resource_cleanup()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('b42923e9-0452-4945-be5b-d362ae533e60')
     def test_volume_type_extra_specs_list(self):
         # List Volume types extra specs.
         extra_specs = {"spec1": "val1"}
@@ -46,6 +47,7 @@
         self.assertIn('spec1', body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('0806db36-b4a0-47a1-b6f3-c2e7f194d017')
     def test_volume_type_extra_specs_update(self):
         # Update volume type extra specs
         extra_specs = {"spec2": "val1"}
@@ -64,6 +66,7 @@
                          "Volume type extra spec incorrectly updated")
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d4772798-601f-408a-b2a5-29e8a59d1220')
     def test_volume_type_extra_spec_create_get_delete(self):
         # Create/Get/Delete volume type extra spec.
         extra_specs = {"spec3": "val1"}
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index 23979cd..6d2c4fb 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -39,6 +39,7 @@
         super(ExtraSpecsNegativeV2Test, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('08961d20-5cbb-4910-ac0f-89ad6dbb2da1')
     def test_update_no_body(self):
         # Should not update volume type extra specs with no body
         extra_spec = {"spec1": "val2"}
@@ -48,6 +49,7 @@
             self.volume_type['id'], extra_spec.keys()[0], None)
 
     @test.attr(type='gate')
+    @test.idempotent_id('25e5a0ee-89b3-4c53-8310-236f76c75365')
     def test_update_nonexistent_extra_spec_id(self):
         # Should not update volume type extra specs with nonexistent id.
         extra_spec = {"spec1": "val2"}
@@ -58,6 +60,7 @@
             extra_spec)
 
     @test.attr(type='gate')
+    @test.idempotent_id('9bf7a657-b011-4aec-866d-81c496fbe5c8')
     def test_update_none_extra_spec_id(self):
         # Should not update volume type extra specs with none id.
         extra_spec = {"spec1": "val2"}
@@ -67,6 +70,7 @@
             self.volume_type['id'], None, extra_spec)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a77dfda2-9100-448e-9076-ed1711f4bdfc')
     def test_update_multiple_extra_spec(self):
         # Should not update volume type extra specs with multiple specs as
             # body.
@@ -78,6 +82,7 @@
             extra_spec)
 
     @test.attr(type='gate')
+    @test.idempotent_id('49d5472c-a53d-4eab-a4d3-450c4db1c545')
     def test_create_nonexistent_type_id(self):
         # Should not create volume type extra spec for nonexistent volume
             # type id.
@@ -88,6 +93,7 @@
             str(uuid.uuid4()), extra_specs)
 
     @test.attr(type='gate')
+    @test.idempotent_id('c821bdc8-43a4-4bf4-86c8-82f3858d5f7d')
     def test_create_none_body(self):
         # Should not create volume type extra spec for none POST body.
         self.assertRaises(
@@ -96,6 +102,7 @@
             self.volume_type['id'], None)
 
     @test.attr(type='gate')
+    @test.idempotent_id('bc772c71-1ed4-4716-b945-8b5ed0f15e87')
     def test_create_invalid_body(self):
         # Should not create volume type extra spec for invalid POST body.
         self.assertRaises(
@@ -104,6 +111,7 @@
             self.volume_type['id'], ['invalid'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('031cda8b-7d23-4246-8bf6-bbe73fd67074')
     def test_delete_nonexistent_volume_type_id(self):
         # Should not delete volume type extra spec for nonexistent
             # type id.
@@ -114,6 +122,7 @@
             str(uuid.uuid4()), extra_specs.keys()[0])
 
     @test.attr(type='gate')
+    @test.idempotent_id('dee5cf0c-cdd6-4353-b70c-e847050d71fb')
     def test_list_nonexistent_volume_type_id(self):
         # Should not list volume type extra spec for nonexistent type id.
         self.assertRaises(
@@ -122,6 +131,7 @@
             str(uuid.uuid4()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('9f402cbd-1838-4eb4-9554-126a6b1908c9')
     def test_get_nonexistent_volume_type_id(self):
         # Should not get volume type extra spec for nonexistent type id.
         extra_specs = {"spec1": "val1"}
@@ -131,6 +141,7 @@
             str(uuid.uuid4()), extra_specs.keys()[0])
 
     @test.attr(type='gate')
+    @test.idempotent_id('c881797d-12ff-4f1a-b09d-9f6212159753')
     def test_get_nonexistent_extra_spec_id(self):
         # Should not get volume type extra spec for nonexistent extra spec
             # id.
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index a40f1c4..eb46a54 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -24,6 +24,7 @@
 class VolumeTypesNegativeV2Test(base.BaseVolumeAdminTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('b48c98f2-e662-4885-9b71-032256906314')
     def test_create_with_nonexistent_volume_type(self):
         # Should not be able to create volume with nonexistent volume_type.
         self.name_field = self.special_fields['name_field']
@@ -34,12 +35,14 @@
                           **params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('878b4e57-faa2-4659-b0d1-ce740a06ae81')
     def test_create_with_empty_name(self):
         # Should not be able to create volume type with an empty name.
         self.assertRaises(lib_exc.BadRequest,
                           self.volume_types_client.create_volume_type, '')
 
     @test.attr(type='gate')
+    @test.idempotent_id('994610d6-0476-4018-a644-a2602ef5d4aa')
     def test_get_nonexistent_type_id(self):
         # Should not be able to get volume type with nonexistent type id.
         self.assertRaises(lib_exc.NotFound,
@@ -47,6 +50,7 @@
                           str(uuid.uuid4()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('6b3926d2-7d73-4896-bc3d-e42dfd11a9f6')
     def test_delete_nonexistent_type_id(self):
         # Should not be able to delete volume type with nonexistent type id.
         self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index fb16872..b0013e6 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -76,6 +76,7 @@
         self.client.wait_for_resource_deletion(temp_volume['id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d063f96e-a2e0-4f34-8b8a-395c42de1845')
     def test_volume_reset_status(self):
         # test volume reset status : available->error->available
         self._reset_volume_status(self.volume['id'], 'error')
@@ -83,15 +84,18 @@
             self.volume['id'])
         self.assertEqual('error', volume_get['status'])
 
+    @test.idempotent_id('21737d5a-92f2-46d7-b009-a0cc0ee7a570')
     def test_volume_force_delete_when_volume_is_creating(self):
         # test force delete when status of volume is creating
         self._create_reset_and_force_delete_temp_volume('creating')
 
+    @test.idempotent_id('db8d607a-aa2e-4beb-b51d-d4005c232011')
     def test_volume_force_delete_when_volume_is_attaching(self):
         # test force delete when status of volume is attaching
         self._create_reset_and_force_delete_temp_volume('attaching')
 
     @test.attr(type='gate')
+    @test.idempotent_id('3e33a8a8-afd4-4d64-a86b-c27a185c5a4a')
     def test_volume_force_delete_when_volume_is_error(self):
         # test force delete when status of volume is error
         self._create_reset_and_force_delete_temp_volume('error')
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index 4db9f7e..6b0580f 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -38,6 +38,7 @@
         cls.volume = cls.create_volume()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('a66eb488-8ee1-47d4-8e9f-575a095728c6')
     def test_volume_backup_create_get_detailed_list_restore_delete(self):
         # Create backup
         backup_name = data_utils.rand_name('Backup')
diff --git a/tempest/api/volume/test_availability_zone.py b/tempest/api/volume/test_availability_zone.py
index b6e226d..e63cfcd 100644
--- a/tempest/api/volume/test_availability_zone.py
+++ b/tempest/api/volume/test_availability_zone.py
@@ -29,6 +29,7 @@
         cls.client = cls.availability_zone_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('01f1ae88-eba9-4c6b-a011-6f7ace06b725')
     def test_get_availability_zone_list(self):
         # List of availability zone
         availability_zone = self.client.get_availability_zone_list()
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
index dbbdea4..e5fe3c8 100644
--- a/tempest/api/volume/test_extensions.py
+++ b/tempest/api/volume/test_extensions.py
@@ -28,6 +28,7 @@
 class ExtensionsV2TestJSON(base.BaseVolumeTest):
 
     @test.attr(type='gate')
+    @test.idempotent_id('94607eb0-43a5-47ca-82aa-736b41bd2e2c')
     def test_list_extensions(self):
         # List of all extensions
         extensions = self.volumes_extension_client.list_extensions()
diff --git a/tempest/api/volume/test_qos.py b/tempest/api/volume/test_qos.py
index 60c327b..b08a019 100644
--- a/tempest/api/volume/test_qos.py
+++ b/tempest/api/volume/test_qos.py
@@ -72,6 +72,7 @@
 
         return associations
 
+    @test.idempotent_id('7e15f883-4bef-49a9-95eb-f94209a1ced1')
     def test_create_delete_qos_with_front_end_consumer(self):
         """Tests the creation and deletion of QoS specs
 
@@ -79,6 +80,7 @@
         """
         self._create_delete_test_qos_with_given_consumer('front-end')
 
+    @test.idempotent_id('b115cded-8f58-4ee4-aab5-9192cfada08f')
     def test_create_delete_qos_with_back_end_consumer(self):
         """Tests the creation and deletion of QoS specs
 
@@ -87,6 +89,7 @@
         self._create_delete_test_qos_with_given_consumer('back-end')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f88d65eb-ea0d-487d-af8d-71f4011575a4')
     def test_create_delete_qos_with_both_consumer(self):
         """Tests the creation and deletion of QoS specs
 
@@ -95,6 +98,7 @@
         self._create_delete_test_qos_with_given_consumer('both')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7aa214cc-ac1a-4397-931f-3bb2e83bb0fd')
     def test_get_qos(self):
         """Tests the detail of a given qos-specs"""
         body = self.volume_qos_client.get_qos(self.created_qos['id'])
@@ -102,12 +106,14 @@
         self.assertEqual(self.qos_consumer, body['consumer'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('75e04226-bcf7-4595-a34b-fdf0736f38fc')
     def test_list_qos(self):
         """Tests the list of all qos-specs"""
         body = self.volume_qos_client.list_qos()
         self.assertIn(self.created_qos, body)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ed00fd85-4494-45f2-8ceb-9e2048919aed')
     def test_set_unset_qos_key(self):
         """Test the addition of a specs key to qos-specs"""
         args = {'iops_bytes': '500'}
@@ -127,6 +133,7 @@
         self.assertNotIn(keys[0], body['specs'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1dd93c76-6420-485d-a771-874044c416ac')
     def test_associate_disassociate_qos(self):
         """Test the following operations :
 
diff --git a/tempest/api/volume/test_snapshot_metadata.py b/tempest/api/volume/test_snapshot_metadata.py
index e1fe779..d4efc2a 100644
--- a/tempest/api/volume/test_snapshot_metadata.py
+++ b/tempest/api/volume/test_snapshot_metadata.py
@@ -39,6 +39,7 @@
         super(SnapshotV2MetadataTestJSON, self).tearDown()
 
     @test.attr(type='gate')
+    @test.idempotent_id('a2f20f99-e363-4584-be97-bc33afb1a56c')
     def test_create_get_delete_snapshot_metadata(self):
         # Create metadata for the snapshot
         metadata = {"key1": "value1",
@@ -58,6 +59,7 @@
         self.assertEqual(expected, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('bd2363bc-de92-48a4-bc98-28943c6e4be1')
     def test_update_snapshot_metadata(self):
         # Update metadata for the snapshot
         metadata = {"key1": "value1",
@@ -79,6 +81,7 @@
         self.assertEqual(update, body)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e8ff85c5-8f97-477f-806a-3ac364a949ed')
     def test_update_snapshot_metadata_item(self):
         # Update metadata item for the snapshot
         metadata = {"key1": "value1",
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index 4739fd2..e601349 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -34,6 +34,7 @@
         super(VolumesV2MetadataTest, self).tearDown()
 
     @test.attr(type='gate')
+    @test.idempotent_id('6f5b125b-f664-44bf-910f-751591fe5769')
     def test_create_get_delete_volume_metadata(self):
         # Create metadata for the volume
         metadata = {"key1": "value1",
@@ -55,6 +56,7 @@
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('774d2918-9beb-4f30-b3d1-2a4e8179ec0a')
     def test_update_volume_metadata(self):
         # Update metadata for the volume
         metadata = {"key1": "value1",
@@ -78,6 +80,7 @@
         self.assertThat(body.items(), matchers.ContainsAll(update.items()))
 
     @test.attr(type='gate')
+    @test.idempotent_id('862261c5-8df4-475a-8c21-946e50e36a20')
     def test_update_volume_metadata_item(self):
         # Update metadata item for the volume
         metadata = {"key1": "value1",
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 6f75403..40947df 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -57,6 +57,7 @@
         self.adm_client.wait_for_resource_deletion(volume_id)
 
     @test.attr(type='gate')
+    @test.idempotent_id('4d75b645-a478-48b1-97c8-503f64242f1a')
     def test_create_get_list_accept_volume_transfer(self):
         # Create a volume first
         volume = self.create_volume()
@@ -83,6 +84,7 @@
                                                       auth_key)
         self.alt_client.wait_for_volume_status(volume['id'], 'available')
 
+    @test.idempotent_id('ab526943-b725-4c07-b875-8e8ef87a2c30')
     def test_create_list_delete_volume_transfer(self):
         # Create a volume first
         volume = self.create_volume()
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index e5f7aa4..5cad6b4 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -56,6 +56,7 @@
 
         super(VolumesV2ActionsTest, cls).resource_cleanup()
 
+    @test.idempotent_id('fff42874-7db5-4487-a8e1-ddda5fb5288d')
     @test.stresstest(class_setup_per='process')
     @test.attr(type='smoke')
     @test.services('compute')
@@ -69,6 +70,7 @@
         self.client.detach_volume(self.volume['id'])
         self.client.wait_for_volume_status(self.volume['id'], 'available')
 
+    @test.idempotent_id('9516a2c8-9135-488c-8dd6-5677a7e5f371')
     @test.stresstest(class_setup_per='process')
     @test.attr(type='gate')
     @test.services('compute')
@@ -94,6 +96,7 @@
         self.assertEqual(self.volume['id'], attachment['volume_id'])
 
     @test.attr(type='gate')
+    @test.idempotent_id('d8f1ca95-3d5b-44a3-b8ca-909691c9532d')
     @test.services('image')
     def test_volume_upload(self):
         # NOTE(gfidente): the volume uploaded in Glance comes from setUpClass,
@@ -110,6 +113,7 @@
         self.client.wait_for_volume_status(self.volume['id'], 'available')
 
     @test.attr(type='gate')
+    @test.idempotent_id('92c4ef64-51b2-40c0-9f7e-4749fbaaba33')
     def test_reserve_unreserve_volume(self):
         # Mark volume as reserved.
         body = self.client.reserve_volume(self.volume['id'])
@@ -126,6 +130,7 @@
         return val in ['true', 'True', True]
 
     @test.attr(type='gate')
+    @test.idempotent_id('fff74e1e-5bd3-4b33-9ea9-24c103bc3f59')
     def test_volume_readonly_update(self):
         # Update volume readonly true
         readonly = True
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index fab25ec..35c12bc 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -28,6 +28,7 @@
         cls.client = cls.volumes_client
 
     @test.attr(type='gate')
+    @test.idempotent_id('9a36df71-a257-43a5-9555-dc7c88e66e0e')
     def test_volume_extend(self):
         # Extend Volume Test.
         self.volume = self.create_volume()
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 3133df4..007b0db 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -123,15 +123,18 @@
             self.assertEqual('false', updated_volume['bootable'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51')
     def test_volume_create_get_update_delete(self):
         self._volume_create_get_update_delete()
 
     @test.attr(type='smoke')
+    @test.idempotent_id('54a01030-c7fc-447c-86ee-c1182beae638')
     @test.services('image')
     def test_volume_create_get_update_delete_from_image(self):
         self._volume_create_get_update_delete(imageRef=CONF.compute.image_ref)
 
     @test.attr(type='gate')
+    @test.idempotent_id('3f591b4a-7dc6-444c-bd51-77469506b3a1')
     def test_volume_create_get_update_delete_as_clone(self):
         origin = self.create_volume()
         self._volume_create_get_update_delete(source_volid=origin['id'])
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 9a8746a..ef7cebb 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -112,6 +112,7 @@
                         self.assertEqual(params[key], volume[key], msg)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('0b6ddd39-b948-471f-8038-4787978747c4')
     def test_volume_list(self):
         # Get a list of Volumes
         # Fetch all volumes
@@ -120,6 +121,7 @@
                              fields=self.VOLUME_FIELDS)
 
     @test.attr(type='gate')
+    @test.idempotent_id('adcbb5a7-5ad8-4b61-bd10-5380e111a877')
     def test_volume_list_with_details(self):
         # Get a list of Volumes with details
         # Fetch all Volumes
@@ -127,6 +129,7 @@
         self.assertVolumesIn(fetched_list, self.volume_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('a28e8da4-0b56-472f-87a8-0f4d3f819c02')
     def test_volume_list_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {self.name: volume[self.name]}
@@ -136,6 +139,7 @@
                          volume[self.name])
 
     @test.attr(type='gate')
+    @test.idempotent_id('2de3a6d4-12aa-403b-a8f2-fdeb42a89623')
     def test_volume_list_details_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {self.name: volume[self.name]}
@@ -145,6 +149,7 @@
                          volume[self.name])
 
     @test.attr(type='gate')
+    @test.idempotent_id('39654e13-734c-4dab-95ce-7613bf8407ce')
     def test_volumes_list_by_status(self):
         params = {'status': 'available'}
         fetched_list = self.client.list_volumes(params)
@@ -153,6 +158,7 @@
                              fields=self.VOLUME_FIELDS)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2943f712-71ec-482a-bf49-d5ca06216b9f')
     def test_volumes_list_details_by_status(self):
         params = {'status': 'available'}
         fetched_list = self.client.list_volumes_with_detail(params)
@@ -161,6 +167,7 @@
         self.assertVolumesIn(fetched_list, self.volume_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('c0cfa863-3020-40d7-b587-e35f597d5d87')
     def test_volumes_list_by_availability_zone(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
@@ -171,6 +178,7 @@
                              fields=self.VOLUME_FIELDS)
 
     @test.attr(type='gate')
+    @test.idempotent_id('e1b80d13-94f0-4ba2-a40e-386af29f8db1')
     def test_volumes_list_details_by_availability_zone(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
@@ -181,18 +189,21 @@
         self.assertVolumesIn(fetched_list, self.volume_list)
 
     @test.attr(type='gate')
+    @test.idempotent_id('b5ebea1b-0603-40a0-bb41-15fcd0a53214')
     def test_volume_list_with_param_metadata(self):
         # Test to list volumes when metadata param is given
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d')
     def test_volume_list_with_detail_param_metadata(self):
         # Test to list volumes details when metadata param is given
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
     @test.attr(type='gate')
+    @test.idempotent_id('777c87c1-2fc4-4883-8b8e-5c0b951d1ec8')
     def test_volume_list_param_display_name_and_status(self):
         # Test to list volume when display name and status param is given
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
@@ -201,6 +212,7 @@
         self._list_by_param_value_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('856ab8ca-6009-4c37-b691-be1065528ad4')
     def test_volume_list_with_detail_param_display_name_and_status(self):
         # Test to list volume when name and status param is given
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index c827f9e..27fd495 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -40,18 +40,21 @@
         cls.mountpoint = "/dev/vdc"
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f131c586-9448-44a4-a8b0-54ca838aa43e')
     def test_volume_get_nonexistent_volume_id(self):
         # Should not be able to get a non-existent volume
         self.assertRaises(lib_exc.NotFound, self.client.get_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('555efa6e-efcd-44ef-8a3b-4a7ca4837a29')
     def test_volume_delete_nonexistent_volume_id(self):
         # Should not be able to delete a non-existent Volume
         self.assertRaises(lib_exc.NotFound, self.client.delete_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1ed83a8a-682d-4dfb-a30e-ee63ffd6c049')
     def test_create_volume_with_invalid_size(self):
         # Should not be able to create volume with invalid size
         # in request
@@ -61,6 +64,7 @@
                           size='#$%', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9387686f-334f-4d31-a439-33494b9e2683')
     def test_create_volume_with_out_passing_size(self):
         # Should not be able to create volume without passing size
         # in request
@@ -70,6 +74,7 @@
                           size='', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @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('Volume-')
@@ -78,6 +83,7 @@
                           size='0', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @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('Volume-')
@@ -86,6 +92,7 @@
                           size='-1', display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @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('Volume-')
@@ -95,6 +102,7 @@
                           display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @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('Volume-')
@@ -104,6 +112,7 @@
                           display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @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('Volume-')
@@ -113,6 +122,7 @@
                           display_name=v_name, metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0186422c-999a-480e-a026-6a665744c30c')
     def test_update_volume_with_nonexistent_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -121,6 +131,7 @@
                           metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e66e40d6-65e6-4e75-bdc7-636792fa152d')
     def test_update_volume_with_invalid_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -129,6 +140,7 @@
                           metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('72aeca85-57a5-4c1f-9057-f320f9ea575b')
     def test_update_volume_with_empty_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -137,28 +149,33 @@
                           metadata=metadata)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('30799cfd-7ee4-446c-b66c-45b383ed211b')
     def test_get_invalid_volume_id(self):
         # Should not be able to get volume with invalid id
         self.assertRaises(lib_exc.NotFound, self.client.get_volume,
                           '#$%%&^&^')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('c6c3db06-29ad-4e91-beb0-2ab195fe49e3')
     def test_get_volume_without_passing_volume_id(self):
         # Should not be able to get volume when empty ID is passed
         self.assertRaises(lib_exc.NotFound, self.client.get_volume, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('1f035827-7c32-4019-9240-b4ec2dbd9dfd')
     def test_delete_invalid_volume_id(self):
         # Should not be able to delete volume when invalid ID is passed
         self.assertRaises(lib_exc.NotFound, self.client.delete_volume,
                           '!@#$%^&*()')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('441a1550-5d44-4b30-af0f-a6d402f52026')
     def test_delete_volume_without_passing_volume_id(self):
         # Should not be able to delete volume when empty ID is passed
         self.assertRaises(lib_exc.NotFound, self.client.delete_volume, '')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('f5e56b0a-5d02-43c1-a2a7-c9b792c2e3f6')
     @test.services('compute')
     def test_attach_volumes_with_nonexistent_volume_id(self):
         srv_name = data_utils.rand_name('Instance-')
@@ -174,12 +191,14 @@
                           self.mountpoint)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9f9c24e4-011d-46b5-b992-952140ce237a')
     def test_detach_volumes_with_invalid_volume_id(self):
         self.assertRaises(lib_exc.NotFound,
                           self.client.detach_volume,
                           'xxx')
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e0c75c74-ee34-41a9-9288-2a2051452854')
     def test_volume_extend_with_size_smaller_than_original_size(self):
         # Extend volume with smaller size than original size.
         extend_size = 0
@@ -187,6 +206,7 @@
                           self.volume['id'], extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('5d0b480d-e833-439f-8a5a-96ad2ed6f22f')
     def test_volume_extend_with_non_number_size(self):
         # Extend volume when size is non number.
         extend_size = 'abc'
@@ -194,6 +214,7 @@
                           self.volume['id'], extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('355218f1-8991-400a-a6bb-971239287d92')
     def test_volume_extend_with_None_size(self):
         # Extend volume with None size.
         extend_size = None
@@ -201,6 +222,7 @@
                           self.volume['id'], extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('8f05a943-013c-4063-ac71-7baf561e82eb')
     def test_volume_extend_with_nonexistent_volume_id(self):
         # Extend volume size when volume is nonexistent.
         extend_size = int(self.volume['size']) + 1
@@ -208,6 +230,7 @@
                           str(uuid.uuid4()), extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('aff8ba64-6d6f-4f2e-bc33-41a08ee9f115')
     def test_volume_extend_without_passing_volume_id(self):
         # Extend volume size when passing volume id is None.
         extend_size = int(self.volume['size']) + 1
@@ -215,18 +238,21 @@
                           None, extend_size)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ac6084c0-0546-45f9-b284-38a367e0e0e2')
     def test_reserve_volume_with_nonexistent_volume_id(self):
         self.assertRaises(lib_exc.NotFound,
                           self.client.reserve_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('eb467654-3dc1-4a72-9b46-47c29d22654c')
     def test_unreserve_volume_with_nonexistent_volume_id(self):
         self.assertRaises(lib_exc.NotFound,
                           self.client.unreserve_volume,
                           str(uuid.uuid4()))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('449c4ed2-ecdd-47bb-98dc-072aeccf158c')
     def test_reserve_volume_with_negative_volume_status(self):
         # Mark volume as reserved.
         self.client.reserve_volume(self.volume['id'])
@@ -238,6 +264,7 @@
         self.client.unreserve_volume(self.volume['id'])
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f')
     def test_list_volumes_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {self.name_field: v_name}
@@ -245,6 +272,7 @@
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('9ca17820-a0e7-4cbd-a7fa-f4468735e359')
     def test_list_volumes_detail_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {self.name_field: v_name}
@@ -253,12 +281,14 @@
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('143b279b-7522-466b-81be-34a87d564a7c')
     def test_list_volumes_with_invalid_status(self):
         params = {'status': 'null'}
         fetched_volume = self.client.list_volumes(params)
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('ba94b27b-be3f-496c-a00e-0283b373fa75')
     def test_list_volumes_detail_with_invalid_status(self):
         params = {'status': 'null'}
         fetched_volume = \
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index c4f8096..3c1cce3 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -62,6 +62,7 @@
                 self.assertEqual(params[key], snap[key], msg)
 
     @test.attr(type='gate')
+    @test.idempotent_id('b467b54c-07a4-446d-a1cf-651dedcc3ff1')
     @test.services('compute')
     def test_snapshot_create_with_volume_in_use(self):
         # Create a snapshot when volume status is in-use
@@ -90,6 +91,7 @@
         self.snapshots.remove(snapshot)
 
     @test.attr(type='gate')
+    @test.idempotent_id('2a8abbe4-d871-46db-b049-c41f5af8216e')
     def test_snapshot_create_get_list_update_delete(self):
         # Create a snapshot
         s_name = data_utils.rand_name('snap')
@@ -130,6 +132,7 @@
         self.snapshots.remove(snapshot)
 
     @test.attr(type='gate')
+    @test.idempotent_id('59f41f43-aebf-48a9-ab5d-d76340fab32b')
     def test_snapshots_list_with_params(self):
         """list snapshots with params."""
         # Create a snapshot
@@ -151,6 +154,7 @@
         self._list_by_param_values_and_assert(params)
 
     @test.attr(type='gate')
+    @test.idempotent_id('220a1022-1fcd-4a74-a7bd-6b859156cda2')
     def test_snapshots_list_details_with_params(self):
         """list snapshot details with params."""
         # Create a snapshot
@@ -170,6 +174,7 @@
         self._list_by_param_values_and_assert(params, with_detail=True)
 
     @test.attr(type='gate')
+    @test.idempotent_id('677863d1-3142-456d-b6ac-9924f667a7f4')
     def test_volume_from_snapshot(self):
         # Create a temporary snap using wrapper method from base, then
         # create a snap based volume and deletes it
diff --git a/tempest/api/volume/test_volumes_snapshots_negative.py b/tempest/api/volume/test_volumes_snapshots_negative.py
index 3ad23f7..fbbc623 100644
--- a/tempest/api/volume/test_volumes_snapshots_negative.py
+++ b/tempest/api/volume/test_volumes_snapshots_negative.py
@@ -31,6 +31,7 @@
             raise cls.skipException("Cinder volume snapshots are disabled")
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('e3e466af-70ab-4f4b-a967-ab04e3532ea7')
     def test_create_snapshot_with_nonexistent_volume_id(self):
         # Create a snapshot with nonexistent volume id
         s_name = data_utils.rand_name('snap')
@@ -39,6 +40,7 @@
                           str(uuid.uuid4()), display_name=s_name)
 
     @test.attr(type=['negative', 'gate'])
+    @test.idempotent_id('bb9da53e-d335-4309-9c15-7e76fd5e4d6d')
     def test_create_snapshot_without_passing_volume_id(self):
         # Create a snapshot without passing volume id
         s_name = data_utils.rand_name('snap')
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 3a21f41..f6b52a9 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -58,6 +58,7 @@
         super(VolumesV2ListTestJSON, cls).resource_cleanup()
 
     @test.attr(type='gate')
+    @test.idempotent_id('2a7064eb-b9c3-429b-b888-33928fc5edd3')
     def test_volume_list_details_with_multiple_params(self):
         # List volumes detail using combined condition
         def _list_details_with_multiple_params(limit=2,
diff --git a/tempest/api_schema/response/compute/aggregates.py b/tempest/api_schema/response/compute/aggregates.py
index 9393a16..fc20885 100644
--- a/tempest/api_schema/response/compute/aggregates.py
+++ b/tempest/api_schema/response/compute/aggregates.py
@@ -14,6 +14,29 @@
 
 import copy
 
+# create-aggregate api doesn't have 'hosts' and 'metadata' attributes.
+aggregate_for_create = {
+    'type': 'object',
+    'properties': {
+        'availability_zone': {'type': ['string', 'null']},
+        'created_at': {'type': 'string'},
+        'deleted': {'type': 'boolean'},
+        'deleted_at': {'type': ['string', 'null']},
+        'id': {'type': 'integer'},
+        'name': {'type': 'string'},
+        'updated_at': {'type': ['string', 'null']}
+    },
+    'required': ['availability_zone', 'created_at', 'deleted',
+                 'deleted_at', 'id', 'name', 'updated_at']
+}
+
+aggregate = copy.deepcopy(aggregate_for_create)
+aggregate['properties'].update({
+    'hosts': {'type': 'array'},
+    'metadata': {'type': 'object'}
+})
+aggregate['required'].extend(['hosts', 'metadata'])
+
 aggregate = {
     'type': 'object',
     'properties': {
@@ -69,18 +92,10 @@
     'response_body': {
         'type': 'object',
         'properties': {
-            'aggregate': aggregate
+            'aggregate': aggregate_for_create
         },
         'required': ['aggregate']
     }
 }
-# create-aggregate api doesn't have 'hosts' and 'metadata' attributes.
-del common_create_aggregate['response_body']['properties']['aggregate'][
-    'properties']['hosts']
-del common_create_aggregate['response_body']['properties']['aggregate'][
-    'properties']['metadata']
-common_create_aggregate['response_body']['properties']['aggregate'][
-    'required'] = ['availability_zone', 'created_at', 'deleted', 'deleted_at',
-                   'id', 'name', 'updated_at']
 
 aggregate_add_remove_host = get_aggregate
diff --git a/tempest/cli/simple_read_only/data_processing/test_sahara.py b/tempest/cli/simple_read_only/data_processing/test_sahara.py
index c06c2c9..153dbd2 100644
--- a/tempest/cli/simple_read_only/data_processing/test_sahara.py
+++ b/tempest/cli/simple_read_only/data_processing/test_sahara.py
@@ -47,11 +47,13 @@
             *args, endpoint_type=CONF.data_processing.endpoint_type, **kwargs)
 
     @test.attr(type='negative')
+    @test.idempotent_id('c8809259-710f-43f9-b452-54b2be3115a9')
     def test_sahara_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.sahara,
                           'this-does-not-exist')
 
+    @test.idempotent_id('39afe90c-0fd8-456e-89e2-da6de9680fff')
     def test_sahara_plugins_list(self):
         plugins = self.parser.listing(self.sahara('plugin-list'))
         self.assertTableStruct(plugins, [
@@ -60,6 +62,7 @@
             'title'
         ])
 
+    @test.idempotent_id('3eb36fd8-bb06-4004-9e90-84ddf4dbcf5b')
     @testtools.skipUnless(CONF.data_processing_feature_enabled.plugins,
                           'No plugins defined')
     def test_sahara_plugins_show(self):
@@ -72,6 +75,7 @@
             'Value'
         ])
 
+    @test.idempotent_id('502b684b-3d41-4619-aa6c-4db3465ae79d')
     def test_sahara_node_group_template_list(self):
         result = self.sahara('node-group-template-list')
         node_group_templates = self.parser.listing(result)
@@ -83,6 +87,7 @@
             'description'
         ])
 
+    @test.idempotent_id('6c36fe4d-3b88-4b0d-b702-2a051db7dae7')
     def test_sahara_cluster_template_list(self):
         result = self.sahara('cluster-template-list')
         cluster_templates = self.parser.listing(result)
@@ -94,6 +99,7 @@
             'description'
         ])
 
+    @test.idempotent_id('b951949d-b9a6-49db-add5-8a18ac533810')
     def test_sahara_cluster_list(self):
         result = self.sahara('cluster-list')
         clusters = self.parser.listing(result)
@@ -104,6 +110,7 @@
             'node_count'
         ])
 
+    @test.idempotent_id('dbc83a8c-15b6-4aa8-b274-5896577397e1')
     def test_sahara_data_source_list(self):
         result = self.sahara('data-source-list')
         data_sources = self.parser.listing(result)
@@ -114,6 +121,7 @@
             'description'
         ])
 
+    @test.idempotent_id('a8f77e05-d4bf-45c3-8245-57835d0de37b')
     def test_sahara_job_binary_data_list(self):
         result = self.sahara('job-binary-data-list')
         job_binary_data_list = self.parser.listing(result)
@@ -122,6 +130,7 @@
             'name'
         ])
 
+    @test.idempotent_id('a8f4d0f3-fa1c-49ce-b73f-d624d89dc381')
     def test_sahara_job_binary_list(self):
         result = self.sahara('job-binary-list')
         job_binaries = self.parser.listing(result)
@@ -131,6 +140,7 @@
             'description'
         ])
 
+    @test.idempotent_id('91164ca4-d049-49e0-a52a-686b408196ff')
     def test_sahara_job_template_list(self):
         result = self.sahara('job-template-list')
         job_templates = self.parser.listing(result)
@@ -140,6 +150,7 @@
             'description'
         ])
 
+    @test.idempotent_id('6829c251-a8b6-449d-af86-7dd98b69a7ce')
     def test_sahara_job_list(self):
         result = self.sahara('job-list')
         jobs = self.parser.listing(result)
@@ -149,10 +160,12 @@
             'status'
         ])
 
+    @test.idempotent_id('e4bd5d3b-474b-4b7a-82ab-f6bb0bc89faf')
     def test_sahara_bash_completion(self):
         self.sahara('bash-completion')
 
     # Optional arguments
+    @test.idempotent_id('699c14e5-632e-46b8-91e5-6bff8c8307e5')
     def test_sahara_help(self):
         help_text = self.sahara('help')
         lines = help_text.split('\n')
@@ -172,6 +185,7 @@
                                'plugin-list', 'job-binary-create', 'help'))
         self.assertFalse(wanted_commands - commands)
 
+    @test.idempotent_id('84a18ea6-6379-4024-af6b-0e938f60dfc2')
     def test_sahara_version(self):
         version = self.sahara('', flags='--version')
         self.assertTrue(re.search('[0-9.]+', version))
diff --git a/tempest/cli/simple_read_only/identity/test_keystone.py b/tempest/cli/simple_read_only/identity/test_keystone.py
index 1fc7908..10a26d5 100644
--- a/tempest/cli/simple_read_only/identity/test_keystone.py
+++ b/tempest/cli/simple_read_only/identity/test_keystone.py
@@ -20,6 +20,7 @@
 from tempest import cli
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 
 CONF = config.CONF
 
@@ -38,11 +39,13 @@
     def keystone(self, *args, **kwargs):
         return self.clients.keystone(*args, **kwargs)
 
+    @test.idempotent_id('19c3ae95-3c19-4bba-8ba3-48ad19939b71')
     def test_admin_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.keystone,
                           'this-does-not-exist')
 
+    @test.idempotent_id('a1100917-c7c5-4887-a4da-f7d7f13194f5')
     def test_admin_catalog_list(self):
         out = self.keystone('catalog')
         catalog = self.parser.details_multiple(out, with_label=True)
@@ -57,6 +60,7 @@
             self.assertIn('publicURL', svc.keys())
             self.assertIn('region', svc.keys())
 
+    @test.idempotent_id('35c73506-eab6-4abc-956e-42da90aba8ec')
     def test_admin_endpoint_list(self):
         out = self.keystone('endpoint-list')
         endpoints = self.parser.listing(out)
@@ -64,6 +68,7 @@
             'id', 'region', 'publicurl', 'internalurl',
             'adminurl', 'service_id'])
 
+    @test.idempotent_id('f17cb155-bd16-4f32-9956-1b073752fc07')
     def test_admin_endpoint_service_match(self):
         endpoints = self.parser.listing(self.keystone('endpoint-list'))
         services = self.parser.listing(self.keystone('service-list'))
@@ -73,33 +78,40 @@
         for endpoint in endpoints:
             self.assertIn(endpoint['service_id'], svc_by_id)
 
+    @test.idempotent_id('be7176f2-9c34-4d84-bb7d-b4bc85d06a33')
     def test_admin_role_list(self):
         roles = self.parser.listing(self.keystone('role-list'))
         self.assertTableStruct(roles, ['id', 'name'])
 
+    @test.idempotent_id('96a4de8d-aa9e-4ca5-89f0-985809eccd66')
     def test_admin_service_list(self):
         services = self.parser.listing(self.keystone('service-list'))
         self.assertTableStruct(services, ['id', 'name', 'type', 'description'])
 
+    @test.idempotent_id('edb45480-0f7b-49eb-8f95-7562cbba96da')
     def test_admin_tenant_list(self):
         tenants = self.parser.listing(self.keystone('tenant-list'))
         self.assertTableStruct(tenants, ['id', 'name', 'enabled'])
 
+    @test.idempotent_id('25a2753d-6bd1-40c0-addc-32864b00cb2d')
     def test_admin_user_list(self):
         users = self.parser.listing(self.keystone('user-list'))
         self.assertTableStruct(users, [
             'id', 'name', 'enabled', 'email'])
 
+    @test.idempotent_id('f92bf8d4-b27b-47c9-8450-e27c57758de9')
     def test_admin_user_role_list(self):
         user_roles = self.parser.listing(self.keystone('user-role-list'))
         self.assertTableStruct(user_roles, [
             'id', 'name', 'user_id', 'tenant_id'])
 
+    @test.idempotent_id('14a2687b-3ce1-404c-9f78-a0e28e2f8f7b')
     def test_admin_discover(self):
         discovered = self.keystone('discover')
         self.assertIn('Keystone found at http', discovered)
         self.assertIn('supports version', discovered)
 
+    @test.idempotent_id('9a567c8c-3787-4e5f-9c30-bed55f2b75c0')
     def test_admin_help(self):
         help_text = self.keystone('help')
         lines = help_text.split('\n')
@@ -118,9 +130,11 @@
                                'token-get', 'discover', 'bootstrap'))
         self.assertFalse(wanted_commands - commands)
 
+    @test.idempotent_id('a7b9e1fe-db31-4846-82c5-52a7aa9863c3')
     def test_admin_bashcompletion(self):
         self.keystone('bash-completion')
 
+    @test.idempotent_id('5328c681-df8b-4874-a65c-8fa278f0af8f')
     def test_admin_ec2_credentials_list(self):
         creds = self.keystone('ec2-credentials-list')
         creds = self.parser.listing(creds)
@@ -128,11 +142,14 @@
 
     # Optional arguments:
 
+    @test.idempotent_id('af95e809-ce95-4505-8627-170d803b1d13')
     def test_admin_version(self):
         self.keystone('', flags='--version')
 
+    @test.idempotent_id('9e26521f-7bfa-4d8e-9d61-fd364f0c20c0')
     def test_admin_debug_list(self):
         self.keystone('catalog', flags='--debug')
 
+    @test.idempotent_id('097b3a52-725f-4df7-84b6-277a2b6f6e38')
     def test_admin_timeout(self):
         self.keystone('catalog', flags='--timeout %d' % CONF.cli.timeout)
diff --git a/tempest/cli/simple_read_only/image/test_glance.py b/tempest/cli/simple_read_only/image/test_glance.py
index 03e00d7..3d7126b 100644
--- a/tempest/cli/simple_read_only/image/test_glance.py
+++ b/tempest/cli/simple_read_only/image/test_glance.py
@@ -20,6 +20,7 @@
 from tempest import cli
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 
 CONF = config.CONF
 
@@ -46,11 +47,13 @@
                                    endpoint_type=CONF.image.endpoint_type,
                                    **kwargs)
 
+    @test.idempotent_id('c6bd9bf9-717f-4458-8d74-05b682ea7adf')
     def test_glance_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.glance,
                           'this-does-not-exist')
 
+    @test.idempotent_id('72bcdaf3-11cd-48cb-bb8e-62b329acc1ef')
     def test_glance_image_list(self):
         out = self.glance('image-list')
         endpoints = self.parser.listing(out)
@@ -58,6 +61,7 @@
             'ID', 'Name', 'Disk Format', 'Container Format',
             'Size', 'Status'])
 
+    @test.idempotent_id('965d294c-8772-4899-ba33-26ee23406135')
     def test_glance_member_list(self):
         tenant_name = '--tenant-id %s' % CONF.identity.admin_tenant_name
         out = self.glance('member-list',
@@ -66,6 +70,7 @@
         self.assertTableStruct(endpoints,
                                ['Image ID', 'Member ID', 'Can Share'])
 
+    @test.idempotent_id('43b80ee5-4297-47f3-ab4c-6f81b9c6edb3')
     def test_glance_help(self):
         help_text = self.glance('help')
         lines = help_text.split('\n')
@@ -88,11 +93,14 @@
 
     # Optional arguments:
 
+    @test.idempotent_id('3b2359ea-3719-4b47-81e5-44a042572b11')
     def test_glance_version(self):
         self.glance('', flags='--version')
 
+    @test.idempotent_id('1a52d3bd-3edf-4d67-b3da-999a5d9e0c5e')
     def test_glance_debug_list(self):
         self.glance('image-list', flags='--debug')
 
+    @test.idempotent_id('6f42b076-f9a7-4e2b-a729-579f53e7814e')
     def test_glance_timeout(self):
         self.glance('image-list', flags='--timeout %d' % CONF.cli.timeout)
diff --git a/tempest/cli/simple_read_only/network/test_neutron.py b/tempest/cli/simple_read_only/network/test_neutron.py
index 6cf0640..8af8ada 100644
--- a/tempest/cli/simple_read_only/network/test_neutron.py
+++ b/tempest/cli/simple_read_only/network/test_neutron.py
@@ -48,28 +48,33 @@
                                     **kwargs)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('84dd7190-2b98-4709-8e2c-3c1d25b9e7d2')
     def test_neutron_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.neutron,
                           'this-does-not-exist')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c598c337-313a-45ac-bf27-d6b4124a9e5b')
     def test_neutron_net_list(self):
         net_list = self.parser.listing(self.neutron('net-list'))
         self.assertTableStruct(net_list, ['id', 'name', 'subnets'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3e172b04-2e3b-4fcf-922d-99d5c803779f')
     def test_neutron_ext_list(self):
         ext = self.parser.listing(self.neutron('ext-list'))
         self.assertTableStruct(ext, ['alias', 'name'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2e0de814-52d6-4f81-be17-fe327072fc23')
     @test.requires_ext(extension='dhcp_agent_scheduler', service='network')
     def test_neutron_dhcp_agent_list_hosting_net(self):
         self.neutron('dhcp-agent-list-hosting-net',
                      params=CONF.compute.fixed_network_name)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('8524a24a-3895-40a5-8c9d-49d4459cdda4')
     @test.requires_ext(extension='agent', service='network')
     def test_neutron_agent_list(self):
         agents = self.parser.listing(self.neutron('agent-list'))
@@ -77,16 +82,19 @@
         self.assertTableStruct(agents, field_names)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('97c3ef92-7303-45f1-80db-b6622f176782')
     @test.requires_ext(extension='router', service='network')
     def test_neutron_floatingip_list(self):
         self.neutron('floatingip-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('823e0fee-404c-49a7-8bf3-d2f0383cc649')
     @test.requires_ext(extension='metering', service='network')
     def test_neutron_meter_label_list(self):
         self.neutron('meter-label-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('7fb76098-01f6-417f-b9c7-e630ba3f394b')
     @test.requires_ext(extension='metering', service='network')
     def test_neutron_meter_label_rule_list(self):
         self.neutron('meter-label-rule-list')
@@ -100,39 +108,47 @@
                 self.fail('%s: Unexpected failure.' % command)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('396d1d87-fd0c-4716-9ff0-f1baa54c6c61')
     def test_neutron_lb_healthmonitor_list(self):
         self._test_neutron_lbaas_command('lb-healthmonitor-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f41fa54d-5cd8-4f2c-bb4e-13abc72dccb6')
     def test_neutron_lb_member_list(self):
         self._test_neutron_lbaas_command('lb-member-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3ec04885-7573-4cce-b086-5722c0b00d85')
     def test_neutron_lb_pool_list(self):
         self._test_neutron_lbaas_command('lb-pool-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1ab530e0-ec87-498f-baf2-85f6635a2ad9')
     def test_neutron_lb_vip_list(self):
         self._test_neutron_lbaas_command('lb-vip-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e92f7362-4009-4b37-afee-f469105b24e7')
     @test.requires_ext(extension='external-net', service='network')
     def test_neutron_net_external_list(self):
         net_ext_list = self.parser.listing(self.neutron('net-external-list'))
         self.assertTableStruct(net_ext_list, ['id', 'name', 'subnets'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('ed840980-7c84-4b6e-b280-f13c5848a0e9')
     def test_neutron_port_list(self):
         port_list = self.parser.listing(self.neutron('port-list'))
         self.assertTableStruct(port_list, ['id', 'name', 'mac_address',
                                            'fixed_ips'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('dded0dfa-f2ac-4c1f-bc90-69fd06dd7132')
     @test.requires_ext(extension='quotas', service='network')
     def test_neutron_quota_list(self):
         self.neutron('quota-list')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('927fca1e-4397-42a2-ba47-d738299466de')
     @test.requires_ext(extension='router', service='network')
     def test_neutron_router_list(self):
         router_list = self.parser.listing(self.neutron('router-list'))
@@ -140,12 +156,14 @@
                                              'external_gateway_info'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e2e3d2d5-1aee-499d-84d9-37382dcf26ff')
     @test.requires_ext(extension='security-group', service='network')
     def test_neutron_security_group_list(self):
         security_grp = self.parser.listing(self.neutron('security-group-list'))
         self.assertTableStruct(security_grp, ['id', 'name', 'description'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('288602c2-8b59-44cd-8c5d-1ec916a114d3')
     @test.requires_ext(extension='security-group', service='network')
     def test_neutron_security_group_rule_list(self):
         security_grp = self.parser.listing(self.neutron
@@ -156,12 +174,14 @@
                                               'remote_group'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('2a874a08-b9c9-4f0f-82ef-8cadb15bbd5d')
     def test_neutron_subnet_list(self):
         subnet_list = self.parser.listing(self.neutron('subnet-list'))
         self.assertTableStruct(subnet_list, ['id', 'name', 'cidr',
                                              'allocation_pools'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('048e1ec3-cf6c-4066-b262-2028e03ce825')
     @test.requires_ext(extension='vpnaas', service='network')
     def test_neutron_vpn_ikepolicy_list(self):
         ikepolicy = self.parser.listing(self.neutron('vpn-ikepolicy-list'))
@@ -171,6 +191,7 @@
                                            'ike_version', 'pfs'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bb8902b7-b2e6-49fd-b9bd-a26dd99732df')
     @test.requires_ext(extension='vpnaas', service='network')
     def test_neutron_vpn_ipsecpolicy_list(self):
         ipsecpolicy = self.parser.listing(self.neutron('vpn-ipsecpolicy-list'))
@@ -180,6 +201,7 @@
                                              'pfs'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('c0f33f9a-0ba9-4177-bcd5-dce34b81d523')
     @test.requires_ext(extension='vpnaas', service='network')
     def test_neutron_vpn_service_list(self):
         vpn_list = self.parser.listing(self.neutron('vpn-service-list'))
@@ -187,6 +209,7 @@
                                           'router_id', 'status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bb142f8a-e568-405f-b1b7-4cb458de7971')
     @test.requires_ext(extension='vpnaas', service='network')
     def test_neutron_ipsec_site_connection_list(self):
         ipsec_site = self.parser.listing(self.neutron
@@ -198,6 +221,7 @@
                                             'auth_mode', 'status'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('89baff14-8cb7-4ad8-9c24-b0278711170b')
     @test.requires_ext(extension='fwaas', service='network')
     def test_neutron_firewall_list(self):
         firewall_list = self.parser.listing(self.neutron
@@ -206,6 +230,7 @@
                                                'firewall_policy_id'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('996e418a-2a51-4018-9602-478ca8053e61')
     @test.requires_ext(extension='fwaas', service='network')
     def test_neutron_firewall_policy_list(self):
         firewall_policy = self.parser.listing(self.neutron
@@ -214,6 +239,7 @@
                                                  'firewall_rules'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d4638dd6-98d4-4400-a920-26572de1a6fc')
     @test.requires_ext(extension='fwaas', service='network')
     def test_neutron_firewall_rule_list(self):
         firewall_rule = self.parser.listing(self.neutron
@@ -223,6 +249,7 @@
                                                'summary', 'enabled'])
 
     @test.attr(type='smoke')
+    @test.idempotent_id('1c4551e1-e3f3-4af2-8a40-c3f551e4a536')
     def test_neutron_help(self):
         help_text = self.neutron('help')
         lines = help_text.split('\n')
@@ -243,13 +270,16 @@
     # Optional arguments:
 
     @test.attr(type='smoke')
+    @test.idempotent_id('381e6fe3-cddc-47c9-a773-70ddb2f79a91')
     def test_neutron_version(self):
         self.neutron('', flags='--version')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('bcad0e07-da8c-4c7c-8ab6-499e5d7ab8cb')
     def test_neutron_debug_net_list(self):
         self.neutron('net-list', flags='--debug')
 
     @test.attr(type='smoke')
+    @test.idempotent_id('3e42d78e-65e5-4e8f-8c29-ca7be8feebb4')
     def test_neutron_quiet_net_list(self):
         self.neutron('net-list', flags='--quiet')
diff --git a/tempest/cli/simple_read_only/object_storage/test_swift.py b/tempest/cli/simple_read_only/object_storage/test_swift.py
index 40c4c15..7201eab 100644
--- a/tempest/cli/simple_read_only/object_storage/test_swift.py
+++ b/tempest/cli/simple_read_only/object_storage/test_swift.py
@@ -19,6 +19,7 @@
 
 from tempest import cli
 from tempest import config
+from tempest import test
 
 CONF = config.CONF
 
@@ -42,14 +43,17 @@
         return self.clients.swift(
             *args, endpoint_type=CONF.object_storage.endpoint_type, **kwargs)
 
+    @test.idempotent_id('74360cdc-e7ec-493f-8a87-2b65f4d54aa3')
     def test_swift_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.swift,
                           'this-does-not-exist')
 
+    @test.idempotent_id('809ec373-828e-4279-8df6-9d4db81c7909')
     def test_swift_list(self):
         self.swift('list')
 
+    @test.idempotent_id('325d5fe4-e5ab-4f52-aec4-357533f24fa1')
     def test_swift_stat(self):
         output = self.swift('stat')
         entries = ['Account', 'Containers', 'Objects', 'Bytes', 'Content-Type',
@@ -57,6 +61,7 @@
         for entry in entries:
             self.assertTrue(entry in output)
 
+    @test.idempotent_id('af1483e1-dafd-4552-a39b-b9d337df808b')
     def test_swift_capabilities(self):
         output = self.swift('capabilities')
         entries = ['account_listing_limit', 'container_listing_limit',
@@ -64,6 +69,7 @@
         for entry in entries:
             self.assertTrue(entry in output)
 
+    @test.idempotent_id('29c83a64-8eb7-418c-a39b-c70cefa5b695')
     def test_swift_help(self):
         help_text = self.swift('', flags='--help')
         lines = help_text.split('\n')
@@ -84,15 +90,19 @@
 
     # Optional arguments:
 
+    @test.idempotent_id('2026be82-4e53-4414-a828-f1c894b8cf0f')
     def test_swift_version(self):
         self.swift('', flags='--version')
 
+    @test.idempotent_id('0ae6172e-3df7-42b8-a987-d42609ada6ed')
     def test_swift_debug_list(self):
         self.swift('list', flags='--debug')
 
+    @test.idempotent_id('1bdf5dd0-7df5-446c-a124-2b0703a5d199')
     def test_swift_retries_list(self):
         self.swift('list', flags='--retries 3')
 
+    @test.idempotent_id('64eae749-8fbd-4d85-bc7f-f706d3581c6f')
     def test_swift_region_list(self):
         region = CONF.object_storage.region
         if not region:
diff --git a/tempest/cli/simple_read_only/orchestration/test_heat.py b/tempest/cli/simple_read_only/orchestration/test_heat.py
index d3a9b01..7751e2c 100644
--- a/tempest/cli/simple_read_only/orchestration/test_heat.py
+++ b/tempest/cli/simple_read_only/orchestration/test_heat.py
@@ -18,6 +18,7 @@
 import tempest.cli
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 
 CONF = config.CONF
 
@@ -46,58 +47,71 @@
         return self.clients.heat(
             *args, endpoint_type=CONF.orchestration.endpoint_type, **kwargs)
 
+    @test.idempotent_id('0ae034bb-ce35-45e8-b7aa-3e339cd3140f')
     def test_heat_stack_list(self):
         self.heat('stack-list')
 
+    @test.idempotent_id('a360d069-7250-4aed-9721-0a6f2db7c3fa')
     def test_heat_stack_list_debug(self):
         self.heat('stack-list', flags='--debug')
 
+    @test.idempotent_id('e1b7c177-5ab4-4d3f-8a26-ea01ebbd2b8c')
     def test_heat_resource_template_fmt_default(self):
         ret = self.heat('resource-template OS::Nova::Server')
         self.assertIn('Type: OS::Nova::Server', ret)
 
+    @test.idempotent_id('93f82f76-aab2-4910-9359-11cf48f2a46b')
     def test_heat_resource_template_fmt_arg_short_yaml(self):
         ret = self.heat('resource-template -F yaml OS::Nova::Server')
         self.assertIn('Type: OS::Nova::Server', ret)
         self.assertIsInstance(yaml.safe_load(ret), dict)
 
+    @test.idempotent_id('7356a98c-e14d-43f0-8c25-c9f7daa0aafa')
     def test_heat_resource_template_fmt_arg_long_json(self):
         ret = self.heat('resource-template --format json OS::Nova::Server')
         self.assertIn('"Type": "OS::Nova::Server"', ret)
         self.assertIsInstance(json.loads(ret), dict)
 
+    @test.idempotent_id('2fd99d20-beff-4667-b42e-de9095f671d7')
     def test_heat_resource_type_list(self):
         ret = self.heat('resource-type-list')
         rsrc_types = self.parser.listing(ret)
         self.assertTableStruct(rsrc_types, ['resource_type'])
 
+    @test.idempotent_id('62f60dbf-d139-4698-b230-a09fb531d643')
     def test_heat_resource_type_show(self):
         rsrc_schema = self.heat('resource-type-show OS::Nova::Server')
         # resource-type-show returns a json resource schema
         self.assertIsInstance(json.loads(rsrc_schema), dict)
 
+    @test.idempotent_id('6ca16ff7-9d5f-4448-a8c2-4cecc7b5ba3a')
     def test_heat_template_validate_yaml(self):
         ret = self.heat('template-validate -f %s' % self.heat_template_path)
         # On success template-validate returns a json representation
         # of the template parameters
         self.assertIsInstance(json.loads(ret), dict)
 
+    @test.idempotent_id('35241014-16ea-4cb6-ad3e-4ee5f41446de')
     def test_heat_template_validate_hot(self):
         ret = self.heat('template-validate -f %s' % self.heat_template_path)
         self.assertIsInstance(json.loads(ret), dict)
 
+    @test.idempotent_id('34d43e0a-36dc-4ea8-9b85-0189e3de89d8')
     def test_heat_help(self):
         self.heat('help')
 
     @tempest.cli.min_client_version(client='heat', version='0.2.7')
+    @test.idempotent_id('c122c08b-839d-49d1-afd1-bc546b2d18d3')
     def test_heat_bash_completion(self):
         self.heat('bash-completion')
 
+    @test.idempotent_id('1b045e12-2fa0-4895-9282-00668428dfbe')
     def test_heat_help_cmd(self):
         # Check requesting help for a specific command works
         help_text = self.heat('help resource-template')
         lines = help_text.split('\n')
         self.assertFirstLineStartsWith(lines, 'usage: heat resource-template')
 
+    @test.idempotent_id('c7837f8f-d0a8-47fd-b75b-14ba3e3fa9a2')
     def test_heat_version(self):
         self.heat('', flags='--version')
diff --git a/tempest/cli/simple_read_only/telemetry/test_ceilometer.py b/tempest/cli/simple_read_only/telemetry/test_ceilometer.py
index f9bf8b2..85db596 100644
--- a/tempest/cli/simple_read_only/telemetry/test_ceilometer.py
+++ b/tempest/cli/simple_read_only/telemetry/test_ceilometer.py
@@ -43,15 +43,19 @@
         return self.clients.ceilometer(
             *args, endpoint_type=CONF.telemetry.endpoint_type, **kwargs)
 
+    @test.idempotent_id('ab717d43-a9c4-4dcf-bad8-c4777933a970')
     def test_ceilometer_meter_list(self):
         self.ceilometer('meter-list')
 
     @test.attr(type='slow')
+    @test.idempotent_id('fe2e52a4-a99b-426e-a52d-d0bde50f3e4c')
     def test_ceilometer_resource_list(self):
         self.ceilometer('resource-list')
 
+    @test.idempotent_id('eede695c-f3bf-449f-a420-02f3cc426d52')
     def test_ceilometermeter_alarm_list(self):
         self.ceilometer('alarm-list')
 
+    @test.idempotent_id('0586bcc4-8e35-415f-8f23-77b590042684')
     def test_ceilometer_version(self):
         self.ceilometer('', flags='--version')
diff --git a/tempest/cli/simple_read_only/volume/test_cinder.py b/tempest/cli/simple_read_only/volume/test_cinder.py
index c2e0a42..cb29cc8 100644
--- a/tempest/cli/simple_read_only/volume/test_cinder.py
+++ b/tempest/cli/simple_read_only/volume/test_cinder.py
@@ -22,6 +22,7 @@
 from tempest import cli
 from tempest import clients
 from tempest import config
+from tempest import test
 
 
 CONF = config.CONF
@@ -51,25 +52,30 @@
                                    endpoint_type=CONF.volume.endpoint_type,
                                    **kwargs)
 
+    @test.idempotent_id('229bc6dc-d804-4668-b753-b590caf63061')
     def test_cinder_fake_action(self):
         self.assertRaises(exceptions.CommandFailed,
                           self.cinder,
                           'this-does-not-exist')
 
+    @test.idempotent_id('77140216-14db-4fc5-a246-e2a587e9e99b')
     def test_cinder_absolute_limit_list(self):
         roles = self.parser.listing(self.cinder('absolute-limits'))
         self.assertTableStruct(roles, ['Name', 'Value'])
 
+    @test.idempotent_id('2206b9ce-1a36-4a0a-a129-e5afc7cee1dd')
     def test_cinder_backup_list(self):
         backup_list = self.parser.listing(self.cinder('backup-list'))
         self.assertTableStruct(backup_list, ['ID', 'Volume ID', 'Status',
                                              'Name', 'Size', 'Object Count',
                                              'Container'])
 
+    @test.idempotent_id('c7f50346-cd99-4e0b-953f-796ff5f47295')
     def test_cinder_extra_specs_list(self):
         extra_specs_list = self.parser.listing(self.cinder('extra-specs-list'))
         self.assertTableStruct(extra_specs_list, ['ID', 'Name', 'extra_specs'])
 
+    @test.idempotent_id('9de694cb-b40b-442c-a30c-5f9873e144f7')
     def test_cinder_volumes_list(self):
         list = self.parser.listing(self.cinder('list'))
         self.assertTableStruct(list, ['ID', 'Status', 'Name', 'Size',
@@ -82,29 +88,34 @@
                           'list',
                           params='--all-tenants bad')
 
+    @test.idempotent_id('56f7c15c-ee82-4f23-bbe8-ce99b66da493')
     def test_cinder_quota_class_show(self):
         """This CLI can accept and string as param."""
         roles = self.parser.listing(self.cinder('quota-class-show',
                                                 params='abc'))
         self.assertTableStruct(roles, ['Property', 'Value'])
 
+    @test.idempotent_id('a919a811-b7f0-47a7-b4e5-f3eb674dd200')
     def test_cinder_quota_defaults(self):
         """This CLI can accept and string as param."""
         roles = self.parser.listing(self.cinder('quota-defaults',
                                                 params=self.admin_tenant_id))
         self.assertTableStruct(roles, ['Property', 'Value'])
 
+    @test.idempotent_id('18166673-ffa8-4df3-b60c-6375532288bc')
     def test_cinder_quota_show(self):
         """This CLI can accept and string as param."""
         roles = self.parser.listing(self.cinder('quota-show',
                                                 params=self.admin_tenant_id))
         self.assertTableStruct(roles, ['Property', 'Value'])
 
+    @test.idempotent_id('b2c66ed9-ca96-4dc4-94cc-8083e664e516')
     def test_cinder_rate_limits(self):
         rate_limits = self.parser.listing(self.cinder('rate-limits'))
         self.assertTableStruct(rate_limits, ['Verb', 'URI', 'Value', 'Remain',
                                              'Unit', 'Next_Available'])
 
+    @test.idempotent_id('7a19955b-807c-481a-a2ee-9d76733eac28')
     @testtools.skipUnless(CONF.volume_feature_enabled.snapshot,
                           'Volume snapshot not available.')
     def test_cinder_snapshot_list(self):
@@ -112,22 +123,27 @@
         self.assertTableStruct(snapshot_list, ['ID', 'Volume ID', 'Status',
                                                'Name', 'Size'])
 
+    @test.idempotent_id('6e54ecd9-7ba9-490d-8e3b-294b67139e73')
     def test_cinder_type_list(self):
         type_list = self.parser.listing(self.cinder('type-list'))
         self.assertTableStruct(type_list, ['ID', 'Name'])
 
+    @test.idempotent_id('2c363583-24a0-4980-b9cb-b50c0d241e82')
     def test_cinder_list_extensions(self):
         roles = self.parser.listing(self.cinder('list-extensions'))
         self.assertTableStruct(roles, ['Name', 'Summary', 'Alias', 'Updated'])
 
+    @test.idempotent_id('691bd6df-30ad-4be7-927b-a02d62aaa38a')
     def test_cinder_credentials(self):
         credentials = self.parser.listing(self.cinder('credentials'))
         self.assertTableStruct(credentials, ['User Credentials', 'Value'])
 
+    @test.idempotent_id('5c6d71a3-4904-4a3a-aec9-7fd4aa830e95')
     def test_cinder_availability_zone_list(self):
         zone_list = self.parser.listing(self.cinder('availability-zone-list'))
         self.assertTableStruct(zone_list, ['Name', 'Status'])
 
+    @test.idempotent_id('9b0fd5a6-f955-42b9-a42f-6f542a80b9a3')
     def test_cinder_endpoints(self):
         out = self.cinder('endpoints')
         tables = self.parser.tables(out)
@@ -136,28 +152,34 @@
             self.assertTrue(2 >= len(headers))
             self.assertEqual('Value', headers[1])
 
+    @test.idempotent_id('301b5ae1-9591-4e9f-999c-d525a9bdf822')
     def test_cinder_service_list(self):
         service_list = self.parser.listing(self.cinder('service-list'))
         self.assertTableStruct(service_list, ['Binary', 'Host', 'Zone',
                                               'Status', 'State', 'Updated_at'])
 
+    @test.idempotent_id('7260ae52-b462-461e-9048-36d0bccf92c6')
     def test_cinder_transfer_list(self):
         transfer_list = self.parser.listing(self.cinder('transfer-list'))
         self.assertTableStruct(transfer_list, ['ID', 'Volume ID', 'Name'])
 
+    @test.idempotent_id('0976dea8-14f3-45a9-8495-3617fc4fbb13')
     def test_cinder_bash_completion(self):
         self.cinder('bash-completion')
 
+    @test.idempotent_id('b7c00361-be80-4512-8735-5f98fc54f2a9')
     def test_cinder_qos_list(self):
         qos_list = self.parser.listing(self.cinder('qos-list'))
         self.assertTableStruct(qos_list, ['ID', 'Name', 'Consumer', 'specs'])
 
+    @test.idempotent_id('2e92dc6e-22b5-4d94-abfc-b543b0c50a89')
     def test_cinder_encryption_type_list(self):
         encrypt_list = self.parser.listing(self.cinder('encryption-type-list'))
         self.assertTableStruct(encrypt_list, ['Volume Type ID', 'Provider',
                                               'Cipher', 'Key Size',
                                               'Control Location'])
 
+    @test.idempotent_id('0ee6cb4c-8de6-4811-a7be-7f4bb75b80cc')
     def test_admin_help(self):
         help_text = self.cinder('help')
         lines = help_text.split('\n')
@@ -178,15 +200,19 @@
 
     # Optional arguments:
 
+    @test.idempotent_id('2fd6f530-183c-4bda-8918-1e59e36c26b9')
     def test_cinder_version(self):
         self.cinder('', flags='--version')
 
+    @test.idempotent_id('306bac51-c443-4426-a6cf-583a953fcd68')
     def test_cinder_debug_list(self):
         self.cinder('list', flags='--debug')
 
+    @test.idempotent_id('6d97fcd2-5dd1-429d-af70-030c949d86cd')
     def test_cinder_retries_list(self):
         self.cinder('list', flags='--retries 3')
 
+    @test.idempotent_id('95a2850c-35b4-4159-bb93-51647a5ad232')
     def test_cinder_region_list(self):
         region = CONF.volume.region
         if not region:
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 480ddd5..7b217bb 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -833,9 +833,9 @@
 
     def save_state(self):
         flavors = self.list()
-        flavor_data = self.data['flavors'] = {}
+        self.data['flavors'] = {}
         for flavor in flavors:
-            flavor_data[flavor['id']] = flavor['name']
+            self.data['flavors'][flavor['id']] = flavor['name']
 
 
 class ImageService(BaseService):
@@ -871,9 +871,9 @@
 
     def save_state(self):
         images = self.list()
-        image_data = self.data['images'] = {}
+        self.data['images'] = {}
         for image in images:
-            image_data[image['id']] = image['name']
+            self.data['images'][image['id']] = image['name']
 
 
 class IdentityService(BaseService):
@@ -919,9 +919,9 @@
 
     def save_state(self):
         users = self.list()
-        user_data = self.data['users'] = {}
+        self.data['users'] = {}
         for user in users:
-            user_data[user['id']] = user['name']
+            self.data['users'][user['id']] = user['name']
 
 
 class RoleService(IdentityService):
@@ -958,9 +958,9 @@
 
     def save_state(self):
         roles = self.list()
-        role_data = self.data['roles'] = {}
+        self.data['roles'] = {}
         for role in roles:
-            role_data[role['id']] = role['name']
+            self.data['roles'][role['id']] = role['name']
 
 
 class TenantService(IdentityService):
@@ -996,9 +996,9 @@
 
     def save_state(self):
         tenants = self.list()
-        tenant_data = self.data['tenants'] = {}
+        self.data['tenants'] = {}
         for tenant in tenants:
-            tenant_data[tenant['id']] = tenant['name']
+            self.data['tenants'][tenant['id']] = tenant['name']
 
 
 class DomainService(BaseService):
@@ -1034,9 +1034,9 @@
 
     def save_state(self):
         domains = self.list()
-        domain_data = self.data['domains'] = {}
+        self.data['domains'] = {}
         for domain in domains:
-            domain_data[domain['id']] = domain['name']
+            self.data['domains'][domain['id']] = domain['name']
 
 
 def get_tenant_cleanup_services():
diff --git a/tempest/scenario/orchestration/test_server_cfn_init.py b/tempest/scenario/orchestration/test_server_cfn_init.py
index 9c38d2f..53f7843 100644
--- a/tempest/scenario/orchestration/test_server_cfn_init.py
+++ b/tempest/scenario/orchestration/test_server_cfn_init.py
@@ -126,6 +126,7 @@
 
     @test.attr(type='slow')
     @decorators.skip_because(bug='1374175')
+    @test.idempotent_id('2be9be1f-8106-4ee2-a7ba-444c7557db2f')
     @test.services('orchestration', 'compute')
     def test_server_cfn_init(self):
         self.assign_keypair()
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 469ac4a..ff450de 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -96,6 +96,7 @@
         self.assertEqual(aggregate['availability_zone'], availability_zone)
         return aggregate
 
+    @test.idempotent_id('cb2b4c4f-0c7c-4164-bdde-6285b302a081')
     @test.services('compute')
     def test_aggregate_basic_ops(self):
         self.useFixture(fixtures.LockFixture('availability_zone'))
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index fe49dc1..434d3df 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -117,6 +117,7 @@
             self.assertEqual(n_port['device_id'], self.instance['id'])
             self.assertEqual(n_port['mac_address'], port['address'])
 
+    @test.idempotent_id('549173a5-38ec-42bb-b0e2-c8b9f4a08943')
     @test.services('baremetal', 'compute', 'image', 'network')
     def test_baremetal_server_ops(self):
         test_filename = '/mnt/rebuild_test.txt'
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index 1313050..4c4dc94 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -89,6 +89,7 @@
         response = self.opener.open(CONF.dashboard.dashboard_url)
         self.assertIn('Overview', response.read())
 
+    @test.idempotent_id('4f8851b1-0e69-482b-b63b-84c6e76f6c80')
     @test.services('dashboard')
     def test_basic_scenario(self):
         creds = self.credentials()
diff --git a/tempest/scenario/test_encrypted_cinder_volumes.py b/tempest/scenario/test_encrypted_cinder_volumes.py
index ac2ef8a..1069908 100644
--- a/tempest/scenario/test_encrypted_cinder_volumes.py
+++ b/tempest/scenario/test_encrypted_cinder_volumes.py
@@ -48,6 +48,7 @@
         self.nova_volume_attach()
         self.nova_volume_detach()
 
+    @test.idempotent_id('79165fb4-5534-4b9d-8429-97ccffb8f86e')
     @test.services('compute', 'volume', 'image')
     def test_encrypted_cinder_volumes_luks(self):
         self.launch_instance()
@@ -55,6 +56,7 @@
                                      'luks.LuksEncryptor')
         self.attach_detach_volume()
 
+    @test.idempotent_id('cbc752ed-b716-4717-910f-956cce965722')
     @test.services('compute', 'volume', 'image')
     def test_encrypted_cinder_volumes_cryptsetup(self):
         self.launch_instance()
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index fca0a2a..af2b4cb 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -104,14 +104,17 @@
         self.glance_image_create()
         self.nova_boot()
 
+    @test.idempotent_id('14ba0e78-2ed9-4d17-9659-a48f4756ecb3')
     @test.services('compute', 'image')
     def test_large_ops_scenario_1(self):
         self._large_ops_scenario()
 
+    @test.idempotent_id('b9b79b88-32aa-42db-8f8f-dcc8f4b4ccfe')
     @test.services('compute', 'image')
     def test_large_ops_scenario_2(self):
         self._large_ops_scenario()
 
+    @test.idempotent_id('3aab7e82-2de3-419a-9da1-9f3a070668fb')
     @test.services('compute', 'image')
     def test_large_ops_scenario_3(self):
         self._large_ops_scenario()
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 426ada3..6f6036f 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -309,6 +309,7 @@
         for member, counter in counters.iteritems():
             self.assertGreater(counter, 0, 'Member %s never balanced' % member)
 
+    @test.idempotent_id('c0c6f1ca-603b-4509-9c0f-2c63f0d838ee')
     @test.services('compute', 'network')
     def test_load_balancer_basic(self):
         self._create_server('server1')
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index e4d7ece..63f74c4 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -119,6 +119,7 @@
                    '%s' % (secgroup['id'], self.server['id']))
             raise exceptions.TimeoutException(msg)
 
+    @test.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
     @test.services('compute', 'volume', 'image', 'network')
     def test_minimum_basic_scenario(self):
         self.glance_image_create()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 598c6d1..6e82a41 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -94,6 +94,7 @@
         self._check_network_connectivity()
 
     @decorators.skip_because(bug="1323658")
+    @test.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
     @test.services('compute', 'network')
     def test_server_connectivity_stop_start(self):
         self._setup_network_and_servers()
@@ -104,12 +105,14 @@
         self.servers_client.start(self.server['id'])
         self._wait_server_status_and_check_network_connectivity()
 
+    @test.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
     @test.services('compute', 'network')
     def test_server_connectivity_reboot(self):
         self._setup_network_and_servers()
         self.servers_client.reboot(self.server['id'], reboot_type='SOFT')
         self._wait_server_status_and_check_network_connectivity()
 
+    @test.idempotent_id('88a529c2-1daa-4c85-9aec-d541ba3eb699')
     @test.services('compute', 'network')
     def test_server_connectivity_rebuild(self):
         self._setup_network_and_servers()
@@ -118,6 +121,7 @@
                                     image_ref=image_ref_alt)
         self._wait_server_status_and_check_network_connectivity()
 
+    @test.idempotent_id('2b2642db-6568-4b35-b812-eceed3fa20ce')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     @test.services('compute', 'network')
@@ -129,6 +133,7 @@
         self.servers_client.unpause_server(self.server['id'])
         self._wait_server_status_and_check_network_connectivity()
 
+    @test.idempotent_id('5cdf9499-541d-4923-804e-b9a60620a7f0')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.services('compute', 'network')
@@ -142,6 +147,7 @@
         self._wait_server_status_and_check_network_connectivity()
 
     @decorators.skip_because(bug="1323658")
+    @test.idempotent_id('719eb59d-2f42-4b66-b8b1-bb1254473967')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize is not available.')
     @test.services('compute', 'network')
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 132afda..f29fecf 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -328,6 +328,7 @@
                 raise
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f323b3ba-82f8-4db7-8ea6-6a895869ec49')
     @test.services('compute', 'network')
     def test_network_basic_ops(self):
         """
@@ -378,6 +379,7 @@
                                                msg="after re-associate "
                                                    "floating ip")
 
+    @test.idempotent_id('c5adff73-e961-41f1-b4a9-343614f18cfa')
     @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
                           'NIC hotplug not available')
     @testtools.skipIf(CONF.network.port_vnic_type in ['direct', 'macvtap'],
@@ -400,6 +402,7 @@
         self._hotplug_server()
         self._check_network_internal_connectivity(network=self.new_net)
 
+    @test.idempotent_id('04b9fe4e-85e8-4aea-b937-ea93885ac59f')
     @testtools.skipIf(CONF.baremetal.driver_enabled,
                       'Router state cannot be altered on a shared baremetal '
                       'network')
@@ -431,6 +434,7 @@
             should_connect=True, msg="after updating "
             "admin_state_up of router to True")
 
+    @test.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
     @testtools.skipUnless(CONF.scenario.dhcp_client,
                           "DHCP client is not available.")
     @test.attr(type='smoke')
@@ -509,6 +513,7 @@
                         msg="DHCP renewal failed to fetch "
                             "new DNS nameservers")
 
+    @test.idempotent_id('f5dfcc22-45fd-409f-954c-5bd500d7890b')
     @testtools.skipIf(CONF.baremetal.driver_enabled,
                       'admin_state of instance ports cannot be altered '
                       'for baremetal nodes')
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index dc82217..979953f 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -142,10 +142,12 @@
         else:
             LOG.warning('Ping6 is not available, skipping')
 
+    @test.idempotent_id('2c92df61-29f0-4eaa-bee3-7c65bef62a43')
     @test.services('compute', 'network')
     def test_slaac_from_os(self):
         self._prepare_and_test(address6_mode='slaac')
 
+    @test.idempotent_id('d7e1f858-187c-45a6-89c9-bdafde619a9f')
     @test.services('compute', 'network')
     def test_dhcp6_stateless_from_os(self):
         self._prepare_and_test(address6_mode='dhcpv6-stateless')
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 394aed0..f3c1f85 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -430,6 +430,7 @@
         self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
 
     @test.attr(type='smoke')
+    @test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
     @test.services('compute', 'network')
     def test_cross_tenant_traffic(self):
         if not self.isolated_creds.is_multi_tenant():
@@ -451,6 +452,7 @@
             raise
 
     @test.attr(type='smoke')
+    @test.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
     @test.services('compute', 'network')
     def test_in_tenant_traffic(self):
         try:
@@ -465,6 +467,7 @@
             raise
 
     @test.attr(type='smoke')
+    @test.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
     @test.services('compute', 'network')
     def test_port_update_new_security_group(self):
         """
@@ -516,6 +519,7 @@
             raise
 
     @test.attr(type='smoke')
+    @test.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
     @test.services('compute', 'network')
     def test_multiple_security_groups(self):
         """
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 0e0e174..d0b595a 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -42,6 +42,7 @@
         cls.set_network_resources()
         super(TestServerAdvancedOps, cls).resource_setup()
 
+    @test.idempotent_id('e6c28180-7454-4b59-b188-0257af08a63b')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize is not available.')
     @test.services('compute')
@@ -62,6 +63,7 @@
         self.servers_client.wait_for_server_status(instance_id,
                                                    'ACTIVE')
 
+    @test.idempotent_id('949da7d5-72c8-4808-8802-e3d70df98e2c')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.services('compute')
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 509ce60..b306b11 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -93,6 +93,7 @@
                 username=self.image_utils.ssh_user(self.image_ref),
                 private_key=self.keypair['private_key'])
 
+    @test.idempotent_id('7fff3fb3-91d8-4fd0-bd7d-0204f1f180ba')
     @test.services('compute', 'network')
     def test_server_basicops(self):
         self.add_keypair()
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index 5ba650d..155ecbf 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -60,6 +60,7 @@
         self.servers_client.unshelve_server(server['id'])
         self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
 
+    @test.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     @test.services('compute', 'network', 'image')
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 5cb7c99..109d36b 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -57,6 +57,7 @@
         got_timestamp = ssh_client.exec_command('cat /tmp/timestamp')
         self.assertEqual(self.timestamp, got_timestamp)
 
+    @test.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @test.services('compute', 'network', 'image')
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index e97f089..bd3cefa 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -24,6 +24,7 @@
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest.scenario import manager
+from tempest import test
 import tempest.test
 
 CONF = config.CONF
@@ -140,6 +141,7 @@
         self.assertEqual(self.timestamp, got_timestamp)
 
     @decorators.skip_because(bug="1205344")
+    @test.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
     @tempest.test.services('compute', 'network', 'volume', 'image')
diff --git a/tempest/scenario/test_swift_basic_ops.py b/tempest/scenario/test_swift_basic_ops.py
index 660b586..b622c4a 100644
--- a/tempest/scenario/test_swift_basic_ops.py
+++ b/tempest/scenario/test_swift_basic_ops.py
@@ -38,6 +38,7 @@
      * change ACL of the container and make sure it works successfully
     """
 
+    @test.idempotent_id('b920faf1-7b8a-4657-b9fe-9c4512bfb381')
     @test.services('object_storage')
     def test_swift_basic_ops(self):
         self.get_swift_stat()
@@ -51,6 +52,7 @@
                                               not_present_obj=[obj_name])
         self.delete_container(container_name)
 
+    @test.idempotent_id('916c7111-cb1f-44b2-816d-8f760e4ea910')
     @test.services('object_storage')
     def test_swift_acl_anonymous_download(self):
         """This test will cover below steps:
diff --git a/tempest/scenario/test_swift_telemetry_middleware.py b/tempest/scenario/test_swift_telemetry_middleware.py
index dd6d855..2427f0f 100644
--- a/tempest/scenario/test_swift_telemetry_middleware.py
+++ b/tempest/scenario/test_swift_telemetry_middleware.py
@@ -99,6 +99,7 @@
                         'Correct notifications were not received after '
                         '%s seconds.' % NOTIFICATIONS_WAIT)
 
+    @test.idempotent_id('6d6b88e5-3e38-41bc-b34a-79f713a6cb84')
     @test.services('object_storage', 'telemetry')
     def test_swift_middleware_notifies(self):
         container_name = self.create_container()
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 21a399c..d1ea270 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -133,6 +133,7 @@
         self.assertEqual(expected, actual)
 
     @decorators.skip_because(bug='1373513')
+    @test.idempotent_id('557cd2c2-4eb8-4dce-98be-f86765ff311b')
     @test.services('compute', 'volume', 'image')
     def test_volume_boot_pattern(self):
         keypair = self.create_keypair()
diff --git a/tempest/test.py b/tempest/test.py
index d4123a4..f04aff7 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -24,6 +24,7 @@
 import uuid
 
 import fixtures
+import six
 import testscenarios
 import testtools
 
@@ -62,6 +63,23 @@
     return decorator
 
 
+def idempotent_id(id):
+    """Stub for metadata decorator"""
+    if not isinstance(id, six.string_types):
+        raise TypeError('Test idempotent_id must be string not %s'
+                        '' % type(id).__name__)
+    uuid.UUID(id)
+
+    def decorator(f):
+        f = testtools.testcase.attr('id-%s' % id)(f)
+        if f.__doc__:
+            f.__doc__ = 'Test idempotent id: %s\n%s' % (id, f.__doc__)
+        else:
+            f.__doc__ = 'Test idempotent id: %s' % id
+        return f
+    return decorator
+
+
 def get_service_list():
     service_list = {
         'compute': CONF.service_available.nova,
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index 1f1835e..5149ba6 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -12,6 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
 
 import mock
 from oslo.config import cfg
@@ -64,6 +65,43 @@
         self._test_attr_helper(expected_attrs=['foo'], type=['foo', 'foo'])
 
 
+class TestIdempotentIdDecorator(BaseDecoratorsTest):
+
+    def _test_helper(self, _id, **decorator_args):
+        @test.idempotent_id(_id)
+        def foo():
+            """Docstring"""
+            pass
+
+        return foo
+
+    def _test_helper_without_doc(self, _id, **decorator_args):
+        @test.idempotent_id(_id)
+        def foo():
+            pass
+
+        return foo
+
+    def test_positive(self):
+        _id = str(uuid.uuid4())
+        foo = self._test_helper(_id)
+        self.assertIn('id-%s' % _id, getattr(foo, '__testtools_attrs'))
+        self.assertTrue(foo.__doc__.startswith('Test idempotent id: %s' % _id))
+
+    def test_positive_without_doc(self):
+        _id = str(uuid.uuid4())
+        foo = self._test_helper_without_doc(_id)
+        self.assertTrue(foo.__doc__.startswith('Test idempotent id: %s' % _id))
+
+    def test_idempotent_id_not_str(self):
+        _id = 42
+        self.assertRaises(TypeError, self._test_helper, _id)
+
+    def test_idempotent_id_not_valid_uuid(self):
+        _id = '42'
+        self.assertRaises(ValueError, self._test_helper, _id)
+
+
 class TestServicesDecorator(BaseDecoratorsTest):
     def _test_services_helper(self, *decorator_args):
         class TestFoo(test.BaseTestCase):
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 707590e..822bf34 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -18,6 +18,7 @@
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 from tempest.thirdparty.boto.utils import s3
 from tempest.thirdparty.boto.utils import wait
@@ -87,6 +88,7 @@
             self.assertInstanceStateWait(instance, '_GONE')
         self.cancelResourceCleanUp(rcuk)
 
+    @test.idempotent_id('c881fbb7-d56e-4054-9d76-1c3a60a207b0')
     def test_run_idempotent_instances(self):
         # EC2 run instances idempotently
 
@@ -119,6 +121,7 @@
         self._terminate_reservation(reservation_1, rcuk_1)
         self._terminate_reservation(reservation_2, rcuk_2)
 
+    @test.idempotent_id('2ea26a39-f96c-48fc-8374-5c10ec184c67')
     def test_run_stop_terminate_instance(self):
         # EC2 run, stop and terminate instance
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -141,6 +144,7 @@
 
         self._terminate_reservation(reservation, rcuk)
 
+    @test.idempotent_id('3d77225a-5cec-4e54-a017-9ebf11a266e6')
     def test_run_stop_terminate_instance_with_tags(self):
         # EC2 run, stop and terminate instance with tags
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -193,6 +197,7 @@
 
         self._terminate_reservation(reservation, rcuk)
 
+    @test.idempotent_id('252945b5-3294-4fda-ae21-928a42f63f76')
     def test_run_terminate_instance(self):
         # EC2 run, terminate immediately
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -205,6 +210,7 @@
             instance.terminate()
         self.assertInstanceStateWait(instance, '_GONE')
 
+    @test.idempotent_id('ab836c29-737b-4101-9fb9-87045eaf89e9')
     def test_compute_with_volumes(self):
         # EC2 1. integration test (not strict)
         image_ami = self.ec2_client.get_image(self.images["ami"]["image_id"])
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index be5db55..36c3386 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
@@ -31,6 +32,7 @@
         cls.ec = cls.ec2_error_code
 
 # TODO(afazekas): merge create, delete, get test cases
+    @test.idempotent_id('54236804-01b7-4cfe-a6f9-bce1340feec8')
     def test_create_ec2_keypair(self):
         # EC2 create KeyPair
         key_name = data_utils.rand_name("keypair-")
@@ -39,6 +41,7 @@
         self.assertTrue(compare_key_pairs(keypair,
                         self.client.get_key_pair(key_name)))
 
+    @test.idempotent_id('3283b898-f90c-4952-b238-3e42b8c3f34f')
     def test_delete_ec2_keypair(self):
         # EC2 delete KeyPair
         key_name = data_utils.rand_name("keypair-")
@@ -46,6 +49,7 @@
         self.client.delete_key_pair(key_name)
         self.assertIsNone(self.client.get_key_pair(key_name))
 
+    @test.idempotent_id('fd89bd26-4d4d-4cf3-a303-65dd9158fcdc')
     def test_get_ec2_keypair(self):
         # EC2 get KeyPair
         key_name = data_utils.rand_name("keypair-")
@@ -54,6 +58,7 @@
         self.assertTrue(compare_key_pairs(keypair,
                         self.client.get_key_pair(key_name)))
 
+    @test.idempotent_id('daa73da1-e11c-4558-8d76-a716be79a401')
     def test_duplicate_ec2_keypair(self):
         # EC2 duplicate KeyPair
         key_name = data_utils.rand_name("keypair-")
diff --git a/tempest/thirdparty/boto/test_ec2_network.py b/tempest/thirdparty/boto/test_ec2_network.py
index 132a5a8..c7ed00d 100644
--- a/tempest/thirdparty/boto/test_ec2_network.py
+++ b/tempest/thirdparty/boto/test_ec2_network.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
@@ -24,6 +25,7 @@
         cls.ec2_client = cls.os.ec2api_client
 
     # Note(afazekas): these tests for things duable without an instance
+    @test.idempotent_id('48b912af-9403-4b4f-aa69-fa76d690a81f')
     def test_disassociate_not_associated_floating_ip(self):
         # EC2 disassociate not associated floating ip
         ec2_codes = self.ec2_error_code
diff --git a/tempest/thirdparty/boto/test_ec2_security_groups.py b/tempest/thirdparty/boto/test_ec2_security_groups.py
index fb3d32b..92fe59d 100644
--- a/tempest/thirdparty/boto/test_ec2_security_groups.py
+++ b/tempest/thirdparty/boto/test_ec2_security_groups.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
@@ -24,6 +25,7 @@
         super(EC2SecurityGroupTest, cls).resource_setup()
         cls.client = cls.os.ec2api_client
 
+    @test.idempotent_id('519b566e-0c38-4629-905e-7d6b6355f524')
     def test_create_authorize_security_group(self):
         # EC2 Create, authorize/revoke security group
         group_name = data_utils.rand_name("securty_group-")
diff --git a/tempest/thirdparty/boto/test_ec2_volumes.py b/tempest/thirdparty/boto/test_ec2_volumes.py
index 9cee8a4..4616851 100644
--- a/tempest/thirdparty/boto/test_ec2_volumes.py
+++ b/tempest/thirdparty/boto/test_ec2_volumes.py
@@ -15,6 +15,7 @@
 
 from tempest import config
 from tempest.openstack.common import log as logging
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 CONF = config.CONF
@@ -39,6 +40,7 @@
         cls.client = cls.os.ec2api_client
         cls.zone = CONF.boto.aws_zone
 
+    @test.idempotent_id('663f0077-c743-48ad-8ae0-46821cbc0918')
     def test_create_get_delete(self):
         # EC2 Create, get, delete Volume
         volume = self.client.create_volume(1, self.zone)
@@ -51,6 +53,7 @@
         self.client.delete_volume(volume.id)
         self.cancelResourceCleanUp(cuk)
 
+    @test.idempotent_id('c6b60d7a-1af7-4f8e-af21-d539d9496149')
     def test_create_volume_from_snapshot(self):
         # EC2 Create volume from snapshot
         volume = self.client.create_volume(1, self.zone)
diff --git a/tempest/thirdparty/boto/test_s3_buckets.py b/tempest/thirdparty/boto/test_s3_buckets.py
index 342fc0e..e3a265e 100644
--- a/tempest/thirdparty/boto/test_s3_buckets.py
+++ b/tempest/thirdparty/boto/test_s3_buckets.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.common.utils import data_utils
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
@@ -24,6 +25,7 @@
         super(S3BucketsTest, cls).resource_setup()
         cls.client = cls.os.s3_client
 
+    @test.idempotent_id('4678525d-8da0-4518-81c1-f1f67d595b00')
     def test_create_and_get_delete_bucket(self):
         # S3 Create, get and delete bucket
         bucket_name = data_utils.rand_name("s3bucket-")
diff --git a/tempest/thirdparty/boto/test_s3_ec2_images.py b/tempest/thirdparty/boto/test_s3_ec2_images.py
index f5dec95..773a193 100644
--- a/tempest/thirdparty/boto/test_s3_ec2_images.py
+++ b/tempest/thirdparty/boto/test_s3_ec2_images.py
@@ -17,6 +17,7 @@
 
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 from tempest.thirdparty.boto.utils import s3
 
@@ -47,6 +48,7 @@
                                cls.bucket_name)
         s3.s3_upload_dir(bucket, cls.materials_path)
 
+    @test.idempotent_id('f9d360a5-0188-4c77-9db2-4c34c28d12a5')
     def test_register_get_deregister_ami_image(self):
         # Register and deregister ami image
         image = {"name": data_utils.rand_name("ami-name-"),
@@ -70,6 +72,7 @@
             self.images_client.get_all_images()))
         self.cancelResourceCleanUp(image["cleanUp"])
 
+    @test.idempotent_id('42cca5b0-453b-4618-b99f-dbc039db426f')
     def test_register_get_deregister_aki_image(self):
         # Register and deregister aki image
         image = {"name": data_utils.rand_name("aki-name-"),
@@ -93,6 +96,7 @@
             self.images_client.get_all_images()))
         self.cancelResourceCleanUp(image["cleanUp"])
 
+    @test.idempotent_id('1359e860-841c-43bb-80f3-bb389cbfd81d')
     def test_register_get_deregister_ari_image(self):
         # Register and deregister ari image
         image = {"name": data_utils.rand_name("ari-name-"),
diff --git a/tempest/thirdparty/boto/test_s3_objects.py b/tempest/thirdparty/boto/test_s3_objects.py
index 43774c2..bc32686 100644
--- a/tempest/thirdparty/boto/test_s3_objects.py
+++ b/tempest/thirdparty/boto/test_s3_objects.py
@@ -18,6 +18,7 @@
 import boto.s3.key
 
 from tempest.common.utils import data_utils
+from tempest import test
 from tempest.thirdparty.boto import test as boto_test
 
 
@@ -28,6 +29,7 @@
         super(S3BucketsTest, cls).resource_setup()
         cls.client = cls.os.s3_client
 
+    @test.idempotent_id('4eea567a-b46a-405b-a475-6097e1faebde')
     def test_create_get_delete_object(self):
         # S3 Create, get and delete object
         bucket_name = data_utils.rand_name("s3bucket-")
diff --git a/tools/check_uuid.py b/tools/check_uuid.py
new file mode 100644
index 0000000..541e6c3
--- /dev/null
+++ b/tools/check_uuid.py
@@ -0,0 +1,354 @@
+# Copyright 2014 Mirantis, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import argparse
+import ast
+import importlib
+import inspect
+import os
+import sys
+import unittest
+import urllib
+import uuid
+
+DECORATOR_MODULE = 'test'
+DECORATOR_NAME = 'idempotent_id'
+DECORATOR_IMPORT = 'tempest.%s' % DECORATOR_MODULE
+IMPORT_LINE = 'from tempest import %s' % DECORATOR_MODULE
+DECORATOR_TEMPLATE = "@%s.%s('%%s')" % (DECORATOR_MODULE,
+                                        DECORATOR_NAME)
+UNIT_TESTS_EXCLUDE = 'tempest.tests'
+
+
+class SourcePatcher(object):
+
+    """"Lazy patcher for python source files"""
+
+    def __init__(self):
+        self.source_files = None
+        self.patches = None
+        self.clear()
+
+    def clear(self):
+        """Clear inner state"""
+        self.source_files = {}
+        self.patches = {}
+
+    @staticmethod
+    def _quote(s):
+        return urllib.quote(s)
+
+    @staticmethod
+    def _unquote(s):
+        return urllib.unquote(s)
+
+    def add_patch(self, filename, patch, line_no):
+        """Add lazy patch"""
+        if filename not in self.source_files:
+            with open(filename) as f:
+                self.source_files[filename] = self._quote(f.read())
+        patch_id = str(uuid.uuid4())
+        if not patch.endswith('\n'):
+            patch += '\n'
+        self.patches[patch_id] = self._quote(patch)
+        lines = self.source_files[filename].split(self._quote('\n'))
+        lines[line_no - 1] = ''.join(('{%s:s}' % patch_id, lines[line_no - 1]))
+        self.source_files[filename] = self._quote('\n').join(lines)
+
+    def _save_changes(self, filename, source):
+        print('%s fixed' % filename)
+        with open(filename, 'w') as f:
+            f.write(source)
+
+    def apply_patches(self):
+        """Apply all patches"""
+        for filename in self.source_files:
+            patched_source = self._unquote(
+                self.source_files[filename].format(**self.patches)
+            )
+            self._save_changes(filename, patched_source)
+        self.clear()
+
+
+class TestChecker(object):
+
+    def __init__(self, package):
+        self.package = package
+        self.base_path = os.path.abspath(os.path.dirname(package.__file__))
+
+    def _path_to_package(self, path):
+        relative_path = path[len(self.base_path) + 1:]
+        if relative_path:
+            return '.'.join((self.package.__name__,) +
+                            tuple(relative_path.split('/')))
+        else:
+            return self.package.__name__
+
+    def _modules_search(self):
+        """Recursive search for python modules in base package"""
+        modules = []
+        for root, dirs, files in os.walk(self.base_path):
+            if not os.path.exists(os.path.join(root, '__init__.py')):
+                continue
+            root_package = self._path_to_package(root)
+            for item in files:
+                if item.endswith('.py'):
+                    module_name = '.'.join((root_package,
+                                           os.path.splitext(item)[0]))
+                    if not module_name.startswith(UNIT_TESTS_EXCLUDE):
+                        modules.append(module_name)
+        return modules
+
+    @staticmethod
+    def _get_idempotent_id(test_node):
+        """
+        Return key-value dict with all metadata from @test.idempotent_id
+        decorators for test method
+        """
+        idempotent_id = None
+        for decorator in test_node.decorator_list:
+            if (hasattr(decorator, 'func') and
+                    decorator.func.attr == DECORATOR_NAME and
+                    decorator.func.value.id == DECORATOR_MODULE):
+                for arg in decorator.args:
+                    idempotent_id = ast.literal_eval(arg)
+        return idempotent_id
+
+    @staticmethod
+    def _is_decorator(line):
+        return line.strip().startswith('@')
+
+    @staticmethod
+    def _is_def(line):
+        return line.strip().startswith('def ')
+
+    def _add_uuid_to_test(self, patcher, test_node, source_path):
+        with open(source_path) as src:
+            src_lines = src.read().split('\n')
+        lineno = test_node.lineno
+        insert_position = lineno
+        while True:
+            if (self._is_def(src_lines[lineno - 1]) or
+                    (self._is_decorator(src_lines[lineno - 1]) and
+                        (DECORATOR_TEMPLATE.split('(')[0] <=
+                            src_lines[lineno - 1].strip().split('(')[0]))):
+                insert_position = lineno
+                break
+            lineno += 1
+        patcher.add_patch(
+            source_path,
+            ' ' * test_node.col_offset + DECORATOR_TEMPLATE % uuid.uuid4(),
+            insert_position
+        )
+
+    @staticmethod
+    def _is_test_case(module, node):
+        if (node.__class__ is ast.ClassDef and
+                hasattr(module, node.name) and
+                inspect.isclass(getattr(module, node.name))):
+            return issubclass(getattr(module, node.name), unittest.TestCase)
+
+    @staticmethod
+    def _is_test_method(node):
+        return (node.__class__ is ast.FunctionDef
+                and node.name.startswith('test_'))
+
+    @staticmethod
+    def _next_node(body, node):
+        if body.index(node) < len(body):
+            return body[body.index(node) + 1]
+
+    @staticmethod
+    def _import_name(node):
+        if type(node) == ast.Import:
+            return node.names[0].name
+        elif type(node) == ast.ImportFrom:
+            return '%s.%s' % (node.module, node.names[0].name)
+
+    def _add_import_for_test_uuid(self, patcher, src_parsed, source_path):
+        with open(source_path) as f:
+            src_lines = f.read().split('\n')
+        line_no = 0
+        tempest_imports = [node for node in src_parsed.body
+                           if self._import_name(node) and
+                           'tempest.' in self._import_name(node)]
+        if not tempest_imports:
+            import_snippet = '\n'.join(('', IMPORT_LINE, ''))
+        else:
+            for node in tempest_imports:
+                if self._import_name(node) < DECORATOR_IMPORT:
+                    continue
+                else:
+                    line_no = node.lineno
+                    import_snippet = IMPORT_LINE
+                    break
+            else:
+                line_no = tempest_imports[-1].lineno
+                while True:
+                    if (not src_lines[line_no - 1] or
+                            getattr(self._next_node(src_parsed.body,
+                                                    tempest_imports[-1]),
+                                    'lineno') == line_no or
+                            line_no == len(src_lines)):
+                        break
+                    line_no += 1
+                import_snippet = '\n'.join((IMPORT_LINE, ''))
+        patcher.add_patch(source_path, import_snippet, line_no)
+
+    def get_tests(self):
+        """Get test methods with sources from base package with metadata"""
+        tests = {}
+        for module_name in self._modules_search():
+            tests[module_name] = {}
+            module = importlib.import_module(module_name)
+            source_path = '.'.join(
+                (os.path.splitext(module.__file__)[0], 'py')
+            )
+            with open(source_path, 'r') as f:
+                source = f.read()
+            tests[module_name]['source_path'] = source_path
+            tests[module_name]['tests'] = {}
+            source_parsed = ast.parse(source)
+            tests[module_name]['ast'] = source_parsed
+            tests[module_name]['import_valid'] = (
+                hasattr(module, DECORATOR_MODULE) and
+                inspect.ismodule(getattr(module, DECORATOR_MODULE))
+            )
+            test_cases = (node for node in source_parsed.body
+                          if self._is_test_case(module, node))
+            for node in test_cases:
+                for subnode in filter(self._is_test_method, node.body):
+                        test_name = '%s.%s' % (node.name, subnode.name)
+                        tests[module_name]['tests'][test_name] = subnode
+        return tests
+
+    @staticmethod
+    def _filter_tests(function, tests):
+        """Filter tests with condition 'function(test_node) == True'"""
+        result = {}
+        for module_name in tests:
+            for test_name in tests[module_name]['tests']:
+                if function(module_name, test_name, tests):
+                    if module_name not in result:
+                        result[module_name] = {
+                            'ast': tests[module_name]['ast'],
+                            'source_path': tests[module_name]['source_path'],
+                            'import_valid': tests[module_name]['import_valid'],
+                            'tests': {}
+                        }
+                    result[module_name]['tests'][test_name] = \
+                        tests[module_name]['tests'][test_name]
+        return result
+
+    def find_untagged(self, tests):
+        """Filter all tests without uuid in metadata"""
+        def check_uuid_in_meta(module_name, test_name, tests):
+            idempotent_id = self._get_idempotent_id(
+                tests[module_name]['tests'][test_name])
+            return not idempotent_id
+        return self._filter_tests(check_uuid_in_meta, tests)
+
+    def report_collisions(self, tests):
+        """Reports collisions if there are any. Returns true if
+        collisions exist.
+        """
+        uuids = {}
+
+        def report(module_name, test_name, tests):
+            test_uuid = self._get_idempotent_id(
+                tests[module_name]['tests'][test_name])
+            if not test_uuid:
+                return
+            if test_uuid in uuids:
+                error_str = "%s:%s\n uuid %s collision: %s<->%s\n%s:%s\n" % (
+                    tests[module_name]['source_path'],
+                    tests[module_name]['tests'][test_name].lineno,
+                    test_uuid,
+                    test_name,
+                    uuids[test_uuid]['test_name'],
+                    uuids[test_uuid]['source_path'],
+                    uuids[test_uuid]['test_node'].lineno,
+                )
+                print(error_str)
+                return True
+            else:
+                uuids[test_uuid] = {
+                    'module': module_name,
+                    'test_name': test_name,
+                    'test_node': tests[module_name]['tests'][test_name],
+                    'source_path': tests[module_name]['source_path']
+                }
+        return bool(self._filter_tests(report, tests))
+
+    def report_untagged(self, tests):
+        """Reports untagged tests if there are any. Returns true if
+        untagged tests exist.
+        """
+        def report(module_name, test_name, tests):
+            error_str = "%s:%s\nmissing @test.idempotent_id('...')\n%s\n" % (
+                tests[module_name]['source_path'],
+                tests[module_name]['tests'][test_name].lineno,
+                test_name
+            )
+            print(error_str)
+            return True
+        return bool(self._filter_tests(report, tests))
+
+    def fix_tests(self, tests):
+        """Add uuids to all tests specified in tests and
+        fix it in source files
+        """
+        patcher = SourcePatcher()
+        for module_name in tests:
+            add_import_once = True
+            for test_name in tests[module_name]['tests']:
+                if not tests[module_name]['import_valid'] and add_import_once:
+                    self._add_import_for_test_uuid(
+                        patcher,
+                        tests[module_name]['ast'],
+                        tests[module_name]['source_path']
+                    )
+                    add_import_once = False
+                self._add_uuid_to_test(
+                    patcher, tests[module_name]['tests'][test_name],
+                    tests[module_name]['source_path'])
+        patcher.apply_patches()
+
+
+def run():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--package', action='store', dest='package',
+                        default='tempest', type=str,
+                        help='Package with tests')
+    parser.add_argument('--fix', action='store_true', dest='fix_tests',
+                        help='Attempt to fix tests without UUIDs')
+    args = parser.parse_args()
+    sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+    pkg = importlib.import_module(args.package)
+    checker = TestChecker(pkg)
+    errors = False
+    tests = checker.get_tests()
+    untagged = checker.find_untagged(tests)
+    errors = checker.report_collisions(tests) or errors
+    if args.fix_tests and untagged:
+        checker.fix_tests(untagged)
+    else:
+        errors = checker.report_untagged(untagged) or errors
+    if errors:
+        sys.exit("@test.idempotent_id existence and uniqueness checks failed\n"
+                 "Run 'tox -v -euuidgen' to automatically fix tests with\n"
+                 "missing @test.idempotent_id decorators.")
+
+if __name__ == '__main__':
+    run()
diff --git a/tox.ini b/tox.ini
index 2e8b509..f3fc8b7 100644
--- a/tox.ini
+++ b/tox.ini
@@ -113,6 +113,11 @@
 commands =
    flake8 {posargs}
    {toxinidir}/tools/config/check_uptodate.sh
+   python tools/check_uuid.py
+
+[testenv:uuidgen]
+commands =
+   python tools/check_uuid.py --fix
 
 [hacking]
 local-check-factory = tempest.hacking.checks.factory