Merge "Split out Neutron security group rules client"
diff --git a/setup.cfg b/setup.cfg
index 183c1fb..cc3a365 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -33,6 +33,7 @@
     tempest-account-generator = tempest.cmd.account_generator:main
     tempest = tempest.cmd.main:main
 tempest.cm =
+    account-generator = tempest.cmd.account_generator:TempestAccountGenerator
     init = tempest.cmd.init:TempestInit
     cleanup = tempest.cmd.cleanup:TempestCleanup
     run-stress = tempest.cmd.run_stress:TempestRunStress
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 7c4c30c..653a3cd 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -79,11 +79,6 @@
     def _get_server_status(self, server_id):
         return self._get_server_details(server_id)['status']
 
-    def _create_server(self, volume_backed=False):
-            server = self.create_test_server(wait_until="ACTIVE",
-                                             volume_backed=volume_backed)
-            return server['id']
-
     def _volume_clean_up(self, server_id, volume_id):
         body = self.volumes_client.show_volume(volume_id)['volume']
         if body['status'] == 'in-use':
@@ -103,7 +98,8 @@
                               volume_backed, *block* migration is not used.
         """
         # Live migrate an instance to another host
-        server_id = self._create_server(volume_backed=volume_backed)
+        server_id = self.create_test_server(wait_until="ACTIVE",
+                                            volume_backed=volume_backed)['id']
         actual_host = self._get_host_for_server(server_id)
         target_host = self._get_host_other_than(actual_host)
 
@@ -153,7 +149,7 @@
                       block_migrate_cinder_iscsi,
                       'Block Live migration not configured for iSCSI')
     def test_iscsi_volume(self):
-        server_id = self._create_server()
+        server_id = self.create_test_server(wait_until="ACTIVE")['id']
         actual_host = self._get_host_for_server(server_id)
         target_host = self._get_host_other_than(actual_host)
 
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index fd6f105..49c7318 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -15,6 +15,7 @@
 from tempest_lib import decorators
 
 from tempest.api.compute import base
+from tempest.common import compute
 from tempest.common import fixed_network
 from tempest.common.utils import data_utils
 from tempest.common import waiters
@@ -104,16 +105,14 @@
     def test_list_servers_filter_by_exist_host(self):
         # Filter the list of servers by existent host
         name = data_utils.rand_name('server')
-        flavor = self.flavor_ref
-        image_id = self.image_ref
         network = self.get_tenant_network()
         network_kwargs = fixed_network.set_networks_kwarg(network)
-        test_server = self.client.create_server(name=name, imageRef=image_id,
-                                                flavorRef=flavor,
-                                                **network_kwargs)['server']
+        # We need to create the server as an admin, so we can't use
+        # self.create_test_server() here as this method creates the server
+        # in the "primary" (i.e non-admin) tenant.
+        test_server, _ = compute.create_test_server(
+            self.os_adm, wait_until="ACTIVE", name=name, **network_kwargs)
         self.addCleanup(self.client.delete_server, test_server['id'])
-        waiters.wait_for_server_status(self.client,
-                                       test_server['id'], 'ACTIVE')
         server = self.client.show_server(test_server['id'])['server']
         self.assertEqual(server['status'], 'ACTIVE')
         hostname = server[self._host_key]
diff --git a/tempest/api/compute/admin/test_servers_on_multinodes.py b/tempest/api/compute/admin/test_servers_on_multinodes.py
new file mode 100644
index 0000000..814a876
--- /dev/null
+++ b/tempest/api/compute/admin/test_servers_on_multinodes.py
@@ -0,0 +1,68 @@
+# Copyright 2016 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.
+
+from tempest.api.compute import base
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class ServersOnMultiNodesTest(base.BaseV2ComputeAdminTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(ServersOnMultiNodesTest, cls).skip_checks()
+
+        if CONF.compute.min_compute_nodes < 2:
+            raise cls.skipException(
+                "Less than 2 compute nodes, skipping multi-nodes test.")
+
+    def _get_host(self, server_id):
+        return self.os_adm.servers_client.show_server(
+            server_id)['server']['OS-EXT-SRV-ATTR:host']
+
+    @test.idempotent_id('26a9d5df-6890-45f2-abc4-a659290cb130')
+    def test_create_servers_on_same_host(self):
+        server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+        hints = {'same_host': server01}
+        server02 = self.create_test_server(scheduler_hints=hints,
+                                           wait_until='ACTIVE')['id']
+        host01 = self._get_host(server01)
+        host02 = self._get_host(server02)
+        self.assertEqual(host01, host02)
+
+    @test.idempotent_id('cc7ca884-6e3e-42a3-a92f-c522fcf25e8e')
+    def test_create_servers_on_different_hosts(self):
+        server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+        hints = {'different_host': server01}
+        server02 = self.create_test_server(scheduler_hints=hints,
+                                           wait_until='ACTIVE')['id']
+        host01 = self._get_host(server01)
+        host02 = self._get_host(server02)
+        self.assertNotEqual(host01, host02)
+
+    @test.idempotent_id('7869cc84-d661-4e14-9f00-c18cdc89cf57')
+    def test_create_servers_on_different_hosts_with_list_of_servers(self):
+        server01 = self.create_test_server(wait_until='ACTIVE')['id']
+
+        # This scheduler-hint supports list of servers also.
+        hints = {'different_host': [server01]}
+        server02 = self.create_test_server(scheduler_hints=hints,
+                                           wait_until='ACTIVE')['id']
+        host01 = self._get_host(server01)
+        host02 = self._get_host(server02)
+        self.assertNotEqual(host01, host02)
diff --git a/tempest/api/compute/keypairs/base.py b/tempest/api/compute/keypairs/base.py
index 15f231b..ebfb724 100644
--- a/tempest/api/compute/keypairs/base.py
+++ b/tempest/api/compute/keypairs/base.py
@@ -27,10 +27,12 @@
     def _delete_keypair(self, keypair_name):
         self.client.delete_keypair(keypair_name)
 
-    def _create_keypair(self, keypair_name, pub_key=None):
+    def _create_keypair(self, keypair_name, pub_key=None, keypair_type=None):
         kwargs = {'name': keypair_name}
         if pub_key:
             kwargs.update({'public_key': pub_key})
+        if keypair_type:
+            kwargs.update({'type': keypair_type})
         body = self.client.create_keypair(**kwargs)['keypair']
         self.addCleanup(self._delete_keypair, keypair_name)
         return body
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index d10bf14..be6f615 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -19,6 +19,8 @@
 
 
 class KeyPairsV2TestJSON(base.BaseKeypairTest):
+    max_microversion = '2.1'
+
     @test.idempotent_id('1d1dbedb-d7a0-432a-9d09-83f543c3c19b')
     def test_keypairs_create_list_delete(self):
         # Keypairs created should be available in the response list
diff --git a/tempest/api/compute/keypairs/test_keypairs_v22.py b/tempest/api/compute/keypairs/test_keypairs_v22.py
new file mode 100644
index 0000000..997ef9b
--- /dev/null
+++ b/tempest/api/compute/keypairs/test_keypairs_v22.py
@@ -0,0 +1,51 @@
+# Copyright 2016 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.
+
+from tempest.api.compute.keypairs import test_keypairs
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class KeyPairsV22TestJSON(test_keypairs.KeyPairsV2TestJSON):
+    min_microversion = '2.2'
+    max_microversion = 'latest'
+
+    def _check_keypair_type(self, keypair, keypair_type):
+        if keypair_type is None:
+            keypair_type = 'ssh'
+        self.assertEqual(keypair_type, keypair['type'])
+
+    def _test_keypairs_create_list_show(self, keypair_type=None):
+        k_name = data_utils.rand_name('keypair')
+        keypair = self._create_keypair(k_name, keypair_type=keypair_type)
+        # Verify whether 'type' is present in keypair create response of
+        # version 2.2 and it is with default value 'ssh'.
+        self._check_keypair_type(keypair, keypair_type)
+        keypair_detail = self.client.show_keypair(k_name)['keypair']
+        self._check_keypair_type(keypair_detail, keypair_type)
+        fetched_list = self.client.list_keypairs()['keypairs']
+        for keypair in fetched_list:
+            # Verify whether 'type' is present in keypair list response of
+            # version 2.2 and it is with default value 'ssh'.
+            if keypair['keypair']['name'] == k_name:
+                self._check_keypair_type(keypair['keypair'], keypair_type)
+
+    @test.idempotent_id('8726fa85-7f98-4b20-af9e-f710a4f3391c')
+    def test_keypairsv22_create_list_show(self):
+        self._test_keypairs_create_list_show()
+
+    @test.idempotent_id('89d59d43-f735-441a-abcf-0601727f47b6')
+    def test_keypairsv22_create_list_show_with_type(self):
+        keypair_type = 'x509'
+        self._test_keypairs_create_list_show(keypair_type=keypair_type)
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index 4e88f65..b6d0c48 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -13,6 +13,7 @@
 #    under the License.
 
 from collections import OrderedDict
+import copy
 
 import six
 from tempest_lib import exceptions as lib_exc
@@ -27,42 +28,93 @@
 """Default templates.
 There should always be at least a master1 and a worker1 node
 group template."""
-DEFAULT_TEMPLATES = {
-    'vanilla': OrderedDict([
-        ('2.6.0', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['namenode', 'resourcemanager',
-                                       'hiveserver']
+BASE_VANILLA_DESC = {
+    'NODES': {
+        'master1': {
+            'count': 1,
+            'node_processes': ['namenode', 'resourcemanager',
+                               'hiveserver']
+        },
+        'master2': {
+            'count': 1,
+            'node_processes': ['oozie', 'historyserver',
+                               'secondarynamenode']
+        },
+        'worker1': {
+            'count': 1,
+            'node_processes': ['datanode', 'nodemanager'],
+            'node_configs': {
+                'MapReduce': {
+                    'yarn.app.mapreduce.am.resource.mb': 256,
+                    'yarn.app.mapreduce.am.command-opts': '-Xmx256m'
                 },
-                'master2': {
-                    'count': 1,
-                    'node_processes': ['oozie', 'historyserver',
-                                       'secondarynamenode']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['datanode', 'nodemanager'],
-                    'node_configs': {
-                        'MapReduce': {
-                            'yarn.app.mapreduce.am.resource.mb': 256,
-                            'yarn.app.mapreduce.am.command-opts': '-Xmx256m'
-                        },
-                        'YARN': {
-                            'yarn.scheduler.minimum-allocation-mb': 256,
-                            'yarn.scheduler.maximum-allocation-mb': 1024,
-                            'yarn.nodemanager.vmem-check-enabled': False
-                        }
-                    }
-                }
-            },
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs.replication': 1
+                'YARN': {
+                    'yarn.scheduler.minimum-allocation-mb': 256,
+                    'yarn.scheduler.maximum-allocation-mb': 1024,
+                    'yarn.nodemanager.vmem-check-enabled': False
                 }
             }
-        }),
+        }
+    },
+    'cluster_configs': {
+        'HDFS': {
+            'dfs.replication': 1
+        }
+    }
+}
+
+BASE_SPARK_DESC = {
+    'NODES': {
+        'master1': {
+            'count': 1,
+            'node_processes': ['namenode', 'master']
+        },
+        'worker1': {
+            'count': 1,
+            'node_processes': ['datanode', 'slave']
+        }
+    },
+    'cluster_configs': {
+        'HDFS': {
+            'dfs.replication': 1
+        }
+    }
+}
+
+BASE_CDH_DESC = {
+    'NODES': {
+        'master1': {
+            'count': 1,
+            'node_processes': ['CLOUDERA_MANAGER']
+        },
+        'master2': {
+            'count': 1,
+            'node_processes': ['HDFS_NAMENODE',
+                               'YARN_RESOURCEMANAGER']
+        },
+        'master3': {
+            'count': 1,
+            'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
+                               'HDFS_SECONDARYNAMENODE',
+                               'HIVE_METASTORE', 'HIVE_SERVER2']
+        },
+        'worker1': {
+            'count': 1,
+            'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
+        }
+    },
+    'cluster_configs': {
+        'HDFS': {
+            'dfs_replication': 1
+        }
+    }
+}
+
+
+DEFAULT_TEMPLATES = {
+    'vanilla': OrderedDict([
+        ('2.6.0', copy.deepcopy(BASE_VANILLA_DESC)),
+        ('2.7.1', copy.deepcopy(BASE_VANILLA_DESC)),
         ('1.2.1', {
             'NODES': {
                 'master1': {
@@ -123,81 +175,13 @@
         })
     ]),
     'spark': OrderedDict([
-        ('1.0.0', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['namenode', 'master']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['datanode', 'slave']
-                }
-            },
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs.replication': 1
-                }
-            }
-        })
+        ('1.0.0', copy.deepcopy(BASE_SPARK_DESC)),
+        ('1.3.1', copy.deepcopy(BASE_SPARK_DESC))
     ]),
     'cdh': OrderedDict([
-        ('5.3.0', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['CLOUDERA_MANAGER']
-                },
-                'master2': {
-                    'count': 1,
-                    'node_processes': ['HDFS_NAMENODE',
-                                       'YARN_RESOURCEMANAGER']
-                },
-                'master3': {
-                    'count': 1,
-                    'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
-                                       'HDFS_SECONDARYNAMENODE',
-                                       'HIVE_METASTORE', 'HIVE_SERVER2']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
-                }
-            },
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs_replication': 1
-                }
-            }
-        }),
-        ('5', {
-            'NODES': {
-                'master1': {
-                    'count': 1,
-                    'node_processes': ['CLOUDERA_MANAGER']
-                },
-                'master2': {
-                    'count': 1,
-                    'node_processes': ['HDFS_NAMENODE',
-                                       'YARN_RESOURCEMANAGER']
-                },
-                'master3': {
-                    'count': 1,
-                    'node_processes': ['OOZIE_SERVER', 'YARN_JOBHISTORY',
-                                       'HDFS_SECONDARYNAMENODE',
-                                       'HIVE_METASTORE', 'HIVE_SERVER2']
-                },
-                'worker1': {
-                    'count': 1,
-                    'node_processes': ['YARN_NODEMANAGER', 'HDFS_DATANODE']
-                }
-            },
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs_replication': 1
-                }
-            }
-        })
+        ('5.4.0', copy.deepcopy(BASE_CDH_DESC)),
+        ('5.3.0', copy.deepcopy(BASE_CDH_DESC)),
+        ('5', copy.deepcopy(BASE_CDH_DESC))
     ]),
     'mapr': OrderedDict([
         ('4.0.1.mrv2', {
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 64f3174..1a84d06 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -18,11 +18,27 @@
 from tempest.api.image import base
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
 
 
+def get_container_and_disk_format():
+    a_formats = ['ami', 'ari', 'aki']
+
+    container_format = CONF.image.container_formats[0]
+    disk_format = CONF.image.disk_formats[0]
+
+    if container_format in a_formats and container_format != disk_format:
+        msg = ("The container format and the disk format don't match. "
+               "Contaiter format: %(container)s, Disk format: %(disk)s." %
+               {'container': container_format, 'disk': disk_format})
+        raise exceptions.InvalidConfiguration(message=msg)
+
+    return container_format, disk_format
+
+
 class CreateRegisterImagesTest(base.BaseV1ImageTest):
     """Here we test the registration and creation of images."""
 
@@ -30,9 +46,10 @@
     def test_register_then_upload(self):
         # Register, then upload an image
         properties = {'prop1': 'val1'}
+        container_format, disk_format = get_container_and_disk_format()
         body = self.create_image(name='New Name',
-                                 container_format='bare',
-                                 disk_format='raw',
+                                 container_format=container_format,
+                                 disk_format=disk_format,
                                  is_public=False,
                                  properties=properties)
         self.assertIn('id', body)
@@ -52,9 +69,10 @@
     @test.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
     def test_register_remote_image(self):
         # Register a new remote image
+        container_format, disk_format = get_container_and_disk_format()
         body = self.create_image(name='New Remote Image',
-                                 container_format='bare',
-                                 disk_format='raw', is_public=False,
+                                 container_format=container_format,
+                                 disk_format=disk_format, is_public=False,
                                  location=CONF.image.http_image,
                                  properties={'key1': 'value1',
                                              'key2': 'value2'})
@@ -68,9 +86,10 @@
 
     @test.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
     def test_register_http_image(self):
+        container_format, disk_format = get_container_and_disk_format()
         body = self.create_image(name='New Http Image',
-                                 container_format='bare',
-                                 disk_format='raw', is_public=False,
+                                 container_format=container_format,
+                                 disk_format=disk_format, is_public=False,
                                  copy_from=CONF.image.http_image)
         self.assertIn('id', body)
         image_id = body.get('id')
@@ -82,10 +101,11 @@
     @test.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
     def test_register_image_with_min_ram(self):
         # Register an image with min ram
+        container_format, disk_format = get_container_and_disk_format()
         properties = {'prop1': 'val1'}
         body = self.create_image(name='New_image_with_min_ram',
-                                 container_format='bare',
-                                 disk_format='raw',
+                                 container_format=container_format,
+                                 disk_format=disk_format,
                                  is_public=False,
                                  min_ram=40,
                                  properties=properties)
@@ -103,22 +123,51 @@
     """Here we test the listing of image information"""
 
     @classmethod
+    def skip_checks(cls):
+        super(ListImagesTest, cls).skip_checks()
+        if (len(CONF.image.container_formats) < 2
+           or len(CONF.image.disk_formats) < 2):
+            skip_msg = ("%s skipped as multiple container formats "
+                        "or disk formats are not available." % cls.__name__)
+            raise cls.skipException(skip_msg)
+
+    @classmethod
     def resource_setup(cls):
         super(ListImagesTest, cls).resource_setup()
         # We add a few images here to test the listing functionality of
         # the images API
-        img1 = cls._create_remote_image('one', 'bare', 'raw')
-        img2 = cls._create_remote_image('two', 'ami', 'ami')
-        img3 = cls._create_remote_image('dup', 'bare', 'raw')
-        img4 = cls._create_remote_image('dup', 'bare', 'raw')
-        img5 = cls._create_standard_image('1', 'ami', 'ami', 42)
-        img6 = cls._create_standard_image('2', 'ami', 'ami', 142)
-        img7 = cls._create_standard_image('33', 'bare', 'raw', 142)
-        img8 = cls._create_standard_image('33', 'bare', 'raw', 142)
+        a_formats = ['ami', 'ari', 'aki']
+
+        (cls.container_format,
+         cls.container_format_alt) = CONF.image.container_formats[:2]
+        cls.disk_format, cls.disk_format_alt = CONF.image.disk_formats[:2]
+        if cls.container_format in a_formats:
+            cls.disk_format = cls.container_format
+        if cls.container_format_alt in a_formats:
+            cls.disk_format_alt = cls.container_format_alt
+
+        img1 = cls._create_remote_image('one', cls.container_format,
+                                        cls.disk_format)
+        img2 = cls._create_remote_image('two', cls.container_format_alt,
+                                        cls.disk_format_alt)
+        img3 = cls._create_remote_image('dup', cls.container_format,
+                                        cls.disk_format)
+        img4 = cls._create_remote_image('dup', cls.container_format,
+                                        cls.disk_format)
+        img5 = cls._create_standard_image('1', cls.container_format_alt,
+                                          cls.disk_format_alt, 42)
+        img6 = cls._create_standard_image('2', cls.container_format_alt,
+                                          cls.disk_format_alt, 142)
+        img7 = cls._create_standard_image('33', cls.container_format,
+                                          cls.disk_format, 142)
+        img8 = cls._create_standard_image('33', cls.container_format,
+                                          cls.disk_format, 142)
         cls.created_set = set(cls.created_images)
-        # 5x bare, 3x ami
-        cls.bare_set = set((img1, img3, img4, img7, img8))
-        cls.ami_set = set((img2, img5, img6))
+        # same container format
+        cls.same_container_format_set = set((img1, img3, img4, img7, img8))
+        # same disk format
+        cls.same_disk_format_set = set((img2, img5, img6))
+
         # 1x with size 42
         cls.size42_set = set((img5,))
         # 3x with size 142
@@ -167,22 +216,25 @@
 
     @test.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
     def test_index_disk_format(self):
-        images_list = self.client.list_images(disk_format='ami')['images']
+        images_list = self.client.list_images(
+            disk_format=self.disk_format_alt)['images']
         for image in images_list:
-            self.assertEqual(image['disk_format'], 'ami')
+            self.assertEqual(image['disk_format'], self.disk_format_alt)
         result_set = set(map(lambda x: x['id'], images_list))
-        self.assertTrue(self.ami_set <= result_set)
-        self.assertFalse(self.created_set - self.ami_set <= result_set)
+        self.assertTrue(self.same_disk_format_set <= result_set)
+        self.assertFalse(self.created_set - self.same_disk_format_set
+                         <= result_set)
 
     @test.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
     def test_index_container_format(self):
-        images_list = (self.client.list_images(container_format='bare')
-                       ['images'])
+        images_list = self.client.list_images(
+            container_format=self.container_format)['images']
         for image in images_list:
-            self.assertEqual(image['container_format'], 'bare')
+            self.assertEqual(image['container_format'], self.container_format)
         result_set = set(map(lambda x: x['id'], images_list))
-        self.assertTrue(self.bare_set <= result_set)
-        self.assertFalse(self.created_set - self.bare_set <= result_set)
+        self.assertTrue(self.same_container_format_set <= result_set)
+        self.assertFalse(self.created_set - self.same_container_format_set
+                         <= result_set)
 
     @test.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
     def test_index_max_size(self):
@@ -231,7 +283,9 @@
     @classmethod
     def resource_setup(cls):
         super(UpdateImageMetaTest, cls).resource_setup()
-        cls.image_id = cls._create_standard_image('1', 'ami', 'ami', 42)
+        container_format, disk_format = get_container_and_disk_format()
+        cls.image_id = cls._create_standard_image('1', container_format,
+                                                  disk_format, 42)
 
     @classmethod
     def _create_standard_image(cls, name, container_format,
diff --git a/tempest/api_schema/response/compute/v2_2/__init__.py b/tempest/api_schema/response/compute/v2_2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_2/__init__.py
diff --git a/tempest/api_schema/response/compute/v2_2/keypairs.py b/tempest/api_schema/response/compute/v2_2/keypairs.py
new file mode 100644
index 0000000..5d8d24d
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_2/keypairs.py
@@ -0,0 +1,41 @@
+# Copyright 2016 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.
+
+import copy
+
+from tempest.api_schema.response.compute.v2_1 import keypairs
+
+get_keypair = copy.deepcopy(keypairs.get_keypair)
+get_keypair['response_body']['properties']['keypair'][
+    'properties'].update({'type': {'type': 'string'}})
+get_keypair['response_body']['properties']['keypair'][
+    'required'].append('type')
+
+create_keypair = copy.deepcopy(keypairs.create_keypair)
+create_keypair['status_code'] = [201]
+create_keypair['response_body']['properties']['keypair'][
+    'properties'].update({'type': {'type': 'string'}})
+create_keypair['response_body']['properties']['keypair'][
+    'required'].append('type')
+
+delete_keypair = {
+    'status_code': [204],
+}
+
+list_keypairs = copy.deepcopy(keypairs.list_keypairs)
+list_keypairs['response_body']['properties']['keypairs'][
+    'items']['properties']['keypair'][
+    'properties'].update({'type': {'type': 'string'}})
+list_keypairs['response_body']['properties']['keypairs'][
+    'items']['properties']['keypair']['required'].append('type')
diff --git a/tempest/clients.py b/tempest/clients.py
index 6ec7e5c..2ff0629 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -71,6 +71,13 @@
 from tempest_lib.services.identity.v2.token_client import TokenClient
 from tempest_lib.services.identity.v3.token_client import V3TokenClient
 from tempest_lib.services.network.floating_ips_client import FloatingIPsClient
+from tempest_lib.services.network.metering_label_rules_client import \
+    MeteringLabelRulesClient
+from tempest_lib.services.network.metering_labels_client import \
+    MeteringLabelsClient
+from tempest_lib.services.network.networks_client import NetworksClient
+from tempest_lib.services.network.ports_client import PortsClient
+from tempest_lib.services.network.subnets_client import SubnetsClient
 
 from tempest.common import negative_rest_client
 from tempest import config
@@ -114,13 +121,7 @@
     MessagingClient
 from tempest.services.network.json.agents_client import AgentsClient \
     as NetworkAgentsClient
-from tempest.services.network.json.metering_label_rules_client import \
-    MeteringLabelRulesClient
-from tempest.services.network.json.metering_labels_client import \
-    MeteringLabelsClient
 from tempest.services.network.json.network_client import NetworkClient
-from tempest.services.network.json.networks_client import NetworksClient
-from tempest.services.network.json.ports_client import PortsClient
 from tempest.services.network.json.quotas_client import QuotasClient \
     as NetworkQuotasClient
 from tempest.services.network.json.security_group_rules_client import \
@@ -128,7 +129,6 @@
 from tempest.services.network.json.security_groups_client import \
     SecurityGroupsClient
 from tempest.services.network.json.subnetpools_client import SubnetpoolsClient
-from tempest.services.network.json.subnets_client import SubnetsClient
 from tempest.services.object_storage.account_client import AccountClient
 from tempest.services.object_storage.container_client import ContainerClient
 from tempest.services.object_storage.object_client import ObjectClient
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 6f74578..32d6ef1 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -85,11 +85,15 @@
 import argparse
 import netaddr
 import os
+import traceback
 
+from cliff import command
 from oslo_log import log as logging
 import tempest_lib.auth
 from tempest_lib.common.utils import data_utils
 import tempest_lib.exceptions
+from tempest_lib.services.network import networks_client
+from tempest_lib.services.network import subnets_client
 import yaml
 
 from tempest.common import identity
@@ -100,11 +104,14 @@
 from tempest.services.identity.v2.json import tenants_client
 from tempest.services.identity.v2.json import users_client
 from tempest.services.network.json import network_client
-from tempest.services.network.json import networks_client
-from tempest.services.network.json import subnets_client
 
 LOG = None
 CONF = config.CONF
+DESCRIPTION = ('Create accounts.yaml file for concurrent test runs.%s'
+               'One primary user, one alt user, '
+               'one swift admin, one stack owner '
+               'and one admin (optionally) will be created '
+               'for each concurrent thread.' % os.linesep)
 
 
 def setup_logging():
@@ -397,20 +404,7 @@
     LOG.info('%s generated successfully!' % opts.accounts)
 
 
-def get_options():
-    usage_string = ('tempest-account-generator [-h] <ARG> ...\n\n'
-                    'To see help on specific argument, do:\n'
-                    'tempest-account-generator <ARG> -h')
-    parser = argparse.ArgumentParser(
-        description='Create accounts.yaml file for concurrent test runs. '
-                    'One primary user, one alt user, '
-                    'one swift admin, one stack owner '
-                    'and one admin (optionally) will be created '
-                    'for each concurrent thread.',
-        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
-        usage=usage_string
-    )
-
+def _parser_add_args(parser):
     parser.add_argument('-c', '--config-file',
                         metavar='/etc/tempest.conf',
                         help='path to tempest config file')
@@ -447,16 +441,50 @@
                         metavar='accounts_file.yaml',
                         help='Output accounts yaml file')
 
+
+def get_options():
+    usage_string = ('tempest-account-generator [-h] <ARG> ...\n\n'
+                    'To see help on specific argument, do:\n'
+                    'tempest-account-generator <ARG> -h')
+    parser = argparse.ArgumentParser(
+        description=DESCRIPTION,
+        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+        usage=usage_string
+    )
+
+    _parser_add_args(parser)
     opts = parser.parse_args()
-    if opts.config_file:
-        config.CONF.set_config_path(opts.config_file)
     return opts
 
 
+class TempestAccountGenerator(command.Command):
+
+    def get_parser(self, prog_name):
+        parser = super(TempestAccountGenerator, self).get_parser(prog_name)
+        _parser_add_args(parser)
+        return parser
+
+    def take_action(self, parsed_args):
+        try:
+            return main(parsed_args)
+        except Exception:
+            LOG.exception("Failure generating test accounts.")
+            traceback.print_exc()
+            raise
+        return 0
+
+    def get_description(self):
+        return DESCRIPTION
+
+
 def main(opts=None):
-    if not opts:
-        opts = get_options()
     setup_logging()
+    if not opts:
+        LOG.warn("Use of: 'tempest-account-generator' is deprecated, "
+                 "please use: 'tempest account-generator'")
+        opts = get_options()
+    if opts.config_file:
+        config.CONF.set_config_path(opts.config_file)
     resources = generate_resources(opts)
     create_resources(opts, resources)
     dump_accounts(opts, resources)
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index a703e8c..8012ad7 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -122,6 +122,7 @@
 from tempest_lib.services.compute import security_group_rules_client
 from tempest_lib.services.compute import security_groups_client
 from tempest_lib.services.compute import servers_client
+from tempest_lib.services.network import subnets_client
 import yaml
 
 from tempest.common import identity
@@ -133,7 +134,6 @@
 from tempest.services.identity.v2.json import users_client
 from tempest.services.image.v2.json import images_client
 from tempest.services.network.json import network_client
-from tempest.services.network.json import subnets_client
 from tempest.services.object_storage import container_client
 from tempest.services.object_storage import object_client
 from tempest.services.telemetry.json import alarming_client
diff --git a/tempest/cmd/main.py b/tempest/cmd/main.py
index 577df9b..acd97a8 100644
--- a/tempest/cmd/main.py
+++ b/tempest/cmd/main.py
@@ -28,6 +28,7 @@
             description='Tempest cli application',
             version=version.VersionInfo('tempest').version_string(),
             command_manager=commandmanager.CommandManager('tempest.cm'),
+            deferred_help=True,
             )
 
     def initialize_app(self, argv):
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 6e6ada8..73505e6 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -29,7 +29,8 @@
 
 def create_test_server(clients, validatable=False, validation_resources=None,
                        tenant_network=None, wait_until=None,
-                       volume_backed=False, **kwargs):
+                       volume_backed=False, name=None, flavor=None,
+                       image_id=None, **kwargs):
     """Common wrapper utility returning a test server.
 
     This method is a common wrapper returning a test server that can be
@@ -48,17 +49,27 @@
 
     # TODO(jlanoux) add support of wait_until PINGABLE/SSHABLE
 
-    name = kwargs.pop('name', data_utils.rand_name(__name__ + "-instance"))
-    flavor = kwargs.pop('flavor', CONF.compute.flavor_ref)
-    image_id = kwargs.pop('image_id', CONF.compute.image_ref)
+    name = name
+    flavor = flavor
+    image_id = image_id
+
+    if name is None:
+        name = data_utils.rand_name(__name__ + "-instance")
+    if flavor is None:
+        flavor = CONF.compute.flavor_ref
+    if image_id is None:
+        image_id = CONF.compute.image_ref
 
     kwargs = fixed_network.set_networks_kwarg(
         tenant_network, kwargs) or {}
 
+    multiple_create_request = (max(kwargs.get('min_count', 0),
+                                   kwargs.get('max_count', 0)) > 1)
+
     if CONF.validation.run_validation and validatable:
         # As a first implementation, multiple pingable or sshable servers will
         # not be supported
-        if 'min_count' in kwargs or 'max_count' in kwargs:
+        if multiple_create_request:
             msg = ("Multiple pingable or sshable servers not supported at "
                    "this stage.")
             raise ValueError(msg)
@@ -112,7 +123,7 @@
 
     # handle the case of multiple servers
     servers = []
-    if 'min_count' in kwargs or 'max_count' in kwargs:
+    if multiple_create_request:
         # Get servers created which name match with name param.
         body_servers = clients.servers_client.list_servers()
         servers = \
diff --git a/tempest/config.py b/tempest/config.py
index 92123b9..6942172 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1046,7 +1046,8 @@
     cfg.StrOpt('img_dir',
                default='/opt/stack/new/devstack/files/images/'
                'cirros-0.3.1-x86_64-uec',
-               help='Directory containing image files'),
+               help='Directory containing image files',
+               deprecated_for_removal=True),
     cfg.StrOpt('img_file', deprecated_name='qcow2_img_file',
                default='cirros-0.3.1-x86_64-disk.img',
                help='Image file name'),
@@ -1060,13 +1061,16 @@
                 'Use for custom images which require them'),
     cfg.StrOpt('ami_img_file',
                default='cirros-0.3.1-x86_64-blank.img',
-               help='AMI image file name'),
+               help='AMI image file name',
+               deprecated_for_removal=True),
     cfg.StrOpt('ari_img_file',
                default='cirros-0.3.1-x86_64-initrd',
-               help='ARI image file name'),
+               help='ARI image file name',
+               deprecated_for_removal=True),
     cfg.StrOpt('aki_img_file',
                default='cirros-0.3.1-x86_64-vmlinuz',
-               help='AKI image file name'),
+               help='AKI image file name',
+               deprecated_for_removal=True),
     cfg.IntOpt(
         'large_ops_number',
         default=0,
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index 1dad3ba..88598de 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -185,7 +185,8 @@
             # the end of a method
             return
 
-        if 'self.get(' not in line:
+        if 'self.get(' not in line and ('self.show_resource(' not in line and
+                                        'self.list_resources(' not in line):
             continue
 
         if METHOD_GET_RESOURCE.match(logical_line):
@@ -211,7 +212,7 @@
             # the end of a method
             return
 
-        if 'self.delete(' not in line:
+        if 'self.delete(' not in line and 'self.delete_resource(' not in line:
             continue
 
         if METHOD_DELETE_RESOURCE.match(logical_line):
diff --git a/tempest/hacking/ignored_list_T110.txt b/tempest/hacking/ignored_list_T110.txt
index 8de3151..ce69931 100644
--- a/tempest/hacking/ignored_list_T110.txt
+++ b/tempest/hacking/ignored_list_T110.txt
@@ -6,3 +6,4 @@
 ./tempest/services/volume/base/base_qos_client.py
 ./tempest/services/volume/base/base_backups_client.py
 ./tempest/services/baremetal/base.py
+./tempest/services/network/json/network_client.py
diff --git a/tempest/hacking/ignored_list_T111.txt b/tempest/hacking/ignored_list_T111.txt
index 8017e76..8130c85 100644
--- a/tempest/hacking/ignored_list_T111.txt
+++ b/tempest/hacking/ignored_list_T111.txt
@@ -1 +1,3 @@
 ./tempest/services/baremetal/base.py
+./tempest/services/network/json/agents_client.py
+./tempest/services/network/json/quotas_client.py
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 53b2481..f4e2185 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -162,7 +162,7 @@
         self.addCleanup(client.delete_keypair, name)
         return body['keypair']
 
-    def create_server(self, name=None, image=None, flavor=None,
+    def create_server(self, name=None, image_id=None, flavor=None,
                       validatable=False, wait_until=None,
                       wait_on_delete=True, clients=None, **kwargs):
         """Wrapper utility that returns a test server.
@@ -242,7 +242,8 @@
             clients,
             tenant_network=tenant_network,
             wait_until=wait_until,
-            **kwargs)
+            name=name, flavor=flavor,
+            image_id=image_id, **kwargs)
 
         # TODO(jlanoux) Move wait_on_delete in compute.py
         if wait_on_delete:
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index ff9dabf..d9c6924 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -47,13 +47,6 @@
 
     """
 
-    def _wait_for_server_status(self, server, status):
-        server_id = server['id']
-        # Raise on error defaults to True, which is consistent with the
-        # original function from scenario tests here
-        waiters.wait_for_server_status(self.servers_client,
-                                       server_id, status)
-
     def nova_list(self):
         servers = self.servers_client.list_servers()
         # The list servers in the compute client is inconsistent...
@@ -81,7 +74,8 @@
 
     def nova_reboot(self, server):
         self.servers_client.reboot_server(server['id'], type='SOFT')
-        self._wait_for_server_status(server, 'ACTIVE')
+        waiters.wait_for_server_status(self.servers_client,
+                                       server['id'], 'ACTIVE')
 
     def check_partitions(self):
         # NOTE(andreaf) The device name may be different on different guest OS
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 81ecda0..7b88025 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -70,7 +70,7 @@
         create_kwargs.update(self._get_bdm(
             vol_id, delete_on_termination=delete_on_termination))
         return self.create_server(
-            image='',
+            image_id='',
             wait_until='ACTIVE',
             **create_kwargs)
 
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 2e22bc6..e956100 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -15,21 +15,28 @@
 
 from oslo_serialization import jsonutils as json
 
-from tempest.api_schema.response.compute.v2_1 import keypairs as schema
+from tempest.api_schema.response.compute.v2_1 import keypairs as schemav21
+from tempest.api_schema.response.compute.v2_2 import keypairs as schemav22
 from tempest.common import service_client
+from tempest.services.compute.json import base
 
 
-class KeyPairsClient(service_client.ServiceClient):
+class KeyPairsClient(base.BaseComputeClient):
+
+    schema_versions_info = [{'min': None, 'max': '2.1', 'schema': schemav21},
+                            {'min': '2.2', 'max': None, 'schema': schemav22}]
 
     def list_keypairs(self):
         resp, body = self.get("os-keypairs")
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.list_keypairs, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def show_keypair(self, keypair_name):
         resp, body = self.get("os-keypairs/%s" % keypair_name)
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.get_keypair, resp, body)
         return service_client.ResponseBody(resp, body)
 
@@ -37,10 +44,12 @@
         post_body = json.dumps({'keypair': kwargs})
         resp, body = self.post("os-keypairs", body=post_body)
         body = json.loads(body)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.create_keypair, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def delete_keypair(self, keypair_name):
         resp, body = self.delete("os-keypairs/%s" % keypair_name)
+        schema = self.get_schema(self.schema_versions_info)
         self.validate_response(schema.delete_keypair, resp, body)
         return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/image/v1/json/images_client.py b/tempest/services/image/v1/json/images_client.py
index 5b6a394..af2e68c 100644
--- a/tempest/services/image/v1/json/images_client.py
+++ b/tempest/services/image/v1/json/images_client.py
@@ -180,21 +180,27 @@
         self.expected_success(200, resp.status)
         return service_client.ResponseBody(resp, body)
 
-    def list_images(self, detail=False, properties=dict(),
-                    changes_since=None, **kwargs):
+    def list_images(self, detail=False, **kwargs):
+        """Return a list of all images filtered by input parameters.
+
+        Available params: see http://developer.openstack.org/
+                              api-ref-image-v1.html#listImage-v1
+
+        Most parameters except the following are passed to the API without
+        any changes.
+        :param changes_since: The name is changed to changes-since
+        """
         url = 'v1/images'
 
         if detail:
             url += '/detail'
 
-        params = {}
-        for key, value in properties.items():
-            params['property-%s' % key] = value
+        properties = kwargs.pop('properties', {})
+        for key, value in six.iteritems(properties):
+            kwargs['property-%s' % key] = value
 
-        kwargs.update(params)
-
-        if changes_since is not None:
-            kwargs['changes-since'] = changes_since
+        if kwargs.get('changes_since'):
+            kwargs['changes-since'] = kwargs.pop('changes_since')
 
         if len(kwargs) > 0:
             url += '?%s' % urllib.urlencode(kwargs)
diff --git a/tempest/services/network/json/metering_label_rules_client.py b/tempest/services/network/json/metering_label_rules_client.py
deleted file mode 100644
index 374a89c..0000000
--- a/tempest/services/network/json/metering_label_rules_client.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#    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.services.network.json import base
-
-
-class MeteringLabelRulesClient(base.BaseNetworkClient):
-
-    def create_metering_label_rule(self, **kwargs):
-        uri = '/metering/metering-label-rules'
-        post_data = {'metering_label_rule': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def show_metering_label_rule(self, metering_label_rule_id, **fields):
-        uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
-        return self.show_resource(uri, **fields)
-
-    def delete_metering_label_rule(self, metering_label_rule_id):
-        uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
-        return self.delete_resource(uri)
-
-    def list_metering_label_rules(self, **filters):
-        uri = '/metering/metering-label-rules'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/metering_labels_client.py b/tempest/services/network/json/metering_labels_client.py
deleted file mode 100644
index 2e5cdae..0000000
--- a/tempest/services/network/json/metering_labels_client.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#    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.services.network.json import base
-
-
-class MeteringLabelsClient(base.BaseNetworkClient):
-
-    def create_metering_label(self, **kwargs):
-        uri = '/metering/metering-labels'
-        post_data = {'metering_label': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def show_metering_label(self, metering_label_id, **fields):
-        uri = '/metering/metering-labels/%s' % metering_label_id
-        return self.show_resource(uri, **fields)
-
-    def delete_metering_label(self, metering_label_id):
-        uri = '/metering/metering-labels/%s' % metering_label_id
-        return self.delete_resource(uri)
-
-    def list_metering_labels(self, **filters):
-        uri = '/metering/metering-labels'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/networks_client.py b/tempest/services/network/json/networks_client.py
deleted file mode 100644
index 2907d44..0000000
--- a/tempest/services/network/json/networks_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#    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.services.network.json import base
-
-
-class NetworksClient(base.BaseNetworkClient):
-
-    def create_network(self, **kwargs):
-        uri = '/networks'
-        post_data = {'network': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_network(self, network_id, **kwargs):
-        uri = '/networks/%s' % network_id
-        post_data = {'network': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_network(self, network_id, **fields):
-        uri = '/networks/%s' % network_id
-        return self.show_resource(uri, **fields)
-
-    def delete_network(self, network_id):
-        uri = '/networks/%s' % network_id
-        return self.delete_resource(uri)
-
-    def list_networks(self, **filters):
-        uri = '/networks'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/ports_client.py b/tempest/services/network/json/ports_client.py
deleted file mode 100644
index d52d65e..0000000
--- a/tempest/services/network/json/ports_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#    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.services.network.json import base
-
-
-class PortsClient(base.BaseNetworkClient):
-
-    def create_port(self, **kwargs):
-        uri = '/ports'
-        post_data = {'port': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_port(self, port_id, **kwargs):
-        uri = '/ports/%s' % port_id
-        post_data = {'port': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_port(self, port_id, **fields):
-        uri = '/ports/%s' % port_id
-        return self.show_resource(uri, **fields)
-
-    def delete_port(self, port_id):
-        uri = '/ports/%s' % port_id
-        return self.delete_resource(uri)
-
-    def list_ports(self, **filters):
-        uri = '/ports'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/json/subnets_client.py b/tempest/services/network/json/subnets_client.py
deleted file mode 100644
index 957b606..0000000
--- a/tempest/services/network/json/subnets_client.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#    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.services.network.json import base
-
-
-class SubnetsClient(base.BaseNetworkClient):
-
-    def create_subnet(self, **kwargs):
-        uri = '/subnets'
-        post_data = {'subnet': kwargs}
-        return self.create_resource(uri, post_data)
-
-    def update_subnet(self, subnet_id, **kwargs):
-        uri = '/subnets/%s' % subnet_id
-        post_data = {'subnet': kwargs}
-        return self.update_resource(uri, post_data)
-
-    def show_subnet(self, subnet_id, **fields):
-        uri = '/subnets/%s' % subnet_id
-        return self.show_resource(uri, **fields)
-
-    def delete_subnet(self, subnet_id):
-        uri = '/subnets/%s' % subnet_id
-        return self.delete_resource(uri)
-
-    def list_subnets(self, **filters):
-        uri = '/subnets'
-        return self.list_resources(uri, **filters)
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index 2fbb206..ab6a7a0 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -24,7 +24,7 @@
 
     def setUp(self):
         super(JavelinUnitTest, self).setUp()
-        javelin.setup_logging()
+        javelin.LOG = mock.MagicMock()
         self.fake_client = mock.MagicMock()
         self.fake_object = mock.MagicMock()
 
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index 5cb204f..4379756 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -324,7 +324,7 @@
             'tempest.services.network.json.network_client.NetworkClient.'
             'add_router_interface_with_subnet_id')
         primary_creds = creds.get_primary_creds()
-        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.assert_called_once_with('1234', '1234')
         network = primary_creds.network
         subnet = primary_creds.subnet
         router = primary_creds.router
@@ -356,7 +356,7 @@
             'tempest.services.network.json.network_client.NetworkClient.'
             'add_router_interface_with_subnet_id')
         creds.get_primary_creds()
-        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.assert_called_once_with('1234', '1234')
         router_interface_mock.reset_mock()
         # Create alternate tenant and network
         self._mock_user_create('12345', 'fake_alt_user')
@@ -365,7 +365,7 @@
         self._mock_subnet_create(creds, '12345', 'fake_alt_subnet')
         self._mock_router_create('12345', 'fake_alt_router')
         creds.get_alt_creds()
-        router_interface_mock.called_once_with('12345', '12345')
+        router_interface_mock.assert_called_once_with('12345', '12345')
         router_interface_mock.reset_mock()
         # Create admin tenant and networks
         self._mock_user_create('123456', 'fake_admin_user')
@@ -463,7 +463,7 @@
             'tempest.services.network.json.network_client.NetworkClient.'
             'add_router_interface_with_subnet_id')
         alt_creds = creds.get_alt_creds()
-        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.assert_called_once_with('1234', '1234')
         network = alt_creds.network
         subnet = alt_creds.subnet
         router = alt_creds.router
@@ -488,7 +488,7 @@
             'add_router_interface_with_subnet_id')
         self._mock_list_roles('123456', 'admin')
         admin_creds = creds.get_admin_creds()
-        router_interface_mock.called_once_with('1234', '1234')
+        router_interface_mock.assert_called_once_with('1234', '1234')
         network = admin_creds.network
         subnet = admin_creds.subnet
         router = admin_creds.router
diff --git a/tools/check_logs.py b/tools/check_logs.py
index c8d3a1a..9b707b0 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -19,7 +19,7 @@
 import gzip
 import os
 import re
-import StringIO
+import six
 import sys
 import urllib2
 
@@ -71,7 +71,7 @@
         req = urllib2.Request(url)
         req.add_header('Accept-Encoding', 'gzip')
         page = urllib2.urlopen(req)
-        buf = StringIO.StringIO(page.read())
+        buf = six.StringIO(page.read())
         f = gzip.GzipFile(fileobj=buf)
         if scan_content(name, f.read().splitlines(), regexp, whitelist):
             logs_with_errors.append(name)
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index 4862d01..49a42fe 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -18,7 +18,7 @@
 import gzip
 import pprint
 import re
-import StringIO
+import six
 import sys
 import urllib2
 
@@ -68,7 +68,7 @@
     req = urllib2.Request(url)
     req.add_header('Accept-Encoding', 'gzip')
     page = urllib2.urlopen(req)
-    buf = StringIO.StringIO(page.read())
+    buf = six.StringIO(page.read())
     f = gzip.GzipFile(fileobj=buf)
     content = f.read()