Merge "Prevent raising exception if IP address is set in _hotplug_server"
diff --git a/.zuul.yaml b/.zuul.yaml
index 87e277c..dfa9add 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -676,7 +676,6 @@
             voting: false
             irrelevant-files: *tempest-irrelevant-files
         - devstack-plugin-ceph-tempest-py3:
-            voting: false
             irrelevant-files: *tempest-irrelevant-files
         - neutron-grenade-multinode:
             irrelevant-files: *tempest-irrelevant-files
@@ -718,6 +717,8 @@
             irrelevant-files: *tempest-irrelevant-files
         - tempest-ipv6-only:
             irrelevant-files: *tempest-irrelevant-files-2
+        - devstack-plugin-ceph-tempest-py3:
+            irrelevant-files: *tempest-irrelevant-files
     experimental:
       jobs:
         - tempest-cinder-v2-api:
diff --git a/doc/requirements.txt b/doc/requirements.txt
index 9f38ada..30394e8 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -1,7 +1,7 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-openstackdocstheme>=1.20.0 # Apache-2.0
-reno>=2.5.0 # Apache-2.0
-sphinx!=1.6.6,!=1.6.7,!=2.1.0,>=1.6.2 # BSD
+openstackdocstheme>=2.2.0 # Apache-2.0
+reno>=3.1.0 # Apache-2.0
+sphinx>=2.0.0,!=2.1.0 # BSD
 sphinxcontrib-svg2pdfconverter>=0.1.0 # BSD
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 7ce431e..dd7c544 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -63,9 +63,10 @@
 todo_include_todos = True
 
 # openstackdocstheme options
-repository_name = 'openstack/tempest'
-bug_project = 'tempest'
-bug_tag = 'doc'
+openstackdocs_repo_name = 'openstack/tempest'
+openstackdocs_bug_project = 'tempest'
+openstackdocs_bug_tag = 'doc'
+openstackdocs_pdf_link = True
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index 50fd4f2..5bc0eac 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -394,6 +394,10 @@
 
   .. _2.57: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id52
 
+  * `2.59`_
+
+  .. _2.59: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id55
+
   * `2.60`_
 
   .. _2.60: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#maximum-in-queens
diff --git a/releasenotes/notes/Set-default-of-operator_role-to-member-f9c3abd2ebde23b7.yaml b/releasenotes/notes/Set-default-of-operator_role-to-member-f9c3abd2ebde23b7.yaml
new file mode 100644
index 0000000..980f4ca
--- /dev/null
+++ b/releasenotes/notes/Set-default-of-operator_role-to-member-f9c3abd2ebde23b7.yaml
@@ -0,0 +1,6 @@
+---
+upgrade:
+  - |
+    ``Member`` role has been deprecated and replaced by ``member``. Therefore
+    the default value of config option ``[object-storage].operator_role`` is
+    changed to ``member``. (Fixes bug #1330132)
diff --git a/releasenotes/notes/account-generator-accepts-positive-numbers-only-33a366a297494ef7.yaml b/releasenotes/notes/account-generator-accepts-positive-numbers-only-33a366a297494ef7.yaml
new file mode 100644
index 0000000..dfee1db
--- /dev/null
+++ b/releasenotes/notes/account-generator-accepts-positive-numbers-only-33a366a297494ef7.yaml
@@ -0,0 +1,7 @@
+---
+fixes:
+  - |
+   Concurrency parameter for account-generator command was accepting
+   negative values and zero. The concurrency parameter now accepts only
+   positive numbers. When a negative value or zero is passed to the
+   program then the program ends and help is displayed.
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
index 92df4c4..71df749 100644
--- a/releasenotes/source/conf.py
+++ b/releasenotes/source/conf.py
@@ -42,9 +42,9 @@
 ]
 
 # openstackdocstheme options
-repository_name = 'openstack/tempest'
-bug_project = 'tempest'
-bug_tag = ''
+openstackdocs_repo_name = 'openstack/tempest'
+openstackdocs_bug_project = 'tempest'
+openstackdocs_bug_tag = ''
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index f42f53a..d6b6b7e 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -107,7 +107,10 @@
         """
         def verify_flavor_response_extension(flavor):
             # check some extensions for the flavor create/show/detail response
-            self.assertEqual(flavor['swap'], '')
+            if self.is_requested_microversion_compatible('2.74'):
+                self.assertEqual(flavor['swap'], '')
+            else:
+                self.assertEqual(flavor['swap'], 0)
             self.assertEqual(int(flavor['rxtx_factor']), 1)
             self.assertEqual(flavor['OS-FLV-EXT-DATA:ephemeral'], 0)
             self.assertEqual(flavor['os-flavor-access:is_public'], True)
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 3fa859e..1247494 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -110,27 +110,29 @@
     create_default_network = True
 
     @classmethod
-    def skip_checks(self):
-        super(BaseServerStableDeviceRescueTest, self).skip_checks()
+    def skip_checks(cls):
+        super(BaseServerStableDeviceRescueTest, cls).skip_checks()
         if not CONF.compute_feature_enabled.rescue:
             msg = "Server rescue not available."
-            raise self.skipException(msg)
+            raise cls.skipException(msg)
         if not CONF.compute_feature_enabled.stable_rescue:
             msg = "Stable rescue not available."
-            raise self.skipException(msg)
+            raise cls.skipException(msg)
 
     def _create_server_and_rescue_image(self, hw_rescue_device=None,
                                         hw_rescue_bus=None,
                                         block_device_mapping_v2=None):
+
+        server_id = self.create_test_server(
+            wait_until='ACTIVE')['id']
+        image_id = self.create_image_from_server(
+            server_id, wait_until='ACTIVE')['id']
+
         if block_device_mapping_v2:
             server_id = self.create_test_server(
                 wait_until='ACTIVE',
                 block_device_mapping_v2=block_device_mapping_v2)['id']
-        else:
-            server_id = self.create_test_server(wait_until='ACTIVE')['id']
 
-        image_id = self.create_image_from_server(server_id,
-                                                 wait_until='ACTIVE')['id']
         if hw_rescue_bus:
             self.images_client.update_image(
                 image_id, [dict(add='/hw_rescue_bus',
@@ -193,43 +195,29 @@
 
     min_microversion = '2.87'
 
+    @decorators.attr(type='slow')
     @decorators.idempotent_id('48f123cb-922a-4065-8db6-b9a9074a556b')
     def test_stable_device_rescue_bfv_blank_volume(self):
         block_device_mapping_v2 = [{
             "boot_index": "0",
             "source_type": "blank",
-            "volume_size": "1",
+            "volume_size": CONF.volume.volume_size,
             "destination_type": "volume"}]
         server_id, rescue_image_id = self._create_server_and_rescue_image(
             hw_rescue_device='disk', hw_rescue_bus='virtio',
             block_device_mapping_v2=block_device_mapping_v2)
         self._test_stable_device_rescue(server_id, rescue_image_id)
 
+    @decorators.attr(type='slow')
     @decorators.idempotent_id('e4636333-c928-40fc-98b7-70a23eef4224')
     def test_stable_device_rescue_bfv_image_volume(self):
         block_device_mapping_v2 = [{
             "boot_index": "0",
             "source_type": "image",
-            "volume_size": "1",
+            "volume_size": CONF.volume.volume_size,
             "uuid": CONF.compute.image_ref,
             "destination_type": "volume"}]
         server_id, rescue_image_id = self._create_server_and_rescue_image(
             hw_rescue_device='disk', hw_rescue_bus='virtio',
             block_device_mapping_v2=block_device_mapping_v2)
         self._test_stable_device_rescue(server_id, rescue_image_id)
-
-    @decorators.idempotent_id('7fcc5d2c-130e-4750-95f5-7343f9d0a2f3')
-    def test_stable_device_rescue_bfv_snapshot_volume(self):
-        volume_id = self.create_volume()['id']
-        self.volumes_client.set_bootable_volume(volume_id, bootable=True)
-        snapshot_id = self.create_volume_snapshot(volume_id)['id']
-        block_device_mapping_v2 = [{
-            "boot_index": "0",
-            "source_type": "snapshot",
-            "volume_size": "1",
-            "uuid": snapshot_id,
-            "destination_type": "volume"}]
-        server_id, rescue_image_id = self._create_server_and_rescue_image(
-            hw_rescue_device='disk', hw_rescue_bus='virtio',
-            block_device_mapping_v2=block_device_mapping_v2)
-        self._test_stable_device_rescue(server_id, rescue_image_id)
diff --git a/tempest/api/identity/v3/test_tokens.py b/tempest/api/identity/v3/test_tokens.py
index fa1c47f..cb05f39 100644
--- a/tempest/api/identity/v3/test_tokens.py
+++ b/tempest/api/identity/v3/test_tokens.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import operator
+
 from oslo_utils import timeutils
 import six
 
@@ -40,6 +42,15 @@
         authenticated_token = self.non_admin_client.show_token(
             subject_token)['token']
         # sanity checking to make sure they are indeed the same token
+        # If there are roles in the token, sort the roles
+        authenticated_token_roles = authenticated_token.get("roles")
+        if authenticated_token_roles:
+            authenticated_token["roles"] = authenticated_token_roles.sort(
+                key=operator.itemgetter('id'))
+        token_body_roles = token_body.get("roles")
+        if token_body_roles:
+            token_body["roles"] = token_body_roles.sort(
+                key=operator.itemgetter('id'))
         self.assertEqual(authenticated_token, token_body)
         # test to see if token has been properly authenticated
         self.assertEqual(authenticated_token['user']['id'], user_id)
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index bf2e510..5e2c8af 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -19,9 +19,11 @@
 
 
 class ImageMembersTest(base.BaseV1ImageMembersTest):
+    """Test image members"""
 
     @decorators.idempotent_id('1d6ef640-3a20-4c84-8710-d95828fdb6ad')
     def test_add_image_member(self):
+        """Test adding member for image"""
         image = self._create_image()
         self.image_member_client.create_image_member(image, self.alt_tenant_id)
         body = self.image_member_client.list_image_members(image)
@@ -33,6 +35,7 @@
 
     @decorators.idempotent_id('6a5328a5-80e8-4b82-bd32-6c061f128da9')
     def test_get_shared_images(self):
+        """Test getting shared images"""
         image = self._create_image()
         self.image_member_client.create_image_member(image, self.alt_tenant_id)
         share_image = self._create_image()
@@ -47,6 +50,7 @@
 
     @decorators.idempotent_id('a76a3191-8948-4b44-a9d6-4053e5f2b138')
     def test_remove_member(self):
+        """Test removing member from image"""
         image_id = self._create_image()
         self.image_member_client.create_image_member(image_id,
                                                      self.alt_tenant_id)
diff --git a/tempest/api/image/v1/test_image_members_negative.py b/tempest/api/image/v1/test_image_members_negative.py
index 2748bd5..4e3c27c 100644
--- a/tempest/api/image/v1/test_image_members_negative.py
+++ b/tempest/api/image/v1/test_image_members_negative.py
@@ -19,11 +19,12 @@
 
 
 class ImageMembersNegativeTest(base.BaseV1ImageMembersTest):
+    """Negative tests of image members"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('147a9536-18e3-45da-91ea-b037a028f364')
     def test_add_member_with_non_existing_image(self):
-        # Add member with non existing image.
+        """Add member with non existing image"""
         non_exist_image = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.image_member_client.create_image_member,
@@ -32,7 +33,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e1559f05-b667-4f1b-a7af-518b52dc0c0f')
     def test_delete_member_with_non_existing_image(self):
-        # Delete member with non existing image.
+        """Delete member with non existing image"""
         non_exist_image = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.image_member_client.delete_image_member,
@@ -41,7 +42,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('f5720333-dd69-4194-bb76-d2f048addd56')
     def test_delete_member_with_non_existing_tenant(self):
-        # Delete member with non existing tenant.
+        """Delete member from image with non existing tenant"""
         image_id = self._create_image()
         non_exist_tenant = data_utils.rand_uuid_hex()
         self.assertRaises(lib_exc.NotFound,
@@ -51,7 +52,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('f25f89e4-0b6c-453b-a853-1f80b9d7ef26')
     def test_get_image_without_membership(self):
-        # Image is hidden from another tenants.
+        """Get image without membership
+
+        Image is hidden from another tenants.
+        """
         image_id = self._create_image()
         self.assertRaises(lib_exc.NotFound,
                           self.alt_img_cli.show_image,
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 2432c8b..595717e 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -57,7 +57,7 @@
 
     @decorators.idempotent_id('3027f8e6-3492-4a11-8575-c3293017af4d')
     def test_register_then_upload(self):
-        # Register, then upload an image
+        """Register, then upload an image"""
         properties = {'prop1': 'val1'}
         container_format, disk_format = get_container_and_disk_format()
         image = self.create_image(name='New Name',
@@ -79,7 +79,7 @@
 
     @decorators.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
     def test_register_remote_image(self):
-        # Register a new remote image
+        """Register a new remote image"""
         container_format, disk_format = get_container_and_disk_format()
         body = self.create_image(name='New Remote Image',
                                  container_format=container_format,
@@ -96,6 +96,7 @@
 
     @decorators.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
     def test_register_http_image(self):
+        """Register a new image from an http image path url"""
         container_format, disk_format = get_container_and_disk_format()
         image = self.create_image(name='New Http Image',
                                   container_format=container_format,
@@ -108,7 +109,7 @@
 
     @decorators.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
     def test_register_image_with_min_ram(self):
-        # Register an image with min ram
+        """Register an image with min ram"""
         container_format, disk_format = get_container_and_disk_format()
         properties = {'prop1': 'val1'}
         body = self.create_image(name='New_image_with_min_ram',
@@ -213,7 +214,7 @@
 
     @decorators.idempotent_id('246178ab-3b33-4212-9a4b-a7fe8261794d')
     def test_index_no_params(self):
-        # Simple test to see all fixture images returned
+        """Simple test to see all fixture images returned"""
         images_list = self.client.list_images()['images']
         image_list = [image['id'] for image in images_list]
         for image_id in self.created_images:
@@ -221,6 +222,7 @@
 
     @decorators.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
     def test_index_disk_format(self):
+        """Test listing images by disk format"""
         images_list = self.client.list_images(
             disk_format=self.disk_format_alt)['images']
         for image in images_list:
@@ -232,6 +234,7 @@
 
     @decorators.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
     def test_index_container_format(self):
+        """Test listing images by container format"""
         images_list = self.client.list_images(
             container_format=self.container_format)['images']
         for image in images_list:
@@ -243,6 +246,7 @@
 
     @decorators.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
     def test_index_max_size(self):
+        """Test listing images by max size"""
         images_list = self.client.list_images(size_max=42)['images']
         for image in images_list:
             self.assertLessEqual(image['size'], 42)
@@ -252,6 +256,7 @@
 
     @decorators.idempotent_id('6ffc16d0-4cbf-4401-95c8-4ac63eac34d8')
     def test_index_min_size(self):
+        """Test listing images by min size"""
         images_list = self.client.list_images(size_min=142)['images']
         for image in images_list:
             self.assertGreaterEqual(image['size'], 142)
@@ -261,6 +266,7 @@
 
     @decorators.idempotent_id('e5dc26d9-9aa2-48dd-bda5-748e1445da98')
     def test_index_status_active_detail(self):
+        """Test listing active images sorting by size in descending order"""
         images_list = self.client.list_images(detail=True,
                                               status='active',
                                               sort_key='size',
@@ -274,6 +280,7 @@
 
     @decorators.idempotent_id('097af10a-bae8-4342-bff4-edf89969ed2a')
     def test_index_name(self):
+        """Test listing images by its name"""
         images_list = self.client.list_images(
             detail=True,
             name='New Remote Image dup')['images']
@@ -285,6 +292,8 @@
 
 
 class UpdateImageMetaTest(base.BaseV1ImageTest):
+    """Test image metadata"""
+
     @classmethod
     def resource_setup(cls):
         super(UpdateImageMetaTest, cls).resource_setup()
@@ -308,6 +317,7 @@
 
     @decorators.idempotent_id('01752c1c-0275-4de3-9e5b-876e44541928')
     def test_list_image_metadata(self):
+        """Test listing image metadata"""
         # All metadata key/value pairs for an image should be returned
         resp = self.client.check_image(self.image_id)
         resp_metadata = common_image.get_image_meta_from_headers(resp)
@@ -316,6 +326,7 @@
 
     @decorators.idempotent_id('d6d7649c-08ce-440d-9ea7-e3dda552f33c')
     def test_update_image_metadata(self):
+        """Test updating image metadata"""
         # The metadata for the image should match the updated values
         req_metadata = {'key1': 'alt1', 'key2': 'value2'}
         resp = self.client.check_image(self.image_id)
diff --git a/tempest/api/image/v1/test_images_negative.py b/tempest/api/image/v1/test_images_negative.py
index 690b8da..2af1288 100644
--- a/tempest/api/image/v1/test_images_negative.py
+++ b/tempest/api/image/v1/test_images_negative.py
@@ -26,7 +26,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('036ede36-6160-4463-8c01-c781eee6369d')
     def test_register_with_invalid_container_format(self):
-        # Negative tests for invalid data supplied to POST /images
+        """Create image with invalid container format
+
+        Negative tests for invalid data supplied to POST /images
+        """
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           headers={'x-image-meta-name': 'test',
                                    'x-image-meta-container_format': 'wrong',
@@ -35,6 +38,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('993face5-921d-4e84-aabf-c1bba4234a67')
     def test_register_with_invalid_disk_format(self):
+        """Create image with invalid disk format"""
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           headers={'x-image-meta-name': 'test',
                                    'x-image-meta-container_format': 'bare',
@@ -43,7 +47,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('ec652588-7e3c-4b67-a2f2-0fa96f57c8fc')
     def test_delete_non_existent_image(self):
-        # Return an error while trying to delete a non-existent image
+        """Return an error while trying to delete a non-existent image"""
 
         non_existent_image_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
@@ -52,13 +56,13 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('04f72aa3-fcec-45a3-81a3-308ef7cc82bc')
     def test_delete_image_blank_id(self):
-        # Return an error while trying to delete an image with blank Id
+        """Return an error while trying to delete an image with blank Id"""
         self.assertRaises(lib_exc.NotFound, self.client.delete_image, '')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('950e5054-a3c7-4dee-ada5-e576f1087abd')
     def test_delete_image_non_hex_string_id(self):
-        # Return an error while trying to delete an image with non hex id
+        """Return an error while trying to delete an image with non hex id"""
         invalid_image_id = data_utils.rand_uuid()[:-1] + "j"
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           invalid_image_id)
@@ -66,13 +70,13 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('4ed757cd-450c-44b1-9fd1-c819748c650d')
     def test_delete_image_negative_image_id(self):
-        # Return an error while trying to delete an image with negative id
+        """Return an error while trying to delete an image with negative id"""
         self.assertRaises(lib_exc.NotFound, self.client.delete_image, -1)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a4a448ab-3db2-4d2d-b9b2-6a1271241dfe')
     def test_delete_image_id_over_character_limit(self):
-        # Return an error while trying to delete image with id over limit
+        """Return an error while trying to delete image with id over limit"""
         overlimit_image_id = data_utils.rand_uuid() + "1"
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           overlimit_image_id)
diff --git a/tempest/api/image/v2/admin/test_images.py b/tempest/api/image/v2/admin/test_images.py
index dbb8c58..7e13d7f 100644
--- a/tempest/api/image/v2/admin/test_images.py
+++ b/tempest/api/image/v2/admin/test_images.py
@@ -19,10 +19,12 @@
 
 
 class BasicOperationsImagesAdminTest(base.BaseV2ImageAdminTest):
+    """"Test image operations about image owner"""
 
     @decorators.related_bug('1420008')
     @decorators.idempotent_id('646a6eaa-135f-4493-a0af-12583021224e')
     def test_create_image_owner_param(self):
+        """Test creating image with specified owner"""
         # NOTE: Create image with owner different from tenant owner by
         # using "owner" parameter requires an admin privileges.
         random_id = data_utils.rand_uuid_hex()
@@ -35,6 +37,7 @@
     @decorators.related_bug('1420008')
     @decorators.idempotent_id('525ba546-10ef-4aad-bba1-1858095ce553')
     def test_update_image_owner_param(self):
+        """Test updating image owner"""
         random_id_1 = data_utils.rand_uuid_hex()
         image = self.admin_client.create_image(
             container_format='bare', disk_format='raw', owner=random_id_1)
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 5a27a43..c4a3e0e 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -88,8 +88,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('f848bb94-1c6e-45a4-8726-39e3a5b23535')
     def test_delete_image(self):
-        # Deletes an image by image_id
-
+        """Test deleting an image by image_id"""
         # Create image
         image_name = data_utils.rand_name('image')
         container_format = CONF.image.container_formats[0]
@@ -110,8 +109,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('f66891a7-a35c-41a8-b590-a065c2a1caa6')
     def test_update_image(self):
-        # Updates an image by image_id
-
+        """Test updating an image by image_id"""
         # Create image
         image_name = data_utils.rand_name('image')
         container_format = CONF.image.container_formats[0]
@@ -135,6 +133,7 @@
 
     @decorators.idempotent_id('951ebe01-969f-4ea9-9898-8a3f1f442ab0')
     def test_deactivate_reactivate_image(self):
+        """Test deactivating and reactivating an image"""
         # Create image
         image_name = data_utils.rand_name('image')
         image = self.create_image(name=image_name,
@@ -235,7 +234,7 @@
 
     @decorators.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
     def test_list_no_params(self):
-        # Simple test to see all fixture images returned
+        """Simple test to see all fixture images returned"""
         images_list = self.client.list_images()['images']
         image_list = [image['id'] for image in images_list]
 
@@ -244,25 +243,25 @@
 
     @decorators.idempotent_id('9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e')
     def test_list_images_param_container_format(self):
-        # Test to get all images with a specific container_format
+        """Test to get all images with a specific container_format"""
         params = {"container_format": self.test_data['container_format']}
         self._list_by_param_value_and_assert(params)
 
     @decorators.idempotent_id('4a4735a7-f22f-49b6-b0d9-66e1ef7453eb')
     def test_list_images_param_disk_format(self):
-        # Test to get all images with disk_format = raw
+        """Test to get all images with disk_format = raw"""
         params = {"disk_format": "raw"}
         self._list_by_param_value_and_assert(params)
 
     @decorators.idempotent_id('7a95bb92-d99e-4b12-9718-7bc6ab73e6d2')
     def test_list_images_param_visibility(self):
-        # Test to get all images with visibility = private
+        """Test to get all images with visibility = private"""
         params = {"visibility": "private"}
         self._list_by_param_value_and_assert(params)
 
     @decorators.idempotent_id('cf1b9a48-8340-480e-af7b-fe7e17690876')
     def test_list_images_param_size(self):
-        # Test to get all images by size
+        """Test to get all images by size"""
         image_id = self.created_images[0]
         # Get image metadata
         image = self.client.show_image(image_id)
@@ -272,7 +271,7 @@
 
     @decorators.idempotent_id('4ad8c157-971a-4ba8-aa84-ed61154b1e7f')
     def test_list_images_param_min_max_size(self):
-        # Test to get all images with size between 2000 to 3000
+        """Test to get all images with min size and max size"""
         image_id = self.created_images[0]
         # Get image metadata
         image = self.client.show_image(image_id)
@@ -290,13 +289,13 @@
 
     @decorators.idempotent_id('7fc9e369-0f58-4d05-9aa5-0969e2d59d15')
     def test_list_images_param_status(self):
-        # Test to get all active images
+        """Test to get all active images"""
         params = {"status": "active"}
         self._list_by_param_value_and_assert(params)
 
     @decorators.idempotent_id('e914a891-3cc8-4b40-ad32-e0a39ffbddbb')
     def test_list_images_param_limit(self):
-        # Test to get images by limit
+        """Test to get images by limit"""
         params = {"limit": 1}
         images_list = self.client.list_images(params=params)['images']
 
@@ -305,7 +304,7 @@
 
     @decorators.idempotent_id('e9a44b91-31c8-4b40-a332-e0a39ffb4dbb')
     def test_list_image_param_owner(self):
-        # Test to get images by owner
+        """Test to get images by owner"""
         image_id = self.created_images[0]
         # Get image metadata
         image = self.client.show_image(image_id)
@@ -315,13 +314,13 @@
 
     @decorators.idempotent_id('55c8f5f5-bfed-409d-a6d5-4caeda985d7b')
     def test_list_images_param_name(self):
-        # Test to get images by name
+        """Test to get images by name"""
         params = {'name': self.test_data['name']}
         self._list_by_param_value_and_assert(params)
 
     @decorators.idempotent_id('aa8ac4df-cff9-418b-8d0f-dd9c67b072c9')
     def test_list_images_param_tag(self):
-        # Test to get images matching a tag
+        """Test to get images matching a tag"""
         params = {'tag': self.test_data['tags'][0]}
         images_list = self.client.list_images(params=params)['images']
         # Validating properties of fetched images
@@ -336,24 +335,26 @@
 
     @decorators.idempotent_id('eeadce49-04e0-43b7-aec7-52535d903e7a')
     def test_list_images_param_sort(self):
+        """Test listing images sorting in descending order"""
         params = {'sort': 'size:desc'}
         self._list_sorted_by_image_size_and_assert(params, desc=True)
 
     @decorators.idempotent_id('9faaa0c2-c3a5-43e1-8f61-61c54b409a49')
     def test_list_images_param_sort_key_dir(self):
+        """Test listing images sorting by size in descending order"""
         params = {'sort_key': 'size', 'sort_dir': 'desc'}
         self._list_sorted_by_image_size_and_assert(params, desc=True)
 
     @decorators.idempotent_id('622b925c-479f-4736-860d-adeaf13bc371')
     def test_get_image_schema(self):
-        # Test to get image schema
+        """Test to get image schema"""
         schema = "image"
         body = self.schemas_client.show_schema(schema)
         self.assertEqual("image", body['name'])
 
     @decorators.idempotent_id('25c8d7b2-df21-460f-87ac-93130bcdc684')
     def test_get_images_schema(self):
-        # Test to get images schema
+        """Test to get images schema"""
         schema = "images"
         body = self.schemas_client.show_schema(schema)
         self.assertEqual("images", body['name'])
@@ -372,6 +373,7 @@
 
     @decorators.idempotent_id('3fa50be4-8e38-4c02-a8db-7811bb780122')
     def test_list_images_param_member_status(self):
+        """Test listing images by member_status and visibility"""
         # Create an image to be shared using default visibility
         image_file = six.BytesIO(data_utils.random_bytes(2048))
         container_format = CONF.image.container_formats[0]
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index e19d8c8..bc67859 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -15,9 +15,11 @@
 
 
 class ImagesMemberTest(base.BaseV2MemberImageTest):
+    """Test image members"""
 
     @decorators.idempotent_id('5934c6ea-27dc-4d6e-9421-eeb5e045494a')
     def test_image_share_accept(self):
+        """Test sharing and accepting an image"""
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
             image_id, member=self.alt_tenant_id)
@@ -41,6 +43,7 @@
 
     @decorators.idempotent_id('d9e83e5f-3524-4b38-a900-22abcb26e90e')
     def test_image_share_reject(self):
+        """Test sharing and rejecting an image"""
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
             image_id, member=self.alt_tenant_id)
@@ -57,6 +60,7 @@
 
     @decorators.idempotent_id('a6ee18b9-4378-465e-9ad9-9a6de58a3287')
     def test_get_image_member(self):
+        """Test getting image members after the image is accepted"""
         image_id = self._create_image()
         self.image_member_client.create_image_member(
             image_id, member=self.alt_tenant_id)
@@ -75,6 +79,7 @@
 
     @decorators.idempotent_id('72989bc7-2268-48ed-af22-8821e835c914')
     def test_remove_image_member(self):
+        """Test removing image members after the image is accepted"""
         image_id = self._create_image()
         self.image_member_client.create_image_member(
             image_id, member=self.alt_tenant_id)
@@ -89,10 +94,12 @@
 
     @decorators.idempotent_id('634dcc3f-f6e2-4409-b8fd-354a0bb25d83')
     def test_get_image_member_schema(self):
+        """Test getting image member schema"""
         body = self.schemas_client.show_schema("member")
         self.assertEqual("member", body['name'])
 
     @decorators.idempotent_id('6ae916ef-1052-4e11-8d36-b3ae14853cbb')
     def test_get_image_members_schema(self):
+        """Test getting image members schema"""
         body = self.schemas_client.show_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 caa90f9..5f6f1ae 100644
--- a/tempest/api/image/v2/test_images_member_negative.py
+++ b/tempest/api/image/v2/test_images_member_negative.py
@@ -16,10 +16,12 @@
 
 
 class ImagesMemberNegativeTest(base.BaseV2MemberImageTest):
+    """Negative tests of image members"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('b79efb37-820d-4cf0-b54c-308b00cf842c')
     def test_image_share_invalid_status(self):
+        """Test updating image member status to invalid status should fail"""
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
             image_id, member=self.alt_tenant_id)
@@ -32,6 +34,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('27002f74-109e-4a37-acd0-f91cd4597967')
     def test_image_share_owner_cannot_accept(self):
+        """Test that image owner can't accept image shared to other member"""
         image_id = self._create_image()
         member = self.image_member_client.create_image_member(
             image_id, member=self.alt_tenant_id)
diff --git a/tempest/api/image/v2/test_images_metadefs_namespace_objects.py b/tempest/api/image/v2/test_images_metadefs_namespace_objects.py
index 80f8112..32b81b1 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespace_objects.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespace_objects.py
@@ -30,6 +30,7 @@
 
     @decorators.idempotent_id('b1a3775e-3b5c-4f6a-a3b4-1ba3574ae718')
     def test_create_update_delete_meta_namespace_objects(self):
+        """Test creating/updating/deleting image metadata namespace objects"""
         # Create a namespace
         namespace = self.create_namespace()
         # Create a namespace object
@@ -52,6 +53,7 @@
 
     @decorators.idempotent_id('a2a3615e-3b5c-3f6a-a2b1-1ba3574ae738')
     def test_list_meta_namespace_objects(self):
+        """Test listing image metadata namespace objects"""
         # Create a namespace object
         namespace = self.create_namespace()
         meta_namespace_object = self._create_namespace_object(namespace)
@@ -64,6 +66,7 @@
 
     @decorators.idempotent_id('b1a3674e-3b4c-3f6a-a3b4-1ba3573ca768')
     def test_show_meta_namespace_objects(self):
+        """Test showing image metadata namespace object"""
         # Create a namespace object
         namespace = self.create_namespace()
         namespace_object = self._create_namespace_object(namespace)
diff --git a/tempest/api/image/v2/test_images_metadefs_namespace_properties.py b/tempest/api/image/v2/test_images_metadefs_namespace_properties.py
index ed91726..1d4f0a6 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespace_properties.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespace_properties.py
@@ -20,6 +20,7 @@
 
     @decorators.idempotent_id('b1a3765e-3a5d-4f6d-a3a7-3ca3476ae768')
     def test_basic_meta_def_namespace_property(self):
+        """Test operations of image metadata definition namespace property"""
         # Get the available resource types and use one resource_type
         body = self.resource_types_client.list_resource_types()
         resource_name = body['resource_types'][0]['name']
diff --git a/tempest/api/image/v2/test_images_metadefs_namespace_tags.py b/tempest/api/image/v2/test_images_metadefs_namespace_tags.py
index 482e808..dc64185 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespace_tags.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespace_tags.py
@@ -43,6 +43,7 @@
 
     @decorators.idempotent_id('a2a3765e-3a6d-4f6d-a3a7-3cc3476aa876')
     def test_create_list_delete_namespace_tags(self):
+        """Test creating/listing/deleting image metadata namespace tags"""
         # Create a namespace
         namespace = self.create_namespace()
         self._create_namespace_tags(namespace)
@@ -62,6 +63,7 @@
 
     @decorators.idempotent_id('a2a3765e-1a2c-3f6d-a3a7-3cc3466ab875')
     def test_create_update_delete_tag(self):
+        """Test creating/updating/deleting image metadata namespace tag"""
         # Create a namespace
         namespace = self.create_namespace()
         self._create_namespace_tags(namespace)
diff --git a/tempest/api/image/v2/test_images_metadefs_namespaces.py b/tempest/api/image/v2/test_images_metadefs_namespaces.py
index f71b16c..502949f 100644
--- a/tempest/api/image/v2/test_images_metadefs_namespaces.py
+++ b/tempest/api/image/v2/test_images_metadefs_namespaces.py
@@ -25,6 +25,7 @@
 
     @decorators.idempotent_id('319b765e-7f3d-4b3d-8b37-3ca3876ee768')
     def test_basic_metadata_definition_namespaces(self):
+        """Test operations of image metadata definition namespaces"""
         # get the available resource types and use one resource_type
         body = self.resource_types_client.list_resource_types()
         resource_name = body['resource_types'][0]['name']
diff --git a/tempest/api/image/v2/test_images_metadefs_resource_types.py b/tempest/api/image/v2/test_images_metadefs_resource_types.py
index c60b3f7..6867f2d 100644
--- a/tempest/api/image/v2/test_images_metadefs_resource_types.py
+++ b/tempest/api/image/v2/test_images_metadefs_resource_types.py
@@ -22,6 +22,7 @@
 
     @decorators.idempotent_id('6f358a4e-5ef0-11e6-a795-080027d0d606')
     def test_basic_meta_def_resource_type_association(self):
+        """Test image resource type associations"""
         # Get the available resource types and use one resource_type
         body = self.resource_types_client.list_resource_types()
         resource_name = body['resource_types'][0]['name']
diff --git a/tempest/api/image/v2/test_images_metadefs_schema.py b/tempest/api/image/v2/test_images_metadefs_schema.py
index 95cc310..7dd36d2 100644
--- a/tempest/api/image/v2/test_images_metadefs_schema.py
+++ b/tempest/api/image/v2/test_images_metadefs_schema.py
@@ -18,64 +18,64 @@
 
 
 class MetadataSchemaTest(base.BaseV2ImageTest):
-    """Test to get metadata schema"""
+    """Test to get image metadata schema"""
 
     @decorators.idempotent_id('e9e44891-3cb8-3b40-a532-e0a39fea3dab')
     def test_get_metadata_namespace_schema(self):
-        # Test to get namespace schema
+        """Test to get image namespace schema"""
         body = self.schemas_client.show_schema("metadefs/namespace")
         self.assertEqual("namespace", body['name'])
 
     @decorators.idempotent_id('ffe44891-678b-3ba0-a3e2-e0a3967b3aeb')
     def test_get_metadata_namespaces_schema(self):
-        # Test to get namespaces schema
+        """Test to get image namespaces schema"""
         body = self.schemas_client.show_schema("metadefs/namespaces")
         self.assertEqual("namespaces", body['name'])
 
     @decorators.idempotent_id('fde34891-678b-3b40-ae32-e0a3e67b6beb')
     def test_get_metadata_resource_type_schema(self):
-        # Test to get resource_type schema
+        """Test to get image resource_type schema"""
         body = self.schemas_client.show_schema("metadefs/resource_type")
         self.assertEqual("resource_type_association", body['name'])
 
     @decorators.idempotent_id('dfe4a891-b38b-3bf0-a3b2-e03ee67b3a3a')
     def test_get_metadata_resources_types_schema(self):
-        # Test to get resource_types schema
+        """Test to get image resource_types schema"""
         body = self.schemas_client.show_schema("metadefs/resource_types")
         self.assertEqual("resource_type_associations", body['name'])
 
     @decorators.idempotent_id('dff4a891-b38b-3bf0-a3b2-e03ee67b3a3b')
     def test_get_metadata_object_schema(self):
-        # Test to get object schema
+        """Test to get image object schema"""
         body = self.schemas_client.show_schema("metadefs/object")
         self.assertEqual("object", body['name'])
 
     @decorators.idempotent_id('dee4a891-b38b-3bf0-a3b2-e03ee67b3a3c')
     def test_get_metadata_objects_schema(self):
-        # Test to get objects schema
+        """Test to get image objects schema"""
         body = self.schemas_client.show_schema("metadefs/objects")
         self.assertEqual("objects", body['name'])
 
     @decorators.idempotent_id('dae4a891-b38b-3bf0-a3b2-e03ee67b3a3d')
     def test_get_metadata_property_schema(self):
-        # Test to get property schema
+        """Test to get image property schema"""
         body = self.schemas_client.show_schema("metadefs/property")
         self.assertEqual("property", body['name'])
 
     @decorators.idempotent_id('dce4a891-b38b-3bf0-a3b2-e03ee67b3a3e')
     def test_get_metadata_properties_schema(self):
-        # Test to get properties schema
+        """Test to get image properties schema"""
         body = self.schemas_client.show_schema("metadefs/properties")
         self.assertEqual("properties", body['name'])
 
     @decorators.idempotent_id('dde4a891-b38b-3bf0-a3b2-e03ee67b3a3e')
     def test_get_metadata_tag_schema(self):
-        # Test to get tag schema
+        """Test to get image tag schema"""
         body = self.schemas_client.show_schema("metadefs/tag")
         self.assertEqual("tag", body['name'])
 
     @decorators.idempotent_id('cde4a891-b38b-3bf0-a3b2-e03ee67b3a3a')
     def test_get_metadata_tags_schema(self):
-        # Test to get tags schema
+        """Test to get image tags schema"""
         body = self.schemas_client.show_schema("metadefs/tags")
         self.assertEqual("tags", body['name'])
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index b4baf05..dc2bb96 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -36,7 +36,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('668743d5-08ad-4480-b2b8-15da34f81d9f')
     def test_get_non_existent_image(self):
-        # get the non-existent image
+        """Get the non-existent image"""
         non_existent_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.show_image,
                           non_existent_id)
@@ -44,14 +44,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('ef45000d-0a72-4781-866d-4cb7bf2562ad')
     def test_get_image_null_id(self):
-        # get image with image_id = NULL
+        """Get image with image_id = NULL"""
         image_id = ""
         self.assertRaises(lib_exc.NotFound, self.client.show_image, image_id)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e57fc127-7ba0-4693-92d7-1d8a05ebcba9')
     def test_get_delete_deleted_image(self):
-        # get and delete the deleted image
+        """Get and delete the deleted image"""
         # create and delete image
         image = self.client.create_image(name='test',
                                          container_format='bare',
@@ -70,7 +70,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('6fe40f1c-57bd-4918-89cc-8500f850f3de')
     def test_delete_non_existing_image(self):
-        # delete non-existent image
+        """Delete non-existent image"""
         non_existent_image_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           non_existent_image_id)
@@ -78,7 +78,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('32248db1-ab88-4821-9604-c7c369f1f88c')
     def test_delete_image_null_id(self):
-        # delete image with image_id=NULL
+        """Delete image with image_id=NULL"""
         image_id = ""
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           image_id)
@@ -86,7 +86,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('292bd310-369b-41c7-a7a3-10276ef76753')
     def test_register_with_invalid_container_format(self):
-        # Negative tests for invalid data supplied to POST /images
+        """Create image with invalid container format
+
+        Negative tests for invalid data supplied to POST /images
+        """
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           name='test', container_format='wrong',
                           disk_format='vhd')
@@ -94,6 +97,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('70c6040c-5a97-4111-9e13-e73665264ce1')
     def test_register_with_invalid_disk_format(self):
+        """Create image with invalid disk format"""
         self.assertRaises(lib_exc.BadRequest, self.client.create_image,
                           name='test', container_format='bare',
                           disk_format='wrong')
@@ -101,7 +105,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('ab980a34-8410-40eb-872b-f264752f46e5')
     def test_delete_protected_image(self):
-        # Create a protected image
+        """Create a protected image"""
         image = self.create_image(protected=True)
         self.addCleanup(self.client.update_image, image['id'],
                         [dict(replace="/protected", value=False)])
diff --git a/tempest/api/image/v2/test_images_tags.py b/tempest/api/image/v2/test_images_tags.py
index 601826e..163063c 100644
--- a/tempest/api/image/v2/test_images_tags.py
+++ b/tempest/api/image/v2/test_images_tags.py
@@ -18,9 +18,11 @@
 
 
 class ImagesTagsTest(base.BaseV2ImageTest):
+    """Test image tags"""
 
     @decorators.idempotent_id('10407036-6059-4f95-a2cd-cbbbee7ed329')
     def test_update_delete_tags_for_image(self):
+        """Test adding and deleting image tags"""
         image = self.create_image(container_format='bare',
                                   disk_format='raw',
                                   visibility='private')
diff --git a/tempest/api/image/v2/test_images_tags_negative.py b/tempest/api/image/v2/test_images_tags_negative.py
index 440fa36..2db4a74 100644
--- a/tempest/api/image/v2/test_images_tags_negative.py
+++ b/tempest/api/image/v2/test_images_tags_negative.py
@@ -19,11 +19,12 @@
 
 
 class ImagesTagsNegativeTest(base.BaseV2ImageTest):
+    """Negative tests of image tags"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('8cd30f82-6f9a-4c6e-8034-c1b51fba43d9')
     def test_update_tags_for_non_existing_image(self):
-        # Update tag with non existing image.
+        """Update image tag with non existing image"""
         tag = data_utils.rand_name('tag')
         non_exist_image = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.add_image_tag,
@@ -32,7 +33,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('39c023a2-325a-433a-9eea-649bf1414b19')
     def test_delete_non_existing_tag(self):
-        # Delete non existing tag.
+        """Delete non existing image tag"""
         image = self.create_image(container_format='bare',
                                   disk_format='raw',
                                   visibility='private'
diff --git a/tempest/api/image/v2/test_versions.py b/tempest/api/image/v2/test_versions.py
index 84f1068..ef91354 100644
--- a/tempest/api/image/v2/test_versions.py
+++ b/tempest/api/image/v2/test_versions.py
@@ -17,10 +17,12 @@
 
 
 class VersionsTest(base.BaseV2ImageTest):
+    """Test image versions"""
 
     @decorators.idempotent_id('659ea30a-a17c-4317-832c-0f68ed23c31d')
     @decorators.attr(type='smoke')
     def test_list_versions(self):
+        """Test listing image versions"""
         versions = self.versions_client.list_versions()['versions']
         expected_resources = ('id', 'links', 'status')
 
diff --git a/tempest/api/network/admin/test_routers.py b/tempest/api/network/admin/test_routers.py
index a4a057c..41f97d8 100644
--- a/tempest/api/network/admin/test_routers.py
+++ b/tempest/api/network/admin/test_routers.py
@@ -212,6 +212,42 @@
              'enable_snat': False})
         self._verify_gateway_port(router['id'])
 
+    @decorators.idempotent_id('cbe42f84-04c2-11e7-8adb-fa163e4fa634')
+    @utils.requires_ext(extension='ext-gw-mode', service='network')
+    def test_create_router_set_gateway_with_fixed_ip(self):
+        # At first create an external network and then use that
+        # to create address and delete
+        network_name = data_utils.rand_name(self.__class__.__name__)
+        network_1 = self.admin_networks_client.create_network(
+            name=network_name, **{'router:external': True})['network']
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_networks_client.delete_network,
+                        network_1['id'])
+        subnet = self.create_subnet(
+            network_1, client=self.admin_subnets_client, enable_dhcp=False)
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self.admin_subnets_client.delete_subnet, subnet['id'])
+        port = self.admin_ports_client.create_port(
+            name=data_utils.rand_name(self.__class__.__name__),
+            network_id=network_1['id'])['port']
+        self.admin_ports_client.delete_port(port_id=port['id'])
+        fixed_ip = {
+            'subnet_id': port['fixed_ips'][0]['subnet_id'],
+            'ip_address': port['fixed_ips'][0]['ip_address']
+        }
+        external_gateway_info = {
+            'network_id': network_1['id'],
+            'external_fixed_ips': [fixed_ip]
+        }
+        # Create a router and set gateway to fixed_ip
+        router = self.admin_routers_client.create_router(
+            external_gateway_info=external_gateway_info)['router']
+        self.admin_routers_client.delete_router(router['id'])
+        # Examine router's gateway is equal to fixed_ip
+        self.assertEqual(router['external_gateway_info'][
+                         'external_fixed_ips'][0]['ip_address'],
+                         fixed_ip['ip_address'])
+
 
 class RoutersIpV6AdminTest(RoutersAdminTest):
     _ip_version = 6
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index ad316d1..30423e3 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -142,39 +142,6 @@
         self.routers_client.remove_router_interface(
             router['id'], port_id=port_body['port']['id'])
 
-    @decorators.idempotent_id('cbe42f84-04c2-11e7-8adb-fa163e4fa634')
-    @utils.requires_ext(extension='ext-gw-mode', service='network')
-    @testtools.skipUnless(CONF.network.public_network_id,
-                          'The public_network_id option must be specified.')
-    @decorators.skip_because(bug='1676207')
-    def test_create_router_set_gateway_with_fixed_ip(self):
-        # Don't know public_network_address, so at first create address
-        # from public_network and delete
-        port = self.admin_ports_client.create_port(
-            name=data_utils.rand_name(self.__class__.__name__),
-            network_id=CONF.network.public_network_id)['port']
-        self.admin_ports_client.delete_port(port_id=port['id'])
-
-        fixed_ip = {
-            'subnet_id': port['fixed_ips'][0]['subnet_id'],
-            'ip_address': port['fixed_ips'][0]['ip_address']
-        }
-        external_gateway_info = {
-            'network_id': CONF.network.public_network_id,
-            'external_fixed_ips': [fixed_ip]
-        }
-
-        # Create a router and set gateway to fixed_ip
-        router = self.admin_routers_client.create_router(
-            external_gateway_info=external_gateway_info)['router']
-        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
-                        self.admin_routers_client.delete_router,
-                        router_id=router['id'])
-        # Examine router's gateway is equal to fixed_ip
-        self.assertEqual(router['external_gateway_info'][
-                         'external_fixed_ips'][0]['ip_address'],
-                         fixed_ip['ip_address'])
-
     @decorators.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
     @utils.requires_ext(extension='extraroute', service='network')
     def test_update_delete_extra_route(self):
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index c1ceeb7..ecc850e 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -127,7 +127,6 @@
         encryption_type = \
             self.admin_encryption_types_client.create_encryption_type(
                 volume_type_id, **create_kwargs)['encryption']
-        self.assertIn('volume_type_id', encryption_type)
         for key in create_kwargs:
             self.assertEqual(create_kwargs[key], encryption_type[key],
                              'The created encryption_type %s is different '
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index bcbcf43..7af5927 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -233,12 +233,15 @@
         return group
 
     def delete_group(self, group_id, delete_volumes=True):
-        self.groups_client.delete_group(group_id, delete_volumes)
+        group_vols = []
         if delete_volumes:
             vols = self.volumes_client.list_volumes(detail=True)['volumes']
             for vol in vols:
                 if vol['group_id'] == group_id:
-                    self.volumes_client.wait_for_resource_deletion(vol['id'])
+                    group_vols.append(vol['id'])
+        self.groups_client.delete_group(group_id, delete_volumes)
+        for vol in group_vols:
+            self.volumes_client.wait_for_resource_deletion(vol)
         self.groups_client.wait_for_resource_deletion(group_id)
 
 
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index b230615..ff552a1 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -97,6 +97,7 @@
 [OPTIONS] <accounts_file.yaml> -h``.
 """
 
+import argparse
 import os
 import traceback
 
@@ -199,6 +200,14 @@
     LOG.info('%s generated successfully!', account_file)
 
 
+def positive_int(number):
+    number = int(number)
+    if number <= 0:
+        raise argparse.ArgumentTypeError("Concurrency value should be a "
+                                         "positive number")
+    return number
+
+
 def _parser_add_args(parser):
     parser.add_argument('-c', '--config-file',
                         metavar='/etc/tempest.conf',
@@ -228,7 +237,7 @@
                         help='Resources tag')
     parser.add_argument('-r', '--concurrency',
                         default=1,
-                        type=int,
+                        type=positive_int,
                         required=False,
                         dest='concurrency',
                         help='Concurrency count')
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 8d5bdbd..235d8e3 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -60,16 +60,16 @@
 """
 
 import argparse
+import configparser
 import os
 import re
 import sys
 import traceback
+from urllib import parse as urlparse
 
 from cliff import command
 from oslo_log import log as logging
 from oslo_serialization import jsonutils as json
-from six import moves
-from six.moves.urllib import parse as urlparse
 
 from tempest import clients
 from tempest.common import credentials_factory as credentials
@@ -439,9 +439,9 @@
 
     if update:
         conf_file = _get_config_file()
-        CONF_PARSER = moves.configparser.ConfigParser()
+        CONF_PARSER = configparser.ConfigParser()
         CONF_PARSER.optionxform = str
-        CONF_PARSER.readfp(conf_file)
+        CONF_PARSER.read_file(conf_file)
 
     # Indicate not to create network resources as part of getting credentials
     net_resources = {
diff --git a/tempest/config.py b/tempest/config.py
index 204d977..e4e17f1 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1021,7 +1021,7 @@
                help="Number of seconds to wait while looping to check the "
                     "status of a container to container synchronization"),
     cfg.StrOpt('operator_role',
-               default='Member',
+               default='member',
                help="Role to add to users created for swift tests to "
                     "enable creating containers"),
     cfg.StrOpt('reseller_admin_role',
diff --git a/tempest/lib/api_schema/response/compute/v2_59/__init__.py b/tempest/lib/api_schema/response/compute/v2_59/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_59/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_59/migrations.py b/tempest/lib/api_schema/response/compute/v2_59/migrations.py
new file mode 100644
index 0000000..a37c0f1
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_59/migrations.py
@@ -0,0 +1,36 @@
+#    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 copy
+
+from tempest.lib.api_schema.response.compute.v2_23 import migrations
+
+###########################################################################
+#
+# 2.59:
+#
+# The uuid value is now returned in the response body in addition to the
+# migration id for the following API responses:
+#
+# - GET /os-migrations
+# - GET /servers/{server_id}/migrations/{migration_id}
+# - GET /servers/{server_id}/migrations
+#
+###########################################################################
+
+uuid = {'type': 'string', 'format': 'uuid'}
+
+list_migrations = copy.deepcopy(migrations.list_migrations)
+list_migrations['response_body']['properties']['migrations']['items'][
+    'properties'].update({'uuid': uuid})
+list_migrations['response_body']['properties']['migrations']['items'][
+    'required'].append('uuid')
diff --git a/tempest/lib/api_schema/response/volume/encryption_types.py b/tempest/lib/api_schema/response/volume/encryption_types.py
new file mode 100755
index 0000000..7e7ca4a
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/encryption_types.py
@@ -0,0 +1,95 @@
+# Copyright 2019 ZTE Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
+show_encryption_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': ['object', 'null'],
+        'properties': {
+            'volume_type_id': {'type': 'string', 'format': 'uuid'},
+            'encryption_id': {'type': 'string', 'format': 'uuid'},
+            'key_size': {'type': ['integer', 'null']},
+            'provider': {'type': 'string'},
+            'control_location': {'enum': ['front-end', 'back-end']},
+            'cipher': {'type': ['string', 'null']},
+            'deleted': {'type': 'boolean'},
+            'created_at': parameter_types.date_time,
+            'updated_at': parameter_types.date_time_or_null,
+            'deleted_at': parameter_types.date_time_or_null
+        },
+        # result of show_encryption_type may be empty list,
+        # so no required fields.
+        'additionalProperties': False,
+    }
+}
+
+show_encryption_specs_item = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'patternProperties': {
+            '^.+$': {'type': 'string'}
+        }
+    }
+}
+
+create_encryption_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'encryption': {
+                'type': 'object',
+                'properties': {
+                    'volume_type_id': {'type': 'string', 'format': 'uuid'},
+                    'encryption_id': {'type': 'string', 'format': 'uuid'},
+                    'key_size': {'type': ['integer', 'null']},
+                    'provider': {'type': 'string'},
+                    'control_location': {'enum': ['front-end', 'back-end']},
+                    'cipher': {'type': ['string', 'null']},
+                },
+                'additionalProperties': False,
+                'required': ['volume_type_id', 'encryption_id']
+            }
+        },
+        'additionalProperties': False,
+        'required': ['encryption']
+    }
+}
+
+delete_encryption_type = {'status_code': [202]}
+
+update_encryption_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'encryption': {
+                'type': 'object',
+                'properties': {
+                    'key_size': {'type': ['integer', 'null']},
+                    'provider': {'type': 'string'},
+                    'control_location': {'enum': ['front-end', 'back-end']},
+                    'cipher': {'type': ['string', 'null']},
+                },
+                # all fields are optional
+                'additionalProperties': False,
+            }
+        },
+        'additionalProperties': False,
+        'required': ['encryption']
+    }
+}
diff --git a/tempest/lib/api_schema/response/volume/group_types.py b/tempest/lib/api_schema/response/volume/group_types.py
new file mode 100644
index 0000000..bcfa32e
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/group_types.py
@@ -0,0 +1,122 @@
+# Copyright 2015 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+group_specs = {
+    'type': 'object',
+    'patternProperties': {
+        '^.+$': {'type': 'string'}
+    }
+}
+
+common_show_group_type = {
+    'type': 'object',
+    'properties': {
+        'id': {'type': 'string'},
+        'is_public': {'type': 'boolean'},
+        'group_specs': group_specs,
+        'description': {'type': ['string', 'null']},
+        'name': {'type': 'string'},
+    },
+    'additionalProperties': False,
+    'required': ['id', 'is_public', 'description', 'name']
+}
+
+create_group_type = {
+    'status_code': [202],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_type': common_show_group_type
+        },
+        'additionalProperties': False,
+        'required': ['group_type']
+    }
+}
+
+delete_group_type = {'status_code': [202]}
+
+list_group_types = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_types': {
+                'type': 'array',
+                'items': common_show_group_type
+            }
+        },
+        'additionalProperties': False,
+        'required': ['group_types'],
+    }
+}
+
+show_group_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_type': common_show_group_type
+        },
+        'additionalProperties': False,
+        'required': ['group_type']
+    }
+}
+
+update_group_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_type': common_show_group_type
+        },
+        'additionalProperties': False,
+        'required': ['group_type']
+    }
+}
+
+create_or_update_group_type_specs = {
+    'status_code': [202],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_specs': group_specs,
+        },
+        'additionalProperties': False,
+        'required': ['group_specs']
+    }
+}
+
+list_group_type_specs = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_specs': group_specs,
+        },
+        'additionalProperties': False,
+        'required': ['group_specs']
+    }
+}
+
+show_group_type_specs_item = {
+    'status_code': [200],
+    'response_body': group_specs
+}
+
+update_group_type_specs_item = {
+    'status_code': [200],
+    'response_body': group_specs
+}
+
+delete_group_type_specs_item = {'status_code': [202]}
diff --git a/tempest/lib/api_schema/response/volume/limits.py b/tempest/lib/api_schema/response/volume/limits.py
new file mode 100644
index 0000000..99af180
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/limits.py
@@ -0,0 +1,55 @@
+# Copyright 2018 ZTE Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+show_limits = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'limits': {
+                'type': 'object',
+                'properties': {
+                    'rate': {'type': 'array'},
+                    'absolute': {
+                        'type': 'object',
+                        'properties': {
+                            'totalSnapshotsUsed': {'type': 'integer'},
+                            'maxTotalBackups': {'type': 'integer'},
+                            'maxTotalVolumeGigabytes': {'type': 'integer'},
+                            'maxTotalSnapshots': {'type': 'integer'},
+                            'maxTotalBackupGigabytes': {'type': 'integer'},
+                            'totalBackupGigabytesUsed': {'type': 'integer'},
+                            'maxTotalVolumes': {'type': 'integer'},
+                            'totalVolumesUsed': {'type': 'integer'},
+                            'totalBackupsUsed': {'type': 'integer'},
+                            'totalGigabytesUsed': {'type': 'integer'},
+                        },
+                        'additionalProperties': False,
+                        'required': ['totalSnapshotsUsed', 'maxTotalBackups',
+                                     'maxTotalVolumeGigabytes',
+                                     'maxTotalSnapshots',
+                                     'maxTotalBackupGigabytes',
+                                     'totalBackupGigabytesUsed',
+                                     'maxTotalVolumes', 'totalVolumesUsed',
+                                     'totalBackupsUsed', 'totalGigabytesUsed']
+                    }
+                },
+                'additionalProperties': False,
+                'required': ['rate', 'absolute'],
+            }
+        },
+        'additionalProperties': False,
+        'required': ['limits']
+    }
+}
diff --git a/tempest/lib/api_schema/response/volume/scheduler_stats.py b/tempest/lib/api_schema/response/volume/scheduler_stats.py
new file mode 100644
index 0000000..b5d7d2c
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/scheduler_stats.py
@@ -0,0 +1,79 @@
+# Copyright 2018 ZTE Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
+get_pools_no_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'pools': {
+                'type': 'array',
+                'items': {
+                    'type': 'object',
+                    'properties': {
+                        'name': {'type': 'string'},
+                    },
+                    'additionalProperties': False,
+                    'required': ['name']
+                }
+            }
+        },
+        'additionalProperties': False,
+        'required': ['pools'],
+    }
+}
+
+get_pools_with_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'pools': {
+                'type': 'array',
+                'items': {
+                    'type': 'object',
+                    'properties': {
+                        'name': {'type': 'string'},
+                        'capabilities': {
+                            'type': ['object', 'null'],
+                            'properties': {
+                                'updated': parameter_types.date_time_or_null,
+                                'QoS_support': {'type': 'boolean'},
+                                'total_capacity_gb': {
+                                    'type': ['number', 'string']
+                                },
+                                'volume_backend_name': {'type': 'string'},
+                                'free_capacity_gb': {
+                                    'type': ['number', 'string']
+                                },
+                                'driver_version': {'type': 'string'},
+                                'reserved_percentage': {'type': 'integer'},
+                                'storage_protocol': {'type': 'string'},
+                                'vendor_name': {'type': 'string'},
+                                'timestamp': parameter_types.date_time_or_null
+                            },
+                            # Because some legacy volumes or backends may not
+                            # support pools, so no required fields here.
+                        },
+                    },
+                    'additionalProperties': False,
+                    'required': ['name', 'capabilities']
+                }
+            }
+        },
+        'additionalProperties': False,
+        'required': ['pools'],
+    }
+}
diff --git a/tempest/lib/api_schema/response/volume/snapshots.py b/tempest/lib/api_schema/response/volume/snapshots.py
new file mode 100644
index 0000000..9d52801
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/snapshots.py
@@ -0,0 +1,198 @@
+# Copyright 2018 ZTE Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+import copy
+
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
+metadata = {
+    'type': 'object',
+    'patternProperties': {
+        '^.+$': {'type': 'string'}
+    }
+}
+
+common_snapshot_schema = {
+    'type': 'object',
+    'properties': {
+        'status': {'type': 'string'},
+        'description': {'type': ['string', 'null']},
+        'created_at': parameter_types.date_time,
+        'name': {'type': ['string', 'null']},
+        'volume_id': {'type': 'string', 'format': 'uuid'},
+        'metadata': metadata,
+        'id': {'type': 'string', 'format': 'uuid'},
+        'size': {'type': 'integer'},
+        'updated_at': parameter_types.date_time_or_null,
+        # TODO(zhufl): user_id is added in 3.41, we should move it
+        # to the 3.41 schema file when microversion is supported
+        # in volume interfaces
+        # 'user_id': {'type': 'string', 'format': 'uuid'}
+    },
+    'additionalProperties': False,
+    'required': ['status', 'description', 'created_at', 'metadata',
+                 'name', 'volume_id', 'id', 'size', 'updated_at']
+}
+
+common_snapshot_detail_schema = copy.deepcopy(common_snapshot_schema)
+common_snapshot_detail_schema['properties'].update(
+    {'os-extended-snapshot-attributes:progress': {'type': 'string'},
+     'os-extended-snapshot-attributes:project_id': {
+         'type': 'string', 'format': 'uuid'}})
+common_snapshot_detail_schema['required'].extend(
+    ['os-extended-snapshot-attributes:progress',
+     'os-extended-snapshot-attributes:project_id'])
+
+list_snapshots_no_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'snapshots': {
+                'type': 'array',
+                'items': common_snapshot_schema
+            },
+            'snapshots_links': parameter_types.links,
+            # TODO(zhufl): count is added in 3.45, we should move
+            # it to the 3.45 schema file when microversion is
+            # supported in volume interfaces
+            # 'count': {'type': 'integer'}
+        },
+        'additionalProperties': False,
+        'required': ['snapshots'],
+    }
+}
+
+list_snapshots_with_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'snapshots': {
+                'type': 'array',
+                'items': common_snapshot_detail_schema
+            },
+            'snapshots_links': parameter_types.links,
+            # TODO(zhufl): count is added in 3.45, we should move
+            # it to the 3.45 schema file when microversion is
+            # supported in volume interfaces
+            # 'count': {'type': 'integer'},
+        },
+        'additionalProperties': False,
+        'required': ['snapshots'],
+    }
+}
+
+show_snapshot = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'snapshot': common_snapshot_detail_schema
+        },
+        'additionalProperties': False,
+        'required': ['snapshot'],
+    }
+}
+
+create_snapshot = {
+    'status_code': [202],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'snapshot': common_snapshot_schema
+        },
+        'additionalProperties': False,
+        'required': ['snapshot'],
+    }
+}
+
+update_snapshot = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'snapshot': common_snapshot_schema
+        },
+        'additionalProperties': False,
+        'required': ['snapshot'],
+    }
+}
+
+delete_snapshot = {'status_code': [202]}
+reset_snapshot_status = {'status_code': [202]}
+update_snapshot_status = {'status_code': [202]}
+
+create_snapshot_metadata = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'metadata': metadata
+        },
+        'additionalProperties': False,
+        'required': ['metadata'],
+    }
+}
+
+show_snapshot_metadata = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'metadata': metadata
+        },
+        'additionalProperties': False,
+        'required': ['metadata'],
+    }
+}
+
+update_snapshot_metadata = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'metadata': metadata
+        },
+        'additionalProperties': False,
+        'required': ['metadata'],
+    }
+}
+
+show_snapshot_metadata_item = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'meta': metadata
+        },
+        'additionalProperties': False,
+        'required': ['meta'],
+    }
+}
+
+update_snapshot_metadata_item = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'meta': metadata
+        },
+        'additionalProperties': False,
+        'required': ['meta'],
+    }
+}
+
+delete_snapshot_metadata_item = {'status_code': [200]}
+force_delete_snapshot = {'status_code': [202]}
+unmanage_snapshot = {'status_code': [202]}
diff --git a/tempest/lib/common/dynamic_creds.py b/tempest/lib/common/dynamic_creds.py
index f27e926..8b82391 100644
--- a/tempest/lib/common/dynamic_creds.py
+++ b/tempest/lib/common/dynamic_creds.py
@@ -207,10 +207,10 @@
         # our newly created user has a role on the newly created project.
         if self.identity_version == 'v3' and not role_assigned:
             try:
-                self.creds_client.create_user_role('Member')
+                self.creds_client.create_user_role('member')
             except lib_exc.Conflict:
-                LOG.warning('Member role already exists, ignoring conflict.')
-            self.creds_client.assign_user_role(user, project, 'Member')
+                LOG.warning('member role already exists, ignoring conflict.')
+            self.creds_client.assign_user_role(user, project, 'member')
 
         creds = self.creds_client.get_credentials(user, project, user_password)
         return cred_provider.TestResources(creds)
diff --git a/tempest/lib/services/compute/migrations_client.py b/tempest/lib/services/compute/migrations_client.py
index 23de064..812dc96 100644
--- a/tempest/lib/services/compute/migrations_client.py
+++ b/tempest/lib/services/compute/migrations_client.py
@@ -18,6 +18,8 @@
 from tempest.lib.api_schema.response.compute.v2_1 import migrations as schema
 from tempest.lib.api_schema.response.compute.v2_23 import migrations \
     as schemav223
+from tempest.lib.api_schema.response.compute.v2_59 import migrations \
+    as schemav259
 from tempest.lib.common import rest_client
 from tempest.lib.services.compute import base_compute_client
 
@@ -25,7 +27,8 @@
 class MigrationsClient(base_compute_client.BaseComputeClient):
     schema_versions_info = [
         {'min': None, 'max': '2.22', 'schema': schema},
-        {'min': '2.23', 'max': None, 'schema': schemav223}]
+        {'min': '2.23', 'max': '2.58', 'schema': schemav223},
+        {'min': '2.59', 'max': None, 'schema': schemav259}]
 
     def list_migrations(self, **params):
         """List all migrations.
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index cbf7a8c..6723516 100644
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -206,11 +206,17 @@
     def action(self, server_id, action_name,
                schema=schema.server_actions_common_schema,
                **kwargs):
-        post_body = json.dumps({action_name: kwargs})
+        if 'body' in kwargs:
+            post_body = json.dumps(kwargs['body'])
+        else:
+            post_body = json.dumps({action_name: kwargs})
         resp, body = self.post('servers/%s/action' % server_id,
                                post_body)
         if body:
             body = json.loads(body)
+        else:
+            if isinstance(body, bytes):
+                body = body.decode('utf-8')
         self.validate_response(schema, resp, body)
         return rest_client.ResponseBody(resp, body)
 
@@ -605,6 +611,15 @@
         API reference:
         https://docs.openstack.org/api-ref/compute/#unshelve-restore-shelved-server-unshelve-action
         """
+        # NOTE(gmann): pass None as request body if nothing is requested.
+        # Nova started the request body check since 2.77 microversion and only
+        # accept AZ or None as valid req body and reject the empty dict {}.
+        # Before 2.77 microverison anything is valid body as Nova does not
+        # check the request body but as per api-ref None is valid request
+        # body to pass so we do not need to check the requested microversion
+        # here and always default req body to None.
+        if not kwargs:
+            kwargs['body'] = {'unshelve': None}
         return self.action(server_id, 'unshelve', **kwargs)
 
     def shelve_offload_server(self, server_id, **kwargs):
diff --git a/tempest/lib/services/volume/v3/encryption_types_client.py b/tempest/lib/services/volume/v3/encryption_types_client.py
index bd809d6..7cced57 100644
--- a/tempest/lib/services/volume/v3/encryption_types_client.py
+++ b/tempest/lib/services/volume/v3/encryption_types_client.py
@@ -15,6 +15,7 @@
 
 from oslo_serialization import jsonutils as json
 
+from tempest.lib.api_schema.response.volume import encryption_types as schema
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions as lib_exc
 
@@ -43,7 +44,7 @@
         url = "/types/%s/encryption" % volume_type_id
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_encryption_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_encryption_specs_item(self, volume_type_id, key):
@@ -51,7 +52,7 @@
         url = "/types/%s/encryption/%s" % (volume_type_id, key)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_encryption_specs_item, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def create_encryption_type(self, volume_type_id, **kwargs):
@@ -65,14 +66,14 @@
         post_body = json.dumps({'encryption': kwargs})
         resp, body = self.post(url, post_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.create_encryption_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_encryption_type(self, volume_type_id):
         """Delete the encryption type for the specified volume-type."""
         resp, body = self.delete(
             "/types/%s/encryption/provider" % volume_type_id)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.delete_encryption_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_encryption_type(self, volume_type_id, **kwargs):
@@ -86,5 +87,5 @@
         put_body = json.dumps({'encryption': kwargs})
         resp, body = self.put(url, put_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.update_encryption_type, resp, body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/group_types_client.py b/tempest/lib/services/volume/v3/group_types_client.py
index 99833ce..e0bf5e2 100644
--- a/tempest/lib/services/volume/v3/group_types_client.py
+++ b/tempest/lib/services/volume/v3/group_types_client.py
@@ -16,6 +16,7 @@
 from oslo_serialization import jsonutils as json
 from six.moves.urllib import parse as urllib
 
+from tempest.lib.api_schema.response.volume import group_types as schema
 from tempest.lib.common import rest_client
 from tempest.lib.services.volume import base_client
 
@@ -38,13 +39,13 @@
         post_body = json.dumps({'group_type': kwargs})
         resp, body = self.post('group_types', post_body)
         body = json.loads(body)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.create_group_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_group_type(self, group_type_id):
         """Deletes the specified group_type."""
         resp, body = self.delete("group_types/%s" % group_type_id)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.delete_group_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def list_group_types(self, **params):
@@ -60,7 +61,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.list_group_types, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_default_group_type(self):
@@ -84,7 +85,7 @@
         url = "group_types/%s" % group_type_id
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_group_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_group_type(self, group_type_id, **kwargs):
@@ -96,8 +97,8 @@
         """
         post_body = json.dumps({'group_type': kwargs})
         resp, body = self.put('group_types/%s' % group_type_id, post_body)
-        self.expected_success(200, resp.status)
         body = json.loads(body)
+        self.validate_response(schema.update_group_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def create_or_update_group_type_specs(self, group_type_id, group_specs):
@@ -111,7 +112,8 @@
         post_body = json.dumps({'group_specs': group_specs})
         resp, body = self.post(url, post_body)
         body = json.loads(body)
-        self.expected_success(202, resp.status)
+        self.validate_response(
+            schema.create_or_update_group_type_specs, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def list_group_type_specs(self, group_type_id):
@@ -119,7 +121,7 @@
         url = 'group_types/%s/group_specs' % group_type_id
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.list_group_type_specs, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_group_type_specs_item(self, group_type_id, spec_id):
@@ -127,7 +129,7 @@
         url = "group_types/%s/group_specs/%s" % (group_type_id, spec_id)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_group_type_specs_item, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_group_type_specs_item(self, group_type_id, spec_id, spec):
@@ -141,12 +143,12 @@
         put_body = json.dumps(spec)
         resp, body = self.put(url, put_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.update_group_type_specs_item, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_group_type_specs_item(self, group_type_id, spec_id):
         """Deletes specified item of group specs for a given group type."""
         resp, body = self.delete("group_types/%s/group_specs/%s" % (
             group_type_id, spec_id))
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.delete_group_type_specs_item, resp, body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/limits_client.py b/tempest/lib/services/volume/v3/limits_client.py
index 9500254..a8d1377 100644
--- a/tempest/lib/services/volume/v3/limits_client.py
+++ b/tempest/lib/services/volume/v3/limits_client.py
@@ -15,6 +15,7 @@
 
 from oslo_serialization import jsonutils as json
 
+from tempest.lib.api_schema.response.volume import limits as schema
 from tempest.lib.common import rest_client
 
 
@@ -26,5 +27,5 @@
         url = "limits"
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_limits, resp, body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/scheduler_stats_client.py b/tempest/lib/services/volume/v3/scheduler_stats_client.py
index 2ae8600..e18980d 100644
--- a/tempest/lib/services/volume/v3/scheduler_stats_client.py
+++ b/tempest/lib/services/volume/v3/scheduler_stats_client.py
@@ -15,6 +15,7 @@
 
 from oslo_serialization import jsonutils as json
 
+from tempest.lib.api_schema.response.volume import scheduler_stats as schema
 from tempest.lib.common import rest_client
 
 
@@ -28,9 +29,11 @@
         https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-all-back-end-storage-pools
         """
         url = 'scheduler-stats/get_pools'
+        schema_get_pools = schema.get_pools_no_detail
         if detail:
             url += '?detail=True'
+            schema_get_pools = schema.get_pools_with_detail
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema_get_pools, resp, body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/snapshots_client.py b/tempest/lib/services/volume/v3/snapshots_client.py
index 264381d..8ca2044 100644
--- a/tempest/lib/services/volume/v3/snapshots_client.py
+++ b/tempest/lib/services/volume/v3/snapshots_client.py
@@ -16,6 +16,7 @@
 from oslo_serialization import jsonutils as json
 from six.moves.urllib import parse as urllib
 
+from tempest.lib.api_schema.response.volume import snapshots as schema
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions as lib_exc
 
@@ -32,14 +33,16 @@
         https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-snapshots-and-details
         """
         url = 'snapshots'
+        list_schema = schema.list_snapshots_no_detail
         if detail:
             url += '/detail'
+            list_schema = schema.list_snapshots_with_detail
         if params:
             url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(list_schema, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_snapshot(self, snapshot_id):
@@ -52,7 +55,7 @@
         url = "snapshots/%s" % snapshot_id
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def create_snapshot(self, **kwargs):
@@ -65,7 +68,7 @@
         post_body = json.dumps({'snapshot': kwargs})
         resp, body = self.post('snapshots', post_body)
         body = json.loads(body)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.create_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_snapshot(self, snapshot_id, **kwargs):
@@ -78,7 +81,7 @@
         put_body = json.dumps({'snapshot': kwargs})
         resp, body = self.put('snapshots/%s' % snapshot_id, put_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.update_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_snapshot(self, snapshot_id):
@@ -89,7 +92,7 @@
         https://docs.openstack.org/api-ref/block-storage/v3/index.html#delete-a-snapshot
         """
         resp, body = self.delete("snapshots/%s" % snapshot_id)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.delete_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def is_resource_deleted(self, id):
@@ -108,7 +111,7 @@
         """Reset the specified snapshot's status."""
         post_body = json.dumps({'os-reset_status': {"status": status}})
         resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.reset_snapshot_status, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_snapshot_status(self, snapshot_id, **kwargs):
@@ -121,7 +124,7 @@
         post_body = json.dumps({'os-update_snapshot_status': kwargs})
         url = 'snapshots/%s/action' % snapshot_id
         resp, body = self.post(url, post_body)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.update_snapshot_status, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def create_snapshot_metadata(self, snapshot_id, metadata):
@@ -135,7 +138,7 @@
         url = "snapshots/%s/metadata" % snapshot_id
         resp, body = self.post(url, put_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.create_snapshot_metadata, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_snapshot_metadata(self, snapshot_id):
@@ -148,7 +151,7 @@
         url = "snapshots/%s/metadata" % snapshot_id
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_snapshot_metadata, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_snapshot_metadata(self, snapshot_id, **kwargs):
@@ -162,7 +165,7 @@
         url = "snapshots/%s/metadata" % snapshot_id
         resp, body = self.put(url, put_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.update_snapshot_metadata, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_snapshot_metadata_item(self, snapshot_id, id):
@@ -170,7 +173,7 @@
         url = "snapshots/%s/metadata/%s" % (snapshot_id, id)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_snapshot_metadata_item, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def update_snapshot_metadata_item(self, snapshot_id, id, **kwargs):
@@ -184,21 +187,23 @@
         url = "snapshots/%s/metadata/%s" % (snapshot_id, id)
         resp, body = self.put(url, put_body)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(
+            schema.update_snapshot_metadata_item, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_snapshot_metadata_item(self, snapshot_id, id):
         """Delete metadata item for the snapshot."""
         url = "snapshots/%s/metadata/%s" % (snapshot_id, id)
         resp, body = self.delete(url)
-        self.expected_success(200, resp.status)
+        self.validate_response(
+            schema.delete_snapshot_metadata_item, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def force_delete_snapshot(self, snapshot_id):
         """Force Delete Snapshot."""
         post_body = json.dumps({'os-force_delete': {}})
         resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.force_delete_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def unmanage_snapshot(self, snapshot_id):
@@ -206,5 +211,5 @@
         post_body = json.dumps({'os-unmanage': {}})
         url = 'snapshots/%s/action' % (snapshot_id)
         resp, body = self.post(url, post_body)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.unmanage_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index efdfe8e..8591771 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -1038,9 +1038,12 @@
         floatingip_id = floating_ip['id']
 
         def refresh():
-            result = (self.floating_ips_client.
-                      show_floatingip(floatingip_id)['floatingip'])
-            return status == result['status']
+            floating_ip = (self.floating_ips_client.
+                           show_floatingip(floatingip_id)['floatingip'])
+            if status == floating_ip['status']:
+                LOG.info("FloatingIP: {fp} is at status: {st}"
+                         .format(fp=floating_ip, st=status))
+            return status == floating_ip['status']
 
         if not test_utils.call_until_true(refresh,
                                           CONF.network.build_timeout,
@@ -1052,8 +1055,6 @@
                                      "failed  to reach status: {st}"
                              .format(fp=floating_ip, cst=floating_ip['status'],
                                      st=status))
-        LOG.info("FloatingIP: {fp} is at status: {st}"
-                 .format(fp=floating_ip, st=status))
 
     def check_tenant_network_connectivity(self, server,
                                           username,
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index a33d4d4..a062d40 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -29,8 +29,10 @@
     The following is the scenario outline:
      * boot an instance and create a timestamp file in it
      * snapshot the instance
+     * add version metadata to the snapshot image
      * boot a second instance from the snapshot
      * check the existence of the timestamp file in the second instance
+     * snapshot the instance again
 
     """
 
@@ -63,6 +65,11 @@
         # snapshot the instance
         snapshot_image = self.create_server_snapshot(server=server)
 
+        # add version metadata to the snapshot image
+        self.image_client.update_image(
+            snapshot_image['id'], [dict(add='/version',
+                                        value='8.0')])
+
         # boot a second instance from the snapshot
         server_from_snapshot = self.create_server(
             image_id=snapshot_image['id'],
@@ -75,3 +82,6 @@
                                         private_key=keypair['private_key'],
                                         server=server_from_snapshot)
         self.assertEqual(timestamp, timestamp2)
+
+        # snapshot the instance again
+        self.create_server_snapshot(server=server_from_snapshot)
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 0782389..3b4bbda 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -252,8 +252,7 @@
     @utils.services('compute', 'volume')
     def test_boot_server_from_encrypted_volume_luks(self):
         # Create an encrypted volume
-        volume = self.create_encrypted_volume('nova.volume.encryptors.'
-                                              'luks.LuksEncryptor',
+        volume = self.create_encrypted_volume('luks',
                                               volume_type='luks')
 
         self.volumes_client.set_bootable_volume(volume['id'], bootable=True)
diff --git a/tempest/tests/api/compute/test_base.py b/tempest/tests/api/compute/test_base.py
index 1593464..74d2625 100644
--- a/tempest/tests/api/compute/test_base.py
+++ b/tempest/tests/api/compute/test_base.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
 
 from oslo_utils import uuidutils
 import six
diff --git a/tempest/tests/base.py b/tempest/tests/base.py
index 0b53b45..e8b2c98 100644
--- a/tempest/tests/base.py
+++ b/tempest/tests/base.py
@@ -12,7 +12,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
+
 from oslotest import base
 
 
diff --git a/tempest/tests/cmd/test_account_generator.py b/tempest/tests/cmd/test_account_generator.py
index a962e37..7d764be 100644
--- a/tempest/tests/cmd/test_account_generator.py
+++ b/tempest/tests/cmd/test_account_generator.py
@@ -12,8 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from unittest import mock
+
 import fixtures
-import mock
 from oslo_config import cfg
 
 from tempest.cmd import account_generator
@@ -336,3 +337,24 @@
     def setUp(self):
         self.mock_domains()
         super(TestDumpAccountsV3, self).setUp()
+
+
+class TestAccountGeneratorCliCheck(base.TestCase):
+
+    def setUp(self):
+        super(TestAccountGeneratorCliCheck, self).setUp()
+        self.account_generator = account_generator.TempestAccountGenerator(
+            app=mock.Mock(), app_args=mock.Mock())
+        self.parser = self.account_generator.get_parser("generator")
+
+    def test_account_generator_zero_concurrency(self):
+        error = self.assertRaises(
+            SystemExit, lambda: self.parser.parse_args(
+                ['-r', '0', 'accounts_file.yaml']))
+        self.assertTrue(error.code != 0)
+
+    def test_account_generator_negative_concurrency(self):
+        error = self.assertRaises(
+            SystemExit, lambda: self.parser.parse_args(
+                ['-r', '-1', 'accounts_file.yaml']))
+        self.assertTrue(error.code != 0)
diff --git a/tempest/tests/cmd/test_cleanup.py b/tempest/tests/cmd/test_cleanup.py
index 1618df9..69e735b 100644
--- a/tempest/tests/cmd/test_cleanup.py
+++ b/tempest/tests/cmd/test_cleanup.py
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import mock
+from unittest import mock
 
 from tempest.cmd import cleanup
 from tempest.tests import base
diff --git a/tempest/tests/cmd/test_cleanup_services.py b/tempest/tests/cmd/test_cleanup_services.py
index 8366290..7bf7315 100644
--- a/tempest/tests/cmd/test_cleanup_services.py
+++ b/tempest/tests/cmd/test_cleanup_services.py
@@ -274,19 +274,22 @@
                     "name": "test"
                 },
                 "name": "test-volume-snapshot",
-                "user_id": "40c2102f4a554b848d96b14f3eec39ed",
                 "volume_id": "173f7b48-c4c1-4e70-9acc-086b39073506",
                 "created_at": "2015-11-29T02:25:51.000000",
                 "size": 1,
                 "updated_at": "2015-11-20T05:36:40.000000",
-                "os-extended-snapshot-attributes:progress": "100%",
                 "id": "b1323cda-8e4b-41c1-afc5-2fc791809c8c",
                 "description": "volume snapshot"
             },
             {
                 "status": "available",
                 "name": "saved-snapshot",
+                "metadata": {},
                 "id": "1ad4c789-7e8w-4dwg-afc5",
+                "size": 1,
+                "volume_id": "af7c41be-1ff6-4233-a690-7ed61c34347f",
+                "created_at": "2015-11-20T05:39:40.000000",
+                "updated_at": "2015-11-20T05:39:40.000000",
                 "description": "snapshot in saved state"
             }
         ]
diff --git a/tempest/tests/cmd/test_run.py b/tempest/tests/cmd/test_run.py
index e9bbcc2..5d9ddfa 100644
--- a/tempest/tests/cmd/test_run.py
+++ b/tempest/tests/cmd/test_run.py
@@ -18,9 +18,9 @@
 import shutil
 import subprocess
 import tempfile
+from unittest import mock
 
 import fixtures
-import mock
 import six
 
 from tempest.cmd import run
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 8dbba38..dad31b4 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -13,9 +13,9 @@
 #    under the License.
 
 import os
+from unittest import mock
 
 import fixtures
-import mock
 from oslo_serialization import jsonutils as json
 
 from tempest import clients
diff --git a/tempest/tests/common/test_compute.py b/tempest/tests/common/test_compute.py
index c108be9..45a439c 100644
--- a/tempest/tests/common/test_compute.py
+++ b/tempest/tests/common/test_compute.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from unittest import mock
+
 from six.moves.urllib import parse as urlparse
 
-import mock
 
 from tempest.common import compute
 from tempest.tests import base
diff --git a/tempest/tests/common/test_credentials_factory.py b/tempest/tests/common/test_credentials_factory.py
index 7cf87f8..0ef3742 100644
--- a/tempest/tests/common/test_credentials_factory.py
+++ b/tempest/tests/common/test_credentials_factory.py
@@ -13,7 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
+
 from oslo_config import cfg
 import testtools
 
diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py
index e3bb836..5f8b990 100755
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -13,8 +13,8 @@
 #    under the License.
 
 import time
+from unittest import mock
 
-import mock
 from oslo_utils.fixture import uuidsentinel as uuids
 
 from tempest.common import waiters
diff --git a/tempest/tests/common/utils/test_net_utils.py b/tempest/tests/common/utils/test_net_utils.py
index 83c6bcc..51d86d1 100644
--- a/tempest/tests/common/utils/test_net_utils.py
+++ b/tempest/tests/common/utils/test_net_utils.py
@@ -10,7 +10,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
 
 from tempest.common.utils import net_utils
 from tempest.lib import exceptions as lib_exc
diff --git a/tempest/tests/lib/cli/test_execute.py b/tempest/tests/lib/cli/test_execute.py
index c069af5..a10e3bb 100644
--- a/tempest/tests/lib/cli/test_execute.py
+++ b/tempest/tests/lib/cli/test_execute.py
@@ -12,8 +12,8 @@
 #    under the License.
 
 import subprocess
+from unittest import mock
 
-import mock
 
 from tempest.lib.cli import base as cli_base
 from tempest.lib import exceptions
diff --git a/tempest/tests/lib/common/test_cred_client.py b/tempest/tests/lib/common/test_cred_client.py
index 3dff16f..860a465 100644
--- a/tempest/tests/lib/common/test_cred_client.py
+++ b/tempest/tests/lib/common/test_cred_client.py
@@ -11,7 +11,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-import mock
+from unittest import mock
 
 from tempest.lib.common import cred_client
 from tempest.tests import base
diff --git a/tempest/tests/lib/common/test_dynamic_creds.py b/tempest/tests/lib/common/test_dynamic_creds.py
index 4723458..e9073cc 100644
--- a/tempest/tests/lib/common/test_dynamic_creds.py
+++ b/tempest/tests/lib/common/test_dynamic_creds.py
@@ -12,8 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from unittest import mock
+
 import fixtures
-import mock
 from oslo_config import cfg
 
 from tempest.common import credentials_factory as credentials
@@ -110,7 +111,7 @@
                           (200,
                            {'roles': [{'id': id, 'name': name},
                                       {'id': '1', 'name': 'FakeRole'},
-                                      {'id': '2', 'name': 'Member'}]}))))
+                                      {'id': '2', 'name': 'member'}]}))))
         return roles_fix
 
     def _mock_list_2_roles(self):
@@ -139,7 +140,7 @@
             return_value=(rest_client.ResponseBody
                           (200, {'roles': [
                               {'id': '1', 'name': 'FakeRole'},
-                              {'id': '2', 'name': 'Member'}]}))))
+                              {'id': '2', 'name': 'member'}]}))))
         return roles_fix
 
     def _mock_list_ec2_credentials(self, user_id, tenant_id):
@@ -664,6 +665,6 @@
         with mock.patch('tempest.lib.common.dynamic_creds.LOG') as log_mock:
             creds._create_creds()
             log_mock.warning.assert_called_once_with(
-                "Member role already exists, ignoring conflict.")
+                "member role already exists, ignoring conflict.")
         creds.creds_client.assign_user_role.assert_called_once_with(
-            mock.ANY, mock.ANY, 'Member')
+            mock.ANY, mock.ANY, 'member')
diff --git a/tempest/tests/lib/common/test_preprov_creds.py b/tempest/tests/lib/common/test_preprov_creds.py
index 25df2a7..579363e 100644
--- a/tempest/tests/lib/common/test_preprov_creds.py
+++ b/tempest/tests/lib/common/test_preprov_creds.py
@@ -15,8 +15,8 @@
 import hashlib
 import os
 import shutil
+from unittest import mock
 
-import mock
 import six
 import testtools
 
diff --git a/tempest/tests/lib/common/test_profiler.py b/tempest/tests/lib/common/test_profiler.py
index 59fa0364..166d831 100644
--- a/tempest/tests/lib/common/test_profiler.py
+++ b/tempest/tests/lib/common/test_profiler.py
@@ -10,7 +10,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
+
 import testtools
 
 from tempest.lib.common import profiler
diff --git a/tempest/tests/lib/common/test_validation_resources.py b/tempest/tests/lib/common/test_validation_resources.py
index d5139f4..d50fd89 100644
--- a/tempest/tests/lib/common/test_validation_resources.py
+++ b/tempest/tests/lib/common/test_validation_resources.py
@@ -11,8 +11,9 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 
+from unittest import mock
+
 import fixtures
-import mock
 import testtools
 
 from tempest.lib.common import validation_resources as vr
diff --git a/tempest/tests/lib/common/utils/linux/test_remote_client.py b/tempest/tests/lib/common/utils/linux/test_remote_client.py
index 7a21a5f..df23e63 100644
--- a/tempest/tests/lib/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/lib/common/utils/linux/test_remote_client.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
 
 from tempest.lib.common import ssh
 from tempest.lib.common.utils.linux import remote_client
diff --git a/tempest/tests/lib/common/utils/test_test_utils.py b/tempest/tests/lib/common/utils/test_test_utils.py
index 865767b..bdc0ea4 100644
--- a/tempest/tests/lib/common/utils/test_test_utils.py
+++ b/tempest/tests/lib/common/utils/test_test_utils.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 import time
+from unittest import mock
 
-import mock
 
 from tempest.lib.common import thread
 from tempest.lib.common.utils import test_utils
diff --git a/tempest/tests/lib/services/compute/test_base_compute_client.py b/tempest/tests/lib/services/compute/test_base_compute_client.py
index 69e8542..5841ae4 100644
--- a/tempest/tests/lib/services/compute/test_base_compute_client.py
+++ b/tempest/tests/lib/services/compute/test_base_compute_client.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
 
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions
diff --git a/tempest/tests/lib/services/compute/test_servers_client.py b/tempest/tests/lib/services/compute/test_servers_client.py
index 86f6ad5..a82b255 100644
--- a/tempest/tests/lib/services/compute/test_servers_client.py
+++ b/tempest/tests/lib/services/compute/test_servers_client.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 import copy
+from unittest import mock
 
-import mock
 
 from tempest.lib.services.compute import base_compute_client
 from tempest.lib.services.compute import servers_client
diff --git a/tempest/tests/lib/services/compute/test_services_client.py b/tempest/tests/lib/services/compute/test_services_client.py
index ba432e3..0c513cc 100644
--- a/tempest/tests/lib/services/compute/test_services_client.py
+++ b/tempest/tests/lib/services/compute/test_services_client.py
@@ -13,8 +13,8 @@
 #    under the License.
 
 import copy
+from unittest import mock
 
-import mock
 
 from tempest.lib.services.compute import base_compute_client
 from tempest.lib.services.compute import services_client
diff --git a/tempest/tests/lib/services/identity/v2/test_token_client.py b/tempest/tests/lib/services/identity/v2/test_token_client.py
index 5b4e210..dc14a50 100644
--- a/tempest/tests/lib/services/identity/v2/test_token_client.py
+++ b/tempest/tests/lib/services/identity/v2/test_token_client.py
@@ -12,7 +12,8 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-import mock
+from unittest import mock
+
 from oslo_serialization import jsonutils as json
 
 from tempest.lib.common import rest_client
diff --git a/tempest/tests/lib/services/identity/v3/test_token_client.py b/tempest/tests/lib/services/identity/v3/test_token_client.py
index 656e10a..1c2295d 100644
--- a/tempest/tests/lib/services/identity/v3/test_token_client.py
+++ b/tempest/tests/lib/services/identity/v3/test_token_client.py
@@ -12,7 +12,8 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-import mock
+from unittest import mock
+
 from oslo_serialization import jsonutils as json
 
 from tempest.lib.common import rest_client
diff --git a/tempest/tests/lib/services/image/v2/test_images_client.py b/tempest/tests/lib/services/image/v2/test_images_client.py
index ee4d4cb..fe671bd 100644
--- a/tempest/tests/lib/services/image/v2/test_images_client.py
+++ b/tempest/tests/lib/services/image/v2/test_images_client.py
@@ -35,14 +35,19 @@
         "created_at": "2012-08-10T19:23:50Z",
         "updated_at": "2012-08-12T11:11:33Z",
         "self": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea",
-        "file": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927dea/file",
+        "file": "/v2/images/da3b75d9-3f4a-40e7-8a2c-bfab23927"
+                "dea/file",
         "schema": "/v2/schemas/image",
         "owner": None,
         "min_ram": None,
         "min_disk": None,
         "disk_format": None,
         "virtual_size": None,
-        "container_format": None
+        "container_format": None,
+        "os_hash_algo": "sha512",
+        "os_hash_value": "ef7d1ed957ffafefb324d50ebc6685ed03d0e645d",
+        "os_hidden": False,
+        "protected": False,
     }
 
     FAKE_LIST_IMAGES = {
@@ -66,7 +71,10 @@
                 "size": 13167616,
                 "min_ram": 0,
                 "schema": "/v2/schemas/image",
-                "virtual_size": None
+                "virtual_size": None,
+                "os_hash_algo": "sha512",
+                "os_hash_value": "ef7d1ed957ffafefb324d50ebc6685ed03d0e645d",
+                "os_hidden": False
             },
             {
                 "status": "active",
@@ -87,7 +95,10 @@
                 "size": 476704768,
                 "min_ram": 0,
                 "schema": "/v2/schemas/image",
-                "virtual_size": None
+                "virtual_size": None,
+                "os_hash_algo": "sha512",
+                "os_hash_value": "ef7d1ed957ffafefb324d50ebc6685ed03d0e645d",
+                "os_hidden": False
             }
         ],
         "schema": "/v2/schemas/images",
diff --git a/tempest/tests/lib/services/network/test_base_network_client.py b/tempest/tests/lib/services/network/test_base_network_client.py
index e121cec..a426397 100644
--- a/tempest/tests/lib/services/network/test_base_network_client.py
+++ b/tempest/tests/lib/services/network/test_base_network_client.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
 
 from tempest.lib.services.network import base as base_network_client
 from tempest.tests.lib import fake_auth_provider
diff --git a/tempest/tests/lib/services/network/test_security_group_rules_client.py b/tempest/tests/lib/services/network/test_security_group_rules_client.py
index b9c17a1..2ecc996 100644
--- a/tempest/tests/lib/services/network/test_security_group_rules_client.py
+++ b/tempest/tests/lib/services/network/test_security_group_rules_client.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 import copy
+from unittest import mock
 
-import mock
 from oslo_serialization import jsonutils as json
 
 from tempest.lib.services.network import base as network_base
diff --git a/tempest/tests/lib/services/network/test_security_groups_client.py b/tempest/tests/lib/services/network/test_security_groups_client.py
index f96805f..501883b 100644
--- a/tempest/tests/lib/services/network/test_security_groups_client.py
+++ b/tempest/tests/lib/services/network/test_security_groups_client.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 import copy
+from unittest import mock
 
-import mock
 from oslo_serialization import jsonutils as json
 
 from tempest.lib.services.network import base as network_base
diff --git a/tempest/tests/lib/services/object_storage/test_object_client.py b/tempest/tests/lib/services/object_storage/test_object_client.py
index 1749b03..c646d61 100644
--- a/tempest/tests/lib/services/object_storage/test_object_client.py
+++ b/tempest/tests/lib/services/object_storage/test_object_client.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 
-import mock
+from unittest import mock
 
 from tempest.lib import exceptions
 from tempest.lib.services.object_storage import object_client
diff --git a/tempest/tests/lib/services/test_clients.py b/tempest/tests/lib/services/test_clients.py
index 43fd88f..f83064a 100644
--- a/tempest/tests/lib/services/test_clients.py
+++ b/tempest/tests/lib/services/test_clients.py
@@ -13,9 +13,9 @@
 # the License.
 
 import types
+from unittest import mock
 
 import fixtures
-import mock
 import six
 import testtools
 
diff --git a/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py b/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
index 70a3ee5..7218224 100644
--- a/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
@@ -20,11 +20,11 @@
 class TestEncryptionTypesClient(base.BaseServiceTest):
     FAKE_CREATE_ENCRYPTION_TYPE = {
         "encryption": {
-            "volume_type_id": "cbc36478b0bd8e67e89",
+            "volume_type_id": "2d29462d-76cb-417c-8a9f-fb23140f1577",
             "control_location": "front-end",
             "encryption_id": "81e069c6-7394-4856-8df7-3b237ca61f74",
             "key_size": 128,
-            "provider": "LuksEncryptor",
+            "provider": "luks",
             "cipher": "aes-xts-plain64"
         }
     }
diff --git a/tempest/tests/lib/services/volume/v3/test_group_types_client.py b/tempest/tests/lib/services/volume/v3/test_group_types_client.py
index 8b853d7..33c7737 100644
--- a/tempest/tests/lib/services/volume/v3/test_group_types_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_group_types_client.py
@@ -23,8 +23,8 @@
     FAKE_CREATE_GROUP_TYPE = {
         "group_type": {
             "id": "6685584b-1eac-4da6-b5c3-555430cf68ff",
-            "name": "grp-type-001",
-            "description": "group type 001",
+            "name": "group-type-001",
+            "description": "Test group type 1",
             "is_public": True,
             "group_specs": {
                 "consistent_group_snapshot_enabled": "<is> False"
diff --git a/tempest/tests/lib/services/volume/v3/test_scheduler_stats_client.py b/tempest/tests/lib/services/volume/v3/test_scheduler_stats_client.py
index 84c7589..7606a52 100644
--- a/tempest/tests/lib/services/volume/v3/test_scheduler_stats_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_scheduler_stats_client.py
@@ -25,12 +25,14 @@
                 "name": "pool1",
                 "capabilities": {
                     "updated": "2014-10-28T00:00:00-00:00",
-                    "total_capacity": 1024,
-                    "free_capacity": 100,
+                    "total_capacity_gb": 1024,
+                    "free_capacity_gb": 100,
                     "volume_backend_name": "pool1",
                     "reserved_percentage": 0,
                     "driver_version": "1.0.0",
+                    "timestamp": "2014-10-28T00:00:00-00:00",
                     "storage_protocol": "iSCSI",
+                    "vendor_name": "vendor",
                     "QoS_support": False
                 }
             },
@@ -38,12 +40,14 @@
                 "name": "pool2",
                 "capabilities": {
                     "updated": "2014-10-28T00:00:00-00:00",
-                    "total_capacity": 512,
-                    "free_capacity": 200,
+                    "total_capacity_gb": 512,
+                    "free_capacity_gb": 200,
                     "volume_backend_name": "pool2",
                     "reserved_percentage": 0,
                     "driver_version": "1.0.2",
+                    "timestamp": "2014-10-28T00:00:00-00:00",
                     "storage_protocol": "iSER",
+                    "vendor_name": "vendor",
                     "QoS_support": True
                 }
             }
diff --git a/tempest/tests/lib/services/volume/v3/test_services_client.py b/tempest/tests/lib/services/volume/v3/test_services_client.py
index f65228f..c807bc2 100644
--- a/tempest/tests/lib/services/volume/v3/test_services_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_services_client.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 import copy
+from unittest import mock
 
-import mock
 from oslo_serialization import jsonutils as json
 
 from tempest.lib.services.volume.v3 import services_client
diff --git a/tempest/tests/lib/services/volume/v3/test_snapshot_manage_client.py b/tempest/tests/lib/services/volume/v3/test_snapshot_manage_client.py
index 1b88020..8309f7a 100644
--- a/tempest/tests/lib/services/volume/v3/test_snapshot_manage_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_snapshot_manage_client.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
 
 from oslo_serialization import jsonutils as json
 
diff --git a/tempest/tests/lib/services/volume/v3/test_transfers_client.py b/tempest/tests/lib/services/volume/v3/test_transfers_client.py
index d631fe7..1dfe2df 100644
--- a/tempest/tests/lib/services/volume/v3/test_transfers_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_transfers_client.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 import copy
+from unittest import mock
 
-import mock
 from oslo_serialization import jsonutils as json
 
 from tempest.lib.services.volume.v3 import transfers_client
diff --git a/tempest/tests/lib/services/volume/v3/test_volume_manage_client.py b/tempest/tests/lib/services/volume/v3/test_volume_manage_client.py
index 902f027..d4313a2 100644
--- a/tempest/tests/lib/services/volume/v3/test_volume_manage_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_volume_manage_client.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
 
 from oslo_serialization import jsonutils as json
 
diff --git a/tempest/tests/lib/test_decorators.py b/tempest/tests/lib/test_decorators.py
index 9c6cac7..e3c17e8 100644
--- a/tempest/tests/lib/test_decorators.py
+++ b/tempest/tests/lib/test_decorators.py
@@ -14,8 +14,8 @@
 #    under the License.
 
 import abc
+from unittest import mock
 
-import mock
 import six
 import testtools
 
diff --git a/tempest/tests/lib/test_ssh.py b/tempest/tests/lib/test_ssh.py
index c849231..85048fb 100644
--- a/tempest/tests/lib/test_ssh.py
+++ b/tempest/tests/lib/test_ssh.py
@@ -13,8 +13,8 @@
 #    under the License.
 
 import socket
+from unittest import mock
 
-import mock
 import six
 from six import StringIO
 import testtools
diff --git a/tempest/tests/test_base_test.py b/tempest/tests/test_base_test.py
index 2b5a947..b154cd5 100644
--- a/tempest/tests/test_base_test.py
+++ b/tempest/tests/test_base_test.py
@@ -12,7 +12,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
+from unittest import mock
+
 from oslo_config import cfg
 
 from tempest import clients
diff --git a/tempest/tests/test_imports.py b/tempest/tests/test_imports.py
index 6f1cfca..ad7bebb 100644
--- a/tempest/tests/test_imports.py
+++ b/tempest/tests/test_imports.py
@@ -12,7 +12,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-import mock
+from unittest import mock
 
 from tempest.tests import base
 
diff --git a/tempest/tests/test_test.py b/tempest/tests/test_test.py
index 49fd010..72e8b6d 100644
--- a/tempest/tests/test_test.py
+++ b/tempest/tests/test_test.py
@@ -15,8 +15,8 @@
 
 import os
 import sys
+from unittest import mock
 
-import mock
 from oslo_config import cfg
 import testtools
 
diff --git a/test-requirements.txt b/test-requirements.txt
index 17a7d2a..17fa9f1 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,7 +2,6 @@
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
 hacking>=3.0.1,<3.1.0;python_version>='3.5' # Apache-2.0
-mock>=2.0.0 # BSD
 coverage!=4.4,>=4.0 # Apache-2.0
 oslotest>=3.2.0 # Apache-2.0
 pycodestyle>=2.0.0,<2.6.0 # MIT
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
index 5ffef3e..530ce5e 100644
--- a/tools/generate-tempest-plugins-list.py
+++ b/tools/generate-tempest-plugins-list.py
@@ -52,6 +52,8 @@
     'x/tap-as-a-service',  # To avoid sanity-job failure
     'x/valet',  # https://review.opendev.org/#/c/638339/
     'x/kingbird',  # https://bugs.launchpad.net/kingbird/+bug/1869722
+    # vmware-nsx is blacklisted since https://review.opendev.org/#/c/736952
+    'x/vmware-nsx-tempest-plugin',
 ]
 
 url = 'https://review.opendev.org/projects/'
diff --git a/tools/tempest-integrated-gate-compute-blacklist.txt b/tools/tempest-integrated-gate-compute-blacklist.txt
index 8805262..2290751 100644
--- a/tools/tempest-integrated-gate-compute-blacklist.txt
+++ b/tools/tempest-integrated-gate-compute-blacklist.txt
@@ -11,3 +11,9 @@
 tempest.scenario.test_object_storage_basic_ops.TestObjectStorageBasicOps.test_swift_basic_ops
 tempest.scenario.test_object_storage_basic_ops.TestObjectStorageBasicOps.test_swift_acl_anonymous_download
 tempest.scenario.test_volume_backup_restore.TestVolumeBackupRestore.test_volume_backup_restore
+
+# Skip test scenario when creating second image from instance
+# https://bugs.launchpad.net/tripleo/+bug/1881592
+# The test is most likely wrong and may fail if the fists image is create quickly.
+# FIXME: Either fix the test so it won't race or consider if we should cover the scenario at all.
+tempest.api.compute.images.test_images_oneserver_negative.ImagesOneServerNegativeTestJSON.test_create_second_image_when_first_image_is_being_saved
diff --git a/tools/tempest-plugin-sanity.sh b/tools/tempest-plugin-sanity.sh
index 2ff4aea..c983da9 100644
--- a/tools/tempest-plugin-sanity.sh
+++ b/tools/tempest-plugin-sanity.sh
@@ -66,7 +66,7 @@
 # function to create virtualenv to perform sanity operation
 function prepare_workspace {
     SANITY_DIR=$(pwd)
-    virtualenv -p python3 --clear "$SANITY_DIR"/.venv
+    python3 -m venv "$SANITY_DIR"/.venv
     export TVENV="$SANITY_DIR/tools/with_venv.sh"
     cd "$SANITY_DIR"