Merge "More javelin unit tests"
diff --git a/HACKING.rst b/HACKING.rst
index 04b5eb6..c776c49 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -14,6 +14,7 @@
 - [T105] Tests cannot use setUpClass/tearDownClass
 - [T106] vim configuration should not be kept in source files.
 - [T107] Check that a service tag isn't in the module path
+- [T108] Check no hyphen at the end of rand_name() argument
 - [N322] Method's default argument shouldn't be mutable
 
 Test Data/Configuration
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 6424f55..4a43282 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -39,8 +39,8 @@
 # Deprecated group/name - [DEFAULT]/logdir
 #log_dir = <None>
 
-# Use syslog for logging. Existing syslog format is DEPRECATED during
-# I, and changed in J to honor RFC5424. (boolean value)
+# Use syslog for logging. Existing syslog format is DEPRECATED and
+# will be changed later to honor RFC5424. (boolean value)
 #use_syslog = false
 
 # (Optional) Enables or disables syslog rfc5424 format for logging. If
@@ -254,6 +254,10 @@
 # value)
 #build_timeout = 300
 
+# Shell fragments to use before executing a command when sshing to a
+# guest. (string value)
+#ssh_shell_prologue = set -eu -o pipefail; PATH=$$PATH:/sbin;
+
 # Auth method used for authenticate to the instance. Valid choices
 # are: keypair, configured, adminpass and disabled. Keypair: start the
 # servers with a ssh keypair. Configured: use the configured user and
diff --git a/requirements.txt b/requirements.txt
index cb0031d..1d512a0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,22 +1,22 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-pbr>=0.11,<2.0
+pbr<2.0,>=0.11
 anyjson>=0.3.3
 httplib2>=0.7.5
-jsonschema>=2.0.0,<3.0.0,!=2.5.0
-testtools>=0.9.36,!=1.2.0
+jsonschema!=2.5.0,<3.0.0,>=2.0.0
+testtools>=1.4.0
 boto>=2.32.1
 paramiko>=1.13.0
 netaddr>=0.7.12
 testrepository>=0.0.18
 pyOpenSSL>=0.11
-oslo.concurrency>=2.0.0         # Apache-2.0
-oslo.config>=1.11.0  # Apache-2.0
-oslo.i18n>=1.5.0  # Apache-2.0
-oslo.log>=1.2.0  # Apache-2.0
-oslo.serialization>=1.4.0               # Apache-2.0
-oslo.utils>=1.4.0                       # Apache-2.0
+oslo.concurrency>=2.0.0 # Apache-2.0
+oslo.config>=1.11.0 # Apache-2.0
+oslo.i18n>=1.5.0 # Apache-2.0
+oslo.log>=1.2.0 # Apache-2.0
+oslo.serialization>=1.4.0 # Apache-2.0
+oslo.utils>=1.6.0 # Apache-2.0
 six>=1.9.0
 iso8601>=0.1.9
 fixtures>=0.3.14
diff --git a/setup.py b/setup.py
old mode 100755
new mode 100644
index 7363757..056c16c
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index 477dc61..981a5c9 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -47,7 +47,7 @@
         else:
             configured_network = networks
         configured_network = configured_network[0]
-        network = self.client.get_network(configured_network['id'])
+        network = self.client.show_network(configured_network['id'])
         self.assertEqual(configured_network['label'], network['label'])
 
     @test.idempotent_id('df3d1046-6fa5-4b2c-ad0c-cfa46a351cb9')
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 01db25c..029e578 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -58,7 +58,7 @@
     def test_get_default_quotas(self):
         # Admin can get the default resource quota set for a tenant
         expected_quota_set = self.default_quota_set | set(['id'])
-        quota_set = self.adm_client.get_default_quota_set(
+        quota_set = self.adm_client.show_default_quota_set(
             self.demo_tenant_id)
         self.assertEqual(quota_set['id'], self.demo_tenant_id)
         for quota in expected_quota_set:
@@ -67,7 +67,7 @@
     @test.idempotent_id('55fbe2bf-21a9-435b-bbd2-4162b0ed799a')
     def test_update_all_quota_resources_for_tenant(self):
         # Admin can update all the resource quota limits for a tenant
-        default_quota_set = self.adm_client.get_default_quota_set(
+        default_quota_set = self.adm_client.show_default_quota_set(
             self.demo_tenant_id)
         new_quota_set = {'injected_file_content_bytes': 20480,
                          'metadata_items': 256, 'injected_files': 10,
@@ -107,7 +107,7 @@
         self.addCleanup(identity_client.delete_tenant, tenant_id)
 
         self.adm_client.update_quota_set(tenant_id, ram='5120')
-        quota_set = self.adm_client.get_quota_set(tenant_id)
+        quota_set = self.adm_client.show_quota_set(tenant_id)
         self.assertEqual(5120, quota_set['ram'])
 
         # Verify that GET shows the updated quota set of user
@@ -124,8 +124,8 @@
         self.adm_client.update_quota_set(tenant_id,
                                          user_id=user_id,
                                          ram='2048')
-        quota_set = self.adm_client.get_quota_set(tenant_id,
-                                                  user_id=user_id)
+        quota_set = self.adm_client.show_quota_set(tenant_id,
+                                                   user_id=user_id)
         self.assertEqual(2048, quota_set['ram'])
 
     @test.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0')
@@ -138,14 +138,14 @@
                                                description=tenant_desc)
         tenant_id = tenant['id']
         self.addCleanup(identity_client.delete_tenant, tenant_id)
-        quota_set_default = self.adm_client.get_quota_set(tenant_id)
+        quota_set_default = self.adm_client.show_quota_set(tenant_id)
         ram_default = quota_set_default['ram']
 
         self.adm_client.update_quota_set(tenant_id, ram='5120')
 
         self.adm_client.delete_quota_set(tenant_id)
 
-        quota_set_new = self.adm_client.get_quota_set(tenant_id)
+        quota_set_new = self.adm_client.show_quota_set(tenant_id)
         self.assertEqual(ram_default, quota_set_new['ram'])
 
 
@@ -176,7 +176,7 @@
     @test.idempotent_id('7932ab0f-5136-4075-b201-c0e2338df51a')
     def test_update_default_quotas(self):
         LOG.debug("get the current 'default' quota class values")
-        body = self.adm_client.get_quota_class_set('default')
+        body = self.adm_client.show_quota_class_set('default')
         self.assertIn('id', body)
         self.assertEqual('default', body.pop('id'))
         # restore the defaults when the test is done
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index d20ebf3..c450a1d 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -54,7 +54,7 @@
     @test.idempotent_id('91058876-9947-4807-9f22-f6eb17140d9b')
     def test_create_server_when_cpu_quota_is_full(self):
         # Disallow server creation when tenant's vcpu quota is full
-        quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
+        quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
         default_vcpu_quota = quota_set['cores']
         vcpu_quota = 0  # Set the quota to zero to conserve resources
 
@@ -71,7 +71,7 @@
     @test.idempotent_id('6fdd7012-584d-4327-a61c-49122e0d5864')
     def test_create_server_when_memory_quota_is_full(self):
         # Disallow server creation when tenant's memory quota is full
-        quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
+        quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
         default_mem_quota = quota_set['ram']
         mem_quota = 0  # Set the quota to zero to conserve resources
 
@@ -88,7 +88,7 @@
     @test.idempotent_id('7c6be468-0274-449a-81c3-ac1c32ee0161')
     def test_create_server_when_instances_quota_is_full(self):
         # Once instances quota limit is reached, disallow server creation
-        quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
+        quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
         default_instances_quota = quota_set['instances']
         instances_quota = 0  # Set quota to zero to disallow server creation
 
@@ -107,7 +107,7 @@
     def test_security_groups_exceed_limit(self):
         # Negative test: Creation Security Groups over limit should FAIL
 
-        quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
+        quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
         default_sg_quota = quota_set['security_groups']
         sg_quota = 0  # Set the quota to zero to conserve resources
 
@@ -136,7 +136,7 @@
         # Negative test: Creation of Security Group Rules should FAIL
         # when we reach limit maxSecurityGroupRules
 
-        quota_set = self.adm_client.get_quota_set(self.demo_tenant_id)
+        quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
         default_sg_rules_quota = quota_set['security_group_rules']
         sg_rules_quota = 0  # Set the quota to zero to conserve resources
 
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index d325bd7..cda4bc4 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -68,7 +68,7 @@
         self.useFixture(fixtures.LockFixture('compute_quotas'))
         flavor_name = data_utils.rand_name("flavor")
         flavor_id = self._get_unused_flavor_id()
-        quota_set = self.quotas_client.get_default_quota_set(self.tenant_id)
+        quota_set = self.quotas_client.show_default_quota_set(self.tenant_id)
         ram = int(quota_set['ram']) + 1
         vcpus = 8
         disk = 10
@@ -91,7 +91,7 @@
         flavor_name = data_utils.rand_name("flavor")
         flavor_id = self._get_unused_flavor_id()
         ram = 512
-        quota_set = self.quotas_client.get_default_quota_set(self.tenant_id)
+        quota_set = self.quotas_client.show_default_quota_set(self.tenant_id)
         vcpus = int(quota_set['cores']) + 1
         disk = 10
         flavor_ref = self.flavors_client.create_flavor(flavor_name,
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 9aacfa5..a1f6f99 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -16,11 +16,10 @@
 import time
 
 from oslo_log import log as logging
-from oslo_utils import excutils
 from tempest_lib.common.utils import data_utils
 from tempest_lib import exceptions as lib_exc
 
-from tempest.common import fixed_network
+from tempest.common import compute
 from tempest import config
 from tempest import exceptions
 import tempest.test
@@ -192,41 +191,21 @@
                               server_group_id)
 
     @classmethod
-    def create_test_server(cls, **kwargs):
-        """Wrapper utility that returns a test server."""
-        name = data_utils.rand_name(cls.__name__ + "-instance")
-        if 'name' in kwargs:
-            name = kwargs.pop('name')
-        flavor = kwargs.get('flavor', cls.flavor_ref)
-        image_id = kwargs.get('image_id', cls.image_ref)
+    def create_test_server(cls, validatable=False, **kwargs):
+        """Wrapper utility that returns a test server.
 
-        kwargs = fixed_network.set_networks_kwarg(
-            cls.get_tenant_network(), kwargs) or {}
-        body = cls.servers_client.create_server(
-            name, image_id, flavor, **kwargs)
-
-        # handle the case of multiple servers
-        servers = [body]
-        if 'min_count' in kwargs or 'max_count' in kwargs:
-            # Get servers created which name match with name param.
-            b = cls.servers_client.list_servers()
-            servers = [s for s in b['servers'] if s['name'].startswith(name)]
-
-        if 'wait_until' in kwargs:
-            for server in servers:
-                try:
-                    cls.servers_client.wait_for_server_status(
-                        server['id'], kwargs['wait_until'])
-                except Exception:
-                    with excutils.save_and_reraise_exception():
-                        if ('preserve_server_on_error' not in kwargs
-                            or kwargs['preserve_server_on_error'] is False):
-                            for server in servers:
-                                try:
-                                    cls.servers_client.delete_server(
-                                        server['id'])
-                                except Exception:
-                                    pass
+        This wrapper utility calls the common create test server and
+        returns a test server. The purpose of this wrapper is to minimize
+        the impact on the code of the tests already using this
+        function.
+        """
+        tenant_network = cls.get_tenant_network()
+        body, servers = compute.create_test_server(
+            cls.os,
+            validatable,
+            validation_resources=cls.validation_resources,
+            tenant_network=tenant_network,
+            **kwargs)
 
         cls.servers.extend(servers)
 
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index 06a77cc..0029bb9 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -27,7 +27,8 @@
     @test.idempotent_id('b54c66af-6ab6-4cf0-a9e5-a0cb58d75e0b')
     def test_absLimits_get(self):
         # To check if all limits are present in the response
-        absolute_limits = self.client.show_limits()
+        limits = self.client.show_limits()
+        absolute_limits = limits['absolute']
         expected_elements = ['maxImageMeta', 'maxPersonality',
                              'maxPersonalitySize',
                              'maxServerMeta', 'maxTotalCores',
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index bdbe3f1..cbd2004 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -38,7 +38,8 @@
     def test_max_image_meta_exceed_limit(self):
         # We should not create vm with image meta over maxImageMeta limit
         # Get max limit value
-        max_meta = self.client.get_specific_absolute_limit('maxImageMeta')
+        limits = self.client.show_limits()
+        max_meta = limits['absolute']['maxImageMeta']
 
         # No point in running this test if there is no limit.
         if int(max_meta) == -1:
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 16b1597..408d4ee 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -53,14 +53,16 @@
         personality = [{'path': '/test.txt',
                        'contents': base64.b64encode(file_contents)}]
         disk_config = cls.disk_config
-        cls.server_initial = cls.create_test_server(name=cls.name,
-                                                    meta=cls.meta,
-                                                    accessIPv4=cls.accessIPv4,
-                                                    accessIPv6=cls.accessIPv6,
-                                                    personality=personality,
-                                                    disk_config=disk_config)
+        cls.server_initial = cls.create_test_server(
+            validatable=True,
+            wait_until='ACTIVE',
+            name=cls.name,
+            meta=cls.meta,
+            accessIPv4=cls.accessIPv4,
+            accessIPv6=cls.accessIPv6,
+            personality=personality,
+            disk_config=disk_config)
         cls.password = cls.server_initial['adminPass']
-        cls.client.wait_for_server_status(cls.server_initial['id'], 'ACTIVE')
         cls.server = cls.client.get_server(cls.server_initial['id'])
 
     @test.attr(type='smoke')
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index 1a977ab..a8f7597 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -137,7 +137,7 @@
         # A 403 Forbidden or 413 Overlimit (old behaviour) exception
         # will be raised while exceeding metadata items limit for
         # tenant.
-        quota_set = self.quotas.get_quota_set(self.tenant_id)
+        quota_set = self.quotas.show_quota_set(self.tenant_id)
         quota_metadata = quota_set['metadata_items']
         if quota_metadata == -1:
             raise self.skipException("No limit for metadata_items")
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index 3a019b4..b3cc072 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -34,8 +34,8 @@
         # number of files are injected into the server.
         file_contents = 'This is a test file.'
         personality = []
-        max_file_limit = \
-            self.user_client.get_specific_absolute_limit("maxPersonality")
+        limits = self.user_client.show_limits()
+        max_file_limit = limits['absolute']['maxPersonality']
         if max_file_limit == -1:
             raise self.skipException("No limit for personality files")
         for i in range(0, int(max_file_limit) + 1):
@@ -52,8 +52,8 @@
         # Server should be created successfully if maximum allowed number of
         # files is injected into the server during creation.
         file_contents = 'This is a test file.'
-        max_file_limit = \
-            self.user_client.get_specific_absolute_limit("maxPersonality")
+        limits = self.user_client.show_limits()
+        max_file_limit = limits['absolute']['maxPersonality']
         if max_file_limit == -1:
             raise self.skipException("No limit for personality files")
         person = []
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index a6e877c..e302798 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -47,14 +47,14 @@
     def test_get_quotas(self):
         # User can get the quota set for it's tenant
         expected_quota_set = self.default_quota_set | set(['id'])
-        quota_set = self.client.get_quota_set(self.tenant_id)
+        quota_set = self.client.show_quota_set(self.tenant_id)
         self.assertEqual(quota_set['id'], self.tenant_id)
         for quota in expected_quota_set:
             self.assertIn(quota, quota_set.keys())
 
         # get the quota set using user id
-        quota_set = self.client.get_quota_set(self.tenant_id,
-                                              self.user_id)
+        quota_set = self.client.show_quota_set(self.tenant_id,
+                                               self.user_id)
         self.assertEqual(quota_set['id'], self.tenant_id)
         for quota in expected_quota_set:
             self.assertIn(quota, quota_set.keys())
@@ -63,7 +63,7 @@
     def test_get_default_quotas(self):
         # User can get the default quota set for it's tenant
         expected_quota_set = self.default_quota_set | set(['id'])
-        quota_set = self.client.get_default_quota_set(self.tenant_id)
+        quota_set = self.client.show_default_quota_set(self.tenant_id)
         self.assertEqual(quota_set['id'], self.tenant_id)
         for quota in expected_quota_set:
             self.assertIn(quota, quota_set.keys())
@@ -72,6 +72,6 @@
     def test_compare_tenant_quotas_with_default_quotas(self):
         # Tenants are created with the default quota values
         defualt_quota_set = \
-            self.client.get_default_quota_set(self.tenant_id)
-        tenant_quota_set = self.client.get_quota_set(self.tenant_id)
+            self.client.show_default_quota_set(self.tenant_id)
+        tenant_quota_set = self.client.show_quota_set(self.tenant_id)
         self.assertEqual(defualt_quota_set, tenant_quota_set)
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index b1a9d3b..94aab5b 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -101,7 +101,7 @@
     @test.idempotent_id('2abf8764-309a-4fa9-bc58-201b799817ad')
     def test_create_domain_without_description(self):
         # Create domain only with name
-        d_name = data_utils.rand_name('domain-')
+        d_name = data_utils.rand_name('domain')
         domain = self.client.create_domain(d_name)
         self.addCleanup(self._delete_domain, domain['id'])
         self.assertIn('id', domain)
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 3ebb90d..8a2d797 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -46,7 +46,7 @@
 
     def create_trustor_and_roles(self):
         # create a project that trusts will be granted on
-        self.trustor_project_name = data_utils.rand_name(name='project-')
+        self.trustor_project_name = data_utils.rand_name(name='project')
         project = self.client.create_project(self.trustor_project_name,
                                              domain_id='default')
         self.trustor_project_id = project['id']
diff --git a/tempest/api/messaging/test_queues.py b/tempest/api/messaging/test_queues.py
index 2dac346..a3541b3 100644
--- a/tempest/api/messaging/test_queues.py
+++ b/tempest/api/messaging/test_queues.py
@@ -33,7 +33,7 @@
     @test.idempotent_id('9f1c4c72-80c5-4dac-acf3-188cef42e36c')
     def test_create_delete_queue(self):
         # Create & Delete Queue
-        queue_name = data_utils.rand_name('test-')
+        queue_name = data_utils.rand_name('test')
         _, body = self.create_queue(queue_name)
 
         self.addCleanup(self.client.delete_queue, queue_name)
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index 2ff8897..38d68c2 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -27,6 +27,7 @@
 
 class L3AgentSchedulerTestJSON(base.BaseAdminNetworkTest):
     _agent_mode = 'legacy'
+    is_dvr_router = False
 
     """
     Tests the following operations in the Neutron API using the REST client for
diff --git a/tempest/api/object_storage/test_object_expiry.py b/tempest/api/object_storage/test_object_expiry.py
index fec6873..b263050 100644
--- a/tempest/api/object_storage/test_object_expiry.py
+++ b/tempest/api/object_storage/test_object_expiry.py
@@ -56,18 +56,33 @@
         # we want to ensure that we will sleep long enough for things to
         # actually expire, so figure out how many secs in the future that is.
         sleepy_time = int(resp['x-delete-at']) - int(time.time())
-
+        sleepy_time = sleepy_time if sleepy_time > 0 else 0
         resp, body = self.object_client.get_object(self.container_name,
                                                    self.object_name)
         self.assertHeaders(resp, 'Object', 'GET')
         self.assertIn('x-delete-at', resp)
 
-        # add a couple of seconds for safety.
-        time.sleep(sleepy_time + 3)
+        # add several seconds for safety.
+        time.sleep(sleepy_time)
+
+        # Checking whether object still exists for several seconds:
+        # sometimes object is not deleted immediately, so we are making
+        # get calls for an approximately 1 minute in a total. Get calls
+        # can take 3s each sometimes so we are making the requests in
+        # exponential periodicity
+        for i in range(1, 6):
+            time.sleep(2 ** i)
+            try:
+                self.object_client.get_object(self.container_name,
+                                              self.object_name)
+            except lib_exc.NotFound:
+                break
 
         # object should not be there anymore
-        self.assertRaises(lib_exc.NotFound, self.object_client.get_object,
-                          self.container_name, self.object_name)
+        self.assertRaises(lib_exc.NotFound,
+                          self.object_client.get_object,
+                          self.container_name,
+                          self.object_name)
 
     @test.idempotent_id('fb024a42-37f3-4ba5-9684-4f40a7910b41')
     def test_get_object_after_expiry_time(self):
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 627895e..3396d8f 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -827,8 +827,8 @@
         resp, _ = self.object_client.create_object(src_container_name,
                                                    object_name, data)
         # set object metadata
-        meta_key = data_utils.rand_name(name='test-')
-        meta_value = data_utils.rand_name(name='MetaValue-')
+        meta_key = data_utils.rand_name(name='test')
+        meta_value = data_utils.rand_name(name='MetaValue')
         orig_metadata = {meta_key: meta_value}
         resp, _ = self.object_client.update_object_metadata(src_container_name,
                                                             object_name,
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index 43180e5..cce8e2a 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -55,8 +55,7 @@
         cls.nova_notifications = ['memory', 'vcpus', 'disk.root.size',
                                   'disk.ephemeral.size']
 
-        cls.glance_notifications = ['image.update', 'image.upload',
-                                    'image.delete']
+        cls.glance_notifications = ['image.size']
 
         cls.glance_v2_notifications = ['image.download', 'image.serve']
 
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index d49b2ba..52793c8 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -10,7 +10,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest_lib import decorators
 import testtools
 
 from tempest.api.telemetry import base
@@ -46,7 +45,6 @@
     @test.services("image")
     @testtools.skipIf(not CONF.image_feature_enabled.api_v1,
                       "Glance api v1 is disabled")
-    @decorators.skip_because(bug='1351627')
     def test_check_glance_v1_notifications(self):
         body = self.create_image(self.image_client)
         self.image_client.update_image(body['id'], data='data')
@@ -63,7 +61,6 @@
     @test.services("image")
     @testtools.skipIf(not CONF.image_feature_enabled.api_v2,
                       "Glance api v2 is disabled")
-    @decorators.skip_because(bug='1351627')
     def test_check_glance_v2_notifications(self):
         body = self.create_image(self.image_client_v2)
 
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 24c7c63..ec8e040 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -98,7 +98,7 @@
     @test.idempotent_id('874b35a9-51f1-4258-bec5-cd561b6690d3')
     def test_delete_quota(self):
         # Admin can delete the resource quota set for a tenant
-        tenant_name = data_utils.rand_name('quota_tenant_')
+        tenant_name = data_utils.rand_name('quota_tenant')
         identity_client = self.os_adm.identity_client
         tenant = identity_client.create_tenant(tenant_name)
         tenant_id = tenant['id']
diff --git a/tempest/api_schema/response/compute/v2_1/agents.py b/tempest/api_schema/response/compute/v2_1/agents.py
index 84c5fd3..da38198 100644
--- a/tempest/api_schema/response/compute/v2_1/agents.py
+++ b/tempest/api_schema/response/compute/v2_1/agents.py
@@ -23,6 +23,7 @@
         'url': {'type': 'string', 'format': 'uri'},
         'md5hash': {'type': 'string'}
     },
+    'additionalProperties': False,
     'required': ['agent_id', 'hypervisor', 'os', 'architecture',
                  'version', 'url', 'md5hash']
 }
@@ -37,6 +38,7 @@
                 'items': common_agent_info
             }
         },
+        'additionalProperties': False,
         'required': ['agents']
     }
 }
@@ -48,6 +50,7 @@
         'properties': {
             'agent': common_agent_info
         },
+        'additionalProperties': False,
         'required': ['agent']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/aggregates.py b/tempest/api_schema/response/compute/v2_1/aggregates.py
index c935592..1a9fe41 100644
--- a/tempest/api_schema/response/compute/v2_1/aggregates.py
+++ b/tempest/api_schema/response/compute/v2_1/aggregates.py
@@ -26,6 +26,7 @@
         'name': {'type': 'string'},
         'updated_at': {'type': ['string', 'null']}
     },
+    'additionalProperties': False,
     'required': ['availability_zone', 'created_at', 'deleted',
                  'deleted_at', 'id', 'name', 'updated_at'],
 }
@@ -47,6 +48,7 @@
                 'items': common_aggregate_info
             }
         },
+        'additionalProperties': False,
         'required': ['aggregates'],
     }
 }
@@ -58,6 +60,7 @@
         'properties': {
             'aggregate': common_aggregate_info
         },
+        'additionalProperties': False,
         'required': ['aggregate'],
     }
 }
@@ -81,6 +84,7 @@
         'properties': {
             'aggregate': aggregate_for_create
         },
+        'additionalProperties': False,
         'required': ['aggregate'],
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/availability_zone.py b/tempest/api_schema/response/compute/v2_1/availability_zone.py
index 5c1224e..d9aebce 100644
--- a/tempest/api_schema/response/compute/v2_1/availability_zone.py
+++ b/tempest/api_schema/response/compute/v2_1/availability_zone.py
@@ -31,16 +31,19 @@
                             'properties': {
                                 'available': {'type': 'boolean'}
                             },
+                            'additionalProperties': False,
                             'required': ['available']
                         },
                         # NOTE: Here is the difference between detail and
                         # non-detail.
                         'hosts': {'type': 'null'}
                     },
+                    'additionalProperties': False,
                     'required': ['zoneName', 'zoneState', 'hosts']
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['availabilityZoneInfo']
     }
 }
@@ -60,6 +63,7 @@
                         'active': {'type': 'boolean'},
                         'updated_at': {'type': ['string', 'null']}
                     },
+                    'additionalProperties': False,
                     'required': ['available', 'active', 'updated_at']
                 }
             }
diff --git a/tempest/api_schema/response/compute/v2_1/baremetal_nodes.py b/tempest/api_schema/response/compute/v2_1/baremetal_nodes.py
index 82506e7..d1ee877 100644
--- a/tempest/api_schema/response/compute/v2_1/baremetal_nodes.py
+++ b/tempest/api_schema/response/compute/v2_1/baremetal_nodes.py
@@ -25,6 +25,7 @@
         'memory_mb': {'type': ['integer', 'string']},
         'disk_gb': {'type': ['integer', 'string']},
     },
+    'additionalProperties': False,
     'required': ['id', 'interfaces', 'host', 'task_state', 'cpus', 'memory_mb',
                  'disk_gb']
 }
@@ -39,6 +40,7 @@
                 'items': node
             }
         },
+        'additionalProperties': False,
         'required': ['nodes']
     }
 }
@@ -50,6 +52,7 @@
         'properties': {
             'node': node
         },
+        'additionalProperties': False,
         'required': ['node']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/certificates.py b/tempest/api_schema/response/compute/v2_1/certificates.py
index 35445d8..4e7cbe4 100644
--- a/tempest/api_schema/response/compute/v2_1/certificates.py
+++ b/tempest/api_schema/response/compute/v2_1/certificates.py
@@ -25,9 +25,11 @@
                     'data': {'type': 'string'},
                     'private_key': {'type': 'string'},
                 },
+                'additionalProperties': False,
                 'required': ['data', 'private_key']
             }
         },
+        'additionalProperties': False,
         'required': ['certificate']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/extensions.py b/tempest/api_schema/response/compute/v2_1/extensions.py
index 570cd03..a6a455c 100644
--- a/tempest/api_schema/response/compute/v2_1/extensions.py
+++ b/tempest/api_schema/response/compute/v2_1/extensions.py
@@ -35,11 +35,13 @@
                         'alias': {'type': 'string'},
                         'description': {'type': 'string'}
                     },
+                    'additionalProperties': False,
                     'required': ['updated', 'name', 'links', 'namespace',
                                  'alias', 'description']
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['extensions']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/fixed_ips.py b/tempest/api_schema/response/compute/v2_1/fixed_ips.py
index 13e70bf..6d5ba67 100644
--- a/tempest/api_schema/response/compute/v2_1/fixed_ips.py
+++ b/tempest/api_schema/response/compute/v2_1/fixed_ips.py
@@ -28,9 +28,11 @@
                     'host': {'type': 'string'},
                     'hostname': {'type': 'string'}
                 },
+                'additionalProperties': False,
                 'required': ['address', 'cidr', 'host', 'hostname']
             }
         },
+        'additionalProperties': False,
         'required': ['fixed_ip']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/flavors.py b/tempest/api_schema/response/compute/v2_1/flavors.py
index 26760ac..5f5b2e3 100644
--- a/tempest/api_schema/response/compute/v2_1/flavors.py
+++ b/tempest/api_schema/response/compute/v2_1/flavors.py
@@ -28,11 +28,13 @@
                         'links': parameter_types.links,
                         'id': {'type': 'string'}
                     },
+                    'additionalProperties': False,
                     'required': ['name', 'links', 'id']
                 }
             },
             'flavors_links': parameter_types.links
         },
+        'additionalProperties': False,
         # NOTE(gmann): flavors_links attribute is not necessary
         # to be present always So it is not 'required'.
         'required': ['flavors']
@@ -56,6 +58,7 @@
         'rxtx_factor': {'type': 'number'},
         'OS-FLV-EXT-DATA:ephemeral': {'type': 'integer'}
     },
+    'additionalProperties': False,
     # 'OS-FLV-DISABLED', 'os-flavor-access', 'rxtx_factor' and
     # 'OS-FLV-EXT-DATA' are API extensions. So they are not 'required'.
     'required': ['name', 'links', 'ram', 'vcpus', 'swap', 'disk', 'id']
@@ -74,6 +77,7 @@
             # to be present always So it is not 'required'.
             'flavors_links': parameter_types.links
         },
+        'additionalProperties': False,
         'required': ['flavors']
     }
 }
@@ -89,6 +93,7 @@
         'properties': {
             'flavor': common_flavor_info
         },
+        'additionalProperties': False,
         'required': ['flavor']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/flavors_access.py b/tempest/api_schema/response/compute/v2_1/flavors_access.py
index cd31b0a..a4d6af0 100644
--- a/tempest/api_schema/response/compute/v2_1/flavors_access.py
+++ b/tempest/api_schema/response/compute/v2_1/flavors_access.py
@@ -25,10 +25,12 @@
                         'flavor_id': {'type': 'string'},
                         'tenant_id': {'type': 'string'},
                     },
+                    'additionalProperties': False,
                     'required': ['flavor_id', 'tenant_id'],
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['flavor_access']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py b/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py
index faa25d0..a438d48 100644
--- a/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py
+++ b/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py
@@ -24,6 +24,7 @@
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['extra_specs']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/floating_ips.py b/tempest/api_schema/response/compute/v2_1/floating_ips.py
index ad1c531..28dd40a 100644
--- a/tempest/api_schema/response/compute/v2_1/floating_ips.py
+++ b/tempest/api_schema/response/compute/v2_1/floating_ips.py
@@ -30,6 +30,7 @@
             'format': 'ip-address'
         }
     },
+    'additionalProperties': False,
     'required': ['id', 'pool', 'instance_id',
                  'ip', 'fixed_ip'],
 
@@ -44,6 +45,7 @@
                 'items': common_floating_ip_info
             },
         },
+        'additionalProperties': False,
         'required': ['floating_ips'],
     }
 }
@@ -55,6 +57,7 @@
         'properties': {
             'floating_ip': common_floating_ip_info
         },
+        'additionalProperties': False,
         'required': ['floating_ip'],
     }
 }
@@ -71,10 +74,12 @@
                     'properties': {
                         'name': {'type': 'string'}
                     },
+                    'additionalProperties': False,
                     'required': ['name'],
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['floating_ip_pools'],
     }
 }
@@ -95,9 +100,11 @@
                     'ip_range': {'type': 'string'},
                     'pool': {'type': ['string', 'null']},
                 },
+                'additionalProperties': False,
                 'required': ['interface', 'ip_range', 'pool'],
             }
         },
+        'additionalProperties': False,
         'required': ['floating_ips_bulk_create'],
     }
 }
@@ -109,6 +116,7 @@
         'properties': {
             'floating_ips_bulk_delete': {'type': 'string'}
         },
+        'additionalProperties': False,
         'required': ['floating_ips_bulk_delete'],
     }
 }
@@ -136,6 +144,7 @@
                             'format': 'ip-address'
                         }
                     },
+                    'additionalProperties': False,
                     # NOTE: fixed_ip is introduced after JUNO release,
                     # So it is not defined as 'required'.
                     'required': ['address', 'instance_uuid', 'interface',
@@ -143,6 +152,7 @@
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['floating_ip_info'],
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/hosts.py b/tempest/api_schema/response/compute/v2_1/hosts.py
index 72d5a07..ae70ff1 100644
--- a/tempest/api_schema/response/compute/v2_1/hosts.py
+++ b/tempest/api_schema/response/compute/v2_1/hosts.py
@@ -29,10 +29,12 @@
                         'service': {'type': 'string'},
                         'zone': {'type': 'string'}
                     },
+                    'additionalProperties': False,
                     'required': ['host_name', 'service', 'zone']
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['hosts']
     }
 }
@@ -56,14 +58,17 @@
                                 'memory_mb': {'type': 'integer'},
                                 'project': {'type': 'string'}
                             },
+                            'additionalProperties': False,
                             'required': ['cpu', 'disk_gb', 'host',
                                          'memory_mb', 'project']
                         }
                     },
+                    'additionalProperties': False,
                     'required': ['resource']
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['host']
     }
 }
@@ -76,6 +81,7 @@
             'host': {'type': 'string'},
             'power_action': {'enum': ['startup']}
         },
+        'additionalProperties': False,
         'required': ['host', 'power_action']
     }
 }
@@ -104,6 +110,7 @@
                                           'off_maintenance']},
             'status': {'enum': ['enabled', 'disabled']}
         },
+        'additionalProperties': False,
         'required': ['host', 'maintenance_mode', 'status']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/hypervisors.py b/tempest/api_schema/response/compute/v2_1/hypervisors.py
index 3efa46b..e24389d 100644
--- a/tempest/api_schema/response/compute/v2_1/hypervisors.py
+++ b/tempest/api_schema/response/compute/v2_1/hypervisors.py
@@ -35,6 +35,7 @@
                     'vcpus': {'type': 'integer'},
                     'vcpus_used': {'type': 'integer'}
                 },
+                'additionalProperties': False,
                 'required': ['count', 'current_workload',
                              'disk_available_least', 'free_disk_gb',
                              'free_ram_mb', 'local_gb', 'local_gb_used',
@@ -42,6 +43,7 @@
                              'vcpus', 'vcpus_used']
             }
         },
+        'additionalProperties': False,
         'required': ['hypervisor_statistics']
     }
 }
@@ -77,11 +79,13 @@
                 'id': {'type': ['integer', 'string']},
                 'disabled_reason': {'type': ['string', 'null']}
             },
+            'additionalProperties': False,
             'required': ['host', 'id']
         },
         'vcpus': {'type': 'integer'},
         'vcpus_used': {'type': 'integer'}
     },
+    'additionalProperties': False,
     # NOTE: When loading os-hypervisor-status extension,
     # a response contains status and state. So these params
     # should not be required.
@@ -104,6 +108,7 @@
                 'items': hypervisor_detail
             }
         },
+        'additionalProperties': False,
         'required': ['hypervisors']
     }
 }
@@ -115,6 +120,7 @@
         'properties': {
             'hypervisor': hypervisor_detail
         },
+        'additionalProperties': False,
         'required': ['hypervisor']
     }
 }
@@ -134,6 +140,7 @@
                         'id': {'type': ['integer', 'string']},
                         'hypervisor_hostname': {'type': 'string'}
                     },
+                    'additionalProperties': False,
                     # NOTE: When loading os-hypervisor-status extension,
                     # a response contains status and state. So these params
                     # should not be required.
@@ -141,6 +148,7 @@
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['hypervisors']
     }
 }
@@ -159,12 +167,14 @@
                     'hypervisor_hostname': {'type': 'string'},
                     'uptime': {'type': 'string'}
                 },
+                'additionalProperties': False,
                 # NOTE: When loading os-hypervisor-status extension,
                 # a response contains status and state. So these params
                 # should not be required.
                 'required': ['id', 'hypervisor_hostname', 'uptime']
             }
         },
+        'additionalProperties': False,
         'required': ['hypervisor']
     }
 }
@@ -178,7 +188,8 @@
             'properties': {
                 'uuid': {'type': 'string'},
                 'name': {'type': 'string'}
-            }
+            },
+            'additionalProperties': False,
         }
     }
 # In V2 API, if there is no servers (VM) on the Hypervisor host then 'servers'
diff --git a/tempest/api_schema/response/compute/v2_1/images.py b/tempest/api_schema/response/compute/v2_1/images.py
index e6f8db6..a513dcb 100644
--- a/tempest/api_schema/response/compute/v2_1/images.py
+++ b/tempest/api_schema/response/compute/v2_1/images.py
@@ -38,11 +38,13 @@
                 'id': {'type': 'string'},
                 'links': parameter_types.links
             },
+            'additionalProperties': False,
             'required': ['id', 'links']
         },
         'OS-EXT-IMG-SIZE:size': {'type': 'integer'},
         'OS-DCF:diskConfig': {'type': 'string'}
     },
+    'additionalProperties': False,
     # 'server' attributes only comes in response body if image is
     # associated with any server. 'OS-EXT-IMG-SIZE:size' & 'OS-DCF:diskConfig'
     # are API extension,  So those are not defined as 'required'.
@@ -58,6 +60,7 @@
         'properties': {
             'image': common_image_schema
         },
+        'additionalProperties': False,
         'required': ['image']
     }
 }
@@ -76,11 +79,13 @@
                         'links': image_links,
                         'name': {'type': 'string'}
                     },
+                    'additionalProperties': False,
                     'required': ['id', 'links', 'name']
                 }
             },
             'images_links': parameter_types.links
         },
+        'additionalProperties': False,
         # NOTE(gmann): images_links attribute is not necessary to be
         # present always So it is not 'required'.
         'required': ['images']
@@ -113,6 +118,7 @@
         'properties': {
             'metadata': {'type': 'object'}
         },
+        'additionalProperties': False,
         'required': ['metadata']
     }
 }
@@ -124,6 +130,7 @@
         'properties': {
             'meta': {'type': 'object'}
         },
+        'additionalProperties': False,
         'required': ['meta']
     }
 }
@@ -139,6 +146,7 @@
             },
             'images_links': parameter_types.links
         },
+        'additionalProperties': False,
         # NOTE(gmann): images_links attribute is not necessary to be
         # present always So it is not 'required'.
         'required': ['images']
diff --git a/tempest/api_schema/response/compute/v2_1/instance_usage_audit_logs.py b/tempest/api_schema/response/compute/v2_1/instance_usage_audit_logs.py
index 658f574..c6c4deb 100644
--- a/tempest/api_schema/response/compute/v2_1/instance_usage_audit_logs.py
+++ b/tempest/api_schema/response/compute/v2_1/instance_usage_audit_logs.py
@@ -30,6 +30,7 @@
         'total_errors': {'type': 'integer'},
         'total_instances': {'type': 'integer'}
     },
+    'additionalProperties': False,
     'required': ['hosts_not_run', 'log', 'num_hosts', 'num_hosts_done',
                  'num_hosts_not_run', 'num_hosts_running', 'overall_status',
                  'period_beginning', 'period_ending', 'total_errors',
@@ -43,6 +44,7 @@
         'properties': {
             'instance_usage_audit_log': common_instance_usage_audit_log
         },
+        'additionalProperties': False,
         'required': ['instance_usage_audit_log']
     }
 }
@@ -54,6 +56,7 @@
         'properties': {
             'instance_usage_audit_logs': common_instance_usage_audit_log
         },
+        'additionalProperties': False,
         'required': ['instance_usage_audit_logs']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/interfaces.py b/tempest/api_schema/response/compute/v2_1/interfaces.py
index 033f816..b18fba6 100644
--- a/tempest/api_schema/response/compute/v2_1/interfaces.py
+++ b/tempest/api_schema/response/compute/v2_1/interfaces.py
@@ -32,6 +32,7 @@
                         'format': 'ipv4'
                     }
                 },
+                'additionalProperties': False,
                 'required': ['subnet_id', 'ip_address']
             }
         },
@@ -39,6 +40,7 @@
         'net_id': {'type': 'string', 'format': 'uuid'},
         'mac_addr': parameter_types.mac_address
     },
+    'additionalProperties': False,
     'required': ['port_state', 'fixed_ips', 'port_id', 'net_id', 'mac_addr']
 }
 
@@ -49,6 +51,7 @@
         'properties': {
             'interfaceAttachment': interface_common_info
         },
+        'additionalProperties': False,
         'required': ['interfaceAttachment']
     }
 }
@@ -63,6 +66,7 @@
                 'items': interface_common_info
             }
         },
+        'additionalProperties': False,
         'required': ['interfaceAttachments']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/keypairs.py b/tempest/api_schema/response/compute/v2_1/keypairs.py
index ceae6cf..9c04c79 100644
--- a/tempest/api_schema/response/compute/v2_1/keypairs.py
+++ b/tempest/api_schema/response/compute/v2_1/keypairs.py
@@ -31,6 +31,7 @@
                     'id': {'type': 'integer'}
 
                 },
+                'additionalProperties': False,
                 # When we run the get keypair API, response body includes
                 # all the above mentioned attributes.
                 # But in Nova API sample file, response body includes only
@@ -39,6 +40,7 @@
                 'required': ['public_key', 'name', 'fingerprint']
             }
         },
+        'additionalProperties': False,
         'required': ['keypair']
     }
 }
@@ -57,12 +59,14 @@
                     'user_id': {'type': 'string'},
                     'private_key': {'type': 'string'}
                 },
+                'additionalProperties': False,
                 # When create keypair API is being called with 'Public key'
                 # (Importing keypair) then, response body does not contain
                 # 'private_key' So it is not defined as 'required'
                 'required': ['fingerprint', 'name', 'public_key', 'user_id']
             }
         },
+        'additionalProperties': False,
         'required': ['keypair']
     }
 }
@@ -88,13 +92,16 @@
                                 'name': {'type': 'string'},
                                 'fingerprint': {'type': 'string'}
                             },
+                            'additionalProperties': False,
                             'required': ['public_key', 'name', 'fingerprint']
                         }
                     },
+                    'additionalProperties': False,
                     'required': ['keypair']
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['keypairs']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/limits.py b/tempest/api_schema/response/compute/v2_1/limits.py
index a7decb7..81f175f 100644
--- a/tempest/api_schema/response/compute/v2_1/limits.py
+++ b/tempest/api_schema/response/compute/v2_1/limits.py
@@ -43,6 +43,7 @@
                             'maxServerGroups': {'type': 'integer'},
                             'totalServerGroupsUsed': {'type': 'integer'}
                         },
+                        'additionalProperties': False,
                         # NOTE(gmann): maxServerGroupMembers,  maxServerGroups
                         # and totalServerGroupsUsed are API extension,
                         # and some environments return a response without these
@@ -84,18 +85,22 @@
                                                 {'type': 'integer'},
                                             'verb':
                                                 {'type': 'string'}
-                                        }
+                                        },
+                                        'additionalProperties': False,
                                     }
                                 },
                                 'regex': {'type': 'string'},
                                 'uri': {'type': 'string'}
-                            }
+                            },
+                            'additionalProperties': False,
                         }
                     }
                 },
+                'additionalProperties': False,
                 'required': ['absolute', 'rate']
             }
         },
+        'additionalProperties': False,
         'required': ['limits']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/migrations.py b/tempest/api_schema/response/compute/v2_1/migrations.py
index 6549272..722372c 100644
--- a/tempest/api_schema/response/compute/v2_1/migrations.py
+++ b/tempest/api_schema/response/compute/v2_1/migrations.py
@@ -35,6 +35,7 @@
                         'created_at': {'type': 'string'},
                         'updated_at': {'type': ['string', 'null']}
                     },
+                    'additionalProperties': False,
                     'required': [
                         'id', 'status', 'instance_uuid', 'source_node',
                         'source_compute', 'dest_node', 'dest_compute',
@@ -44,6 +45,7 @@
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['migrations']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/parameter_types.py b/tempest/api_schema/response/compute/v2_1/parameter_types.py
index 90d4c8f..7b4264c 100644
--- a/tempest/api_schema/response/compute/v2_1/parameter_types.py
+++ b/tempest/api_schema/response/compute/v2_1/parameter_types.py
@@ -23,6 +23,7 @@
             },
             'rel': {'type': 'string'}
         },
+        'additionalProperties': False,
         'required': ['href', 'rel']
     }
 }
@@ -60,6 +61,7 @@
                         ]
                     }
                 },
+                'additionalProperties': False,
                 'required': ['version', 'addr']
             }
         }
diff --git a/tempest/api_schema/response/compute/v2_1/quotas.py b/tempest/api_schema/response/compute/v2_1/quotas.py
index 9141f7e..7953983 100644
--- a/tempest/api_schema/response/compute/v2_1/quotas.py
+++ b/tempest/api_schema/response/compute/v2_1/quotas.py
@@ -37,6 +37,7 @@
                     'injected_file_content_bytes': {'type': 'integer'},
                     'injected_file_path_bytes': {'type': 'integer'}
                 },
+                'additionalProperties': False,
                 # NOTE: server_group_members and server_groups are represented
                 # when enabling quota_server_group extension. So they should
                 # not be required.
@@ -48,6 +49,7 @@
                              'injected_file_path_bytes']
             }
         },
+        'additionalProperties': False,
         'required': ['quota_set']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/security_group_default_rule.py b/tempest/api_schema/response/compute/v2_1/security_group_default_rule.py
index 9246ab8..2ec2826 100644
--- a/tempest/api_schema/response/compute/v2_1/security_group_default_rule.py
+++ b/tempest/api_schema/response/compute/v2_1/security_group_default_rule.py
@@ -23,10 +23,12 @@
             'properties': {
                 'cidr': {'type': 'string'}
             },
+            'additionalProperties': False,
             'required': ['cidr'],
         },
         'to_port': {'type': 'integer'},
     },
+    'additionalProperties': False,
     'required': ['from_port', 'id', 'ip_protocol', 'ip_range', 'to_port'],
 }
 
@@ -38,6 +40,7 @@
             'security_group_default_rule':
                 common_security_group_default_rule_info
         },
+        'additionalProperties': False,
         'required': ['security_group_default_rule']
     }
 }
@@ -56,6 +59,7 @@
                 'items': common_security_group_default_rule_info
             }
         },
+        'additionalProperties': False,
         'required': ['security_group_default_rules']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/security_groups.py b/tempest/api_schema/response/compute/v2_1/security_groups.py
index 9a852e5..5ed5a5c 100644
--- a/tempest/api_schema/response/compute/v2_1/security_groups.py
+++ b/tempest/api_schema/response/compute/v2_1/security_groups.py
@@ -20,7 +20,8 @@
         'properties': {
             'tenant_id': {'type': 'string'},
             'name': {'type': 'string'}
-        }
+        },
+        'additionalProperties': False,
     },
     'ip_protocol': {'type': ['string', 'null']},
     # 'parent_group_id' can be UUID so defining it as 'string' also.
@@ -29,7 +30,8 @@
         'type': 'object',
         'properties': {
             'cidr': {'type': 'string'}
-        }
+        },
+        'additionalProperties': False,
         # When optional argument is provided in request body
         # like 'group_id' then, attribute 'cidr' does not
         # comes in response body. So it is not 'required'.
@@ -47,11 +49,13 @@
             'type': 'array',
             'items': {
                 'type': ['object', 'null'],
-                'properties': common_security_group_rule
+                'properties': common_security_group_rule,
+                'additionalProperties': False,
             }
         },
         'description': {'type': 'string'},
     },
+    'additionalProperties': False,
     'required': ['id', 'name', 'tenant_id', 'rules', 'description'],
 }
 
@@ -65,6 +69,7 @@
                 'items': common_security_group
             }
         },
+        'additionalProperties': False,
         'required': ['security_groups']
     }
 }
@@ -76,6 +81,7 @@
         'properties': {
             'security_group': common_security_group
         },
+        'additionalProperties': False,
         'required': ['security_group']
     }
 }
@@ -92,10 +98,12 @@
             'security_group_rule': {
                 'type': 'object',
                 'properties': common_security_group_rule,
+                'additionalProperties': False,
                 'required': ['from_port', 'to_port', 'group', 'ip_protocol',
                              'parent_group_id', 'id', 'ip_range']
             }
         },
+        'additionalProperties': False,
         'required': ['security_group_rule']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/servers.py b/tempest/api_schema/response/compute/v2_1/servers.py
index 875f607..44ab9e9 100644
--- a/tempest/api_schema/response/compute/v2_1/servers.py
+++ b/tempest/api_schema/response/compute/v2_1/servers.py
@@ -29,12 +29,14 @@
                     'links': parameter_types.links,
                     'OS-DCF:diskConfig': {'type': 'string'}
                 },
+                'additionalProperties': False,
                 # NOTE: OS-DCF:diskConfig & security_groups are API extension,
                 # and some environments return a response without these
                 # attributes.So they are not 'required'.
                 'required': ['id', 'links']
             }
         },
+        'additionalProperties': False,
         'required': ['server']
     }
 }
@@ -59,11 +61,13 @@
                         'links': parameter_types.links,
                         'name': {'type': 'string'}
                     },
+                    'additionalProperties': False,
                     'required': ['id', 'links', 'name']
                 }
             },
             'servers_links': parameter_types.links
         },
+        'additionalProperties': False,
         # NOTE(gmann): servers_links attribute is not necessary to be
         # present always So it is not 'required'.
         'required': ['servers']
@@ -86,6 +90,7 @@
                     'id': {'type': 'string'},
                     'links': parameter_types.links
                 },
+                'additionalProperties': False,
                 'required': ['id', 'links']},
             {'type': ['string', 'null']}
         ]},
@@ -95,6 +100,7 @@
                 'id': {'type': 'string'},
                 'links': parameter_types.links
             },
+            'additionalProperties': False,
             'required': ['id', 'links']
         },
         'fault': {
@@ -105,6 +111,7 @@
                 'message': {'type': 'string'},
                 'details': {'type': 'string'},
             },
+            'additionalProperties': False,
             # NOTE(gmann): 'details' is not necessary to be present
             #  in the 'fault'. So it is not defined as 'required'.
             'required': ['code', 'created', 'message']
@@ -122,6 +129,7 @@
         'accessIPv4': parameter_types.access_ip_v4,
         'accessIPv6': parameter_types.access_ip_v6
     },
+    'additionalProperties': False,
     # 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")
@@ -142,6 +150,7 @@
         'properties': {
             'server': common_show_server
         },
+        'additionalProperties': False,
         'required': ['server']
     }
 }
@@ -184,6 +193,7 @@
         'properties': {
             'server': server_detail
         },
+        'additionalProperties': False,
         'required': ['server']
     }
 }
@@ -199,6 +209,7 @@
             },
             'servers_links': parameter_types.links
         },
+        'additionalProperties': False,
         # NOTE(gmann): servers_links attribute is not necessary to be
         # present always So it is not 'required'.
         'required': ['servers']
@@ -221,6 +232,7 @@
         'properties': {
             'adminPass': {'type': 'string'}
         },
+        'additionalProperties': False,
         'required': ['adminPass']
     }
 }
@@ -239,12 +251,14 @@
                         'mac_address': parameter_types.mac_address,
                         'OS-EXT-VIF-NET:net_id': {'type': 'string'}
                     },
+                    'additionalProperties': False,
                     # 'OS-EXT-VIF-NET:net_id' is API extension So it is
                     # not defined as 'required'
                     'required': ['id', 'mac_address']
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['virtual_interfaces']
     }
 }
@@ -257,6 +271,7 @@
         'volumeId': {'type': 'string'},
         'serverId': {'type': ['integer', 'string']}
     },
+    'additionalProperties': False,
     'required': ['id', 'device', 'volumeId', 'serverId']
 }
 
@@ -267,6 +282,7 @@
         'properties': {
             'volumeAttachment': common_attach_volume_info
         },
+        'additionalProperties': False,
         'required': ['volumeAttachment']
     }
 }
@@ -289,6 +305,7 @@
                 'items': common_attach_volume_info
             }
         },
+        'additionalProperties': False,
         'required': ['volumeAttachments']
     }
 }
@@ -308,6 +325,7 @@
         'properties': {
             'addresses': parameter_types.addresses
         },
+        'additionalProperties': False,
         'required': ['addresses']
     }
 }
@@ -329,6 +347,7 @@
         },
         'metadata': {'type': 'object'}
     },
+    'additionalProperties': False,
     'required': ['id', 'name', 'policies', 'members', 'metadata']
 }
 
@@ -339,6 +358,7 @@
         'properties': {
             'server_group': common_server_group
         },
+        'additionalProperties': False,
         'required': ['server_group']
     }
 }
@@ -357,6 +377,7 @@
                 'items': common_server_group
             }
         },
+        'additionalProperties': False,
         'required': ['server_groups']
     }
 }
@@ -372,6 +393,7 @@
         'message': {'type': ['string', 'null']},
         'instance_uuid': {'type': 'string'}
     },
+    'additionalProperties': False,
     'required': ['action', 'request_id', 'user_id', 'project_id',
                  'start_time', 'message', 'instance_uuid']
 }
@@ -387,6 +409,7 @@
             'result': {'type': 'string'},
             'traceback': {'type': ['string', 'null']}
         },
+        'additionalProperties': False,
         'required': ['event', 'start_time', 'finish_time', 'result',
                      'traceback']
     }
@@ -402,6 +425,7 @@
                 'items': instance_actions
             }
         },
+        'additionalProperties': False,
         'required': ['instanceActions']
     }
 }
@@ -419,6 +443,7 @@
         'properties': {
             'instanceAction': instance_actions_with_events
         },
+        'additionalProperties': False,
         'required': ['instanceAction']
     }
 }
@@ -430,6 +455,7 @@
         'properties': {
             'password': {'type': 'string'}
         },
+        'additionalProperties': False,
         'required': ['password']
     }
 }
@@ -448,9 +474,11 @@
                         'format': 'uri'
                     }
                 },
+                'additionalProperties': False,
                 'required': ['type', 'url']
             }
         },
+        'additionalProperties': False,
         'required': ['console']
     }
 }
@@ -462,6 +490,7 @@
         'properties': {
             'output': {'type': 'string'}
         },
+        'additionalProperties': False,
         'required': ['output']
     }
 }
@@ -478,6 +507,7 @@
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['metadata']
     }
 }
@@ -502,6 +532,7 @@
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['meta']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/services.py b/tempest/api_schema/response/compute/v2_1/services.py
index 6f361ef..c2c7a51 100644
--- a/tempest/api_schema/response/compute/v2_1/services.py
+++ b/tempest/api_schema/response/compute/v2_1/services.py
@@ -32,11 +32,13 @@
                         'updated_at': {'type': ['string', 'null']},
                         'disabled_reason': {'type': ['string', 'null']}
                     },
+                    'additionalProperties': False,
                     'required': ['id', 'zone', 'host', 'state', 'binary',
                                  'status', 'updated_at', 'disabled_reason']
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['services']
     }
 }
@@ -53,9 +55,11 @@
                     'binary': {'type': 'string'},
                     'host': {'type': 'string'}
                 },
+                'additionalProperties': False,
                 'required': ['status', 'binary', 'host']
             }
         },
+        'additionalProperties': False,
         'required': ['service']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/tenant_networks.py b/tempest/api_schema/response/compute/v2_1/tenant_networks.py
index 0b2868a..ddfab96 100644
--- a/tempest/api_schema/response/compute/v2_1/tenant_networks.py
+++ b/tempest/api_schema/response/compute/v2_1/tenant_networks.py
@@ -19,6 +19,7 @@
         'cidr': {'type': ['string', 'null']},
         'label': {'type': 'string'}
     },
+    'additionalProperties': False,
     'required': ['id', 'cidr', 'label']
 }
 
@@ -33,6 +34,7 @@
                 'items': param_network
             }
         },
+        'additionalProperties': False,
         'required': ['networks']
     }
 }
@@ -45,6 +47,7 @@
         'properties': {
             'network': param_network
         },
+        'additionalProperties': False,
         'required': ['network']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2_1/volumes.py b/tempest/api_schema/response/compute/v2_1/volumes.py
index 541d3ff..bb34acb 100644
--- a/tempest/api_schema/response/compute/v2_1/volumes.py
+++ b/tempest/api_schema/response/compute/v2_1/volumes.py
@@ -39,7 +39,8 @@
                                 'device': {'type': 'string'},
                                 'volumeId': {'type': 'string'},
                                 'serverId': {'type': 'string'}
-                            }
+                            },
+                            'additionalProperties': False,
                             # NOTE- If volume is not attached to any server
                             # then, 'attachments' attributes comes as array
                             # with empty objects "[{}]" due to that elements
@@ -49,11 +50,13 @@
                         }
                     }
                 },
+                'additionalProperties': False,
                 'required': ['id', 'status', 'displayName', 'availabilityZone',
                              'createdAt', 'displayDescription', 'volumeType',
                              'snapshotId', 'metadata', 'size', 'attachments']
             }
         },
+        'additionalProperties': False,
         'required': ['volume']
     }
 }
@@ -87,7 +90,8 @@
                                     'device': {'type': 'string'},
                                     'volumeId': {'type': 'string'},
                                     'serverId': {'type': 'string'}
-                                }
+                                },
+                                'additionalProperties': False,
                                 # NOTE- If volume is not attached to any server
                                 # then, 'attachments' attributes comes as array
                                 # with empty object "[{}]" due to that elements
@@ -97,6 +101,7 @@
                             }
                         }
                     },
+                    'additionalProperties': False,
                     'required': ['id', 'status', 'displayName',
                                  'availabilityZone', 'createdAt',
                                  'displayDescription', 'volumeType',
@@ -105,6 +110,7 @@
                 }
             }
         },
+        'additionalProperties': False,
         'required': ['volumes']
     }
 }
diff --git a/tempest/clients.py b/tempest/clients.py
index 9f6a9bb..f0aedd5 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -56,7 +56,8 @@
 from tempest.services.compute.json.migrations_client import \
     MigrationsClientJSON
 from tempest.services.compute.json.networks_client import NetworksClientJSON
-from tempest.services.compute.json.quotas_client import QuotaClassesClientJSON
+from tempest.services.compute.json.quota_classes_client import \
+    QuotaClassesClientJSON
 from tempest.services.compute.json.quotas_client import QuotasClientJSON
 from tempest.services.compute.json.security_group_default_rules_client import \
     SecurityGroupDefaultRulesClientJSON
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 4dc03f9..8ec4670 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -378,7 +378,7 @@
     def dry_run(self):
         client = self.limits_client
         quotas = client.show_limits()
-        self.data['compute_quotas'] = quotas
+        self.data['compute_quotas'] = quotas['absolute']
 
 
 # Begin network service classes
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
new file mode 100644
index 0000000..5de4b0e
--- /dev/null
+++ b/tempest/common/compute.py
@@ -0,0 +1,124 @@
+# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+
+from oslo_log import log as logging
+from oslo_utils import excutils
+from tempest_lib.common.utils import data_utils
+
+from tempest.common import fixed_network
+from tempest import config
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+
+def create_test_server(clients, validatable, validation_resources=None,
+                       tenant_network=None, **kwargs):
+    """Common wrapper utility returning a test server.
+
+    This method is a common wrapper returning a test server that can be
+    pingable or sshable.
+
+    :param clients: Client manager which provides Openstack Tempest clients.
+    :param validatable: Whether the server will be pingable or sshable.
+    :param validation_resources: Resources created for the connection to the
+    server. Include a keypair, a security group and an IP.
+    :returns a tuple
+    """
+
+    # TODO(jlanoux) add support of wait_until PINGABLE/SSHABLE
+
+    if 'name' in kwargs:
+        name = kwargs.pop('name')
+    else:
+        name = data_utils.rand_name(__name__ + "-instance")
+
+    flavor = kwargs.get('flavor', CONF.compute.flavor_ref)
+    image_id = kwargs.get('image_id', CONF.compute.image_ref)
+
+    kwargs = fixed_network.set_networks_kwarg(
+        tenant_network, kwargs) or {}
+
+    if CONF.validation.run_validation and validatable:
+        # As a first implementation, multiple pingable or sshable servers will
+        # not be supported
+        if 'min_count' in kwargs or 'max_count' in kwargs:
+            msg = ("Multiple pingable or sshable servers not supported at "
+                   "this stage.")
+            raise ValueError(msg)
+
+        if 'security_groups' in kwargs:
+            kwargs['security_groups'].append(
+                {'name': validation_resources['security_group']['name']})
+        else:
+            try:
+                kwargs['security_groups'] = [
+                    {'name': validation_resources['security_group']['name']}]
+            except KeyError:
+                LOG.debug("No security group provided.")
+
+        if 'key_name' not in kwargs:
+            try:
+                kwargs['key_name'] = validation_resources['keypair']['name']
+            except KeyError:
+                LOG.debug("No key provided.")
+
+        if CONF.validation.connect_method == 'floating':
+            if 'wait_until' not in kwargs:
+                kwargs['wait_until'] = 'ACTIVE'
+
+    body = clients.servers_client.create_server(name, image_id, flavor,
+                                                **kwargs)
+
+    # handle the case of multiple servers
+    servers = [body]
+    if 'min_count' in kwargs or 'max_count' in kwargs:
+        # Get servers created which name match with name param.
+        body_servers = clients.servers_client.list_servers()
+        servers = \
+            [s for s in body_servers['servers'] if s['name'].startswith(name)]
+
+    # The name of the method to associate a floating IP to as server is too
+    # long for PEP8 compliance so:
+    assoc = clients.floating_ips_client.associate_floating_ip_to_server
+
+    if 'wait_until' in kwargs:
+        for server in servers:
+            try:
+                clients.servers_client.wait_for_server_status(
+                    server['id'], kwargs['wait_until'])
+
+                # Multiple validatable servers are not supported for now. Their
+                # creation will fail with the condition above (l.58).
+                if CONF.validation.run_validation and validatable:
+                    if CONF.validation.connect_method == 'floating':
+                        assoc(floating_ip=validation_resources[
+                              'floating_ip']['ip'],
+                              server_id=servers[0]['id'])
+
+            except Exception:
+                with excutils.save_and_reraise_exception():
+                    if ('preserve_server_on_error' not in kwargs
+                        or kwargs['preserve_server_on_error'] is False):
+                        for server in servers:
+                            try:
+                                clients.servers_client.delete_server(
+                                    server['id'])
+                            except Exception:
+                                LOG.exception('Deleting server %s failed'
+                                              % server['id'])
+
+    return body, servers
diff --git a/tempest/common/fixed_network.py b/tempest/common/fixed_network.py
index 18386ce..de44c4d 100644
--- a/tempest/common/fixed_network.py
+++ b/tempest/common/fixed_network.py
@@ -40,7 +40,8 @@
     if not name:
         raise exceptions.InvalidConfiguration()
 
-    networks = compute_networks_client.list_networks(name=name)
+    networks = compute_networks_client.list_networks()
+    networks = [n for n in networks if n['label'] == name]
 
     # Check that a network exists, else raise an InvalidConfigurationException
     if len(networks) == 1:
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 4b3995b..d4e6eb8 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -14,6 +14,7 @@
 import re
 import time
 
+from oslo_log import log as logging
 import six
 from tempest_lib.common import ssh
 
@@ -22,6 +23,8 @@
 
 CONF = config.CONF
 
+LOG = logging.getLogger(__name__)
+
 
 class RemoteClient(object):
 
@@ -48,7 +51,8 @@
     def exec_command(self, cmd):
         # Shell options below add more clearness on failures,
         # path is extended for some non-cirros guest oses (centos7)
-        cmd = "set -eu -o pipefail; PATH=$PATH:/sbin; " + cmd
+        cmd = CONF.compute.ssh_shell_prologue + " " + cmd
+        LOG.debug("Remote command: %s" % cmd)
         return self.ssh_client.exec_command(cmd)
 
     def validate_authentication(self):
diff --git a/tempest/config.py b/tempest/config.py
index 0fa5bf5..fc55723 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -206,6 +206,10 @@
                help="Timeout in seconds to wait for an instance to build. "
                     "Other services that do not define build_timeout will "
                     "inherit this value."),
+    cfg.StrOpt('ssh_shell_prologue',
+               default="set -eu -o pipefail; PATH=$$PATH:/sbin;",
+               help="Shell fragments to use before executing a command "
+                    "when sshing to a guest."),
     cfg.StrOpt('ssh_auth_method',
                default='keypair',
                help="Auth method used for authenticate to the instance. "
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index 29898a9..db6375f 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -27,6 +27,7 @@
 SETUP_TEARDOWN_CLASS_DEFINITION = re.compile(r'^\s+def (setUp|tearDown)Class')
 SCENARIO_DECORATOR = re.compile(r'\s*@.*services\((.*)\)')
 VI_HEADER_RE = re.compile(r"^#\s+vim?:.+")
+RAND_NAME_HYPHEN_RE = re.compile(r".*rand_name\(.+[\-\_][\"\']\)")
 mutable_default_args = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
 
 
@@ -106,6 +107,21 @@
                             "T107: service tag should not be in path")
 
 
+def no_hyphen_at_end_of_rand_name(logical_line, filename):
+    """Check no hyphen at the end of rand_name() argument
+
+    T108
+    """
+    if './tempest/api/network/' in filename:
+        # Network API tests are migrating from Tempest to Neutron repo now.
+        # So here should avoid network API tests checks.
+        return
+
+    msg = "T108: hyphen should not be specified at the end of rand_name()"
+    if RAND_NAME_HYPHEN_RE.match(logical_line):
+        return 0, msg
+
+
 def no_mutable_default_args(logical_line):
     """Check that mutable object isn't used as default argument
 
@@ -122,4 +138,5 @@
     register(no_setup_teardown_class_for_tests)
     register(no_vi_headers)
     register(service_tags_not_in_module_path)
+    register(no_hyphen_at_end_of_rand_name)
     register(no_mutable_default_args)
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index 347467d..1454b73 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -25,13 +25,4 @@
         resp, body = self.get("limits")
         body = json.loads(body)
         self.validate_response(schema.get_limit, resp, body)
-        return service_client.ResponseBody(resp, body['limits']['absolute'])
-
-    def get_specific_absolute_limit(self, absolute_limit):
-        resp, body = self.get("limits")
-        body = json.loads(body)
-        self.validate_response(schema.get_limit, resp, body)
-        if absolute_limit not in body['limits']['absolute']:
-            return None
-        else:
-            return body['limits']['absolute'][absolute_limit]
+        return service_client.ResponseBody(resp, body['limits'])
diff --git a/tempest/services/compute/json/networks_client.py b/tempest/services/compute/json/networks_client.py
index 0ae0920..e641787 100644
--- a/tempest/services/compute/json/networks_client.py
+++ b/tempest/services/compute/json/networks_client.py
@@ -20,17 +20,13 @@
 
 class NetworksClientJSON(service_client.ServiceClient):
 
-    def list_networks(self, name=None):
+    def list_networks(self):
         resp, body = self.get("os-networks")
         body = json.loads(body)
         self.expected_success(200, resp.status)
-        if name:
-            networks = [n for n in body['networks'] if n['label'] == name]
-        else:
-            networks = body['networks']
-        return service_client.ResponseBodyList(resp, networks)
+        return service_client.ResponseBodyList(resp, body['networks'])
 
-    def get_network(self, network_id):
+    def show_network(self, network_id):
         resp, body = self.get("os-networks/%s" % str(network_id))
         body = json.loads(body)
         self.expected_success(200, resp.status)
diff --git a/tempest/services/compute/json/quota_classes_client.py b/tempest/services/compute/json/quota_classes_client.py
new file mode 100644
index 0000000..ad35e3f
--- /dev/null
+++ b/tempest/services/compute/json/quota_classes_client.py
@@ -0,0 +1,46 @@
+# Copyright 2012 NTT Data
+# 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 json
+
+from tempest.api_schema.response.compute.v2_1\
+    import quota_classes as classes_schema
+from tempest.common import service_client
+
+
+class QuotaClassesClientJSON(service_client.ServiceClient):
+
+    def show_quota_class_set(self, quota_class_id):
+        """List the quota class set for a quota class."""
+
+        url = 'os-quota-class-sets/%s' % quota_class_id
+        resp, body = self.get(url)
+        body = json.loads(body)
+        self.validate_response(classes_schema.get_quota_class_set, resp, body)
+        return service_client.ResponseBody(resp, body['quota_class_set'])
+
+    def update_quota_class_set(self, quota_class_id, **kwargs):
+        """
+        Updates the quota class's limits for one or more resources.
+        """
+        post_body = json.dumps({'quota_class_set': kwargs})
+
+        resp, body = self.put('os-quota-class-sets/%s' % quota_class_id,
+                              post_body)
+
+        body = json.loads(body)
+        self.validate_response(classes_schema.update_quota_class_set,
+                               resp, body)
+        return service_client.ResponseBody(resp, body['quota_class_set'])
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 6e38c47..f488817 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -15,29 +15,27 @@
 
 import json
 
-from tempest.api_schema.response.compute.v2_1\
-    import quota_classes as classes_schema
 from tempest.api_schema.response.compute.v2_1 import quotas as schema
 from tempest.common import service_client
 
 
 class QuotasClientJSON(service_client.ServiceClient):
 
-    def get_quota_set(self, tenant_id, user_id=None):
+    def show_quota_set(self, tenant_id, user_id=None):
         """List the quota set for a tenant."""
 
-        url = 'os-quota-sets/%s' % str(tenant_id)
+        url = 'os-quota-sets/%s' % tenant_id
         if user_id:
-            url += '?user_id=%s' % str(user_id)
+            url += '?user_id=%s' % user_id
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.get_quota_set, resp, body)
         return service_client.ResponseBody(resp, body['quota_set'])
 
-    def get_default_quota_set(self, tenant_id):
+    def show_default_quota_set(self, tenant_id):
         """List the default quota set for a tenant."""
 
-        url = 'os-quota-sets/%s/defaults' % str(tenant_id)
+        url = 'os-quota-sets/%s/defaults' % tenant_id
         resp, body = self.get(url)
         body = json.loads(body)
         self.validate_response(schema.get_quota_set, resp, body)
@@ -99,9 +97,9 @@
 
         if user_id:
             resp, body = self.put('os-quota-sets/%s?user_id=%s' %
-                                  (str(tenant_id), str(user_id)), post_body)
+                                  (tenant_id, user_id), post_body)
         else:
-            resp, body = self.put('os-quota-sets/%s' % str(tenant_id),
+            resp, body = self.put('os-quota-sets/%s' % tenant_id,
                                   post_body)
 
         body = json.loads(body)
@@ -110,32 +108,6 @@
 
     def delete_quota_set(self, tenant_id):
         """Delete the tenant's quota set."""
-        resp, body = self.delete('os-quota-sets/%s' % str(tenant_id))
+        resp, body = self.delete('os-quota-sets/%s' % tenant_id)
         self.validate_response(schema.delete_quota, resp, body)
         return service_client.ResponseBody(resp, body)
-
-
-class QuotaClassesClientJSON(service_client.ServiceClient):
-
-    def get_quota_class_set(self, quota_class_id):
-        """List the quota class set for a quota class."""
-
-        url = 'os-quota-class-sets/%s' % str(quota_class_id)
-        resp, body = self.get(url)
-        body = json.loads(body)
-        self.validate_response(classes_schema.get_quota_class_set, resp, body)
-        return service_client.ResponseBody(resp, body['quota_class_set'])
-
-    def update_quota_class_set(self, quota_class_id, **kwargs):
-        """
-        Updates the quota class's limits for one or more resources.
-        """
-        post_body = json.dumps({'quota_class_set': kwargs})
-
-        resp, body = self.put('os-quota-class-sets/%s' % str(quota_class_id),
-                              post_body)
-
-        body = json.loads(body)
-        self.validate_response(classes_schema.update_quota_class_set,
-                               resp, body)
-        return service_client.ResponseBody(resp, body['quota_class_set'])
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index 9fdb394..b2a30e9 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -91,8 +91,8 @@
 
     def _create_sec_group(self):
         sec_grp_cli = self.manager.security_groups_client
-        s_name = data_utils.rand_name('sec_grp-')
-        s_description = data_utils.rand_name('desc-')
+        s_name = data_utils.rand_name('sec_grp')
+        s_description = data_utils.rand_name('desc')
         self.sec_grp = sec_grp_cli.create_security_group(s_name,
                                                          s_description)
         create_rule = sec_grp_cli.create_security_group_rule
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index 3064989..f0921d5 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -109,7 +109,7 @@
         self.fake_client.identity.get_tenant_by_name.return_value = \
             self.fake_object['tenant']
         self.fake_client.identity.get_user_by_username.side_effect = \
-            lib_exc.NotFound()
+            lib_exc.NotFound("user is not found")
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
                                               return_value=self.fake_client))
 
@@ -126,7 +126,7 @@
 
     def test_create_user_missing_tenant(self):
         self.fake_client.identity.get_tenant_by_name.side_effect = \
-            lib_exc.NotFound()
+            lib_exc.NotFound("tenant is not found")
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
                                               return_value=self.fake_client))
 
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index 596e811..e713969 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -299,7 +299,8 @@
         test_accounts_class = accounts.Accounts('v2', 'test_name')
         with mock.patch('tempest.services.compute.json.networks_client.'
                         'NetworksClientJSON.list_networks',
-                        return_value=[{'name': 'network-2', 'id': 'fake-id'}]):
+                        return_value=[{'name': 'network-2', 'id': 'fake-id',
+                                       'label': 'network-2'}]):
             creds = test_accounts_class.get_creds_by_roles(['role-7'])
         self.assertTrue(isinstance(creds, cred_provider.TestResources))
         network = creds.network
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index 9bb58b0..c6c1053 100644
--- a/tempest/tests/common/test_service_clients.py
+++ b/tempest/tests/common/test_service_clients.py
@@ -34,6 +34,7 @@
 from tempest.services.compute.json import limits_client
 from tempest.services.compute.json import migrations_client
 from tempest.services.compute.json import networks_client as nova_net_client
+from tempest.services.compute.json import quota_classes_client
 from tempest.services.compute.json import quotas_client
 from tempest.services.compute.json import security_group_default_rules_client \
     as nova_secgrop_default_client
@@ -122,7 +123,7 @@
             migrations_client.MigrationsClientJSON,
             nova_net_client.NetworksClientJSON,
             quotas_client.QuotasClientJSON,
-            quotas_client.QuotaClassesClientJSON,
+            quota_classes_client.QuotaClassesClientJSON,
             nova_secgrop_default_client.SecurityGroupDefaultRulesClientJSON,
             security_groups_client.SecurityGroupsClientJSON,
             servers_client.ServersClientJSON,
diff --git a/tempest/tests/test_hacking.py b/tempest/tests/test_hacking.py
index fd01887..9bc9cfe 100644
--- a/tempest/tests/test_hacking.py
+++ b/tempest/tests/test_hacking.py
@@ -119,6 +119,13 @@
         self.assertFalse(checks.service_tags_not_in_module_path(
             "@test.services('compute')", './tempest/api/image/fake_test.py'))
 
+    def test_no_hyphen_at_end_of_rand_name(self):
+        self.assertIsNone(checks.no_hyphen_at_end_of_rand_name(
+            'data_utils.rand_name("fake-resource")', './tempest/test_foo.py'))
+        self.assertEqual(2, len(list(checks.no_hyphen_at_end_of_rand_name(
+            'data_utils.rand_name("fake-resource-")', './tempest/test_foo.py')
+        )))
+
     def test_no_mutable_default_args(self):
         self.assertEqual(1, len(list(checks.no_mutable_default_args(
             " def function1(para={}):"))))
diff --git a/test-requirements.txt b/test-requirements.txt
index 7169610..9bd3f46 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,11 +3,11 @@
 # process, which may cause wedges in the gate later.
 hacking<0.11,>=0.10.0
 # needed for doc build
-sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
+sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
 python-subunit>=0.0.18
-oslosphinx>=2.5.0  # Apache-2.0
+oslosphinx>=2.5.0 # Apache-2.0
 mox>=0.5.3
 mock>=1.0
 coverage>=3.6
-oslotest>=1.5.1  # Apache-2.0
-stevedore>=1.5.0  # Apache-2.0
+oslotest>=1.5.1 # Apache-2.0
+stevedore>=1.5.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index 4bb5df6..b495fd6 100644
--- a/tox.ini
+++ b/tox.ini
@@ -13,6 +13,13 @@
 [testenv]
 setenv = VIRTUAL_ENV={envdir}
          OS_TEST_PATH=./tempest/tests
+passenv = OS_STDOUT_CAPTURE
+          OS_STDERR_CAPTURE
+          OS_TEST_TIMEOUT
+          OS_TEST_LOCK_PATH
+          OS_TEST_PATH
+          TEMPEST_CONFIG
+          TEMPEST_CONFIG_DIR
 usedevelop = True
 install_command = pip install -U {opts} {packages}
 whitelist_externals = *