Merge "Retry on ServerFault in call_and_ignore_notfound_exc()"
diff --git a/releasenotes/notes/add-show-default-volume-types-api-to-v3-types-client-44b2676f217d78dc.yaml b/releasenotes/notes/add-show-default-volume-types-api-to-v3-types-client-44b2676f217d78dc.yaml
new file mode 100644
index 0000000..2cd5af6
--- /dev/null
+++ b/releasenotes/notes/add-show-default-volume-types-api-to-v3-types-client-44b2676f217d78dc.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Add show type API to v3 types_client library.
+
+    * default_volume_type
diff --git a/releasenotes/notes/new-placement-client-methods-e35c473e29494928.yaml b/releasenotes/notes/new-placement-client-methods-e35c473e29494928.yaml
new file mode 100644
index 0000000..9e6d49a
--- /dev/null
+++ b/releasenotes/notes/new-placement-client-methods-e35c473e29494928.yaml
@@ -0,0 +1,11 @@
+---
+features:
+  - |
+    Add ``placement`` API methods for testing Routed Provider Networks feature.
+    The following API calls are available for tempest from now in the new
+    resource_providers_client:
+
+    * GET /resource_providers
+    * GET /resource_providers/{uuid}
+    * GET /resource_providers/{uuid}/inventories
+    * GET /resource_providers/{uuid}/aggregates
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index a697b95..655909c 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -45,7 +45,7 @@
         # Attempt to start a server with a meta-data key that is > 255
         # characters
 
-        # Tryset_server_metadata_item a few values
+        # Try create a server with the metadata for a few values
         for sz in [256, 257, 511, 1023]:
             key = "k" * sz
             meta = {key: 'data1'}
@@ -86,11 +86,15 @@
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('0025fbd6-a4ba-4cde-b8c2-96805dcfdabc')
-    def test_wrong_key_passed_in_body(self):
+    def test_set_metadata_invalid_key(self):
         """Test setting server metadata item with wrong key in body
 
         Raise BadRequest if key in uri does not match the key passed in body.
         """
+        if not CONF.compute_feature_enabled.xenapi_apis:
+            raise self.skipException(
+                'Metadata is read-only on non-Xen-based deployments.')
+
         meta = {'testkey': 'testvalue'}
         self.assertRaises(lib_exc.BadRequest,
                           self.client.set_server_metadata_item,
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index ba2adbb..8a05e7a 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -29,6 +29,7 @@
 
 class ServerPersonalityTestJSON(base.BaseV2ComputeTest):
     """Test servers with injected files"""
+    max_microversion = '2.56'
 
     @classmethod
     def setup_credentials(cls):
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 76c22f0..389d3be 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -127,14 +127,14 @@
     def test_update_volume_with_nonexistent_volume_id(self):
         """Test updating non existent volume should fail"""
         self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
-                          volume_id=data_utils.rand_uuid())
+                          volume_id=data_utils.rand_uuid(), name="n")
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e66e40d6-65e6-4e75-bdc7-636792fa152d')
     def test_update_volume_with_invalid_volume_id(self):
         """Test updating volume with invalid volume id should fail"""
         self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
-                          volume_id=data_utils.rand_name('invalid'))
+                          volume_id=data_utils.rand_name('invalid'), name="n")
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('72aeca85-57a5-4c1f-9057-f320f9ea575b')
diff --git a/tempest/clients.py b/tempest/clients.py
index 8363a8d..6d19a0c 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -44,7 +44,7 @@
         self._set_object_storage_clients()
         self._set_image_clients()
         self._set_network_clients()
-        self.placement_client = self.placement.PlacementClient()
+        self._set_placement_clients()
         # TODO(andreaf) This is maintained for backward compatibility
         # with plugins, but it should removed eventually, since it was
         # never a stable interface and it's not useful anyways
@@ -139,6 +139,11 @@
         self.snapshots_extensions_client = self.compute.SnapshotsClient(
             **params_volume)
 
+    def _set_placement_clients(self):
+        self.placement_client = self.placement.PlacementClient()
+        self.resource_providers_client = \
+            self.placement.ResourceProvidersClient()
+
     def _set_identity_clients(self):
         # Clients below use the admin endpoint type of Keystone API v2
         params_v2_admin = {
diff --git a/tempest/lib/api_schema/response/compute/v2_71/servers.py b/tempest/lib/api_schema/response/compute/v2_71/servers.py
index 5cf0f8a..f4c01ee 100644
--- a/tempest/lib/api_schema/response/compute/v2_71/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_71/servers.py
@@ -79,3 +79,6 @@
 check_tag_existence = copy.deepcopy(servers270.check_tag_existence)
 update_tag = copy.deepcopy(servers270.update_tag)
 delete_tag = copy.deepcopy(servers270.delete_tag)
+attach_volume = copy.deepcopy(servers270.attach_volume)
+show_volume_attachment = copy.deepcopy(servers270.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers270.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_73/servers.py b/tempest/lib/api_schema/response/compute/v2_73/servers.py
index 6e491e9..ae7ebc4 100644
--- a/tempest/lib/api_schema/response/compute/v2_73/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_73/servers.py
@@ -76,3 +76,6 @@
 check_tag_existence = copy.deepcopy(servers271.check_tag_existence)
 update_tag = copy.deepcopy(servers271.update_tag)
 delete_tag = copy.deepcopy(servers271.delete_tag)
+attach_volume = copy.deepcopy(servers271.attach_volume)
+show_volume_attachment = copy.deepcopy(servers271.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers271.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/volume/groups.py b/tempest/lib/api_schema/response/volume/groups.py
index cb31269..f6e4bc2 100644
--- a/tempest/lib/api_schema/response/volume/groups.py
+++ b/tempest/lib/api_schema/response/volume/groups.py
@@ -64,7 +64,10 @@
                         'type': 'array',
                         'items': {'type': 'string', 'format': 'uuid'}
                     },
-                    'replication_status': {'type': 'string'}
+                    # TODO(zhufl): replication_status is added in 3.38, we
+                    # should move it to the 3.38 schema file when microversion
+                    # is supported in volume interfaces
+                    'replication_status': {'type': ['string', 'null']}
                 },
                 'additionalProperties': False,
                 'required': ['status', 'description', 'created_at',
@@ -129,6 +132,10 @@
                             'type': 'array',
                             'items': {'type': 'string', 'format': 'uuid'}
                         },
+                        # TODO(zhufl): replication_status is added in 3.38, we
+                        # should move it to the 3.38 schema file when
+                        # microversion is supported in volume interfaces
+                        'replication_status': {'type': ['string', 'null']}
                     },
                     'additionalProperties': False,
                     'required': ['status', 'description', 'created_at',
diff --git a/tempest/lib/services/placement/__init__.py b/tempest/lib/services/placement/__init__.py
index 5c20c57..daeaeab 100644
--- a/tempest/lib/services/placement/__init__.py
+++ b/tempest/lib/services/placement/__init__.py
@@ -14,5 +14,7 @@
 
 from tempest.lib.services.placement.placement_client import \
     PlacementClient
+from tempest.lib.services.placement.resource_providers_client import \
+    ResourceProvidersClient
 
-__all__ = ['PlacementClient']
+__all__ = ['PlacementClient', 'ResourceProvidersClient']
diff --git a/tempest/lib/services/placement/resource_providers_client.py b/tempest/lib/services/placement/resource_providers_client.py
new file mode 100644
index 0000000..56f6409
--- /dev/null
+++ b/tempest/lib/services/placement/resource_providers_client.py
@@ -0,0 +1,82 @@
+#    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 oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest.lib.common import rest_client
+from tempest.lib.services.placement import base_placement_client
+
+
+class ResourceProvidersClient(base_placement_client.BasePlacementClient):
+    """Client class for resource provider related methods
+
+    This client class aims to support read-only API operations for resource
+    providers. The following resources are supported:
+    * resource providers
+    * resource provider inventories
+    * resource provider aggregates
+    """
+
+    def list_resource_providers(self, **params):
+        """List resource providers.
+
+        For full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/placement/#list-resource-providers
+        """
+        url = '/resource_providers'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def show_resource_provider(self, rp_uuid):
+        """Show resource provider.
+
+        For full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/placement/#show-resource-provider
+        """
+        url = '/resource_providers/%s' % rp_uuid
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_resource_provider_inventories(self, rp_uuid):
+        """List resource provider inventories.
+
+        For full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/placement/#list-resource-provider-inventories
+        """
+        url = '/resource_providers/%s/inventories' % rp_uuid
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def list_resource_provider_aggregates(self, rp_uuid):
+        """List resource provider aggregates.
+
+        For full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/placement/#list-resource-provider-aggregates
+        """
+        url = '/resource_providers/%s/aggregates' % rp_uuid
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/types_client.py b/tempest/lib/services/volume/v3/types_client.py
index 7fa24a4..1ebd447 100644
--- a/tempest/lib/services/volume/v3/types_client.py
+++ b/tempest/lib/services/volume/v3/types_client.py
@@ -65,6 +65,19 @@
         self.validate_response(schema.show_volume_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
+    def show_default_volume_type(self):
+        """Returns the details of a single volume type.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/block-storage/v3/index.html#show-default-volume-type
+        """
+        url = "types/default"
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.validate_response(schema.show_volume_type, resp, body)
+        return rest_client.ResponseBody(resp, body)
+
     def create_volume_type(self, **kwargs):
         """Create volume type.
 
diff --git a/tempest/scenario/test_minbw_allocation_placement.py b/tempest/scenario/test_minbw_allocation_placement.py
index 5eab1da..74d4ed9 100644
--- a/tempest/scenario/test_minbw_allocation_placement.py
+++ b/tempest/scenario/test_minbw_allocation_placement.py
@@ -178,7 +178,13 @@
         for rp, resources in allocations['allocations'].items():
             if self.INGRESS_RESOURCE_CLASS in resources['resources']:
                 bw_resource_in_alloc = True
+                allocation_rp = rp
         self.assertTrue(bw_resource_in_alloc)
+        # Check that binding_profile of the port is not empty and equals with
+        # the rp uuid
+        port = self.os_admin.ports_client.show_port(valid_port['id'])
+        self.assertEqual(allocation_rp,
+                         port['port']['binding:profile']['allocation'])
 
         # boot another vm with max int bandwidth
         not_valid_port = self.create_port(
@@ -196,3 +202,6 @@
         server2 = self.servers_client.show_server(server2['id'])
         self.assertIn('fault', server2['server'])
         self.assertIn('No valid host', server2['server']['fault']['message'])
+        # Check that binding_profile of the port is empty
+        port = self.os_admin.ports_client.show_port(not_valid_port['id'])
+        self.assertEqual(0, len(port['port']['binding:profile']))
diff --git a/tempest/tests/lib/services/network/test_floating_ips_client.py b/tempest/tests/lib/services/network/test_floating_ips_client.py
index c5b1845..e8f2e5a 100644
--- a/tempest/tests/lib/services/network/test_floating_ips_client.py
+++ b/tempest/tests/lib/services/network/test_floating_ips_client.py
@@ -27,6 +27,8 @@
             {
                 "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f",
                 "description": "for test",
+                "dns_domain": "my-domain.org.",
+                "dns_name": "myfip",
                 "created_at": "2016-12-21T10:55:50Z",
                 "updated_at": "2016-12-21T10:55:53Z",
                 "revision_number": 1,
@@ -37,11 +39,24 @@
                 "floating_ip_address": "172.24.4.228",
                 "port_id": "ce705c24-c1ef-408a-bda3-7bbd946164ab",
                 "id": "2f245a7b-796b-4f26-9cf9-9e82d248fda7",
-                "status": "ACTIVE"
+                "status": "ACTIVE",
+                "port_details": {
+                    "status": "ACTIVE",
+                    "name": "",
+                    "admin_state_up": True,
+                    "network_id": "02dd8479-ef26-4398-a102-d19d0a7b3a1f",
+                    "device_owner": "compute:nova",
+                    "mac_address": "fa:16:3e:b1:3b:30",
+                    "device_id": "8e3941b4-a6e9-499f-a1ac-2a4662025cba"
+                },
+                "tags": ["tag1,tag2"],
+                "port_forwardings": []
             },
             {
                 "router_id": None,
                 "description": "for test",
+                "dns_domain": "my-domain.org.",
+                "dns_name": "myfip2",
                 "created_at": "2016-12-21T11:55:50Z",
                 "updated_at": "2016-12-21T11:55:53Z",
                 "revision_number": 2,
@@ -52,7 +67,10 @@
                 "floating_ip_address": "172.24.4.227",
                 "port_id": None,
                 "id": "61cea855-49cb-4846-997d-801b70c71bdd",
-                "status": "DOWN"
+                "status": "DOWN",
+                "port_details": None,
+                "tags": ["tag1,tag2"],
+                "port_forwardings": []
             }
         ]
     }
diff --git a/tempest/tests/lib/services/network/test_networks_client.py b/tempest/tests/lib/services/network/test_networks_client.py
index 078f4b0..17233bc 100644
--- a/tempest/tests/lib/services/network/test_networks_client.py
+++ b/tempest/tests/lib/services/network/test_networks_client.py
@@ -31,12 +31,17 @@
                     "nova"
                 ],
                 "created_at": "2016-03-08T20:19:41",
+                "dns_domain": "my-domain.org.",
                 "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+                "ipv4_address_scope": None,
+                "ipv6_address_scope": None,
+                "l2_adjacency": False,
                 "mtu": 0,
                 "name": "net1",
                 "port_security_enabled": True,
                 "project_id": "4fd44f30292945e481c7b8a0c8908869",
                 "qos_policy_id": "6a8454ade84346f59e8d40665f878b2e",
+                "revision_number": 1,
                 "router:external": False,
                 "shared": False,
                 "status": "ACTIVE",
@@ -46,7 +51,8 @@
                 "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
                 "updated_at": "2016-03-08T20:19:41",
                 "vlan_transparent": True,
-                "description": ""
+                "description": "",
+                "is_default": False
             },
             {
                 "admin_state_up": True,
@@ -54,12 +60,18 @@
                 "availability_zones": [
                     "nova"
                 ],
+                "created_at": "2016-03-08T20:19:41",
+                "dns_domain": "my-domain.org.",
                 "id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
+                "ipv4_address_scope": None,
+                "ipv6_address_scope": None,
+                "l2_adjacency": False,
                 "mtu": 0,
                 "name": "net2",
                 "port_security_enabled": True,
                 "project_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
                 "qos_policy_id": "bfdb6c39f71e4d44b1dfbda245c50819",
+                "revision_number": 3,
                 "router:external": False,
                 "shared": False,
                 "status": "ACTIVE",
@@ -69,7 +81,8 @@
                 "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
                 "updated_at": "2016-03-08T20:19:41",
                 "vlan_transparent": False,
-                "description": ""
+                "description": "",
+                "is_default": False
             }
         ]
     }
@@ -108,6 +121,7 @@
                 "alive": True,
                 "topic": "dhcp_agent",
                 "host": "osboxes",
+                "ha_state": None,
                 "agent_type": "DHCP agent",
                 "resource_versions": {},
                 "created_at": "2017-06-19 21:39:51",
diff --git a/tempest/tests/lib/services/placement/test_resource_providers_client.py b/tempest/tests/lib/services/placement/test_resource_providers_client.py
new file mode 100644
index 0000000..11aeaf2
--- /dev/null
+++ b/tempest/tests/lib/services/placement/test_resource_providers_client.py
@@ -0,0 +1,119 @@
+#    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.services.placement import resource_providers_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestResourceProvidersClient(base.BaseServiceTest):
+    FAKE_RESOURCE_PROVIDER_UUID = '3722a86e-a563-11e9-9abb-c3d41b6d3abf'
+    FAKE_ROOT_PROVIDER_UUID = '4a6a57c8-a563-11e9-914e-f3e0478fce53'
+    FAKE_RESOURCE_PROVIDER = {
+        'generation': 0,
+        'name': 'Ceph Storage Pool',
+        'uuid': FAKE_RESOURCE_PROVIDER_UUID,
+        'parent_provider_uuid': FAKE_ROOT_PROVIDER_UUID,
+        'root_provider_uuid': FAKE_ROOT_PROVIDER_UUID
+    }
+
+    FAKE_RESOURCE_PROVIDERS = {
+        'resource_providers': [FAKE_RESOURCE_PROVIDER]
+    }
+
+    FAKE_RESOURCE_PROVIDER_INVENTORIES = {
+        'inventories': {
+            'DISK_GB': {
+                'allocation_ratio': 1.0,
+                'max_unit': 35,
+                'min_unit': 1,
+                'reserved': 0,
+                'step_size': 1,
+                'total': 35
+            }
+        },
+        'resource_provider_generation': 7
+    }
+
+    FAKE_AGGREGATE_UUID = '1166be40-a567-11e9-9f2a-53827f9311fa'
+    FAKE_RESOURCE_PROVIDER_AGGREGATES = {
+        'aggregates': [FAKE_AGGREGATE_UUID]
+    }
+
+    def setUp(self):
+        super(TestResourceProvidersClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = resource_providers_client.ResourceProvidersClient(
+            fake_auth, 'placement', 'regionOne')
+
+    def _test_list_resource_providers(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_resource_providers,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_RESOURCE_PROVIDERS,
+            to_utf=bytes_body,
+            status=200
+        )
+
+    def test_list_resource_providers_with_bytes_body(self):
+        self._test_list_resource_providers()
+
+    def test_list_resource_providers_with_str_body(self):
+        self._test_list_resource_providers(bytes_body=True)
+
+    def _test_show_resource_provider(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_resource_provider,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_RESOURCE_PROVIDER,
+            to_utf=bytes_body,
+            status=200,
+            rp_uuid=self.FAKE_RESOURCE_PROVIDER_UUID
+        )
+
+    def test_show_resource_provider_with_str_body(self):
+        self._test_show_resource_provider()
+
+    def test_show_resource_provider_with_bytes_body(self):
+        self._test_show_resource_provider(bytes_body=True)
+
+    def _test_list_resource_provider_inventories(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_resource_provider_inventories,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_RESOURCE_PROVIDER_INVENTORIES,
+            to_utf=bytes_body,
+            status=200,
+            rp_uuid=self.FAKE_RESOURCE_PROVIDER_UUID
+        )
+
+    def test_list_resource_provider_inventories_with_str_body(self):
+        self._test_list_resource_provider_inventories()
+
+    def test_list_resource_provider_inventories_with_bytes_body(self):
+        self._test_list_resource_provider_inventories(bytes_body=True)
+
+    def _test_list_resource_provider_aggregates(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.list_resource_provider_aggregates,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_RESOURCE_PROVIDER_AGGREGATES,
+            to_utf=bytes_body,
+            status=200,
+            rp_uuid=self.FAKE_RESOURCE_PROVIDER_UUID
+        )
+
+    def test_list_resource_provider_aggregates_with_str_body(self):
+        self._test_list_resource_provider_aggregates()
+
+    def test_list_resource_provider_aggregates_with_bytes_body(self):
+        self._test_list_resource_provider_aggregates(bytes_body=True)
diff --git a/tempest/tests/lib/services/volume/v3/test_types_client.py b/tempest/tests/lib/services/volume/v3/test_types_client.py
index 336aa32..19d6591 100644
--- a/tempest/tests/lib/services/volume/v3/test_types_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_types_client.py
@@ -121,6 +121,13 @@
             to_utf=bytes_body,
             volume_type_id="6685584b-1eac-4da6-b5c3-555430cf68ff")
 
+    def _test_show_default_volume_type(self, bytes_body=False):
+        self.check_service_client_function(
+            self.client.show_default_volume_type,
+            'tempest.lib.common.rest_client.RestClient.get',
+            self.FAKE_DEFAULT_VOLUME_TYPE_INFO,
+            to_utf=bytes_body)
+
     def _test_create_volume_type(self, bytes_body=False):
         self.check_service_client_function(
             self.client.create_volume_type,
@@ -224,6 +231,12 @@
     def test_show_volume_type_with_bytes_body(self):
         self._test_show_volume_type(bytes_body=True)
 
+    def test_show_default_volume_type_with_str_body(self):
+        self._test_show_default_volume_type()
+
+    def test_show_default_volume_type_with_bytes_body(self):
+        self._test_show_default_volume_type(bytes_body=True)
+
     def test_create_volume_type_str_body(self):
         self._test_create_volume_type()
 
diff --git a/tox.ini b/tox.ini
index 031a400..2ea8129 100644
--- a/tox.ini
+++ b/tox.ini
@@ -279,7 +279,6 @@
 [testenv:docs]
 deps =
   -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-  -r{toxinidir}/requirements.txt
   -r{toxinidir}/doc/requirements.txt
 commands =
   sphinx-apidoc -f -o doc/source/tests/compute tempest/api/compute
@@ -365,7 +364,6 @@
 [testenv:releasenotes]
 deps =
   -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-  -r{toxinidir}/requirements.txt
   -r{toxinidir}/doc/requirements.txt
 commands =
   rm -rf releasenotes/build