Merge "Tox.ini: removed an outdated code comment."
diff --git a/releasenotes/notes/remove-negative-test-generator-1653f4c0f86ccf75.yaml b/releasenotes/notes/remove-negative-test-generator-1653f4c0f86ccf75.yaml
new file mode 100644
index 0000000..a734d15
--- /dev/null
+++ b/releasenotes/notes/remove-negative-test-generator-1653f4c0f86ccf75.yaml
@@ -0,0 +1,4 @@
+---
+upgrade:
+  - The Negative Tests Generator has been removed (it was not used by any
+    Tempest tests).
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index 55134b1..1f043dc 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -87,7 +87,7 @@
         ironic_only = True
         hypers_without_ironic = []
         for hyper in hypers:
-            details = (self.client.show_hypervisor(hypers[0]['id'])
+            details = (self.client.show_hypervisor(hyper['id'])
                        ['hypervisor'])
             if details['hypervisor_type'] != 'ironic':
                 hypers_without_ironic.append(hyper)
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index 9acc2b1..7252e1b 100644
--- a/tempest/api/compute/servers/test_device_tagging.py
+++ b/tempest/api/compute/servers/test_device_tagging.py
@@ -21,7 +21,7 @@
 from tempest.common.utils.linux import remote_client
 from tempest.common import waiters
 from tempest import config
-from tempest import exceptions
+from tempest.lib import exceptions
 from tempest import test
 
 
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index 6688849..ab291b4 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -123,7 +123,7 @@
             path = '/test' + str(i) + '.txt'
             person.append({
                 'path': path,
-                'contents': base64.encode_as_text(file_contents),
+                'contents': base64.encode_as_text(file_contents + str(i)),
             })
         password = data_utils.rand_password()
         created_server = self.create_test_server(personality=person,
diff --git a/tempest/api/compute/test_live_block_migration_negative.py b/tempest/api/compute/test_live_block_migration_negative.py
index bd2b185..f072b81 100644
--- a/tempest/api/compute/test_live_block_migration_negative.py
+++ b/tempest/api/compute/test_live_block_migration_negative.py
@@ -33,7 +33,6 @@
     @classmethod
     def setup_clients(cls):
         super(LiveBlockMigrationNegativeTestJSON, cls).setup_clients()
-        cls.admin_hosts_client = cls.os_adm.hosts_client
         cls.admin_servers_client = cls.os_adm.servers_client
 
     def _migrate_server_to(self, server_id, dest_host):
diff --git a/tempest/api/image/v2/test_images_metadefs_schema.py b/tempest/api/image/v2/test_images_metadefs_schema.py
new file mode 100644
index 0000000..7edf1af
--- /dev/null
+++ b/tempest/api/image/v2/test_images_metadefs_schema.py
@@ -0,0 +1,81 @@
+# Copyright 2016 EasyStack.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.image import base
+from tempest import test
+
+
+class MetadataSchemaTest(base.BaseV2ImageTest):
+    """Test to get metadata schema"""
+
+    @test.idempotent_id('e9e44891-3cb8-3b40-a532-e0a39fea3dab')
+    def test_get_metadata_namespace_schema(self):
+        # Test to get namespace schema
+        body = self.schemas_client.show_schema("metadefs/namespace")
+        self.assertEqual("namespace", body['name'])
+
+    @test.idempotent_id('ffe44891-678b-3ba0-a3e2-e0a3967b3aeb')
+    def test_get_metadata_namespaces_schema(self):
+        # Test to get namespaces schema
+        body = self.schemas_client.show_schema("metadefs/namespaces")
+        self.assertEqual("namespaces", body['name'])
+
+    @test.idempotent_id('fde34891-678b-3b40-ae32-e0a3e67b6beb')
+    def test_get_metadata_resource_type_schema(self):
+        # Test to get resource_type schema
+        body = self.schemas_client.show_schema("metadefs/resource_type")
+        self.assertEqual("resource_type_association", body['name'])
+
+    @test.idempotent_id('dfe4a891-b38b-3bf0-a3b2-e03ee67b3a3a')
+    def test_get_metadata_resources_types_schema(self):
+        # Test to get resource_types schema
+        body = self.schemas_client.show_schema("metadefs/resource_types")
+        self.assertEqual("resource_type_associations", body['name'])
+
+    @test.idempotent_id('dff4a891-b38b-3bf0-a3b2-e03ee67b3a3b')
+    def test_get_metadata_object_schema(self):
+        # Test to get object schema
+        body = self.schemas_client.show_schema("metadefs/object")
+        self.assertEqual("object", body['name'])
+
+    @test.idempotent_id('dee4a891-b38b-3bf0-a3b2-e03ee67b3a3c')
+    def test_get_metadata_objects_schema(self):
+        # Test to get objects schema
+        body = self.schemas_client.show_schema("metadefs/objects")
+        self.assertEqual("objects", body['name'])
+
+    @test.idempotent_id('dae4a891-b38b-3bf0-a3b2-e03ee67b3a3d')
+    def test_get_metadata_property_schema(self):
+        # Test to get property schema
+        body = self.schemas_client.show_schema("metadefs/property")
+        self.assertEqual("property", body['name'])
+
+    @test.idempotent_id('dce4a891-b38b-3bf0-a3b2-e03ee67b3a3e')
+    def test_get_metadata_properties_schema(self):
+        # Test to get properties schema
+        body = self.schemas_client.show_schema("metadefs/properties")
+        self.assertEqual("properties", body['name'])
+
+    @test.idempotent_id('dde4a891-b38b-3bf0-a3b2-e03ee67b3a3e')
+    def test_get_metadata_tag_schema(self):
+        # Test to get tag schema
+        body = self.schemas_client.show_schema("metadefs/tag")
+        self.assertEqual("tag", body['name'])
+
+    @test.idempotent_id('cde4a891-b38b-3bf0-a3b2-e03ee67b3a3a')
+    def test_get_metadata_tags_schema(self):
+        # Test to get tags schema
+        body = self.schemas_client.show_schema("metadefs/tags")
+        self.assertEqual("tags", body['name'])
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 1b1ffd1..52b0a9c 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import time
+
 from tempest.common import custom_matchers
 from tempest import config
 from tempest.lib.common.utils import data_utils
@@ -102,6 +104,10 @@
         The containers should be visible from the container_client given.
         Will not throw any error if the containers don't exist.
         Will not check that object and container deletions succeed.
+        After delete all the objects from a container, it will wait 2
+        seconds before delete the container itself, in order to deployments
+        using HA proxy sync the deletion properly, otherwise, the container
+        might fail to be deleted because it's not empty.
 
         :param container_client: if None, use cls.container_client, this means
             that the default testing user will be used (see 'username' in
@@ -121,6 +127,9 @@
                 for obj in objlist:
                     test_utils.call_and_ignore_notfound_exc(
                         object_client.delete_object, cont, obj['name'])
+                # sleep 2 seconds to sync the deletion of the objects
+                # in HA deployment
+                time.sleep(2)
                 container_client.delete_container(cont)
             except lib_exc.NotFound:
                 pass
diff --git a/tempest/api/object_storage/test_container_services_negative.py b/tempest/api/object_storage/test_container_services_negative.py
index e6c53ec..df91325 100644
--- a/tempest/api/object_storage/test_container_services_negative.py
+++ b/tempest/api/object_storage/test_container_services_negative.py
@@ -13,11 +13,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest.api.object_storage import base
+from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib import exceptions
 from tempest import test
 
+CONF = config.CONF
+
 
 class ContainerNegativeTest(base.BaseObjectTest):
 
@@ -25,12 +30,16 @@
     def resource_setup(cls):
         super(ContainerNegativeTest, cls).resource_setup()
 
-        # use /info to get default constraints
-        _, body = cls.account_client.list_extensions()
-        cls.constraints = body['swift']
+        if CONF.object_storage_feature_enabled.discoverability:
+            # use /info to get default constraints
+            _, body = cls.account_client.list_extensions()
+            cls.constraints = body['swift']
 
     @test.attr(type=["negative"])
     @test.idempotent_id('30686921-4bed-4764-a038-40d741ed4e78')
+    @testtools.skipUnless(
+        CONF.object_storage_feature_enabled.discoverability,
+        'Discoverability function is disabled')
     def test_create_container_name_exceeds_max_length(self):
         # Attempts to create a container name that is longer than max
         max_length = self.constraints['max_container_name_length']
@@ -44,6 +53,9 @@
 
     @test.attr(type=["negative"])
     @test.idempotent_id('41e645bf-2e68-4f84-bf7b-c71aa5cd76ce')
+    @testtools.skipUnless(
+        CONF.object_storage_feature_enabled.discoverability,
+        'Discoverability function is disabled')
     def test_create_container_metadata_name_exceeds_max_length(self):
         # Attempts to create container with metadata name
         # that is longer than max.
@@ -58,6 +70,9 @@
 
     @test.attr(type=["negative"])
     @test.idempotent_id('81e36922-326b-4b7c-8155-3bbceecd7a82')
+    @testtools.skipUnless(
+        CONF.object_storage_feature_enabled.discoverability,
+        'Discoverability function is disabled')
     def test_create_container_metadata_value_exceeds_max_length(self):
         # Attempts to create container with metadata value
         # that is longer than max.
@@ -72,6 +87,9 @@
 
     @test.attr(type=["negative"])
     @test.idempotent_id('ac666539-d566-4f02-8ceb-58e968dfb732')
+    @testtools.skipUnless(
+        CONF.object_storage_feature_enabled.discoverability,
+        'Discoverability function is disabled')
     def test_create_container_metadata_exceeds_overall_metadata_count(self):
         # Attempts to create container with metadata that exceeds the
         # default count
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index bffcb64..6d27502 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -77,7 +77,7 @@
             cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
             resources = (cls.client.list_resources(cls.stack_identifier)
                          ['resources'])
-        except exceptions.TimeoutException as e:
+        except exceptions.TimeoutException:
             if CONF.compute_feature_enabled.console_output:
                 # attempt to log the server console to help with debugging
                 # the cause of the server not signalling the waitcondition
@@ -89,7 +89,7 @@
                 output = cls.servers_client.get_console_output(
                     server_id)['output']
                 LOG.debug(output)
-            raise e
+            raise
 
         cls.test_resources = {}
         for resource in resources:
diff --git a/tempest/common/generator/__init__.py b/tempest/common/generator/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/common/generator/__init__.py
+++ /dev/null
diff --git a/tempest/common/generator/base_generator.py b/tempest/common/generator/base_generator.py
deleted file mode 100644
index 0647edb..0000000
--- a/tempest/common/generator/base_generator.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# Copyright 2014 Deutsche Telekom AG
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import copy
-import functools
-
-import jsonschema
-import six
-
-
-def _check_for_expected_result(name, schema):
-    expected_result = None
-    if "results" in schema:
-        if name in schema["results"]:
-            expected_result = schema["results"][name]
-    return expected_result
-
-
-def generator_type(*args, **kwargs):
-    def wrapper(func):
-        func.types = args
-        for key in kwargs:
-            setattr(func, key, kwargs[key])
-        return func
-    return wrapper
-
-
-def simple_generator(fn):
-    """Decorator for simple generators that return one value"""
-    @functools.wraps(fn)
-    def wrapped(self, schema):
-        result = fn(self, schema)
-        if result is not None:
-            expected_result = _check_for_expected_result(fn.__name__, schema)
-            return (fn.__name__, result, expected_result)
-        return
-    return wrapped
-
-
-class BasicGeneratorSet(object):
-    _instance = None
-
-    schema = {
-        "type": "object",
-        "properties": {
-            "name": {"type": "string"},
-            "http-method": {
-                "enum": ["GET", "PUT", "HEAD",
-                         "POST", "PATCH", "DELETE", 'COPY']
-            },
-            "admin_client": {"type": "boolean"},
-            "url": {"type": "string"},
-            "default_result_code": {"type": "integer"},
-            "json-schema": {},
-            "resources": {
-                "type": "array",
-                "items": {
-                    "oneOf": [
-                        {"type": "string"},
-                        {
-                            "type": "object",
-                            "properties": {
-                                "name": {"type": "string"},
-                                "expected_result": {"type": "integer"}
-                            }
-                        }
-                    ]
-                }
-            },
-            "results": {
-                "type": "object",
-                "properties": {}
-            }
-        },
-        "required": ["name", "http-method", "url"],
-        "additionalProperties": False,
-    }
-
-    def __init__(self):
-        self.types_dict = {}
-        for m in dir(self):
-            if callable(getattr(self, m)) and not'__' in m:
-                method = getattr(self, m)
-                if hasattr(method, "types"):
-                    for type in method.types:
-                        if type not in self.types_dict:
-                            self.types_dict[type] = []
-                        self.types_dict[type].append(method)
-
-    def validate_schema(self, schema):
-        if "json-schema" in schema:
-            jsonschema.Draft4Validator.check_schema(schema['json-schema'])
-        jsonschema.validate(schema, self.schema)
-
-    def generate_scenarios(self, schema, path=None):
-        """Generate scenario (all possible test cases) out of the given schema
-
-        :param schema: a dict style schema (see ``BasicGeneratorSet.schema``)
-        :param path: the schema path if the given schema is a subschema
-        """
-        schema_type = schema['type']
-        scenarios = []
-
-        if schema_type == 'object':
-            properties = schema["properties"]
-            for attribute, definition in six.iteritems(properties):
-                current_path = copy.copy(path)
-                if path is not None:
-                    current_path.append(attribute)
-                else:
-                    current_path = [attribute]
-                scenarios.extend(
-                    self.generate_scenarios(definition, current_path))
-        elif isinstance(schema_type, list):
-            if "integer" in schema_type:
-                schema_type = "integer"
-            else:
-                raise Exception("non-integer list types not supported")
-        for generator in self.types_dict[schema_type]:
-            if hasattr(generator, "needed_property"):
-                prop = generator.needed_property
-                if (prop not in schema or
-                    schema[prop] is None or
-                    schema[prop] is False):
-                    continue
-
-            name = generator.__name__
-            if ("exclude_tests" in schema and
-               name in schema["exclude_tests"]):
-                continue
-            if path is not None:
-                name = "%s_%s" % ("_".join(path), name)
-            scenarios.append({
-                "_negtest_name": name,
-                "_negtest_generator": generator,
-                "_negtest_schema": schema,
-                "_negtest_path": path})
-        return scenarios
-
-    def generate_payload(self, test, schema):
-        """Generates one jsonschema out of the given test.
-
-        It's mandatory to use generate_scenarios before to register all needed
-        variables to the test.
-
-        :param test: A test object (scenario) with all _negtest variables on it
-        :param schema: schema for the test
-        """
-        generator = test._negtest_generator
-        ret = generator(test._negtest_schema)
-        path = copy.copy(test._negtest_path)
-        expected_result = None
-
-        if ret is not None:
-            generator_result = generator(test._negtest_schema)
-            invalid_snippet = generator_result[1]
-            expected_result = generator_result[2]
-            element = path.pop()
-            if len(path) > 0:
-                schema_snip = six.moves.reduce(dict.get, path, schema)
-                schema_snip[element] = invalid_snippet
-            else:
-                schema[element] = invalid_snippet
-        return expected_result
diff --git a/tempest/common/generator/negative_generator.py b/tempest/common/generator/negative_generator.py
deleted file mode 100644
index 67ace54..0000000
--- a/tempest/common/generator/negative_generator.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2014 Deutsche Telekom AG
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import copy
-
-import tempest.common.generator.base_generator as base
-import tempest.common.generator.valid_generator as valid
-
-
-class NegativeTestGenerator(base.BasicGeneratorSet):
-    @base.generator_type("string")
-    @base.simple_generator
-    def gen_int(self, _):
-        return 4
-
-    @base.generator_type("integer")
-    @base.simple_generator
-    def gen_string(self, _):
-        return "XXXXXX"
-
-    @base.generator_type("integer", "string")
-    def gen_none(self, schema):
-        # Note(mkoderer): it's not using the decorator otherwise it'd be
-        # filtered
-        expected_result = base._check_for_expected_result('gen_none', schema)
-        return ('gen_none', None, expected_result)
-
-    @base.generator_type("string")
-    @base.simple_generator
-    def gen_str_min_length(self, schema):
-        min_length = schema.get("minLength", 0)
-        if min_length > 0:
-            return "x" * (min_length - 1)
-
-    @base.generator_type("string", needed_property="maxLength")
-    @base.simple_generator
-    def gen_str_max_length(self, schema):
-        max_length = schema.get("maxLength", -1)
-        return "x" * (max_length + 1)
-
-    @base.generator_type("integer", needed_property="minimum")
-    @base.simple_generator
-    def gen_int_min(self, schema):
-        minimum = schema["minimum"]
-        if "exclusiveMinimum" not in schema:
-            minimum -= 1
-        return minimum
-
-    @base.generator_type("integer", needed_property="maximum")
-    @base.simple_generator
-    def gen_int_max(self, schema):
-        maximum = schema["maximum"]
-        if "exclusiveMaximum" not in schema:
-            maximum += 1
-        return maximum
-
-    @base.generator_type("object", needed_property="additionalProperties")
-    @base.simple_generator
-    def gen_obj_add_attr(self, schema):
-        valid_schema = valid.ValidTestGenerator().generate_valid(schema)
-        new_valid = copy.deepcopy(valid_schema)
-        new_valid["$$$$$$$$$$"] = "xxx"
-        return new_valid
diff --git a/tempest/common/generator/valid_generator.py b/tempest/common/generator/valid_generator.py
deleted file mode 100644
index 3070489..0000000
--- a/tempest/common/generator/valid_generator.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2014 Deutsche Telekom AG
-# 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 six
-
-import tempest.common.generator.base_generator as base
-
-
-class ValidTestGenerator(base.BasicGeneratorSet):
-    @base.generator_type("string")
-    @base.simple_generator
-    def generate_valid_string(self, schema):
-        size = schema.get("minLength", 1)
-        # TODO(dkr mko): handle format and pattern
-        return "x" * size
-
-    @base.generator_type("integer")
-    @base.simple_generator
-    def generate_valid_integer(self, schema):
-        # TODO(dkr mko): handle multipleOf
-        if "minimum" in schema:
-            minimum = schema["minimum"]
-            if "exclusiveMinimum" not in schema:
-                return minimum
-            else:
-                return minimum + 1
-        if "maximum" in schema:
-            maximum = schema["maximum"]
-            if "exclusiveMaximum" not in schema:
-                return maximum
-            else:
-                return maximum - 1
-        return 0
-
-    @base.generator_type("object")
-    @base.simple_generator
-    def generate_valid_object(self, schema):
-        obj = {}
-        for k, v in six.iteritems(schema["properties"]):
-            obj[k] = self.generate_valid(v)
-        return obj
-
-    def generate(self, schema):
-        schema_type = schema["type"]
-        if isinstance(schema_type, list):
-            if "integer" in schema_type:
-                schema_type = "integer"
-            else:
-                raise Exception("non-integer list types not supported")
-        result = []
-        if schema_type not in self.types_dict:
-            raise TypeError("generator (%s) doesn't support type: %s"
-                            % (self.__class__.__name__, schema_type))
-        for generator in self.types_dict[schema_type]:
-            ret = generator(schema)
-            if ret is not None:
-                if isinstance(ret, list):
-                    result.extend(ret)
-                elif isinstance(ret, tuple):
-                    result.append(ret)
-                else:
-                    raise Exception("generator (%s) returns invalid result: %s"
-                                    % (generator, ret))
-        return result
-
-    def generate_valid(self, schema):
-        return self.generate(schema)[0][1]
diff --git a/tempest/config.py b/tempest/config.py
index 7550287..47eb427 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1075,14 +1075,6 @@
                     "step in Node cleaning.")
 ]
 
-negative_group = cfg.OptGroup(name='negative', title="Negative Test Options")
-
-NegativeGroup = [
-    cfg.StrOpt('test_generator',
-               default='tempest.common.' +
-               'generator.negative_generator.NegativeTestGenerator',
-               help="Test generator class for all negative tests"),
-]
 
 DefaultGroup = [
     cfg.StrOpt('resources_prefix',
@@ -1115,7 +1107,6 @@
     (debug_group, DebugGroup),
     (baremetal_group, BaremetalGroup),
     (input_scenario_group, InputScenarioGroup),
-    (negative_group, NegativeGroup),
     (None, DefaultGroup)
 ]
 
@@ -1179,7 +1170,6 @@
         self.debug = _CONF.debug
         self.baremetal = _CONF.baremetal
         self.input_scenario = _CONF['input-scenario']
-        self.negative = _CONF.negative
         logging.tempest_set_log_file('tempest.log')
 
     def __init__(self, parse_conf=True, config_path=None):
diff --git a/tempest/lib/cmd/check_uuid.py b/tempest/lib/cmd/check_uuid.py
index 1239ac5..88ce775 100755
--- a/tempest/lib/cmd/check_uuid.py
+++ b/tempest/lib/cmd/check_uuid.py
@@ -23,6 +23,7 @@
 import unittest
 import uuid
 
+from oslo_utils import uuidutils
 import six.moves.urllib.parse as urlparse
 
 DECORATOR_MODULE = 'test'
@@ -61,7 +62,7 @@
         if filename not in self.source_files:
             with open(filename) as f:
                 self.source_files[filename] = self._quote(f.read())
-        patch_id = str(uuid.uuid4())
+        patch_id = uuidutils.generate_uuid()
         if not patch.endswith('\n'):
             patch += '\n'
         self.patches[patch_id] = self._quote(patch)
diff --git a/tempest/lib/common/utils/data_utils.py b/tempest/lib/common/utils/data_utils.py
index 4095c77..75c2e51 100644
--- a/tempest/lib/common/utils/data_utils.py
+++ b/tempest/lib/common/utils/data_utils.py
@@ -21,6 +21,7 @@
 
 from debtcollector import removals
 from oslo_utils import netutils
+from oslo_utils import uuidutils
 import six.moves
 
 
@@ -30,7 +31,7 @@
     :return: a random UUID (e.g. '1dc12c7d-60eb-4b61-a7a2-17cf210155b6')
     :rtype: string
     """
-    return str(uuid.uuid4())
+    return uuidutils.generate_uuid()
 
 
 def rand_uuid_hex():
diff --git a/tempest/lib/exceptions.py b/tempest/lib/exceptions.py
index a6c01bb..108ba70 100644
--- a/tempest/lib/exceptions.py
+++ b/tempest/lib/exceptions.py
@@ -71,54 +71,70 @@
     message = "The success code is different than the expected one"
 
 
-class NotFound(ClientRestClientException):
-    message = "Object not found"
+class BadRequest(ClientRestClientException):
+    status_code = 400
+    message = "Bad request"
 
 
 class Unauthorized(ClientRestClientException):
+    status_code = 401
     message = 'Unauthorized'
 
 
 class Forbidden(ClientRestClientException):
+    status_code = 403
     message = "Forbidden"
 
 
-class TimeoutException(OtherRestClientException):
-    message = "Request timed out"
-
-
-class BadRequest(ClientRestClientException):
-    message = "Bad request"
-
-
-class UnprocessableEntity(ClientRestClientException):
-    message = "Unprocessable entity"
-
-
-class RateLimitExceeded(ClientRestClientException):
-    message = "Rate limit exceeded"
-
-
-class OverLimit(ClientRestClientException):
-    message = "Request entity is too large"
-
-
-class ServerFault(ServerRestClientException):
-    message = "Got server fault"
-
-
-class NotImplemented(ServerRestClientException):
-    message = "Got NotImplemented error"
+class NotFound(ClientRestClientException):
+    status_code = 404
+    message = "Object not found"
 
 
 class Conflict(ClientRestClientException):
+    status_code = 409
     message = "An object with that identifier already exists"
 
 
 class Gone(ClientRestClientException):
+    status_code = 410
     message = "The requested resource is no longer available"
 
 
+class RateLimitExceeded(ClientRestClientException):
+    status_code = 413
+    message = "Rate limit exceeded"
+
+
+class OverLimit(ClientRestClientException):
+    status_code = 413
+    message = "Request entity is too large"
+
+
+class InvalidContentType(ClientRestClientException):
+    status_code = 415
+    message = "Invalid content type provided"
+
+
+class UnprocessableEntity(ClientRestClientException):
+    status_code = 422
+    message = "Unprocessable entity"
+
+
+class ServerFault(ServerRestClientException):
+    status_code = 500
+    message = "Got server fault"
+
+
+class NotImplemented(ServerRestClientException):
+    status_code = 501
+    message = "Got NotImplemented error"
+
+
+class TimeoutException(OtherRestClientException):
+    message = "Request timed out"
+
+
 class ResponseWithNonEmptyBody(OtherRestClientException):
     message = ("RFC Violation! Response with %(status)d HTTP Status Code "
                "MUST NOT have a body")
@@ -137,10 +153,6 @@
     message = "HTTP response header is invalid"
 
 
-class InvalidContentType(ClientRestClientException):
-    message = "Invalid content type provided"
-
-
 class UnexpectedContentType(OtherRestClientException):
     message = "Unexpected content type provided"
 
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 3ac6759..f2f17d2 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -16,8 +16,8 @@
 from tempest.common import custom_matchers
 from tempest.common import waiters
 from tempest import config
-from tempest import exceptions
 from tempest.lib.common.utils import test_utils
+from tempest.lib import exceptions
 from tempest.scenario import manager
 from tempest import test
 
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 3aab2b8..2d2f7df 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -18,8 +18,8 @@
 
 from tempest.common import waiters
 from tempest import config
-from tempest import exceptions
 from tempest.lib.common.utils import test_utils
+from tempest.lib import exceptions
 from tempest.scenario import manager
 from tempest import test
 
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index db5e009..46aebfe 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -148,10 +148,13 @@
 
         # create a 3rd instance from snapshot
         LOG.info("Creating third instance from snapshot: %s" % snapshot['id'])
-        volume = self.create_volume(snapshot_id=snapshot['id'])
+        volume = self.create_volume(snapshot_id=snapshot['id'],
+                                    size=snapshot['size'])
+        LOG.info("Booting third instance from snapshot")
         server_from_snapshot = (
             self._boot_instance_from_volume(volume['id'],
                                             keypair, security_group))
+        LOG.info("Booted third instance %s", server_from_snapshot)
 
         # check the content of written file
         LOG.info("Logging into third instance to get timestamp: %s" %
diff --git a/tempest/tests/negative/test_negative_generators.py b/tempest/tests/negative/test_negative_generators.py
deleted file mode 100644
index 7e1ee2c..0000000
--- a/tempest/tests/negative/test_negative_generators.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright 2014 Deutsche Telekom AG
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import copy
-
-import jsonschema
-import mock
-import six
-
-from tempest.common.generator import base_generator
-from tempest.common.generator import negative_generator
-from tempest.common.generator import valid_generator
-from tempest.tests import base
-
-
-class TestNegativeBasicGenerator(base.TestCase):
-    valid_desc = {
-        "name": "list-flavors-with-detail",
-        "http-method": "GET",
-        "url": "flavors/detail",
-        "json-schema": {
-            "type": "object",
-            "properties": {
-                "minRam": {"type": "integer"},
-                "minDisk": {"type": "integer"}
-            }
-        },
-        "resources": ["flavor", "volume", "image"]
-    }
-
-    minimal_desc = {
-        "name": "list-flavors-with-detail",
-        "http-method": "GET",
-        "url": "flavors/detail",
-    }
-
-    add_prop_desc = {
-        "name": "list-flavors-with-detail",
-        "http-method": "GET",
-        "url": "flavors/detail",
-        "unknown_field": [12]
-    }
-
-    invalid_json_schema_desc = {
-        "name": "list-flavors-with-detail",
-        "http-method": "GET",
-        "url": "flavors/detail",
-        "json-schema": {"type": "NotExistingType"}
-    }
-
-    def setUp(self):
-        super(TestNegativeBasicGenerator, self).setUp()
-        self.generator = base_generator.BasicGeneratorSet()
-
-    def _assert_valid_jsonschema_call(self, jsonschema_mock, desc):
-        self.assertEqual(jsonschema_mock.call_count, 1)
-        jsonschema_mock.assert_called_with(desc, self.generator.schema)
-
-    @mock.patch('jsonschema.validate', wraps=jsonschema.validate)
-    def test_validate_schema_with_valid_input(self, jsonschema_mock):
-        self.generator.validate_schema(self.valid_desc)
-        self._assert_valid_jsonschema_call(jsonschema_mock, self.valid_desc)
-
-    @mock.patch('jsonschema.validate', wraps=jsonschema.validate)
-    def test_validate_schema_with_minimal_input(self, jsonschema_mock):
-        self.generator.validate_schema(self.minimal_desc)
-        self._assert_valid_jsonschema_call(jsonschema_mock, self.minimal_desc)
-
-    def test_validate_schema_with_invalid_input(self):
-        self.assertRaises(jsonschema.ValidationError,
-                          self.generator.validate_schema, self.add_prop_desc)
-        self.assertRaises(jsonschema.SchemaError,
-                          self.generator.validate_schema,
-                          self.invalid_json_schema_desc)
-
-
-class BaseNegativeGenerator(object):
-    types = ['string', 'integer', 'object']
-
-    fake_input_obj = {"type": "object",
-                      "properties": {"minRam": {"type": "integer"},
-                                     "diskName": {"type": "string"},
-                                     "maxRam": {"type": "integer", }
-                                     }
-                      }
-
-    unknown_type_schema = {
-        "type": "not_defined"
-    }
-
-    class fake_test_class(object):
-        def __init__(self, scenario):
-            for k, v in six.iteritems(scenario):
-                setattr(self, k, v)
-
-    def _validate_result(self, valid_schema, invalid_schema):
-        for k, v in six.iteritems(valid_schema):
-            self.assertIn(k, invalid_schema)
-
-    def test_generator_mandatory_functions(self):
-        for data_type in self.types:
-            self.assertIn(data_type, self.generator.types_dict)
-
-    def test_generate_with_unknown_type(self):
-        self.assertRaises(TypeError, self.generator.generate_payload,
-                          self.unknown_type_schema)
-
-
-class TestNegativeValidGenerator(base.TestCase, BaseNegativeGenerator):
-    def setUp(self):
-        super(TestNegativeValidGenerator, self).setUp()
-        self.generator = valid_generator.ValidTestGenerator()
-
-    def test_generate_valid(self):
-        result = self.generator.generate_valid(self.fake_input_obj)
-        self.assertIn("minRam", result)
-        self.assertIsInstance(result["minRam"], int)
-        self.assertIn("diskName", result)
-        self.assertIsInstance(result["diskName"], str)
-
-
-class TestNegativeNegativeGenerator(base.TestCase, BaseNegativeGenerator):
-    def setUp(self):
-        super(TestNegativeNegativeGenerator, self).setUp()
-        self.generator = negative_generator.NegativeTestGenerator()
-
-    def test_generate_obj(self):
-        schema = self.fake_input_obj
-        scenarios = self.generator.generate_scenarios(schema)
-        for scenario in scenarios:
-            test = self.fake_test_class(scenario)
-            valid_schema = \
-                valid_generator.ValidTestGenerator().generate_valid(schema)
-            schema_under_test = copy.copy(valid_schema)
-            expected_result = \
-                self.generator.generate_payload(test, schema_under_test)
-            self.assertIsNone(expected_result)
-            self._validate_result(valid_schema, schema_under_test)
diff --git a/tox.ini b/tox.ini
index e378586..8e3cfcc 100644
--- a/tox.ini
+++ b/tox.ini
@@ -146,6 +146,7 @@
 ignore = E125,E123,E129
 show-source = True
 exclude = .git,.venv,.tox,dist,doc,*egg
+enable-extensions = H106,H203
 
 [testenv:releasenotes]
 commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html