Merge "VPNaaS API Tests Enhancements"
diff --git a/tempest/api/baremetal/test_nodes.py b/tempest/api/baremetal/test_nodes.py
index b6432ad..1572840 100644
--- a/tempest/api/baremetal/test_nodes.py
+++ b/tempest/api/baremetal/test_nodes.py
@@ -87,3 +87,11 @@
         resp, node = self.client.show_node(node['uuid'])
         self.assertEqual('200', resp['status'])
         self._assertExpected(new_p, node['properties'])
+
+    @test.attr(type='smoke')
+    def test_validate_driver_interface(self):
+        resp, body = self.client.validate_driver_interface(self.node['uuid'])
+        self.assertEqual('200', resp['status'])
+        core_interfaces = ['power', 'deploy']
+        for interface in core_interfaces:
+            self.assertIn(interface, body)
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 15025ba..cccaf13 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -55,6 +55,8 @@
         return flavor_id
 
     @test.skip_because(bug="1298131")
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resize_server_using_overlimit_ram(self):
         flavor_name = data_utils.rand_name("flavor-")
@@ -74,6 +76,8 @@
                           flavor_ref['id'])
 
     @test.skip_because(bug="1298131")
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resize_server_using_overlimit_vcpus(self):
         flavor_name = data_utils.rand_name("flavor-")
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 0e6b9d6..c1c2d05 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -89,44 +89,40 @@
     @test.attr(type='gate')
     def test_list_flavors_detailed_filter_by_min_disk(self):
         # The detailed list of flavors should be filtered by disk space
-        resp, flavors = self.client.list_flavors_with_detail()
-        flavors = sorted(flavors, key=lambda k: k['disk'])
-        flavor_id = flavors[0]['id']
+        resp, flavor = self.client.get_flavor_details(self.flavor_ref)
+        flavor_id = flavor['id']
 
-        params = {self._min_disk: flavors[0]['disk'] + 1}
+        params = {self._min_disk: flavor['disk'] + 1}
         resp, flavors = self.client.list_flavors_with_detail(params)
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
     def test_list_flavors_detailed_filter_by_min_ram(self):
         # The detailed list of flavors should be filtered by RAM
-        resp, flavors = self.client.list_flavors_with_detail()
-        flavors = sorted(flavors, key=lambda k: k['ram'])
-        flavor_id = flavors[0]['id']
+        resp, flavor = self.client.get_flavor_details(self.flavor_ref)
+        flavor_id = flavor['id']
 
-        params = {self._min_ram: flavors[0]['ram'] + 1}
+        params = {self._min_ram: flavor['ram'] + 1}
         resp, flavors = self.client.list_flavors_with_detail(params)
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
     def test_list_flavors_filter_by_min_disk(self):
         # The list of flavors should be filtered by disk space
-        resp, flavors = self.client.list_flavors_with_detail()
-        flavors = sorted(flavors, key=lambda k: k['disk'])
-        flavor_id = flavors[0]['id']
+        resp, flavor = self.client.get_flavor_details(self.flavor_ref)
+        flavor_id = flavor['id']
 
-        params = {self._min_disk: flavors[0]['disk'] + 1}
+        params = {self._min_disk: flavor['disk'] + 1}
         resp, flavors = self.client.list_flavors(params)
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
     @test.attr(type='gate')
     def test_list_flavors_filter_by_min_ram(self):
         # The list of flavors should be filtered by RAM
-        resp, flavors = self.client.list_flavors_with_detail()
-        flavors = sorted(flavors, key=lambda k: k['ram'])
-        flavor_id = flavors[0]['id']
+        resp, flavor = self.client.get_flavor_details(self.flavor_ref)
+        flavor_id = flavor['id']
 
-        params = {self._min_ram: flavors[0]['ram'] + 1}
+        params = {self._min_ram: flavor['ram'] + 1}
         resp, flavors = self.client.list_flavors(params)
         self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
 
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 6343ead..d3297ce 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -106,6 +106,8 @@
         self.assertRaises(exceptions.BadRequest,
                           self.create_test_server, accessIPv6=IPv6)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resize_nonexistent_server(self):
         # Resize a non-existent server
@@ -114,6 +116,8 @@
                           self.client.resize,
                           nonexistent_server, self.flavor_ref)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resize_server_with_non_existent_flavor(self):
         # Resize a server with non-existent flavor
@@ -121,6 +125,8 @@
         self.assertRaises(exceptions.BadRequest, self.client.resize,
                           self.server_id, flavor_ref=nonexistent_flavor)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
     @test.attr(type=['negative', 'gate'])
     def test_resize_server_with_null_flavor(self):
         # Resize a server with null flavor
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 375ddf8..fb8ded3 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import StringIO
+
 from tempest.api.compute import base
 from tempest import clients
 from tempest.common.utils import data_utils
@@ -27,9 +29,10 @@
 
 
 class AuthorizationTestJSON(base.BaseV2ComputeTest):
-
     @classmethod
     def setUpClass(cls):
+        if not CONF.service_available.glance:
+            raise cls.skipException('Glance is not available.')
         # No network resources required for this test
         cls.set_network_resources()
         super(AuthorizationTestJSON, cls).setUpClass()
@@ -38,6 +41,7 @@
             raise cls.skipException(msg)
         cls.client = cls.os.servers_client
         cls.images_client = cls.os.images_client
+        cls.glance_client = cls.os.image_client
         cls.keypairs_client = cls.os.keypairs_client
         cls.security_client = cls.os.security_groups_client
 
@@ -57,9 +61,14 @@
         resp, cls.server = cls.client.get_server(server['id'])
 
         name = data_utils.rand_name('image')
-        resp, body = cls.images_client.create_image(server['id'], name)
-        image_id = data_utils.parse_image_id(resp['location'])
-        cls.images_client.wait_for_image_status(image_id, 'ACTIVE')
+        resp, body = cls.glance_client.create_image(name=name,
+                                                   container_format='bare',
+                                                   disk_format='raw',
+                                                   is_public=False)
+        image_id = body['id']
+        image_file = StringIO.StringIO(('*' * 1024))
+        resp, body = cls.glance_client.update_image(image_id, data=image_file)
+        cls.glance_client.wait_for_image_status(image_id, 'active')
         resp, cls.image = cls.images_client.get_image(image_id)
 
         cls.keypairname = data_utils.rand_name('keypair')
diff --git a/tempest/api/compute/v3/admin/test_flavors.py b/tempest/api/compute/v3/admin/test_flavors.py
index 8a4e3cf..09d76b8 100644
--- a/tempest/api/compute/v3/admin/test_flavors.py
+++ b/tempest/api/compute/v3/admin/test_flavors.py
@@ -294,7 +294,7 @@
         flavor_name = data_utils.rand_name(self.flavor_name_prefix)
         new_flavor_id = data_utils.rand_int_id(start=1000)
 
-        ram = " 1024 "
+        ram = "1024"
         resp, flavor = self.client.create_flavor(flavor_name,
                                                  ram, self.vcpus,
                                                  self.disk,
diff --git a/tempest/api/compute/v3/admin/test_flavors_negative.py b/tempest/api/compute/v3/admin/test_flavors_negative.py
index 3f8a2da..6d3308e 100644
--- a/tempest/api/compute/v3/admin/test_flavors_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_negative.py
@@ -57,7 +57,7 @@
         resp, flavor = self.client.create_flavor(flavor_name,
                                                  self.ram,
                                                  self.vcpus, self.disk,
-                                                 '',
+                                                 None,
                                                  ephemeral=self.ephemeral,
                                                  swap=self.swap,
                                                  rxtx=self.rxtx)
diff --git a/tempest/api/compute/v3/servers/test_instance_actions.py b/tempest/api/compute/v3/servers/test_instance_actions.py
index 399541b..64339b8 100644
--- a/tempest/api/compute/v3/servers/test_instance_actions.py
+++ b/tempest/api/compute/v3/servers/test_instance_actions.py
@@ -40,12 +40,10 @@
         self.assertTrue(any([i for i in body if i['action'] == 'create']))
         self.assertTrue(any([i for i in body if i['action'] == 'reboot']))
 
-    @test.skip_because(bug="1206032")
     @test.attr(type='gate')
-    @test.skip_because(bug="1281915")
     def test_get_server_action(self):
         # Get the action details of the provided server
-        request_id = self.resp['x-compute-request-id']
+        request_id = self.resp['x-openstack-request-id']
         resp, body = self.client.get_server_action(self.server_id,
                                                    request_id)
         self.assertEqual(200, resp.status)
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index 0d6773c..ab0e83a 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -29,8 +29,8 @@
         if not CONF.service_available.sahara:
             raise cls.skipException('Sahara support is required')
 
-        os = cls.get_client_manager()
-        cls.client = os.data_processing_client
+        cls.os = cls.get_client_manager()
+        cls.client = cls.os.data_processing_client
 
         cls.flavor_ref = CONF.compute.flavor_ref
 
diff --git a/tempest/api/data_processing/test_job_binaries.py b/tempest/api/data_processing/test_job_binaries.py
new file mode 100644
index 0000000..689c1fe
--- /dev/null
+++ b/tempest/api/data_processing/test_job_binaries.py
@@ -0,0 +1,148 @@
+# Copyright (c) 2014 Mirantis Inc.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.data_processing import base as dp_base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class JobBinaryTest(dp_base.BaseDataProcessingTest):
+    """Link to the API documentation is http://docs.openstack.org/developer/
+    sahara/restapi/rest_api_v1.1_EDP.html#job-binaries
+    """
+    @classmethod
+    @test.safe_setup
+    def setUpClass(cls):
+        super(JobBinaryTest, cls).setUpClass()
+        cls.swift_job_binary_with_extra = {
+            'url': 'swift://sahara-container.sahara/example.jar',
+            'description': 'Test job binary',
+            'extra': {
+                'user': cls.os.credentials.username,
+                'password': cls.os.credentials.password
+            }
+        }
+        # Create extra cls.swift_job_binary variable to use for comparison to
+        # job binary response body because response body has no 'extra' field.
+        cls.swift_job_binary = cls.swift_job_binary_with_extra.copy()
+        del cls.swift_job_binary['extra']
+
+        name = data_utils.rand_name('sahara-internal-job-binary')
+        cls.job_binary_data = 'Some script may be data'
+        job_binary_internal = cls.create_job_binary_internal(
+            name, cls.job_binary_data)[1]
+        cls.internal_db_job_binary = {
+            'url': 'internal-db://%s' % job_binary_internal['id'],
+            'description': 'Test job binary',
+        }
+
+    def _create_job_binary(self, binary_body, binary_name=None):
+        """Creates Job Binary with optional name specified.
+
+        It creates a link to data (jar, pig files, etc.) and ensures response
+        status, job binary name and response body. Returns id and name of
+        created job binary. Data may not exist when using Swift
+        as data storage. In other cases data must exist in storage.
+        """
+        if not binary_name:
+            # generate random name if it's not specified
+            binary_name = data_utils.rand_name('sahara-job-binary')
+
+        # create job binary
+        resp, body = self.create_job_binary(binary_name, **binary_body)
+
+        # ensure that binary created successfully
+        self.assertEqual(202, resp.status)
+        self.assertEqual(binary_name, body['name'])
+        if 'swift' in binary_body['url']:
+            binary_body = self.swift_job_binary
+        self.assertDictContainsSubset(binary_body, body)
+
+        return body['id'], binary_name
+
+    @test.attr(type='smoke')
+    def test_swift_job_binary_create(self):
+        self._create_job_binary(self.swift_job_binary_with_extra)
+
+    @test.attr(type='smoke')
+    def test_swift_job_binary_list(self):
+        binary_info = self._create_job_binary(self.swift_job_binary_with_extra)
+
+        # check for job binary in list
+        resp, binaries = self.client.list_job_binaries()
+        self.assertEqual(200, resp.status)
+        binaries_info = [(binary['id'], binary['name']) for binary in binaries]
+        self.assertIn(binary_info, binaries_info)
+
+    @test.attr(type='smoke')
+    def test_swift_job_binary_get(self):
+        binary_id, binary_name = self._create_job_binary(
+            self.swift_job_binary_with_extra)
+
+        # check job binary fetch by id
+        resp, binary = self.client.get_job_binary(binary_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(binary_name, binary['name'])
+        self.assertDictContainsSubset(self.swift_job_binary, binary)
+
+    @test.attr(type='smoke')
+    def test_swift_job_binary_delete(self):
+        binary_id = self._create_job_binary(
+            self.swift_job_binary_with_extra)[0]
+
+        # delete the job binary by id
+        resp = self.client.delete_job_binary(binary_id)[0]
+        self.assertEqual(204, resp.status)
+
+    @test.attr(type='smoke')
+    def test_internal_db_job_binary_create(self):
+        self._create_job_binary(self.internal_db_job_binary)
+
+    @test.attr(type='smoke')
+    def test_internal_db_job_binary_list(self):
+        binary_info = self._create_job_binary(self.internal_db_job_binary)
+
+        # check for job binary in list
+        resp, binaries = self.client.list_job_binaries()
+        self.assertEqual(200, resp.status)
+        binaries_info = [(binary['id'], binary['name']) for binary in binaries]
+        self.assertIn(binary_info, binaries_info)
+
+    @test.attr(type='smoke')
+    def test_internal_db_job_binary_get(self):
+        binary_id, binary_name = self._create_job_binary(
+            self.internal_db_job_binary)
+
+        # check job binary fetch by id
+        resp, binary = self.client.get_job_binary(binary_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(binary_name, binary['name'])
+        self.assertDictContainsSubset(self.internal_db_job_binary, binary)
+
+    @test.attr(type='smoke')
+    def test_internal_db_job_binary_delete(self):
+        binary_id = self._create_job_binary(self.internal_db_job_binary)[0]
+
+        # delete the job binary by id
+        resp = self.client.delete_job_binary(binary_id)[0]
+        self.assertEqual(204, resp.status)
+
+    @test.attr(type='smoke')
+    def test_job_binary_get_data(self):
+        binary_id = self._create_job_binary(self.internal_db_job_binary)[0]
+
+        # get data of job binary by id
+        resp, data = self.client.get_job_binary_data(binary_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(data, self.job_binary_data)
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index a307986..d1a8faf 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -85,3 +85,50 @@
         self.assertEqual('200', resp['status'])
         for q in non_default_quotas['quotas']:
             self.assertNotEqual(tenant_id, q['tenant_id'])
+
+    @test.requires_ext(extension='lbaas', service='network')
+    @test.attr(type='gate')
+    def test_lbaas_quotas(self):
+        # Add a tenant to conduct the test
+        test_tenant = data_utils.rand_name('test_tenant_')
+        test_description = data_utils.rand_name('desc_')
+        _, tenant = self.identity_admin_client.create_tenant(
+            name=test_tenant,
+            description=test_description)
+        tenant_id = tenant['id']
+        self.addCleanup(self.identity_admin_client.delete_tenant, tenant_id)
+        # Change lbaas quotas for tenant
+        new_quotas = {'vip': 1, 'pool': 2,
+                      'member': 3, 'health_monitor': 4}
+
+        resp, quota_set = self.admin_client.update_quotas(tenant_id,
+                                                          **new_quotas)
+        self.assertEqual('200', resp['status'])
+        self.addCleanup(self.admin_client.reset_quotas, tenant_id)
+        self.assertEqual(1, quota_set['vip'])
+        self.assertEqual(2, quota_set['pool'])
+        self.assertEqual(3, quota_set['member'])
+        self.assertEqual(4, quota_set['health_monitor'])
+        # Confirm our tenant is listed among tenants with non default quotas
+        resp, non_default_quotas = self.admin_client.list_quotas()
+        self.assertEqual('200', resp['status'])
+        found = False
+        for qs in non_default_quotas['quotas']:
+            if qs['tenant_id'] == tenant_id:
+                found = True
+        self.assertTrue(found)
+        # Confirm from APi quotas were changed as requested for tenant
+        resp, quota_set = self.admin_client.show_quotas(tenant_id)
+        quota_set = quota_set['quota']
+        self.assertEqual('200', resp['status'])
+        self.assertEqual(1, quota_set['vip'])
+        self.assertEqual(2, quota_set['pool'])
+        self.assertEqual(3, quota_set['member'])
+        self.assertEqual(4, quota_set['health_monitor'])
+        # Reset quotas to default and confirm
+        resp, body = self.admin_client.reset_quotas(tenant_id)
+        self.assertEqual('204', resp['status'])
+        resp, non_default_quotas = self.admin_client.list_quotas()
+        self.assertEqual('200', resp['status'])
+        for q in non_default_quotas['quotas']:
+            self.assertNotEqual(tenant_id, q['tenant_id'])
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index e0e26da..c897716 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -70,6 +70,27 @@
         self.assertTrue(port, msg)
         self._confirm_allowed_address_pair(port[0], self.ip_address)
 
+    @test.attr(type='smoke')
+    def test_update_port_with_address_pair(self):
+        # Create a port without allowed address pair
+        resp, body = self.client.create_port(network_id=self.network['id'])
+        self.assertEqual('201', resp['status'])
+        port_id = body['port']['id']
+        self.addCleanup(self.client.delete_port, port_id)
+
+        # Confirm  port is created
+        resp, body = self.client.show_port(port_id)
+        self.assertEqual('200', resp['status'])
+
+        # Update allowed address pair attribute of port
+        allowed_address_pairs = [{'ip_address': self.ip_address,
+                                  'mac_address': self.mac_address}]
+        resp, body = self.client.update_port(port_id,
+                          allowed_address_pairs=allowed_address_pairs)
+        self.assertEqual('200', resp['status'])
+        newport = body['port']
+        self._confirm_allowed_address_pair(newport, self.ip_address)
+
     def _confirm_allowed_address_pair(self, port, ip):
         msg = 'Port allowed address pairs should not be empty'
         self.assertTrue(port['allowed_address_pairs'], msg)
diff --git a/tempest/api_schema/compute/agents.py b/tempest/api_schema/compute/agents.py
index b9ad240..e5f3a8d 100644
--- a/tempest/api_schema/compute/agents.py
+++ b/tempest/api_schema/compute/agents.py
@@ -22,7 +22,7 @@
                 'items': {
                     'type': 'object',
                     'properties': {
-                        'agent_id': {'type': ['integer', 'string']},
+                        'agent_id': {'type': 'integer'},
                         'hypervisor': {'type': 'string'},
                         'os': {'type': 'string'},
                         'architecture': {'type': 'string'},
diff --git a/tempest/api_schema/compute/keypairs.py b/tempest/api_schema/compute/keypairs.py
index b8f905f..2ae410c 100644
--- a/tempest/api_schema/compute/keypairs.py
+++ b/tempest/api_schema/compute/keypairs.py
@@ -49,10 +49,7 @@
                 'fingerprint': {'type': 'string'},
                 'name': {'type': 'string'},
                 'public_key': {'type': 'string'},
-                # NOTE: Now the type of 'user_id' is integer, but here
-                # allows 'string' also because we will be able to change
-                # it to 'uuid' in the future.
-                'user_id': {'type': ['integer', 'string']},
+                'user_id': {'type': 'string'},
                 'private_key': {'type': 'string'}
             },
             # When create keypair API is being called with 'Public key'
diff --git a/tempest/api_schema/compute/migrations.py b/tempest/api_schema/compute/migrations.py
index 6723869..6549272 100644
--- a/tempest/api_schema/compute/migrations.py
+++ b/tempest/api_schema/compute/migrations.py
@@ -22,10 +22,7 @@
                 'items': {
                     'type': 'object',
                     'properties': {
-                        # NOTE: Now the type of 'id' is integer, but here
-                        # allows 'string' also because we will be able to
-                        # change it to 'uuid' in the future.
-                        'id': {'type': ['integer', 'string']},
+                        'id': {'type': 'integer'},
                         'status': {'type': 'string'},
                         'instance_uuid': {'type': 'string'},
                         'source_node': {'type': 'string'},
@@ -33,12 +30,8 @@
                         'dest_node': {'type': 'string'},
                         'dest_compute': {'type': 'string'},
                         'dest_host': {'type': 'string'},
-                        'old_instance_type_id': {
-                            'type': ['integer', 'string']
-                        },
-                        'new_instance_type_id': {
-                            'type': ['integer', 'string']
-                        },
+                        'old_instance_type_id': {'type': 'integer'},
+                        'new_instance_type_id': {'type': 'integer'},
                         'created_at': {'type': 'string'},
                         'updated_at': {'type': ['string', 'null']}
                     },
diff --git a/tempest/api_schema/compute/servers.py b/tempest/api_schema/compute/servers.py
index 14e9ce9..2519eb5 100644
--- a/tempest/api_schema/compute/servers.py
+++ b/tempest/api_schema/compute/servers.py
@@ -56,13 +56,13 @@
             'server': {
                 'type': 'object',
                 'properties': {
-                    'id': {'type': ['integer', 'string']},
+                    'id': {'type': 'string'},
                     'name': {'type': 'string'},
                     'status': {'type': 'string'},
                     'image': {
                         'type': 'object',
                         'properties': {
-                            'id': {'type': ['integer', 'string']},
+                            'id': {'type': 'string'},
                             'links': parameter_types.links
                         },
                         'required': ['id', 'links']
@@ -70,7 +70,7 @@
                     'flavor': {
                         'type': 'object',
                         'properties': {
-                            'id': {'type': ['integer', 'string']},
+                            'id': {'type': 'string'},
                             'links': parameter_types.links
                         },
                         'required': ['id', 'links']
diff --git a/tempest/api_schema/compute/services.py b/tempest/api_schema/compute/services.py
index 4c58013..eaba129 100644
--- a/tempest/api_schema/compute/services.py
+++ b/tempest/api_schema/compute/services.py
@@ -22,10 +22,7 @@
                 'items': {
                     'type': 'object',
                     'properties': {
-                        # NOTE: Now the type of 'id' is integer, but here
-                        # allows 'string' also because we will be able to
-                        # change it to 'uuid' in the future.
-                        'id': {'type': ['integer', 'string']},
+                        'id': {'type': 'integer'},
                         'zone': {'type': 'string'},
                         'host': {'type': 'string'},
                         'state': {'type': 'string'},
diff --git a/tempest/api_schema/compute/v2/floating_ips.py b/tempest/api_schema/compute/v2/floating_ips.py
index 03e6aef..fb3667b 100644
--- a/tempest/api_schema/compute/v2/floating_ips.py
+++ b/tempest/api_schema/compute/v2/floating_ips.py
@@ -27,7 +27,7 @@
                         # able to change it to 'uuid' in the future.
                         'id': {'type': ['integer', 'string']},
                         'pool': {'type': ['string', 'null']},
-                        'instance_id': {'type': ['integer', 'string', 'null']},
+                        'instance_id': {'type': ['string', 'null']},
                         'ip': {
                             'type': 'string',
                             'format': 'ip-address'
@@ -58,7 +58,7 @@
                     # 'uuid' in the future.
                     'id': {'type': ['integer', 'string']},
                     'pool': {'type': ['string', 'null']},
-                    'instance_id': {'type': ['integer', 'string', 'null']},
+                    'instance_id': {'type': ['string', 'null']},
                     'ip': {
                         'type': 'string',
                         'format': 'ip-address'
@@ -117,3 +117,14 @@
         'required': ['floating_ips_bulk_create']
     }
 }
+
+delete_floating_ips_bulk = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'floating_ips_bulk_delete': {'type': 'string'}
+        },
+        'required': ['floating_ips_bulk_delete']
+    }
+}
diff --git a/tempest/api_schema/compute/v2/images.py b/tempest/api_schema/compute/v2/images.py
index d121060..90737a2 100644
--- a/tempest/api_schema/compute/v2/images.py
+++ b/tempest/api_schema/compute/v2/images.py
@@ -30,10 +30,7 @@
         'server': {
             'type': 'object',
             'properties': {
-                # NOTE: Now the type of 'id' is integer, but here
-                # allows 'string' also because we will be able to
-                # change it to 'uuid' in the future.
-                'id': {'type': ['integer', 'string']},
+                'id': {'type': 'string'},
                 'links': parameter_types.links
             },
             'required': ['id', 'links']
diff --git a/tempest/api_schema/compute/v2/keypairs.py b/tempest/api_schema/compute/v2/keypairs.py
index 9a025c3..32d8cca 100644
--- a/tempest/api_schema/compute/v2/keypairs.py
+++ b/tempest/api_schema/compute/v2/keypairs.py
@@ -25,10 +25,7 @@
                     'public_key': {'type': 'string'},
                     'name': {'type': 'string'},
                     'fingerprint': {'type': 'string'},
-                    # NOTE: Now the type of 'user_id' is integer, but here
-                    # allows 'string' also because we will be able to change
-                    # it to 'uuid' in the future.
-                    'user_id': {'type': ['integer', 'string']},
+                    'user_id': {'type': 'string'},
                     'deleted': {'type': 'boolean'},
                     'created_at': {'type': 'string'},
                     'updated_at': {'type': ['string', 'null']},
diff --git a/tempest/api_schema/compute/v2/servers.py b/tempest/api_schema/compute/v2/servers.py
index fe53abd..5e9fbd5 100644
--- a/tempest/api_schema/compute/v2/servers.py
+++ b/tempest/api_schema/compute/v2/servers.py
@@ -25,10 +25,7 @@
             'server': {
                 'type': 'object',
                 'properties': {
-                    # NOTE: Now the type of 'id' is uuid, but here allows
-                    # 'integer' also because old OpenStack uses 'integer'
-                    # as a server id.
-                    'id': {'type': ['integer', 'string']},
+                    'id': {'type': 'string'},
                     'security_groups': {'type': 'array'},
                     'links': parameter_types.links,
                     'adminPass': {'type': 'string'},
diff --git a/tempest/api_schema/compute/v2/volumes.py b/tempest/api_schema/compute/v2/volumes.py
index 84a659c..1af951f 100644
--- a/tempest/api_schema/compute/v2/volumes.py
+++ b/tempest/api_schema/compute/v2/volumes.py
@@ -38,7 +38,7 @@
                                 'id': {'type': 'string'},
                                 'device': {'type': 'string'},
                                 'volumeId': {'type': 'string'},
-                                'serverId': {'type': ['integer', 'string']}
+                                'serverId': {'type': 'string'}
                             }
                             # NOTE- If volume is not attached to any server
                             # then, 'attachments' attributes comes as array
@@ -86,7 +86,7 @@
                                     'id': {'type': 'string'},
                                     'device': {'type': 'string'},
                                     'volumeId': {'type': 'string'},
-                                    'serverId': {'type': ['integer', 'string']}
+                                    'serverId': {'type': 'string'}
                                 }
                                 # NOTE- If volume is not attached to any server
                                 # then, 'attachments' attributes comes as array
diff --git a/tempest/api_schema/compute/v3/servers.py b/tempest/api_schema/compute/v3/servers.py
index 4fb2d87..7572029 100644
--- a/tempest/api_schema/compute/v3/servers.py
+++ b/tempest/api_schema/compute/v3/servers.py
@@ -25,10 +25,7 @@
             'server': {
                 'type': 'object',
                 'properties': {
-                    # NOTE: Now the type of 'id' is uuid, but here allows
-                    # 'integer' also because old OpenStack uses 'integer'
-                    # as a server id.
-                    'id': {'type': ['integer', 'string']},
+                    'id': {'type': 'string'},
                     'os-security-groups:security_groups': {'type': 'array'},
                     'links': parameter_types.links,
                     'admin_password': {'type': 'string'},
diff --git a/tempest/cli/simple_read_only/test_cinder.py b/tempest/cli/simple_read_only/test_cinder.py
index e9a0cee..63ad0e3 100644
--- a/tempest/cli/simple_read_only/test_cinder.py
+++ b/tempest/cli/simple_read_only/test_cinder.py
@@ -96,7 +96,6 @@
         self.cinder('type-list')
 
     def test_cinder_list_extensions(self):
-        self.cinder('list-extensions')
         roles = self.parser.listing(self.cinder('list-extensions'))
         self.assertTableStruct(roles, ['Name', 'Summary', 'Alias', 'Updated'])
 
diff --git a/tempest/cli/simple_read_only/test_neutron.py b/tempest/cli/simple_read_only/test_neutron.py
index c1d58b5..49d079e 100644
--- a/tempest/cli/simple_read_only/test_neutron.py
+++ b/tempest/cli/simple_read_only/test_neutron.py
@@ -49,7 +49,8 @@
 
     @test.attr(type='smoke')
     def test_neutron_net_list(self):
-        self.neutron('net-list')
+        net_list = self.parser.listing(self.neutron('net-list'))
+        self.assertTableStruct(net_list, ['id', 'name', 'subnets'])
 
     @test.attr(type='smoke')
     def test_neutron_ext_list(self):
@@ -111,11 +112,14 @@
     @test.attr(type='smoke')
     @test.requires_ext(extension='external-net', service='network')
     def test_neutron_net_external_list(self):
-        self.neutron('net-external-list')
+        net_ext_list = self.parser.listing(self.neutron('net-external-list'))
+        self.assertTableStruct(net_ext_list, ['id', 'name', 'subnets'])
 
     @test.attr(type='smoke')
     def test_neutron_port_list(self):
-        self.neutron('port-list')
+        port_list = self.parser.listing(self.neutron('port-list'))
+        self.assertTableStruct(port_list, ['id', 'name', 'mac_address',
+                                           'fixed_ips'])
 
     @test.attr(type='smoke')
     @test.requires_ext(extension='quotas', service='network')
@@ -125,7 +129,9 @@
     @test.attr(type='smoke')
     @test.requires_ext(extension='router', service='network')
     def test_neutron_router_list(self):
-        self.neutron('router-list')
+        router_list = self.parser.listing(self.neutron('router-list'))
+        self.assertTableStruct(router_list, ['id', 'name',
+                                             'external_gateway_info'])
 
     @test.attr(type='smoke')
     @test.requires_ext(extension='security-group', service='network')
@@ -136,11 +142,18 @@
     @test.attr(type='smoke')
     @test.requires_ext(extension='security-group', service='network')
     def test_neutron_security_group_rule_list(self):
-        self.neutron('security-group-rule-list')
+        security_grp = self.parser.listing(self.neutron
+                                           ('security-group-rule-list'))
+        self.assertTableStruct(security_grp, ['id', 'security_group',
+                                              'direction', 'protocol',
+                                              'remote_ip_prefix',
+                                              'remote_group'])
 
     @test.attr(type='smoke')
     def test_neutron_subnet_list(self):
-        self.neutron('subnet-list')
+        subnet_list = self.parser.listing(self.neutron('subnet-list'))
+        self.assertTableStruct(subnet_list, ['id', 'name', 'cidr',
+                                             'allocation_pools'])
 
     @test.attr(type='smoke')
     def test_neutron_help(self):
diff --git a/tempest/common/commands.py b/tempest/common/commands.py
index 6720847..2ab008d 100644
--- a/tempest/common/commands.py
+++ b/tempest/common/commands.py
@@ -50,7 +50,7 @@
 
 
 def iptables_raw(table):
-    return sudo_cmd_call("iptables -v -S -t " + table)
+    return sudo_cmd_call("iptables --line-numbers -L -nv -t " + table)
 
 
 def ip_ns_list():
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index 4e35aaa..93329bc 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -105,9 +105,24 @@
                             "T107: service tag should not be in path")
 
 
+def no_official_client_manager_in_api_tests(physical_line, filename):
+    """Check that the OfficialClientManager isn't used in the api tests
+
+    The api tests should not use the official clients.
+
+    T108: Can not use OfficialClientManager in the API tests
+    """
+    if 'tempest/api' in filename:
+        if 'OfficialClientManager' in physical_line:
+            return (physical_line.find('OfficialClientManager'),
+                    'T108: OfficialClientManager can not be used in the api '
+                    'tests')
+
+
 def factory(register):
     register(import_no_clients_in_api)
     register(scenario_tests_need_service_tags)
     register(no_setupclass_for_unit_tests)
     register(no_vi_headers)
     register(service_tags_not_in_module_path)
+    register(no_official_client_manager_in_api_tests)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 07d8828..e6593db 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -21,6 +21,7 @@
 import subprocess
 import time
 
+from cinderclient import exceptions as cinder_exceptions
 from heatclient import exc as heat_exceptions
 import netaddr
 from neutronclient.common import exceptions as exc
@@ -354,7 +355,7 @@
         return server
 
     def create_volume(self, client=None, size=1, name=None,
-                      snapshot_id=None, imageRef=None):
+                      snapshot_id=None, imageRef=None, volume_type=None):
         if client is None:
             client = self.volume_client
         if name is None:
@@ -362,7 +363,8 @@
         LOG.debug("Creating a volume (size: %s, name: %s)", size, name)
         volume = client.volumes.create(size=size, display_name=name,
                                        snapshot_id=snapshot_id,
-                                       imageRef=imageRef)
+                                       imageRef=imageRef,
+                                       volume_type=volume_type)
         self.set_resource(name, volume)
         self.assertEqual(name, volume.display_name)
         self.status_timeout(client.volumes, volume.id, 'available')
@@ -623,6 +625,84 @@
             timeout=CONF.baremetal.unprovision_timeout)
 
 
+class EncryptionScenarioTest(OfficialClientTest):
+    """
+    Base class for encryption scenario tests
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(EncryptionScenarioTest, cls).setUpClass()
+
+        # use admin credentials to create encrypted volume types
+        admin_creds = cls.admin_credentials()
+        manager = clients.OfficialClientManager(credentials=admin_creds)
+        cls.admin_volume_client = manager.volume_client
+
+    def _wait_for_volume_status(self, status):
+        self.status_timeout(
+            self.volume_client.volumes, self.volume.id, status)
+
+    def _wait_for_volume_deletion(self):
+        self.delete_timeout(
+            self.volume_client.volumes, self.volume.id,
+            not_found_exception=cinder_exceptions.NotFound)
+
+    def nova_boot(self):
+        self.keypair = self.create_keypair()
+        create_kwargs = {'key_name': self.keypair.name}
+        self.server = self.create_server(self.compute_client,
+                                         image=self.image,
+                                         create_kwargs=create_kwargs)
+
+    def create_volume_type(self, client=None, name=None):
+        if not client:
+            client = self.admin_volume_client
+        if not name:
+            name = 'generic'
+        randomized_name = data_utils.rand_name('scenario-type-' + name + '-')
+        LOG.debug("Creating a volume type: %s", randomized_name)
+        volume_type = client.volume_types.create(randomized_name)
+        self.addCleanup(client.volume_types.delete, volume_type.id)
+        return volume_type
+
+    def create_encryption_type(self, client=None, type_id=None, provider=None,
+                               key_size=None, cipher=None,
+                               control_location=None):
+        if not client:
+            client = self.admin_volume_client
+        if not type_id:
+            volume_type = self.create_volume_type()
+            type_id = volume_type.id
+        LOG.debug("Creating an encryption type for volume type: %s", type_id)
+        client.volume_encryption_types.create(type_id,
+                                              {'provider': provider,
+                                               'key_size': key_size,
+                                               'cipher': cipher,
+                                               'control_location':
+                                               control_location})
+
+    def nova_volume_attach(self):
+        attach_volume_client = self.compute_client.volumes.create_server_volume
+        volume = attach_volume_client(self.server.id,
+                                      self.volume.id,
+                                      '/dev/vdb')
+        self.assertEqual(self.volume.id, volume.id)
+        self._wait_for_volume_status('in-use')
+
+    def nova_volume_detach(self):
+        detach_volume_client = self.compute_client.volumes.delete_server_volume
+        detach_volume_client(self.server.id, self.volume.id)
+        self._wait_for_volume_status('available')
+
+        volume = self.volume_client.volumes.get(self.volume.id)
+        self.assertEqual('available', volume.status)
+
+    def cinder_delete_encrypted(self):
+        self.volume_client.volumes.delete(self.volume.id)
+        self._wait_for_volume_deletion()
+
+
 class NetworkScenarioTest(OfficialClientTest):
     """
     Base class for network scenario tests
diff --git a/tempest/scenario/test_encrypted_cinder_volumes.py b/tempest/scenario/test_encrypted_cinder_volumes.py
new file mode 100644
index 0000000..f223cbf
--- /dev/null
+++ b/tempest/scenario/test_encrypted_cinder_volumes.py
@@ -0,0 +1,69 @@
+# Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory
+# 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.scenario import manager
+from tempest import test
+
+
+class TestEncryptedCinderVolumes(manager.EncryptionScenarioTest):
+
+    """
+    This test is for verifying the functionality of encrypted cinder volumes.
+
+    For both LUKS and cryptsetup encryption types, this test performs
+    the following:
+        * Creates an image in Glance
+        * Boots an instance from the image
+        * Creates an encryption type (as admin)
+        * Creates a volume of that encryption type (as a regular user)
+        * Attaches and detaches the encrypted volume to the instance
+        * Deletes the encrypted volume
+    """
+
+    def launch_instance(self):
+        self.glance_image_create()
+        self.nova_boot()
+
+    def create_encrypted_volume(self, encryption_provider):
+        volume_type = self.create_volume_type(name='luks')
+        self.create_encryption_type(type_id=volume_type.id,
+                                    provider=encryption_provider,
+                                    key_size=512,
+                                    cipher='aes-xts-plain64',
+                                    control_location='front-end')
+        self.volume = self.create_volume(volume_type=volume_type.name)
+
+    def attach_detach_volume(self):
+        self.nova_volume_attach()
+        self.nova_volume_detach()
+
+    def delete_volume(self):
+        self.cinder_delete_encrypted()
+
+    @test.services('compute', 'volume', 'image')
+    def test_encrypted_cinder_volumes_luks(self):
+        self.launch_instance()
+        self.create_encrypted_volume('nova.volume.encryptors.'
+                                     'luks.LuksEncryptor')
+        self.attach_detach_volume()
+        self.delete_volume()
+
+    @test.services('compute', 'volume', 'image')
+    def test_encrypted_cinder_volumes_cryptsetup(self):
+        self.launch_instance()
+        self.create_encrypted_volume('nova.volume.encryptors.'
+                                     'cryptsetup.CryptsetupEncryptor')
+        self.attach_detach_volume()
+        self.delete_volume()
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index 321b08b..f98ecff 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -122,7 +122,7 @@
 
         return resp, self.deserialize(body)
 
-    def _show_request(self, resource, uuid, permanent=False):
+    def _show_request(self, resource, uuid, permanent=False, **kwargs):
         """
         Gets a specific object of the specified type.
 
@@ -130,7 +130,10 @@
         :return: Serialized object as a dictionary.
 
         """
-        uri = self._get_uri(resource, uuid=uuid, permanent=permanent)
+        if 'uri' in kwargs:
+            uri = kwargs['uri']
+        else:
+            uri = self._get_uri(resource, uuid=uuid, permanent=permanent)
         resp, body = self.get(uri)
 
         return resp, self.deserialize(body)
diff --git a/tempest/services/baremetal/v1/base_v1.py b/tempest/services/baremetal/v1/base_v1.py
index ea0ccc9..61342eb 100644
--- a/tempest/services/baremetal/v1/base_v1.py
+++ b/tempest/services/baremetal/v1/base_v1.py
@@ -239,3 +239,19 @@
         target = {'target': state}
         return self._put_request('nodes/%s/states/power' % node_uuid,
                                  target)
+
+    @base.handle_errors
+    def validate_driver_interface(self, node_uuid):
+        """
+        Get all driver interfaces of a specific node.
+
+        :param uuid: Unique identifier of the node in UUID format.
+
+        """
+
+        uri = '{pref}/{res}/{uuid}/{postf}'.format(pref=self.uri_prefix,
+                                                   res='nodes',
+                                                   uuid=node_uuid,
+                                                   postf='validate')
+
+        return self._show_request('nodes', node_uuid, uri=uri)
diff --git a/tempest/services/botoclients.py b/tempest/services/botoclients.py
index 7616a99..7af904b 100644
--- a/tempest/services/botoclients.py
+++ b/tempest/services/botoclients.py
@@ -37,13 +37,16 @@
                  *args, **kwargs):
         # FIXME(andreaf) replace credentials and auth_url with auth_provider
 
+        insecure_ssl = CONF.identity.disable_ssl_certificate_validation
+
         self.connection_timeout = str(CONF.boto.http_socket_timeout)
         self.num_retries = str(CONF.boto.num_retries)
         self.build_timeout = CONF.boto.build_timeout
         self.ks_cred = {"username": username,
                         "password": password,
                         "auth_url": auth_url,
-                        "tenant_name": tenant_name}
+                        "tenant_name": tenant_name,
+                        "insecure": insecure_ssl}
 
     def _keystone_aws_get(self):
         # FIXME(andreaf) Move EC2 credentials to AuthProvider
@@ -90,7 +93,10 @@
         self._config_boto_timeout(self.connection_timeout, self.num_retries)
         if not all((self.connection_data["aws_access_key_id"],
                    self.connection_data["aws_secret_access_key"])):
-            if all(self.ks_cred.itervalues()):
+            if all([self.ks_cred.get('auth_url'),
+                    self.ks_cred.get('username'),
+                    self.ks_cred.get('tenant_name'),
+                    self.ks_cred.get('password')]):
                 ec2_cred = self._keystone_aws_get()
                 self.connection_data["aws_access_key_id"] = \
                     ec2_cred.access
@@ -109,6 +115,7 @@
 
     def __init__(self, *args, **kwargs):
         super(APIClientEC2, self).__init__(*args, **kwargs)
+        insecure_ssl = CONF.identity.disable_ssl_certificate_validation
         aws_access = CONF.boto.aws_access
         aws_secret = CONF.boto.aws_secret
         purl = urlparse.urlparse(CONF.boto.ec2_url)
@@ -129,6 +136,7 @@
         self.connection_data = {"aws_access_key_id": aws_access,
                                 "aws_secret_access_key": aws_secret,
                                 "is_secure": purl.scheme == "https",
+                                "validate_certs": not insecure_ssl,
                                 "region": region,
                                 "host": purl.hostname,
                                 "port": port,
@@ -187,6 +195,7 @@
 
     def __init__(self, *args, **kwargs):
         super(ObjectClientS3, self).__init__(*args, **kwargs)
+        insecure_ssl = CONF.identity.disable_ssl_certificate_validation
         aws_access = CONF.boto.aws_access
         aws_secret = CONF.boto.aws_secret
         purl = urlparse.urlparse(CONF.boto.s3_url)
@@ -201,6 +210,7 @@
         self.connection_data = {"aws_access_key_id": aws_access,
                                 "aws_secret_access_key": aws_secret,
                                 "is_secure": purl.scheme == "https",
+                                "validate_certs": not insecure_ssl,
                                 "host": purl.hostname,
                                 "port": port,
                                 "calling_format": boto.s3.connection.
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 92b4ddf..0028eea 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -137,4 +137,5 @@
         post_body = json.dumps({'ip_range': ip_range})
         resp, body = self.put('os-floating-ips-bulk/delete', post_body)
         body = json.loads(body)
+        self.validate_response(schema.delete_floating_ips_bulk, resp, body)
         return resp, body['floating_ips_bulk_delete']
diff --git a/tempest/tests/test_commands.py b/tempest/tests/test_commands.py
index bdb9269..1e2925b 100644
--- a/tempest/tests/test_commands.py
+++ b/tempest/tests/test_commands.py
@@ -47,7 +47,8 @@
     @mock.patch('subprocess.Popen')
     def test_iptables_raw(self, mock):
         table = 'filter'
-        expected = ['/usr/bin/sudo', '-n', 'iptables', '-v', '-S', '-t',
+        expected = ['/usr/bin/sudo', '-n', 'iptables', '--line-numbers',
+                    '-L', '-nv', '-t',
                     '%s' % table]
         commands.iptables_raw(table)
         mock.assert_called_once_with(expected, **self.subprocess_args)
diff --git a/tempest/tests/test_hacking.py b/tempest/tests/test_hacking.py
index 91c3274..52fdf7e 100644
--- a/tempest/tests/test_hacking.py
+++ b/tempest/tests/test_hacking.py
@@ -99,3 +99,11 @@
             './tempest/scenario/compute/fake_test.py'))
         self.assertFalse(checks.service_tags_not_in_module_path(
             "@test.services('compute')", './tempest/api/image/fake_test.py'))
+
+    def test_no_official_client_manager_in_api_tests(self):
+        self.assertTrue(checks.no_official_client_manager_in_api_tests(
+            "cls.official_client = clients.OfficialClientManager(credentials)",
+            "tempest/api/compute/base.py"))
+        self.assertFalse(checks.no_official_client_manager_in_api_tests(
+            "cls.official_client = clients.OfficialClientManager(credentials)",
+            "tempest/scenario/fake_test.py"))
diff --git a/tempest/tests/test_ssh.py b/tempest/tests/test_ssh.py
index bf1f553..27cd6b5 100644
--- a/tempest/tests/test_ssh.py
+++ b/tempest/tests/test_ssh.py
@@ -36,13 +36,13 @@
             rsa_mock.assert_called_once_with(mock.sentinel.csio)
             cs_mock.assert_called_once_with('mykey')
             rsa_mock.reset_mock()
-            cs_mock.rest_mock()
+            cs_mock.reset_mock()
             pkey = mock.sentinel.pkey
             # Shouldn't call out to load a file from RSAKey, since
             # a sentinel isn't a basestring...
             ssh.Client('localhost', 'root', pkey=pkey)
-            rsa_mock.assert_not_called()
-            cs_mock.assert_not_called()
+            self.assertEqual(0, rsa_mock.call_count)
+            self.assertEqual(0, cs_mock.call_count)
 
     def _set_ssh_connection_mocks(self):
         client_mock = mock.MagicMock()
@@ -75,7 +75,7 @@
             password=None
         )]
         self.assertEqual(expected_connect, client_mock.connect.mock_calls)
-        s_mock.assert_not_called()
+        self.assertEqual(0, s_mock.call_count)
 
     def test_get_ssh_connection_two_attemps(self):
         c_mock, aa_mock, client_mock = self._set_ssh_connection_mocks()