Merge "Cleanup some details about the accounts files"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 1010ba5..2a72635 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -802,6 +802,10 @@
 # attributes ipv6_ra_mode and ipv6_address_mode (boolean value)
 #ipv6_subnet_attributes = false
 
+# Does the test environment support changing port admin state (boolean
+# value)
+#port_admin_state_change = true
+
 
 [object-storage]
 
diff --git a/requirements.txt b/requirements.txt
index bf7471e..0d7fc0d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -12,7 +12,6 @@
 python-glanceclient>=0.15.0
 python-cinderclient>=1.1.0
 python-heatclient>=0.3.0
-python-swiftclient>=2.2.0
 testrepository>=0.0.18
 oslo.concurrency>=1.8.0,<1.9.0         # Apache-2.0
 oslo.config>=1.9.3,<1.10.0  # Apache-2.0
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 3a34a2e..c4cb11a 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -102,7 +102,7 @@
         aggregate = self.client.create_aggregate(name=aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
-        body = self.client.get_aggregate(aggregate['id'])
+        body = self.client.show_aggregate(aggregate['id'])
         self.assertEqual(aggregate['name'], body['name'])
         self.assertEqual(aggregate['availability_zone'],
                          body['availability_zone'])
@@ -114,7 +114,7 @@
         self.assertEqual(meta, body["metadata"])
 
         # verify the metadata has been set
-        body = self.client.get_aggregate(aggregate['id'])
+        body = self.client.show_aggregate(aggregate['id'])
         self.assertEqual(meta, body["metadata"])
 
     @test.attr(type='gate')
@@ -198,7 +198,7 @@
         self.client.add_host(aggregate['id'], self.host)
         self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
 
-        body = self.client.get_aggregate(aggregate['id'])
+        body = self.client.show_aggregate(aggregate['id'])
         self.assertEqual(aggregate_name, body['name'])
         self.assertIsNone(body['availability_zone'])
         self.assertIn(self.host, body['hosts'])
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index f6d6ad3..882986c 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -110,7 +110,7 @@
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
 
         self.assertRaises(lib_exc.Forbidden,
-                          self.user_client.get_aggregate,
+                          self.user_client.show_aggregate,
                           aggregate['id'])
 
     @test.attr(type=['negative', 'gate'])
@@ -125,7 +125,7 @@
     def test_aggregate_get_details_with_invalid_id(self):
         # Get aggregate details with invalid id should raise exceptions.
         self.assertRaises(lib_exc.NotFound,
-                          self.client.get_aggregate, -1)
+                          self.client.show_aggregate, -1)
 
     @test.attr(type=['negative', 'gate'])
     @test.idempotent_id('0ef07828-12b4-45ba-87cc-41425faf5711')
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index eadc15a..1ec171b 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -32,12 +32,12 @@
     @test.idempotent_id('d3431479-8a09-4f76-aa2d-26dc580cb27c')
     def test_get_availability_zone_list(self):
         # List of availability zone
-        availability_zone = self.client.get_availability_zone_list()
+        availability_zone = self.client.list_availability_zones()
         self.assertTrue(len(availability_zone) > 0)
 
     @test.attr(type='gate')
     @test.idempotent_id('ef726c58-530f-44c2-968c-c7bed22d5b8c')
     def test_get_availability_zone_list_detail(self):
         # List of availability zones and available services
-        availability_zone = self.client.get_availability_zone_list_detail()
+        availability_zone = self.client.list_availability_zones(detail=True)
         self.assertTrue(len(availability_zone) > 0)
diff --git a/tempest/api/compute/admin/test_availability_zone_negative.py b/tempest/api/compute/admin/test_availability_zone_negative.py
index d6e577e..e9de628 100644
--- a/tempest/api/compute/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/admin/test_availability_zone_negative.py
@@ -36,4 +36,4 @@
         # non-administrator user
         self.assertRaises(
             lib_exc.Forbidden,
-            self.non_adm_client.get_availability_zone_list_detail)
+            self.non_adm_client.list_availability_zones, detail=True)
diff --git a/tempest/api/compute/admin/test_baremetal_nodes.py b/tempest/api/compute/admin/test_baremetal_nodes.py
index 64099c3..9b88938 100644
--- a/tempest/api/compute/admin/test_baremetal_nodes.py
+++ b/tempest/api/compute/admin/test_baremetal_nodes.py
@@ -52,5 +52,5 @@
 
         # Test getting each individually
         for node in test_nodes:
-            baremetal_node = self.client.get_baremetal_node(node['uuid'])
+            baremetal_node = self.client.show_baremetal_node(node['uuid'])
             self.assertEqual(node['uuid'], baremetal_node['id'])
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index 2be201a..4fe87ad 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -33,6 +33,6 @@
     @test.idempotent_id('3ac273d0-92d2-4632-bdfc-afbc21d4606c')
     def test_get_root_certificate(self):
         # get the root certificate
-        body = self.certificates_client.get_certificate('root')
+        body = self.certificates_client.show_certificate('root')
         self.assertIn('data', body)
         self.assertIn('private_key', body)
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index ab21ad7..52d47dd 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import StringIO
+import six
 
 from tempest_lib.common.utils import data_utils
 
@@ -51,7 +51,7 @@
                                               is_public=False)
         cls.image_id = body['id']
         cls.images.append(cls.image_id)
-        image_file = StringIO.StringIO(('*' * 1024))
+        image_file = six.StringIO(('*' * 1024))
         cls.glance_client.update_image(cls.image_id, data=image_file)
         cls.client.wait_for_image_status(cls.image_id, 'ACTIVE')
 
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 2c6d2df..430ca35 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -13,10 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import StringIO
 import time
 
 from oslo_log import log as logging
+import six
 from tempest_lib.common.utils import data_utils
 import testtools
 
@@ -59,7 +59,7 @@
             # Wait 1 second between creation and upload to ensure a delta
             # between created_at and updated_at.
             time.sleep(1)
-            image_file = StringIO.StringIO(('*' * 1024))
+            image_file = six.StringIO(('*' * 1024))
             cls.glance_client.update_image(image_id, data=image_file)
             cls.client.wait_for_image_status(image_id, 'ACTIVE')
             body = cls.client.get_image(image_id)
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index e069f6e..3a6b42d 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -156,7 +156,7 @@
 
     @test.idempotent_id('00579617-fe04-4e1c-9d08-ca7467d2e34b')
     @testtools.skipIf(CONF.service_available.neutron,
-                      "Neutron not check the security_group_id")
+                      "Neutron does not check the security group ID")
     @test.attr(type=['negative', 'smoke'])
     @test.services('network')
     def test_update_security_group_with_invalid_sg_id(self):
@@ -171,7 +171,7 @@
 
     @test.idempotent_id('cda8d8b4-59f8-4087-821d-20cf5a03b3b1')
     @testtools.skipIf(CONF.service_available.neutron,
-                      "Neutron not check the security_group_name")
+                      "Neutron does not check the security group name")
     @test.attr(type=['negative', 'smoke'])
     @test.services('network')
     def test_update_security_group_with_invalid_sg_name(self):
@@ -187,7 +187,7 @@
 
     @test.idempotent_id('97d12b1c-a610-4194-93f1-ba859e718b45')
     @testtools.skipIf(CONF.service_available.neutron,
-                      "Neutron not check the security_group_description")
+                      "Neutron does not check the security group description")
     @test.attr(type=['negative', 'smoke'])
     @test.services('network')
     def test_update_security_group_with_invalid_sg_des(self):
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index f3650ac..8d3f31c 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -32,5 +32,5 @@
     @test.idempotent_id('a8333aa2-205c-449f-a828-d38c2489bf25')
     def test_get_availability_zone_list_with_non_admin_user(self):
         # List of availability zone with non-administrator user
-        availability_zone = self.client.get_availability_zone_list()
+        availability_zone = self.client.list_availability_zones()
         self.assertTrue(len(availability_zone) > 0)
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index f9ee75b..2baf608 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import StringIO
+import six
 
 from oslo_log import log as logging
 from tempest_lib.common.utils import data_utils
@@ -75,7 +75,7 @@
                                               disk_format='raw',
                                               is_public=False)
         image_id = body['id']
-        image_file = StringIO.StringIO(('*' * 1024))
+        image_file = six.StringIO(('*' * 1024))
         body = cls.glance_client.update_image(image_id, data=image_file)
         cls.glance_client.wait_for_image_status(image_id, 'active')
         cls.image = cls.images_client.get_image(image_id)
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index 5b14071..09927fc 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -50,5 +50,5 @@
     @test.attr(type='gate')
     def test_get_extension(self):
         # get the specified extensions
-        extension = self.extensions_client.get_extension('os-consoles')
+        extension = self.extensions_client.show_extension('os-consoles')
         self.assertEqual('os-consoles', extension['alias'])
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index d91fbaa..5a903b7 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -12,14 +12,216 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from collections import OrderedDict
+
+import six
 from tempest_lib import exceptions as lib_exc
 
 from tempest import config
+from tempest import exceptions
 import tempest.test
 
 
 CONF = config.CONF
 
+"""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']
+                },
+                '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
+                }
+            }
+        }),
+        ('1.2.1', {
+            'NODES': {
+                'master1': {
+                    'count': 1,
+                    'node_processes': ['namenode', 'jobtracker']
+                },
+                'worker1': {
+                    'count': 1,
+                    'node_processes': ['datanode', 'tasktracker'],
+                    'node_configs': {
+                        'HDFS': {
+                            'Data Node Heap Size': 1024
+                        },
+                        'MapReduce': {
+                            'Task Tracker Heap Size': 1024
+                        }
+                    }
+                }
+            },
+            'cluster_configs': {
+                'HDFS': {
+                    'dfs.replication': 1
+                },
+                'MapReduce': {
+                    'mapred.map.tasks.speculative.execution': False,
+                    'mapred.child.java.opts': '-Xmx500m'
+                },
+                'general': {
+                    'Enable Swift': False
+                }
+            }
+        })
+    ]),
+    'hdp': OrderedDict([
+        ('2.0.6', {
+            'NODES': {
+                'master1': {
+                    'count': 1,
+                    'node_processes': ['NAMENODE', 'SECONDARY_NAMENODE',
+                                       'ZOOKEEPER_SERVER', 'AMBARI_SERVER',
+                                       'HISTORYSERVER', 'RESOURCEMANAGER',
+                                       'GANGLIA_SERVER', 'NAGIOS_SERVER',
+                                       'OOZIE_SERVER']
+                },
+                'worker1': {
+                    'count': 1,
+                    'node_processes': ['HDFS_CLIENT', 'DATANODE',
+                                       'YARN_CLIENT', 'ZOOKEEPER_CLIENT',
+                                       'MAPREDUCE2_CLIENT', 'NODEMANAGER',
+                                       'PIG', 'OOZIE_CLIENT']
+                }
+            },
+            'cluster_configs': {
+                'HDFS': {
+                    'dfs.replication': 1
+                }
+            }
+        })
+    ]),
+    '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
+                }
+            }
+        })
+    ]),
+    '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
+                }
+            }
+        })
+    ]),
+    'mapr': OrderedDict([
+        ('4.0.1.mrv2', {
+            'NODES': {
+                'master1': {
+                    'count': 1,
+                    'node_processes': ['CLDB', 'FileServer', 'ZooKeeper',
+                                       'NodeManager', 'ResourceManager',
+                                       'HistoryServer', 'Oozie']
+                },
+                'worker1': {
+                    'count': 1,
+                    'node_processes': ['FileServer', 'NodeManager', 'Pig']
+                }
+            },
+            'cluster_configs': {
+                'Hive': {
+                    'Hive Version': '0.13',
+                }
+            }
+        })
+    ]),
+}
+
 
 class BaseDataProcessingTest(tempest.test.BaseTestCase):
 
@@ -28,6 +230,7 @@
         super(BaseDataProcessingTest, cls).skip_checks()
         if not CONF.service_available.sahara:
             raise cls.skipException('Sahara support is required')
+        cls.default_plugin = cls._get_default_plugin()
 
     @classmethod
     def setup_credentials(cls):
@@ -43,6 +246,10 @@
     def resource_setup(cls):
         super(BaseDataProcessingTest, cls).resource_setup()
 
+        cls.default_version = cls._get_default_version()
+        if cls.default_plugin is not None and cls.default_version is None:
+            raise exceptions.InvalidConfiguration(
+                message="No known Sahara plugin version was found")
         cls.flavor_ref = CONF.compute.flavor_ref
 
         # add lists for watched resources
@@ -172,3 +379,100 @@
         cls._jobs.append(resp_body['id'])
 
         return resp_body
+
+    @classmethod
+    def _get_default_plugin(cls):
+        """Returns the default plugin used for testing."""
+        if len(CONF.data_processing_feature_enabled.plugins) == 0:
+            return None
+
+        for plugin in CONF.data_processing_feature_enabled.plugins:
+            if plugin in DEFAULT_TEMPLATES.keys():
+                break
+        else:
+            plugin = ''
+        return plugin
+
+    @classmethod
+    def _get_default_version(cls):
+        """Returns the default plugin version used for testing.
+        This is gathered separately from the plugin to allow
+        the usage of plugin name in skip_checks. This method is
+        rather invoked into resource_setup, which allows API calls
+        and exceptions.
+        """
+        if not cls.default_plugin:
+            return None
+        plugin = cls.client.get_plugin(cls.default_plugin)
+
+        for version in DEFAULT_TEMPLATES[cls.default_plugin].keys():
+            if version in plugin['versions']:
+                break
+        else:
+            version = None
+
+        return version
+
+    @classmethod
+    def get_node_group_template(cls, nodegroup='worker1'):
+        """Returns a node group template for the default plugin."""
+        try:
+            plugin_data = (
+                DEFAULT_TEMPLATES[cls.default_plugin][cls.default_version]
+            )
+            nodegroup_data = plugin_data['NODES'][nodegroup]
+            node_group_template = {
+                'description': 'Test node group template',
+                'plugin_name': cls.default_plugin,
+                'hadoop_version': cls.default_version,
+                'node_processes': nodegroup_data['node_processes'],
+                'flavor_id': cls.flavor_ref,
+                'node_configs': nodegroup_data.get('node_configs', {}),
+            }
+            return node_group_template
+        except (IndexError, KeyError):
+            return None
+
+    @classmethod
+    def get_cluster_template(cls, node_group_template_ids=None):
+        """Returns a cluster template for the default plugin.
+        node_group_template_defined contains the type and ID of pre-defined
+        node group templates that have to be used in the cluster template
+        (instead of dynamically defining them with 'node_processes').
+        """
+        if node_group_template_ids is None:
+            node_group_template_ids = {}
+        try:
+            plugin_data = (
+                DEFAULT_TEMPLATES[cls.default_plugin][cls.default_version]
+            )
+
+            all_node_groups = []
+            for ng_name, ng_data in six.iteritems(plugin_data['NODES']):
+                node_group = {
+                    'name': '%s-node' % (ng_name),
+                    'flavor_id': cls.flavor_ref,
+                    'count': ng_data['count']
+                }
+                if ng_name in node_group_template_ids.keys():
+                    # node group already defined, use it
+                    node_group['node_group_template_id'] = (
+                        node_group_template_ids[ng_name]
+                    )
+                else:
+                    # node_processes list defined on-the-fly
+                    node_group['node_processes'] = ng_data['node_processes']
+                if 'node_configs' in ng_data:
+                    node_group['node_configs'] = ng_data['node_configs']
+                all_node_groups.append(node_group)
+
+            cluster_template = {
+                'description': 'Test cluster template',
+                'plugin_name': cls.default_plugin,
+                'hadoop_version': cls.default_version,
+                'cluster_configs': plugin_data.get('cluster_configs', {}),
+                'node_groups': all_node_groups,
+            }
+            return cluster_template
+        except (IndexError, KeyError):
+            return None
diff --git a/tempest/api/data_processing/test_cluster_templates.py b/tempest/api/data_processing/test_cluster_templates.py
index 8a63c3f..cebf493 100644
--- a/tempest/api/data_processing/test_cluster_templates.py
+++ b/tempest/api/data_processing/test_cluster_templates.py
@@ -15,6 +15,7 @@
 from tempest_lib.common.utils import data_utils
 
 from tempest.api.data_processing import base as dp_base
+from tempest import exceptions
 from tempest import test
 
 
@@ -23,55 +24,30 @@
     sahara/restapi/rest_api_v1.0.html#cluster-templates
     """
     @classmethod
+    def skip_checks(cls):
+        super(ClusterTemplateTest, cls).skip_checks()
+        if cls.default_plugin is None:
+            raise cls.skipException("No Sahara plugins configured")
+
+    @classmethod
     def resource_setup(cls):
         super(ClusterTemplateTest, cls).resource_setup()
-        # create node group template
-        node_group_template = {
-            'name': data_utils.rand_name('sahara-ng-template'),
-            'description': 'Test node group template',
-            'plugin_name': 'vanilla',
-            'hadoop_version': '1.2.1',
-            'node_processes': ['datanode'],
-            'flavor_id': cls.flavor_ref,
-            'node_configs': {
-                'HDFS': {
-                    'Data Node Heap Size': 1024
-                }
-            }
-        }
-        resp_body = cls.create_node_group_template(**node_group_template)
-        node_group_template_id = resp_body['id']
 
-        cls.full_cluster_template = {
-            'description': 'Test cluster template',
-            'plugin_name': 'vanilla',
-            'hadoop_version': '1.2.1',
-            'cluster_configs': {
-                'HDFS': {
-                    'dfs.replication': 2
-                },
-                'MapReduce': {
-                    'mapred.map.tasks.speculative.execution': False,
-                    'mapred.child.java.opts': '-Xmx500m'
-                },
-                'general': {
-                    'Enable Swift': False
-                }
-            },
-            'node_groups': [
-                {
-                    'name': 'master-node',
-                    'flavor_id': cls.flavor_ref,
-                    'node_processes': ['namenode'],
-                    'count': 1
-                },
-                {
-                    'name': 'worker-node',
-                    'node_group_template_id': node_group_template_id,
-                    'count': 3
-                }
-            ]
-        }
+        # pre-define a node group templates
+        node_group_template_w = cls.get_node_group_template('worker1')
+        if node_group_template_w is None:
+            raise exceptions.InvalidConfiguration(
+                message="No known Sahara plugin was found")
+
+        node_group_template_w['name'] = data_utils.rand_name(
+            'sahara-ng-template')
+        resp_body = cls.create_node_group_template(**node_group_template_w)
+        node_group_template_id = resp_body['id']
+        configured_node_group_templates = {'worker1': node_group_template_id}
+
+        cls.full_cluster_template = cls.get_cluster_template(
+            configured_node_group_templates)
+
         # create cls.cluster_template variable to use for comparison to cluster
         # template response body. The 'node_groups' field in the response body
         # has some extra info that post body does not have. The 'node_groups'
diff --git a/tempest/api/data_processing/test_node_group_templates.py b/tempest/api/data_processing/test_node_group_templates.py
index d7381f4..4068027 100644
--- a/tempest/api/data_processing/test_node_group_templates.py
+++ b/tempest/api/data_processing/test_node_group_templates.py
@@ -19,27 +19,16 @@
 
 
 class NodeGroupTemplateTest(dp_base.BaseDataProcessingTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(NodeGroupTemplateTest, cls).skip_checks()
+        if cls.default_plugin is None:
+            raise cls.skipException("No Sahara plugins configured")
+
     @classmethod
     def resource_setup(cls):
         super(NodeGroupTemplateTest, cls).resource_setup()
-        cls.node_group_template = {
-            'description': 'Test node group template',
-            'plugin_name': 'vanilla',
-            'hadoop_version': '1.2.1',
-            'node_processes': [
-                'datanode',
-                'tasktracker'
-            ],
-            'flavor_id': cls.flavor_ref,
-            'node_configs': {
-                'HDFS': {
-                    'Data Node Heap Size': 1024
-                },
-                'MapReduce': {
-                    'Task Tracker Heap Size': 1024
-                }
-            }
-        }
 
     def _create_node_group_template(self, template_name=None):
         """Creates Node Group Template with optional name specified.
@@ -47,6 +36,10 @@
         It creates template, ensures template name and response body.
         Returns id and name of created template.
         """
+        self.node_group_template = self.get_node_group_template()
+        self.assertIsNotNone(self.node_group_template,
+                             "No known Sahara plugin was found")
+
         if not template_name:
             # generate random name if it's not specified
             template_name = data_utils.rand_name('sahara-ng-template')
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index d513b0c..74044dc 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -12,9 +12,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import cStringIO as StringIO
-
 from oslo_log import log as logging
+from six import moves
 from tempest_lib.common.utils import data_utils
 from tempest_lib import exceptions as lib_exc
 
@@ -113,7 +112,7 @@
         cls.alt_tenant_id = cls.alt_img_cli.tenant_id
 
     def _create_image(self):
-        image_file = StringIO.StringIO(data_utils.random_bytes())
+        image_file = moves.cStringIO(data_utils.random_bytes())
         image = self.create_image(container_format='bare',
                                   disk_format='raw',
                                   is_public=False,
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index bd672c9..49e167b 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -13,8 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import cStringIO as StringIO
-
+from six import moves
 from tempest_lib.common.utils import data_utils
 
 from tempest.api.image import base
@@ -46,7 +45,7 @@
             self.assertEqual(val, body.get('properties')[key])
 
         # Now try uploading an image file
-        image_file = StringIO.StringIO(data_utils.random_bytes())
+        image_file = moves.cStringIO(data_utils.random_bytes())
         body = self.client.update_image(image_id, data=image_file)
         self.assertIn('size', body)
         self.assertEqual(1024, body.get('size'))
@@ -161,7 +160,7 @@
         image. Note that the size of the new image is a random number between
         1024 and 4096
         """
-        image_file = StringIO.StringIO(data_utils.random_bytes(size))
+        image_file = moves.cStringIO(data_utils.random_bytes(size))
         name = 'New Standard Image %s' % name
         image = cls.create_image(name=name,
                                  container_format=container_format,
@@ -257,7 +256,7 @@
         Create a new standard image and return the ID of the newly-registered
         image.
         """
-        image_file = StringIO.StringIO(data_utils.random_bytes(size))
+        image_file = moves.cStringIO(data_utils.random_bytes(size))
         name = 'New Standard Image %s' % name
         image = cls.create_image(name=name,
                                  container_format=container_format,
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index a00296c..ef0b5f1 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -14,9 +14,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import cStringIO as StringIO
 import random
 
+from six import moves
 from tempest_lib.common.utils import data_utils
 
 from tempest.api.image import base
@@ -55,7 +55,7 @@
 
         # Now try uploading an image file
         file_content = data_utils.random_bytes()
-        image_file = StringIO.StringIO(file_content)
+        image_file = moves.cStringIO(file_content)
         self.client.store_image(image_id, image_file)
 
         # Now try to get image details
@@ -108,7 +108,7 @@
         image_id = body['id']
 
         # Now try uploading an image file
-        image_file = StringIO.StringIO(data_utils.random_bytes())
+        image_file = moves.cStringIO(data_utils.random_bytes())
         self.client.store_image(image_id, image_file)
 
         # Update Image
@@ -149,7 +149,7 @@
         1024 and 4096
         """
         size = random.randint(1024, 4096)
-        image_file = StringIO.StringIO(data_utils.random_bytes(size))
+        image_file = moves.cStringIO(data_utils.random_bytes(size))
         name = data_utils.rand_name('image')
         body = cls.create_image(name=name,
                                 container_format=container_format,
diff --git a/tempest/api/messaging/base.py b/tempest/api/messaging/base.py
index b3ed941..c4214f2 100644
--- a/tempest/api/messaging/base.py
+++ b/tempest/api/messaging/base.py
@@ -71,7 +71,7 @@
     @classmethod
     def check_queue_exists(cls, queue_name):
         """Wrapper utility that checks the existence of a test queue."""
-        resp, body = cls.client.get_queue(queue_name)
+        resp, body = cls.client.show_queue(queue_name)
         return resp, body
 
     @classmethod
@@ -89,13 +89,13 @@
     @classmethod
     def get_queue_stats(cls, queue_name):
         """Wrapper utility that returns the queue stats."""
-        resp, body = cls.client.get_queue_stats(queue_name)
+        resp, body = cls.client.show_queue_stats(queue_name)
         return resp, body
 
     @classmethod
     def get_queue_metadata(cls, queue_name):
         """Wrapper utility that gets a queue metadata."""
-        resp, body = cls.client.get_queue_metadata(queue_name)
+        resp, body = cls.client.show_queue_metadata(queue_name)
         return resp, body
 
     @classmethod
@@ -121,14 +121,14 @@
     @classmethod
     def get_single_message(cls, message_uri):
         """Wrapper utility that gets a single message."""
-        resp, body = cls.client.get_single_message(message_uri)
+        resp, body = cls.client.show_single_message(message_uri)
 
         return resp, body
 
     @classmethod
     def get_multiple_messages(cls, message_uri):
         """Wrapper utility that gets multiple messages."""
-        resp, body = cls.client.get_multiple_messages(message_uri)
+        resp, body = cls.client.show_multiple_messages(message_uri)
 
         return resp, body
 
diff --git a/tempest/api/messaging/test_messages.py b/tempest/api/messaging/test_messages.py
index f982f59..c8640b3 100644
--- a/tempest/api/messaging/test_messages.py
+++ b/tempest/api/messaging/test_messages.py
@@ -49,7 +49,7 @@
 
         # Get on the posted messages
         message_uri = resp['location']
-        resp, _ = self.client.get_multiple_messages(message_uri)
+        resp, _ = self.client.show_multiple_messages(message_uri)
         # The test has an assertion here, because the response cannot be 204
         # in this case (the client allows 200 or 204 for this API call).
         self.assertEqual('200', resp['status'])
@@ -74,7 +74,7 @@
         message_uri = body['resources'][0]
 
         # Get posted message
-        resp, _ = self.client.get_single_message(message_uri)
+        resp, _ = self.client.show_single_message(message_uri)
         # The test has an assertion here, because the response cannot be 204
         # in this case (the client allows 200 or 204 for this API call).
         self.assertEqual('200', resp['status'])
@@ -87,7 +87,7 @@
         message_uri = resp['location']
 
         # Get posted messages
-        resp, _ = self.client.get_multiple_messages(message_uri)
+        resp, _ = self.client.show_multiple_messages(message_uri)
         # The test has an assertion here, because the response cannot be 204
         # in this case (the client allows 200 or 204 for this API call).
         self.assertEqual('200', resp['status'])
@@ -103,7 +103,7 @@
         self.client.delete_messages(message_uri)
 
         message_uri = message_uri.replace('/messages/', '/messages?ids=')
-        resp, _ = self.client.get_multiple_messages(message_uri)
+        resp, _ = self.client.show_multiple_messages(message_uri)
         # The test has an assertion here, because the response has to be 204
         # in this case (the client allows 200 or 204 for this API call).
         self.assertEqual('204', resp['status'])
@@ -117,7 +117,7 @@
 
         # Delete multiple messages
         self.client.delete_messages(message_uri)
-        resp, _ = self.client.get_multiple_messages(message_uri)
+        resp, _ = self.client.show_multiple_messages(message_uri)
         # The test has an assertion here, because the response has to be 204
         # in this case (the client allows 200 or 204 for this API call).
         self.assertEqual('204', resp['status'])
diff --git a/tempest/api/messaging/test_queues.py b/tempest/api/messaging/test_queues.py
index c444e0b..2dac346 100644
--- a/tempest/api/messaging/test_queues.py
+++ b/tempest/api/messaging/test_queues.py
@@ -44,7 +44,7 @@
 
         self.delete_queue(queue_name)
         self.assertRaises(lib_exc.NotFound,
-                          self.client.get_queue,
+                          self.client.show_queue,
                           queue_name)
 
 
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 2091eb5..5797e7f 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -13,7 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import cStringIO as StringIO
 import hashlib
 import random
 import re
@@ -21,6 +20,7 @@
 import zlib
 
 import six
+from six import moves
 from tempest_lib.common.utils import data_utils
 
 from tempest.api.object_storage import base
@@ -216,7 +216,7 @@
         status, _, resp_headers = self.object_client.put_object_with_chunk(
             container=self.container_name,
             name=object_name,
-            contents=StringIO.StringIO(data),
+            contents=moves.cStringIO(data),
             chunk_size=512)
         self.assertHeaders(resp_headers, 'Object', 'PUT')
 
diff --git a/tempest/api/telemetry/test_telemetry_alarming_api.py b/tempest/api/telemetry/test_telemetry_alarming_api.py
index 8bc97e8..d106b28 100644
--- a/tempest/api/telemetry/test_telemetry_alarming_api.py
+++ b/tempest/api/telemetry/test_telemetry_alarming_api.py
@@ -67,13 +67,13 @@
         self.assertEqual(alarm_name, body['name'])
         self.assertDictContainsSubset(new_rule, body['threshold_rule'])
         # Get and verify details of an alarm after update
-        body = self.telemetry_client.get_alarm(alarm_id)
+        body = self.telemetry_client.show_alarm(alarm_id)
         self.assertEqual(alarm_name, body['name'])
         self.assertDictContainsSubset(new_rule, body['threshold_rule'])
         # Delete alarm and verify if deleted
         self.telemetry_client.delete_alarm(alarm_id)
         self.assertRaises(lib_exc.NotFound,
-                          self.telemetry_client.get_alarm, alarm_id)
+                          self.telemetry_client.show_alarm, alarm_id)
 
     @test.attr(type="gate")
     @test.idempotent_id('aca49486-70bb-4016-87e0-f6131374f741')
@@ -87,7 +87,7 @@
                                                       new_state)
         self.assertEqual(new_state, state.data)
         # Get alarm state and verify
-        state = self.telemetry_client.alarm_get_state(alarm['alarm_id'])
+        state = self.telemetry_client.show_alarm_state(alarm['alarm_id'])
         self.assertEqual(new_state, state.data)
 
     @test.attr(type="gate")
@@ -106,4 +106,4 @@
         # Verify alarm delete
         self.telemetry_client.delete_alarm(alarm_id)
         self.assertRaises(lib_exc.NotFound,
-                          self.telemetry_client.get_alarm, alarm_id)
+                          self.telemetry_client.show_alarm, alarm_id)
diff --git a/tempest/api_schema/response/compute/servers.py b/tempest/api_schema/response/compute/servers.py
deleted file mode 100644
index 3950173..0000000
--- a/tempest/api_schema/response/compute/servers.py
+++ /dev/null
@@ -1,238 +0,0 @@
-# Copyright 2014 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 import parameter_types
-
-get_password = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'password': {'type': 'string'}
-        },
-        'required': ['password']
-    }
-}
-
-get_vnc_console = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'console': {
-                'type': 'object',
-                'properties': {
-                    'type': {'type': 'string'},
-                    'url': {
-                        'type': 'string',
-                        'format': 'uri'
-                    }
-                },
-                'required': ['type', 'url']
-            }
-        },
-        'required': ['console']
-    }
-}
-
-common_show_server = {
-    'type': 'object',
-    'properties': {
-        'id': {'type': 'string'},
-        'name': {'type': 'string'},
-        'status': {'type': 'string'},
-        'image': {'oneOf': [
-            {'type': 'object',
-                'properties': {
-                    'id': {'type': 'string'},
-                    'links': parameter_types.links
-                },
-                'required': ['id', 'links']},
-            {'type': ['string', 'null']}
-        ]},
-        'flavor': {
-            'type': 'object',
-            'properties': {
-                'id': {'type': 'string'},
-                'links': parameter_types.links
-            },
-            'required': ['id', 'links']
-        },
-        'fault': {
-            'type': 'object',
-            'properties': {
-                'code': {'type': 'integer'},
-                'created': {'type': 'string'},
-                'message': {'type': 'string'},
-                'details': {'type': 'string'},
-            },
-            # NOTE(gmann): 'details' is not necessary to be present
-            #  in the 'fault'. So it is not defined as 'required'.
-            'required': ['code', 'created', 'message']
-        },
-        'user_id': {'type': 'string'},
-        'tenant_id': {'type': 'string'},
-        'created': {'type': 'string'},
-        'updated': {'type': 'string'},
-        'progress': {'type': 'integer'},
-        'metadata': {'type': 'object'},
-        'links': parameter_types.links,
-        'addresses': parameter_types.addresses,
-    },
-    # NOTE(GMann): 'progress' attribute is present in the response
-    # only when server's status is one of the progress statuses
-    # ("ACTIVE","BUILD", "REBUILD", "RESIZE","VERIFY_RESIZE")
-    # 'fault' attribute is present in the response
-    # only when server's status is one of the  "ERROR", "DELETED".
-    # So they are not defined as 'required'.
-    'required': ['id', 'name', 'status', 'image', 'flavor',
-                 'user_id', 'tenant_id', 'created', 'updated',
-                 'metadata', 'links', 'addresses']
-}
-
-base_update_get_server = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'server': common_show_server
-        },
-        'required': ['server']
-    }
-}
-
-delete_server = {
-    'status_code': [204],
-}
-
-set_server_metadata = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'metadata': {
-                'type': 'object',
-                'patternProperties': {
-                    '^.+$': {'type': 'string'}
-                }
-            }
-        },
-        'required': ['metadata']
-    }
-}
-
-list_server_metadata = copy.deepcopy(set_server_metadata)
-
-update_server_metadata = copy.deepcopy(set_server_metadata)
-
-delete_server_metadata_item = {
-    'status_code': [204]
-}
-
-list_servers = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'servers': {
-                'type': 'array',
-                'items': {
-                    'type': 'object',
-                    'properties': {
-                        'id': {'type': 'string'},
-                        'links': parameter_types.links,
-                        'name': {'type': 'string'}
-                    },
-                    'required': ['id', 'links', 'name']
-                }
-            },
-            'servers_links': parameter_types.links
-        },
-        # NOTE(gmann): servers_links attribute is not necessary to be
-        # present always So it is not 'required'.
-        'required': ['servers']
-    }
-}
-
-server_actions_common_schema = {
-    'status_code': [202]
-}
-
-server_actions_delete_password = {
-    'status_code': [204]
-}
-
-get_console_output = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'output': {'type': 'string'}
-        },
-        'required': ['output']
-    }
-}
-
-common_instance_actions = {
-    'type': 'object',
-    'properties': {
-        'action': {'type': 'string'},
-        'request_id': {'type': 'string'},
-        'user_id': {'type': 'string'},
-        'project_id': {'type': 'string'},
-        'start_time': {'type': 'string'},
-        'message': {'type': ['string', 'null']}
-    },
-    'required': ['action', 'request_id', 'user_id', 'project_id',
-                 'start_time', 'message']
-}
-
-instance_action_events = {
-    'type': 'array',
-    'items': {
-        'type': 'object',
-        'properties': {
-            'event': {'type': 'string'},
-            'start_time': {'type': 'string'},
-            'finish_time': {'type': 'string'},
-            'result': {'type': 'string'},
-            'traceback': {'type': ['string', 'null']}
-        },
-        'required': ['event', 'start_time', 'finish_time', 'result',
-                     'traceback']
-    }
-}
-
-common_get_instance_action = copy.deepcopy(common_instance_actions)
-
-common_get_instance_action['properties'].update({
-    'events': instance_action_events})
-# 'events' does not come in response body always so it is not
-# defined as 'required'
-
-base_list_servers_detail = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'servers': {
-                'type': 'array',
-                'items': common_show_server
-            }
-        },
-        'required': ['servers']
-    }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/servers.py b/tempest/api_schema/response/compute/v2_1/servers.py
index ebee697..726f9b1 100644
--- a/tempest/api_schema/response/compute/v2_1/servers.py
+++ b/tempest/api_schema/response/compute/v2_1/servers.py
@@ -15,7 +15,6 @@
 import copy
 
 from tempest.api_schema.response.compute import parameter_types
-from tempest.api_schema.response.compute import servers
 
 create_server = {
     'status_code': [202],
@@ -46,24 +45,110 @@
 create_server_with_admin_pass['response_body']['properties']['server'][
     'required'].append('adminPass')
 
-update_server = copy.deepcopy(servers.base_update_get_server)
-update_server['response_body']['properties']['server']['properties'].update({
-    'hostId': {'type': 'string'},
-    'OS-DCF:diskConfig': {'type': 'string'},
-    'accessIPv4': parameter_types.access_ip_v4,
-    'accessIPv6': parameter_types.access_ip_v6
-})
-update_server['response_body']['properties']['server']['required'].append(
-    # NOTE: OS-DCF:diskConfig and accessIPv4/v6 are API
-    # extensions, and some environments return a response
-    # without these attributes. So they are not 'required'.
-    'hostId'
-)
+list_servers = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'servers': {
+                'type': 'array',
+                'items': {
+                    'type': 'object',
+                    'properties': {
+                        'id': {'type': 'string'},
+                        'links': parameter_types.links,
+                        'name': {'type': 'string'}
+                    },
+                    'required': ['id', 'links', 'name']
+                }
+            },
+            'servers_links': parameter_types.links
+        },
+        # NOTE(gmann): servers_links attribute is not necessary to be
+        # present always So it is not 'required'.
+        'required': ['servers']
+    }
+}
 
-get_server = copy.deepcopy(servers.base_update_get_server)
-get_server['response_body']['properties']['server']['properties'].update({
+delete_server = {
+    'status_code': [204],
+}
+
+common_show_server = {
+    'type': 'object',
+    'properties': {
+        'id': {'type': 'string'},
+        'name': {'type': 'string'},
+        'status': {'type': 'string'},
+        'image': {'oneOf': [
+            {'type': 'object',
+                'properties': {
+                    'id': {'type': 'string'},
+                    'links': parameter_types.links
+                },
+                'required': ['id', 'links']},
+            {'type': ['string', 'null']}
+        ]},
+        'flavor': {
+            'type': 'object',
+            'properties': {
+                'id': {'type': 'string'},
+                'links': parameter_types.links
+            },
+            'required': ['id', 'links']
+        },
+        'fault': {
+            'type': 'object',
+            'properties': {
+                'code': {'type': 'integer'},
+                'created': {'type': 'string'},
+                'message': {'type': 'string'},
+                'details': {'type': 'string'},
+            },
+            # NOTE(gmann): 'details' is not necessary to be present
+            #  in the 'fault'. So it is not defined as 'required'.
+            'required': ['code', 'created', 'message']
+        },
+        'user_id': {'type': 'string'},
+        'tenant_id': {'type': 'string'},
+        'created': {'type': 'string'},
+        'updated': {'type': 'string'},
+        'progress': {'type': 'integer'},
+        'metadata': {'type': 'object'},
+        'links': parameter_types.links,
+        'addresses': parameter_types.addresses,
+        'hostId': {'type': 'string'},
+        'OS-DCF:diskConfig': {'type': 'string'},
+        'accessIPv4': parameter_types.access_ip_v4,
+        'accessIPv6': parameter_types.access_ip_v6
+    },
+    # NOTE(GMann): 'progress' attribute is present in the response
+    # only when server's status is one of the progress statuses
+    # ("ACTIVE","BUILD", "REBUILD", "RESIZE","VERIFY_RESIZE")
+    # 'fault' attribute is present in the response
+    # only when server's status is one of the  "ERROR", "DELETED".
+    # OS-DCF:diskConfig and accessIPv4/v6 are API
+    # extensions, and some environments return a response
+    # without these attributes.So these are not defined as 'required'.
+    'required': ['id', 'name', 'status', 'image', 'flavor',
+                 'user_id', 'tenant_id', 'created', 'updated',
+                 'metadata', 'links', 'addresses', 'hostId']
+}
+
+update_server = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'server': common_show_server
+        },
+        'required': ['server']
+    }
+}
+
+server_detail = copy.deepcopy(common_show_server)
+server_detail['properties'].update({
     'key_name': {'type': ['string', 'null']},
-    'hostId': {'type': 'string'},
     'security_groups': {'type': 'array'},
 
     # NOTE: Non-admin users also can see "OS-SRV-USG" and "OS-EXT-AZ"
@@ -81,27 +166,64 @@
     'OS-EXT-SRV-ATTR:instance_name': {'type': 'string'},
     'OS-EXT-SRV-ATTR:hypervisor_hostname': {'type': ['string', 'null']},
     'os-extended-volumes:volumes_attached': {'type': 'array'},
-    'OS-DCF:diskConfig': {'type': 'string'},
-    'accessIPv4': parameter_types.access_ip_v4,
-    'accessIPv6': parameter_types.access_ip_v6,
     'config_drive': {'type': 'string'}
 })
-get_server['response_body']['properties']['server']['required'].append(
-    # NOTE: OS-SRV-USG, OS-EXT-AZ, OS-EXT-STS, OS-EXT-SRV-ATTR,
-    # os-extended-volumes, OS-DCF and accessIPv4/v6 are API
-    # extension, and some environments return a response without
-    # these attributes. So they are not 'required'.
-    'hostId'
-)
+server_detail['properties']['addresses']['patternProperties'][
+    '^[a-zA-Z0-9-_.]+$']['items']['properties'].update({
+        'OS-EXT-IPS:type': {'type': 'string'},
+        'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address})
 # NOTE(gmann): Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr
 # attributes in server address. Those are API extension,
 # and some environments return a response without
 # these attributes. So they are not 'required'.
-get_server['response_body']['properties']['server']['properties'][
-    'addresses']['patternProperties']['^[a-zA-Z0-9-_.]+$']['items'][
-    'properties'].update({
-        'OS-EXT-IPS:type': {'type': 'string'},
-        'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address})
+
+get_server = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'server': server_detail
+        },
+        'required': ['server']
+    }
+}
+
+list_servers_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'servers': {
+                'type': 'array',
+                'items': server_detail
+            },
+            'servers_links': parameter_types.links
+        },
+        # NOTE(gmann): servers_links attribute is not necessary to be
+        # present always So it is not 'required'.
+        'required': ['servers']
+    }
+}
+
+rebuild_server = copy.deepcopy(update_server)
+rebuild_server['status_code'] = [202]
+
+rebuild_server_with_admin_pass = copy.deepcopy(rebuild_server)
+rebuild_server_with_admin_pass['response_body']['properties']['server'][
+    'properties'].update({'adminPass': {'type': 'string'}})
+rebuild_server_with_admin_pass['response_body']['properties']['server'][
+    'required'].append('adminPass')
+
+rescue_server = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'adminPass': {'type': 'string'}
+        },
+        'required': ['adminPass']
+    }
+}
 
 list_virtual_interfaces = {
     'status_code': [200],
@@ -174,30 +296,11 @@
     'volumeAttachments']['items']['properties'].update(
     {'serverId': {'type': 'string'}})
 
-set_get_server_metadata_item = {
-    'status_code': [200],
-    'response_body': {
-        'type': 'object',
-        'properties': {
-            'meta': {
-                'type': 'object',
-                'patternProperties': {
-                    '^.+$': {'type': 'string'}
-                }
-            }
-        },
-        'required': ['meta']
-    }
-}
-
 list_addresses_by_network = {
     'status_code': [200],
     'response_body': parameter_types.addresses
 }
 
-server_actions_confirm_resize = copy.deepcopy(
-    servers.server_actions_delete_password)
-
 list_addresses = {
     'status_code': [200],
     'response_body': {
@@ -258,10 +361,36 @@
     }
 }
 
-instance_actions_object = copy.deepcopy(servers.common_instance_actions)
-instance_actions_object[
-    'properties'].update({'instance_uuid': {'type': 'string'}})
-instance_actions_object['required'].extend(['instance_uuid'])
+instance_actions = {
+    'type': 'object',
+    'properties': {
+        'action': {'type': 'string'},
+        'request_id': {'type': 'string'},
+        'user_id': {'type': 'string'},
+        'project_id': {'type': 'string'},
+        'start_time': {'type': 'string'},
+        'message': {'type': ['string', 'null']},
+        'instance_uuid': {'type': 'string'}
+    },
+    'required': ['action', 'request_id', 'user_id', 'project_id',
+                 'start_time', 'message', 'instance_uuid']
+}
+
+instance_action_events = {
+    'type': 'array',
+    'items': {
+        'type': 'object',
+        'properties': {
+            'event': {'type': 'string'},
+            'start_time': {'type': 'string'},
+            'finish_time': {'type': 'string'},
+            'result': {'type': 'string'},
+            'traceback': {'type': ['string', 'null']}
+        },
+        'required': ['event', 'start_time', 'finish_time', 'result',
+                     'traceback']
+    }
+}
 
 list_instance_actions = {
     'status_code': [200],
@@ -270,93 +399,120 @@
         'properties': {
             'instanceActions': {
                 'type': 'array',
-                'items': instance_actions_object
+                'items': instance_actions
             }
         },
         'required': ['instanceActions']
     }
 }
 
-get_instance_actions_object = copy.deepcopy(servers.common_get_instance_action)
-get_instance_actions_object[
-    'properties'].update({'instance_uuid': {'type': 'string'}})
-get_instance_actions_object['required'].extend(['instance_uuid'])
+instance_actions_with_events = copy.deepcopy(instance_actions)
+instance_actions_with_events['properties'].update({
+    'events': instance_action_events})
+# 'events' does not come in response body always so it is not
+# defined as 'required'
 
 get_instance_action = {
     'status_code': [200],
     'response_body': {
         'type': 'object',
         'properties': {
-            'instanceAction': get_instance_actions_object
+            'instanceAction': instance_actions_with_events
         },
         'required': ['instanceAction']
     }
 }
 
-list_servers_detail = copy.deepcopy(servers.base_list_servers_detail)
-list_servers_detail['response_body']['properties']['servers']['items'][
-    'properties'].update({
-        'key_name': {'type': ['string', 'null']},
-        'hostId': {'type': 'string'},
-        'OS-DCF:diskConfig': {'type': 'string'},
-        'security_groups': {'type': 'array'},
-
-        # NOTE: Non-admin users also can see "OS-SRV-USG" and "OS-EXT-AZ"
-        # attributes.
-        'OS-SRV-USG:launched_at': {'type': ['string', 'null']},
-        'OS-SRV-USG:terminated_at': {'type': ['string', 'null']},
-        'OS-EXT-AZ:availability_zone': {'type': 'string'},
-
-        # NOTE: Admin users only can see "OS-EXT-STS" and "OS-EXT-SRV-ATTR"
-        # attributes.
-        'OS-EXT-STS:task_state': {'type': ['string', 'null']},
-        'OS-EXT-STS:vm_state': {'type': 'string'},
-        'OS-EXT-STS:power_state': {'type': 'integer'},
-        'OS-EXT-SRV-ATTR:host': {'type': ['string', 'null']},
-        'OS-EXT-SRV-ATTR:instance_name': {'type': 'string'},
-        'OS-EXT-SRV-ATTR:hypervisor_hostname': {'type': ['string', 'null']},
-        'os-extended-volumes:volumes_attached': {'type': 'array'},
-        'accessIPv4': parameter_types.access_ip_v4,
-        'accessIPv6': parameter_types.access_ip_v6,
-        'config_drive': {'type': 'string'}
-    })
-# NOTE(GMann): OS-SRV-USG, OS-EXT-AZ, OS-EXT-STS, OS-EXT-SRV-ATTR,
-# os-extended-volumes, OS-DCF and accessIPv4/v6 are API
-# extensions, and some environments return a response without
-# these attributes. So they are not 'required'.
-list_servers_detail['response_body']['properties']['servers']['items'][
-    'required'].append('hostId')
-# NOTE(gmann): Update OS-EXT-IPS:type and OS-EXT-IPS-MAC:mac_addr
-# attributes in server address. Those are API extension,
-# and some environments return a response without
-# these attributes. So they are not 'required'.
-list_servers_detail['response_body']['properties']['servers']['items'][
-    'properties']['addresses']['patternProperties']['^[a-zA-Z0-9-_.]+$'][
-    'items']['properties'].update({
-        'OS-EXT-IPS:type': {'type': 'string'},
-        'OS-EXT-IPS-MAC:mac_addr': parameter_types.mac_address})
-# Defining 'servers_links' attributes for V2 server schema
-list_servers_detail['response_body'][
-    'properties'].update({'servers_links': parameter_types.links})
-# NOTE(gmann): servers_links attribute is not necessary to be
-# present always So it is not 'required'.
-
-rebuild_server = copy.deepcopy(update_server)
-rebuild_server['status_code'] = [202]
-
-rebuild_server_with_admin_pass = copy.deepcopy(rebuild_server)
-rebuild_server_with_admin_pass['response_body']['properties']['server'][
-    'properties'].update({'adminPass': {'type': 'string'}})
-rebuild_server_with_admin_pass['response_body']['properties']['server'][
-    'required'].append('adminPass')
-
-rescue_server = {
+get_password = {
     'status_code': [200],
     'response_body': {
         'type': 'object',
         'properties': {
-            'adminPass': {'type': 'string'}
+            'password': {'type': 'string'}
         },
-        'required': ['adminPass']
+        'required': ['password']
     }
 }
+
+get_vnc_console = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'console': {
+                'type': 'object',
+                'properties': {
+                    'type': {'type': 'string'},
+                    'url': {
+                        'type': 'string',
+                        'format': 'uri'
+                    }
+                },
+                'required': ['type', 'url']
+            }
+        },
+        'required': ['console']
+    }
+}
+
+get_console_output = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'output': {'type': 'string'}
+        },
+        'required': ['output']
+    }
+}
+
+set_server_metadata = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'metadata': {
+                'type': 'object',
+                'patternProperties': {
+                    '^.+$': {'type': 'string'}
+                }
+            }
+        },
+        'required': ['metadata']
+    }
+}
+
+list_server_metadata = copy.deepcopy(set_server_metadata)
+
+update_server_metadata = copy.deepcopy(set_server_metadata)
+
+delete_server_metadata_item = {
+    'status_code': [204]
+}
+
+set_get_server_metadata_item = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'meta': {
+                'type': 'object',
+                'patternProperties': {
+                    '^.+$': {'type': 'string'}
+                }
+            }
+        },
+        'required': ['meta']
+    }
+}
+
+server_actions_common_schema = {
+    'status_code': [202]
+}
+
+server_actions_delete_password = {
+    'status_code': [204]
+}
+
+server_actions_confirm_resize = copy.deepcopy(
+    server_actions_delete_password)
diff --git a/tempest/api_schema/response/compute/version.py b/tempest/api_schema/response/compute/version.py
index 32c6d96..6579c63 100644
--- a/tempest/api_schema/response/compute/version.py
+++ b/tempest/api_schema/response/compute/version.py
@@ -45,8 +45,12 @@
                         }
                     },
                     'status': {'type': 'string'},
-                    'updated': {'type': 'string', 'format': 'date-time'}
+                    'updated': {'type': 'string', 'format': 'date-time'},
+                    'version': {'type': 'string'},
+                    'min_version': {'type': 'string'}
                 },
+                # NOTE: version and min_version have been added since Kilo,
+                # so they should not be required.
                 'required': ['id', 'links', 'media-types', 'status', 'updated']
             }
         },
diff --git a/tempest/cli/simple_read_only/object_storage/__init__.py b/tempest/cli/simple_read_only/object_storage/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/object_storage/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/object_storage/test_swift.py b/tempest/cli/simple_read_only/object_storage/test_swift.py
deleted file mode 100644
index 7201eab..0000000
--- a/tempest/cli/simple_read_only/object_storage/test_swift.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright 2014 OpenStack Foundation
-# 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 re
-
-from tempest_lib import exceptions
-
-from tempest import cli
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-
-class SimpleReadOnlySwiftClientTest(cli.ClientTestBase):
-    """Basic, read-only tests for Swift CLI client.
-
-    Checks return values and output of read-only commands.
-    These tests do not presume any content, nor do they create
-    their own. They only verify the structure of output if present.
-    """
-
-    @classmethod
-    def resource_setup(cls):
-        if not CONF.service_available.swift:
-            msg = ("%s skipped as Swift is not available" % cls.__name__)
-            raise cls.skipException(msg)
-        super(SimpleReadOnlySwiftClientTest, cls).resource_setup()
-
-    def swift(self, *args, **kwargs):
-        return self.clients.swift(
-            *args, endpoint_type=CONF.object_storage.endpoint_type, **kwargs)
-
-    @test.idempotent_id('74360cdc-e7ec-493f-8a87-2b65f4d54aa3')
-    def test_swift_fake_action(self):
-        self.assertRaises(exceptions.CommandFailed,
-                          self.swift,
-                          'this-does-not-exist')
-
-    @test.idempotent_id('809ec373-828e-4279-8df6-9d4db81c7909')
-    def test_swift_list(self):
-        self.swift('list')
-
-    @test.idempotent_id('325d5fe4-e5ab-4f52-aec4-357533f24fa1')
-    def test_swift_stat(self):
-        output = self.swift('stat')
-        entries = ['Account', 'Containers', 'Objects', 'Bytes', 'Content-Type',
-                   'X-Timestamp', 'X-Trans-Id']
-        for entry in entries:
-            self.assertTrue(entry in output)
-
-    @test.idempotent_id('af1483e1-dafd-4552-a39b-b9d337df808b')
-    def test_swift_capabilities(self):
-        output = self.swift('capabilities')
-        entries = ['account_listing_limit', 'container_listing_limit',
-                   'max_file_size', 'Additional middleware']
-        for entry in entries:
-            self.assertTrue(entry in output)
-
-    @test.idempotent_id('29c83a64-8eb7-418c-a39b-c70cefa5b695')
-    def test_swift_help(self):
-        help_text = self.swift('', flags='--help')
-        lines = help_text.split('\n')
-        self.assertFirstLineStartsWith(lines, 'Usage: swift')
-
-        commands = []
-        cmds_start = lines.index('Positional arguments:')
-        cmds_end = lines.index('Examples:')
-        command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)')
-        for line in lines[cmds_start:cmds_end]:
-            match = command_pattern.match(line)
-            if match:
-                commands.append(match.group(1))
-        commands = set(commands)
-        wanted_commands = set(('stat', 'list', 'delete',
-                               'download', 'post', 'upload'))
-        self.assertFalse(wanted_commands - commands)
-
-    # Optional arguments:
-
-    @test.idempotent_id('2026be82-4e53-4414-a828-f1c894b8cf0f')
-    def test_swift_version(self):
-        self.swift('', flags='--version')
-
-    @test.idempotent_id('0ae6172e-3df7-42b8-a987-d42609ada6ed')
-    def test_swift_debug_list(self):
-        self.swift('list', flags='--debug')
-
-    @test.idempotent_id('1bdf5dd0-7df5-446c-a124-2b0703a5d199')
-    def test_swift_retries_list(self):
-        self.swift('list', flags='--retries 3')
-
-    @test.idempotent_id('64eae749-8fbd-4d85-bc7f-f706d3581c6f')
-    def test_swift_region_list(self):
-        region = CONF.object_storage.region
-        if not region:
-            region = CONF.identity.region
-        self.swift('list', flags='--os-region-name ' + region)
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index acf6d4f..93c8bcf 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -180,12 +180,20 @@
             useable_hashes = hashes
         return useable_hashes
 
+    def _sanitize_creds(self, creds):
+        temp_creds = creds.copy()
+        temp_creds.pop('password')
+        return temp_creds
+
     def _get_creds(self, roles=None):
         if self.use_default_creds:
             raise exceptions.InvalidConfiguration(
                 "Account file %s doesn't exist" % CONF.auth.test_accounts_file)
         useable_hashes = self._get_match_hash_list(roles)
         free_hash = self._get_free_hash(useable_hashes)
+        clean_creds = self._sanitize_creds(
+            self.hash_dict['creds'][free_hash])
+        LOG.info('%s allocated creds:\n%s' % (self.name, clean_creds))
         return self._wrap_creds_with_network(free_hash)
 
     @lockutils.synchronized('test_accounts_io', external=True)
@@ -216,7 +224,9 @@
 
     def remove_credentials(self, creds):
         _hash = self.get_hash(creds)
+        clean_creds = self._sanitize_creds(self.hash_dict['creds'][_hash])
         self.remove_hash(_hash)
+        LOG.info("%s returned allocated creds:\n%s" % (self.name, clean_creds))
 
     def get_primary_creds(self):
         if self.isolated_creds.get('primary'):
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index c6b8ba3..ee07e73 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -22,13 +22,13 @@
 import posixpath
 import re
 import socket
-import StringIO
 import struct
 import urlparse
 
 
 import OpenSSL
 from oslo_log import log as logging
+import six
 from six import moves
 from tempest_lib import exceptions as lib_exc
 
@@ -129,7 +129,7 @@
         # Read body into string if it isn't obviously image data
         if resp.getheader('content-type', None) != 'application/octet-stream':
             body_str = ''.join([body_chunk for body_chunk in body_iter])
-            body_iter = StringIO.StringIO(body_str)
+            body_iter = six.StringIO(body_str)
             self._log_response(resp, None)
         else:
             self._log_response(resp, body_iter)
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
index fe67ff8..d0e484c 100644
--- a/tempest/common/ssh.py
+++ b/tempest/common/ssh.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-
-import cStringIO
 import select
 import socket
 import time
@@ -22,6 +20,7 @@
 
 from oslo_log import log as logging
 import six
+from six import moves
 
 from tempest import exceptions
 
@@ -43,7 +42,7 @@
         self.password = password
         if isinstance(pkey, six.string_types):
             pkey = paramiko.RSAKey.from_private_key(
-                cStringIO.StringIO(str(pkey)))
+                moves.cStringIO(str(pkey)))
         self.pkey = pkey
         self.look_for_keys = look_for_keys
         self.key_filename = key_filename
diff --git a/tempest/config.py b/tempest/config.py
index 6b8113e..bcbe41f 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -506,6 +506,10 @@
                      "the extended IPv6 attributes ipv6_ra_mode "
                      "and ipv6_address_mode"
                 ),
+    cfg.BoolOpt('port_admin_state_change',
+                default=True,
+                help="Does the test environment support changing"
+                     " port admin state"),
 ]
 
 messaging_group = cfg.OptGroup(name='messaging',
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index d2c41f0..cc152d2 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -319,10 +319,18 @@
 
         if username is None:
             username = CONF.scenario.ssh_user
-        if private_key is None:
-            private_key = self.keypair['private_key']
+        # Set this with 'keypair' or others to log in with keypair or
+        # username/password.
+        if CONF.compute.ssh_auth_method == 'keypair':
+            password = None
+            if private_key is None:
+                private_key = self.keypair['private_key']
+        else:
+            password = CONF.compute.image_ssh_password
+            private_key = None
         linux_client = remote_client.RemoteClient(ip, username,
-                                                  pkey=private_key)
+                                                  pkey=private_key,
+                                                  password=password)
         try:
             linux_client.validate_authentication()
         except Exception:
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index c5e8012..b1d3418 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -80,7 +80,7 @@
 
     def _check_aggregate_details(self, aggregate, aggregate_name, azone,
                                  hosts, metadata):
-        aggregate = self.aggregates_client.get_aggregate(aggregate['id'])
+        aggregate = self.aggregates_client.show_aggregate(aggregate['id'])
         self.assertEqual(aggregate_name, aggregate['name'])
         self.assertEqual(azone, aggregate['availability_zone'])
         self.assertEqual(hosts, aggregate['hosts'])
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 0d17048..8f37d74 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -185,7 +185,7 @@
             # Start netcat
             start_server = ('while true; do '
                             'sudo nc -ll -p %(port)s -e sh /tmp/%(script)s; '
-                            'done &')
+                            'done > /dev/null &')
             cmd = start_server % {'port': self.port1,
                                   'script': 'script1'}
             ssh_client.exec_command(cmd)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 2c9e845..b97ad0b 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -590,6 +590,9 @@
     @testtools.skipIf(CONF.baremetal.driver_enabled,
                       'admin_state of instance ports cannot be altered '
                       'for baremetal nodes')
+    @testtools.skipUnless(CONF.network_feature_enabled.port_admin_state_change,
+                          "Changing a port's admin state is not supported "
+                          "by the test environment")
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_update_instance_port_admin_state(self):
@@ -653,22 +656,3 @@
         self.assertEqual(self.network['id'], port['network_id'])
         self.assertEqual('', port['device_id'])
         self.assertEqual('', port['device_owner'])
-
-    @test.idempotent_id('51641c7d-119a-44cd-aac6-b5b9f86dd808')
-    @test.services('compute', 'network')
-    def test_creation_of_server_attached_to_user_created_port(self):
-        self.security_group = (
-            self._create_security_group(tenant_id=self.tenant_id))
-        network, subnet, router = self.create_networks()
-        kwargs = {
-            'security_groups': [self.security_group['id']],
-        }
-
-        port = self._create_port(network.id, **kwargs)
-        name = data_utils.rand_name('server-smoke')
-        server = self._create_server(name, network, port.id)
-        self._check_tenant_network_connectivity()
-        floating_ip = self.create_floating_ip(server)
-        self.floating_ip_tuple = Floating_IP_tuple(floating_ip, server)
-        self.check_public_network_connectivity(
-            should_connect=True)
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 36a347b..6c02b63 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -30,7 +30,7 @@
         self.validate_response(schema.list_aggregates, resp, body)
         return service_client.ResponseBodyList(resp, body['aggregates'])
 
-    def get_aggregate(self, aggregate_id):
+    def show_aggregate(self, aggregate_id):
         """Get details of the given aggregate."""
         resp, body = self.get("os-aggregates/%s" % str(aggregate_id))
         body = json.loads(body)
@@ -67,7 +67,7 @@
 
     def is_resource_deleted(self, id):
         try:
-            self.get_aggregate(id)
+            self.show_aggregate(id)
         except lib_exc.NotFound:
             return True
         return False
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index 6c50398..925d79f 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -22,17 +22,15 @@
 
 class AvailabilityZoneClientJSON(service_client.ServiceClient):
 
-    def get_availability_zone_list(self):
-        resp, body = self.get('os-availability-zone')
-        body = json.loads(body)
-        self.validate_response(schema.list_availability_zone_list, resp, body)
-        return service_client.ResponseBodyList(resp,
-                                               body['availabilityZoneInfo'])
+    def list_availability_zones(self, detail=False):
+        url = 'os-availability-zone'
+        schema_list = schema.list_availability_zone_list
+        if detail:
+            url += '/detail'
+            schema_list = schema.list_availability_zone_list_detail
 
-    def get_availability_zone_list_detail(self):
-        resp, body = self.get('os-availability-zone/detail')
+        resp, body = self.get(url)
         body = json.loads(body)
-        self.validate_response(schema.list_availability_zone_list_detail, resp,
-                               body)
+        self.validate_response(schema_list, resp, body)
         return service_client.ResponseBodyList(resp,
                                                body['availabilityZoneInfo'])
diff --git a/tempest/services/compute/json/baremetal_nodes_client.py b/tempest/services/compute/json/baremetal_nodes_client.py
index d8bbadd..e4a4e88 100644
--- a/tempest/services/compute/json/baremetal_nodes_client.py
+++ b/tempest/services/compute/json/baremetal_nodes_client.py
@@ -34,7 +34,7 @@
         self.validate_response(schema.list_baremetal_nodes, resp, body)
         return service_client.ResponseBodyList(resp, body['nodes'])
 
-    def get_baremetal_node(self, baremetal_node_id):
+    def show_baremetal_node(self, baremetal_node_id):
         """Returns the details of a single baremetal node."""
         url = 'os-baremetal-nodes/%s' % baremetal_node_id
         resp, body = self.get(url)
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index e6b72bb..752a48e 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -21,7 +21,7 @@
 
 class CertificatesClientJSON(service_client.ServiceClient):
 
-    def get_certificate(self, id):
+    def show_certificate(self, id):
         url = "os-certificates/%s" % (id)
         resp, body = self.get(url)
         body = json.loads(body)
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index 5c69085..265b381 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -33,7 +33,7 @@
         exts = extensions['extensions']
         return any([e for e in exts if e['name'] == extension])
 
-    def get_extension(self, extension_alias):
+    def show_extension(self, extension_alias):
         resp, body = self.get('extensions/%s' % extension_alias)
         body = json.loads(body)
         return service_client.ResponseBody(resp, body['extension'])
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index c3bfa99..223e90b 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -16,8 +16,8 @@
 import json
 import time
 
-from tempest.api_schema.response.compute import servers as servers_schema
 from tempest.api_schema.response.compute.v2_1 import interfaces as schema
+from tempest.api_schema.response.compute.v2_1 import servers as servers_schema
 from tempest.common import service_client
 from tempest import exceptions
 
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index bd27668..c9ba2c3 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -20,7 +20,6 @@
 
 from tempest_lib import exceptions as lib_exc
 
-from tempest.api_schema.response.compute import servers as common_schema
 from tempest.api_schema.response.compute.v2_1 import servers as schema
 from tempest.common import service_client
 from tempest.common import waiters
@@ -147,7 +146,7 @@
     def delete_server(self, server_id):
         """Deletes the given server."""
         resp, body = self.delete("servers/%s" % str(server_id))
-        self.validate_response(common_schema.delete_server, resp, body)
+        self.validate_response(schema.delete_server, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def list_servers(self, params=None):
@@ -159,7 +158,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
-        self.validate_response(common_schema.list_servers, resp, body)
+        self.validate_response(schema.list_servers, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def list_servers_with_detail(self, params=None):
@@ -216,7 +215,7 @@
         return service_client.ResponseBody(resp, body)
 
     def action(self, server_id, action_name, response_key,
-               schema=common_schema.server_actions_common_schema,
+               schema=schema.server_actions_common_schema,
                response_class=service_client.ResponseBody, **kwargs):
         post_body = json.dumps({action_name: kwargs})
         resp, body = self.post('servers/%s/action' % str(server_id),
@@ -253,7 +252,7 @@
         resp, body = self.get("servers/%s/os-server-password" %
                               str(server_id))
         body = json.loads(body)
-        self.validate_response(common_schema.get_password, resp, body)
+        self.validate_response(schema.get_password, resp, body)
         return service_client.ResponseBody(resp, body)
 
     def delete_password(self, server_id):
@@ -264,7 +263,7 @@
         """
         resp, body = self.delete("servers/%s/os-server-password" %
                                  str(server_id))
-        self.validate_response(common_schema.server_actions_delete_password,
+        self.validate_response(schema.server_actions_delete_password,
                                resp, body)
         return service_client.ResponseBody(resp, body)
 
@@ -306,7 +305,7 @@
     def list_server_metadata(self, server_id):
         resp, body = self.get("servers/%s/metadata" % str(server_id))
         body = json.loads(body)
-        self.validate_response(common_schema.list_server_metadata, resp, body)
+        self.validate_response(schema.list_server_metadata, resp, body)
         return service_client.ResponseBody(resp, body['metadata'])
 
     def set_server_metadata(self, server_id, meta, no_metadata_field=False):
@@ -317,7 +316,7 @@
         resp, body = self.put('servers/%s/metadata' % str(server_id),
                               post_body)
         body = json.loads(body)
-        self.validate_response(common_schema.set_server_metadata, resp, body)
+        self.validate_response(schema.set_server_metadata, resp, body)
         return service_client.ResponseBody(resp, body['metadata'])
 
     def update_server_metadata(self, server_id, meta):
@@ -325,7 +324,7 @@
         resp, body = self.post('servers/%s/metadata' % str(server_id),
                                post_body)
         body = json.loads(body)
-        self.validate_response(common_schema.update_server_metadata,
+        self.validate_response(schema.update_server_metadata,
                                resp, body)
         return service_client.ResponseBody(resp, body['metadata'])
 
@@ -348,7 +347,7 @@
     def delete_server_metadata_item(self, server_id, key):
         resp, body = self.delete("servers/%s/metadata/%s" %
                                  (str(server_id), key))
-        self.validate_response(common_schema.delete_server_metadata_item,
+        self.validate_response(schema.delete_server_metadata_item,
                                resp, body)
         return service_client.ResponseBody(resp, body)
 
@@ -415,7 +414,7 @@
         req_body = json.dumps({'os-migrateLive': migrate_params})
 
         resp, body = self.post("servers/%s/action" % str(server_id), req_body)
-        self.validate_response(common_schema.server_actions_common_schema,
+        self.validate_response(schema.server_actions_common_schema,
                                resp, body)
         return service_client.ResponseBody(resp, body)
 
@@ -466,7 +465,7 @@
     def get_console_output(self, server_id, length):
         kwargs = {'length': length} if length else {}
         return self.action(server_id, 'os-getConsoleOutput', 'output',
-                           common_schema.get_console_output,
+                           schema.get_console_output,
                            response_class=service_client.ResponseBodyData,
                            **kwargs)
 
@@ -531,7 +530,7 @@
     def get_vnc_console(self, server_id, console_type):
         """Get URL of VNC console."""
         return self.action(server_id, "os-getVNCConsole",
-                           "console", common_schema.get_vnc_console,
+                           "console", schema.get_vnc_console,
                            type=console_type)
 
     def create_server_group(self, name, policies):
diff --git a/tempest/services/messaging/json/messaging_client.py b/tempest/services/messaging/json/messaging_client.py
index 36444a9..483ba93 100644
--- a/tempest/services/messaging/json/messaging_client.py
+++ b/tempest/services/messaging/json/messaging_client.py
@@ -58,7 +58,7 @@
         self.expected_success(201, resp.status)
         return resp, body
 
-    def get_queue(self, queue_name):
+    def show_queue(self, queue_name):
         uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name)
         resp, body = self.get(uri)
         self.expected_success(204, resp.status)
@@ -76,14 +76,14 @@
         self.expected_success(204, resp.status)
         return resp, body
 
-    def get_queue_stats(self, queue_name):
+    def show_queue_stats(self, queue_name):
         uri = '{0}/queues/{1}/stats'.format(self.uri_prefix, queue_name)
         resp, body = self.get(uri)
         body = json.loads(body)
         self.validate_response(queues_schema.queue_stats, resp, body)
         return resp, body
 
-    def get_queue_metadata(self, queue_name):
+    def show_queue_metadata(self, queue_name):
         uri = '{0}/queues/{1}/metadata'.format(self.uri_prefix, queue_name)
         resp, body = self.get(uri)
         self.expected_success(200, resp.status)
@@ -117,7 +117,7 @@
 
         return resp, body
 
-    def get_single_message(self, message_uri):
+    def show_single_message(self, message_uri):
         resp, body = self.get(message_uri, extra_headers=True,
                               headers=self.headers)
         if resp['status'] != '204':
@@ -126,7 +126,7 @@
                                    body)
         return resp, body
 
-    def get_multiple_messages(self, message_uri):
+    def show_multiple_messages(self, message_uri):
         resp, body = self.get(message_uri, extra_headers=True,
                               headers=self.headers)
 
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index 36c123b..0c01908 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -50,7 +50,7 @@
         body = self.deserialize(body)
         return service_client.ResponseBody(resp, body)
 
-    def helper_list(self, uri, query=None, period=None):
+    def _helper_list(self, uri, query=None, period=None):
         uri_dict = {}
         if query:
             uri_dict = {'q.field': query[0],
@@ -67,32 +67,32 @@
 
     def list_resources(self, query=None):
         uri = '%s/resources' % self.uri_prefix
-        return self.helper_list(uri, query)
+        return self._helper_list(uri, query)
 
     def list_meters(self, query=None):
         uri = '%s/meters' % self.uri_prefix
-        return self.helper_list(uri, query)
+        return self._helper_list(uri, query)
 
     def list_alarms(self, query=None):
         uri = '%s/alarms' % self.uri_prefix
-        return self.helper_list(uri, query)
+        return self._helper_list(uri, query)
 
     def list_statistics(self, meter, period=None, query=None):
         uri = "%s/meters/%s/statistics" % (self.uri_prefix, meter)
-        return self.helper_list(uri, query, period)
+        return self._helper_list(uri, query, period)
 
     def list_samples(self, meter_id, query=None):
         uri = '%s/meters/%s' % (self.uri_prefix, meter_id)
-        return self.helper_list(uri, query)
+        return self._helper_list(uri, query)
 
-    def get_resource(self, resource_id):
+    def show_resource(self, resource_id):
         uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
         resp, body = self.get(uri)
         self.expected_success(200, resp.status)
         body = self.deserialize(body)
         return service_client.ResponseBody(resp, body)
 
-    def get_alarm(self, alarm_id):
+    def show_alarm(self, alarm_id):
         uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id)
         resp, body = self.get(uri)
         self.expected_success(200, resp.status)
@@ -123,7 +123,7 @@
         body = self.deserialize(body)
         return service_client.ResponseBody(resp, body)
 
-    def alarm_get_state(self, alarm_id):
+    def show_alarm_state(self, alarm_id):
         uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
         resp, body = self.get(uri)
         self.expected_success(200, resp.status)
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index b176675..b4048ba 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -68,13 +68,8 @@
              'password': 'p', 'roles': [cfg.CONF.identity.admin_role]},
             {'username': 'test_user12', 'tenant_name': 'test_tenant12',
              'password': 'p', 'roles': [cfg.CONF.identity.admin_role]},
-            {'username': 'test_user13', 'tenant_name': 'test_tenant13',
-             'password': 'p', 'resources': {'network': 'network-1'}},
-            {'username': 'test_user14', 'tenant_name': 'test_tenant14',
-             'password': 'p', 'roles': ['role-7', 'role-11'],
-             'resources': {'network': 'network-2'}},
         ]
-        self.useFixture(mockpatch.Patch(
+        self.accounts_mock = self.useFixture(mockpatch.Patch(
             'tempest.common.accounts.read_accounts_yaml',
             return_value=self.test_accounts))
         cfg.CONF.set_default('test_accounts_file', 'fake_path', group='auth')
@@ -281,14 +276,22 @@
         calls = get_free_hash_mock.mock.mock_calls
         self.assertEqual(len(calls), 1)
         args = calls[0][1][0]
-        self.assertEqual(len(args), 12)
+        self.assertEqual(len(args), 10)
         for i in admin_hashes:
             self.assertNotIn(i, args)
 
     def test_networks_returned_with_creds(self):
+        test_accounts = [
+            {'username': 'test_user13', 'tenant_name': 'test_tenant13',
+             'password': 'p', 'resources': {'network': 'network-1'}},
+            {'username': 'test_user14', 'tenant_name': 'test_tenant14',
+             'password': 'p', 'roles': ['role-7', 'role-11'],
+             'resources': {'network': 'network-2'}}]
+        # Clear previous mock using self.test_accounts
+        self.accounts_mock.cleanUp()
         self.useFixture(mockpatch.Patch(
             'tempest.common.accounts.read_accounts_yaml',
-            return_value=self.test_accounts))
+            return_value=test_accounts))
         test_accounts_class = accounts.Accounts('v2', 'test_name')
         with mock.patch('tempest.services.compute.json.networks_client.'
                         'NetworksClientJSON.list_networks',
diff --git a/tempest/tests/test_ssh.py b/tempest/tests/test_ssh.py
index 27cd6b5..aaacaab 100644
--- a/tempest/tests/test_ssh.py
+++ b/tempest/tests/test_ssh.py
@@ -29,7 +29,7 @@
     def test_pkey_calls_paramiko_RSAKey(self):
         with contextlib.nested(
             mock.patch('paramiko.RSAKey.from_private_key'),
-            mock.patch('cStringIO.StringIO')) as (rsa_mock, cs_mock):
+            mock.patch('six.moves.cStringIO')) as (rsa_mock, cs_mock):
             cs_mock.return_value = mock.sentinel.csio
             pkey = 'mykey'
             ssh.Client('localhost', 'root', pkey=pkey)
diff --git a/tempest/tests/test_wrappers.py b/tempest/tests/test_wrappers.py
index ae7860d..a4ef699 100644
--- a/tempest/tests/test_wrappers.py
+++ b/tempest/tests/test_wrappers.py
@@ -14,10 +14,11 @@
 
 import os
 import shutil
-import StringIO
 import subprocess
 import tempfile
 
+import six
+
 from tempest.tests import base
 
 DEVNULL = open(os.devnull, 'wb')
@@ -50,8 +51,8 @@
         shutil.copy('tools/pretty_tox_serial.sh',
                     os.path.join(self.directory, 'pretty_tox_serial.sh'))
 
-        self.stdout = StringIO.StringIO()
-        self.stderr = StringIO.StringIO()
+        self.stdout = six.StringIO()
+        self.stderr = six.StringIO()
         # Change directory, run wrapper and check result
         self.addCleanup(os.chdir, os.path.abspath(os.curdir))
         os.chdir(self.directory)