Merge "Add multiple negative test generator support"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index e46b813..eb2340a 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -391,6 +391,20 @@
 #endpoint_type=publicURL
 
 
+[database]
+
+#
+# Options defined in tempest.config
+#
+
+# Catalog type of the Database service. (string value)
+#catalog_type=database
+
+# Valid primary flavor to use in database tests. (string
+# value)
+#db_flavor_ref=1
+
+
 [debug]
 
 #
@@ -584,9 +598,6 @@
 # The mask bits for tenant ipv4 subnets (integer value)
 #tenant_network_mask_bits=28
 
-# Allow the execution of IPv6 tests (boolean value)
-#ipv6_enabled=true
-
 # The cidr block to allocate tenant ipv6 subnets from (string
 # value)
 #tenant_network_v6_cidr=2003::/64
@@ -613,6 +624,9 @@
 # Options defined in tempest.config
 #
 
+# Allow the execution of IPv6 tests (boolean value)
+#ipv6=true
+
 # A list of enabled network extensions with a special entry
 # all which indicates every extension is enabled (list value)
 #api_extensions=all
@@ -689,7 +703,7 @@
 
 # Timeout in seconds to wait for a stack to build. (integer
 # value)
-#build_timeout=300
+#build_timeout=600
 
 # Instance type for tests. Needs to be big enough for a full
 # OS plus the test workload (string value)
@@ -783,6 +797,10 @@
 # value)
 #ironic=false
 
+# Whether or not Trove is expected to be available (boolean
+# value)
+#trove=false
+
 
 [stress]
 
diff --git a/tempest/api/compute/v3/admin/test_servers.py b/tempest/api/compute/v3/admin/test_servers.py
index 7787770..fb8afe4 100644
--- a/tempest/api/compute/v3/admin/test_servers.py
+++ b/tempest/api/compute/v3/admin/test_servers.py
@@ -174,3 +174,13 @@
         resp, server = self.non_admin_client.get_server(rebuilt_server['id'])
         rebuilt_image_id = server['image']['id']
         self.assertEqual(self.image_ref_alt, rebuilt_image_id)
+
+    @test.attr(type='gate')
+    def test_reset_network_inject_network_info(self):
+        resp, server = self.create_test_server(wait_until='ACTIVE')
+        # Reset Network of a Server
+        resp, server_body = self.client.reset_network(server['id'])
+        self.assertEqual(202, resp.status)
+        # Inject the Network Info into Server
+        resp, server = self.client.inject_network_info(server['id'])
+        self.assertEqual(202, resp.status)
diff --git a/tempest/api/compute/v3/images/test_images.py b/tempest/api/compute/v3/images/test_images.py
index 656f7ba..bb81626 100644
--- a/tempest/api/compute/v3/images/test_images.py
+++ b/tempest/api/compute/v3/images/test_images.py
@@ -15,7 +15,6 @@
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -30,42 +29,8 @@
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
         cls.client = cls.images_client
-        cls.servers_client = cls.servers_client
 
-    def __create_image__(self, server_id, name, meta=None):
-        resp, body = self.servers_client.create_image(server_id, name, meta)
-        image_id = data_utils.parse_image_id(resp['location'])
-        self.addCleanup(self.client.delete_image, image_id)
-        self.client.wait_for_image_status(image_id, 'ACTIVE')
-        return resp, body
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_image_from_deleted_server(self):
-        # An image should not be created if the server instance is removed
-        resp, server = self.create_test_server(wait_until='ACTIVE')
-
-        # Delete server before trying to create server
-        self.servers_client.delete_server(server['id'])
-        self.servers_client.wait_for_server_termination(server['id'])
-        # Create a new image after server is deleted
-        name = data_utils.rand_name('image')
-        meta = {'image_type': 'test'}
-        self.assertRaises(exceptions.NotFound,
-                          self.__create_image__,
-                          server['id'], name, meta)
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_image_from_invalid_server(self):
-        # An image should not be created with invalid server id
-        # Create a new image with invalid server id
-        name = data_utils.rand_name('image')
-        meta = {'image_type': 'test'}
-        resp = {}
-        resp['status'] = None
-        self.assertRaises(exceptions.NotFound, self.__create_image__,
-                          '!@#$%^&*()', name, meta)
-
-    @test.attr(type=['negative', 'gate'])
+    @test.attr(type='gate')
     def test_create_image_from_stopped_server(self):
         resp, server = self.create_test_server(wait_until='ACTIVE')
         self.servers_client.stop(server['id'])
@@ -89,21 +54,3 @@
                                                     wait_until='queued')
         resp, body = self.client.delete_image(image['id'])
         self.assertEqual('200', resp['status'])
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_image_specify_uuid_35_characters_or_less(self):
-        # Return an error if Image ID passed is 35 characters or less
-        snapshot_name = data_utils.rand_name('test-snap-')
-        test_uuid = ('a' * 35)
-        self.assertRaises(exceptions.NotFound,
-                          self.servers_client.create_image,
-                          test_uuid, snapshot_name)
-
-    @test.attr(type=['negative', 'gate'])
-    def test_create_image_specify_uuid_37_characters_or_more(self):
-        # Return an error if Image ID passed is 37 characters or more
-        snapshot_name = data_utils.rand_name('test-snap-')
-        test_uuid = ('a' * 37)
-        self.assertRaises(exceptions.NotFound,
-                          self.servers_client.create_image,
-                          test_uuid, snapshot_name)
diff --git a/tempest/api/compute/v3/images/test_images_negative.py b/tempest/api/compute/v3/images/test_images_negative.py
new file mode 100644
index 0000000..c38373f
--- /dev/null
+++ b/tempest/api/compute/v3/images/test_images_negative.py
@@ -0,0 +1,82 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest import exceptions
+from tempest import test
+
+CONF = config.CONF
+
+
+class ImagesNegativeV3Test(base.BaseV3ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(ImagesNegativeV3Test, cls).setUpClass()
+        if not CONF.service_available.glance:
+            skip_msg = ("%s skipped as glance is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+        cls.client = cls.images_client
+
+    def __create_image__(self, server_id, name, meta=None):
+        resp, body = self.servers_client.create_image(server_id, name, meta)
+        image_id = data_utils.parse_image_id(resp['location'])
+        self.addCleanup(self.client.delete_image, image_id)
+        self.client.wait_for_image_status(image_id, 'ACTIVE')
+        return resp, body
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_image_from_deleted_server(self):
+        # An image should not be created if the server instance is removed
+        resp, server = self.create_test_server(wait_until='ACTIVE')
+
+        # Delete server before trying to create server
+        self.servers_client.delete_server(server['id'])
+        self.servers_client.wait_for_server_termination(server['id'])
+        # Create a new image after server is deleted
+        name = data_utils.rand_name('image')
+        meta = {'image_type': 'test'}
+        self.assertRaises(exceptions.NotFound,
+                          self.__create_image__,
+                          server['id'], name, meta)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_image_from_nonexistent_server(self):
+        # An image should not be created with invalid server id
+        # Create a new image with invalid server id
+        nonexistent_server_id = data_utils.rand_uuid()
+        name = data_utils.rand_name('image')
+        meta = {'image_type': 'test'}
+        self.assertRaises(exceptions.NotFound, self.__create_image__,
+                          nonexistent_server_id, name, meta)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_image_specify_uuid_35_characters_or_less(self):
+        # Return an error if Image ID passed is 35 characters or less
+        snapshot_name = data_utils.rand_name('test-snap-')
+        test_uuid = ('a' * 35)
+        self.assertRaises(exceptions.NotFound,
+                          self.servers_client.create_image,
+                          test_uuid, snapshot_name)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_image_specify_uuid_37_characters_or_more(self):
+        # Return an error if Image ID passed is 37 characters or more
+        snapshot_name = data_utils.rand_name('test-snap-')
+        test_uuid = ('a' * 37)
+        self.assertRaises(exceptions.NotFound,
+                          self.servers_client.create_image,
+                          test_uuid, snapshot_name)
diff --git a/tempest/api/compute/v3/servers/test_server_rescue.py b/tempest/api/compute/v3/servers/test_server_rescue.py
index 5d7f91d..b3dcb51 100644
--- a/tempest/api/compute/v3/servers/test_server_rescue.py
+++ b/tempest/api/compute/v3/servers/test_server_rescue.py
@@ -14,9 +14,7 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.common.utils import data_utils
-from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ServerRescueV3Test(base.BaseV3ComputeTest):
@@ -24,56 +22,14 @@
     @classmethod
     def setUpClass(cls):
         super(ServerRescueV3Test, cls).setUpClass()
-        cls.device = 'vdf'
-
-        # Create a volume and wait for it to become ready for attach
-        resp, cls.volume = cls.volumes_client.create_volume(
-            1, display_name=data_utils.rand_name(cls.__name__ + '_volume'))
-        cls.volumes_client.wait_for_volume_status(
-            cls.volume['id'], 'available')
 
         # Server for positive tests
         resp, server = cls.create_test_server(wait_until='BUILD')
-        resp, resc_server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
         cls.password = server['admin_password']
         cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
 
-        # Server for negative tests
-        cls.rescue_id = resc_server['id']
-        cls.rescue_password = resc_server['admin_password']
-
-        cls.servers_client.rescue_server(
-            cls.rescue_id, admin_password=cls.rescue_password)
-        cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
-
-    def setUp(self):
-        super(ServerRescueV3Test, self).setUp()
-
-    @classmethod
-    def tearDownClass(cls):
-        cls.delete_volume(cls.volume['id'])
-        super(ServerRescueV3Test, cls).tearDownClass()
-
-    def tearDown(self):
-        super(ServerRescueV3Test, self).tearDown()
-
-    def _detach(self, server_id, volume_id):
-        self.servers_client.detach_volume(server_id, volume_id)
-        self.volumes_client.wait_for_volume_status(volume_id,
-                                                   'available')
-
-    def _unrescue(self, server_id):
-        resp, body = self.servers_client.unrescue_server(server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-
-    def _unpause(self, server_id):
-        resp, body = self.servers_client.unpause_server(server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
-
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_rescue_unrescue_instance(self):
         resp, body = self.servers_client.rescue_server(
             self.server_id, admin_password=self.password)
@@ -82,71 +38,3 @@
         resp, body = self.servers_client.unrescue_server(self.server_id)
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-
-    @attr(type=['negative', 'gate'])
-    def test_rescue_paused_instance(self):
-        # Rescue a paused server
-        resp, body = self.servers_client.pause_server(
-            self.server_id)
-        self.addCleanup(self._unpause, self.server_id)
-        self.assertEqual(202, resp.status)
-        self.servers_client.wait_for_server_status(self.server_id, 'PAUSED')
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.rescue_server,
-                          self.server_id)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_reboot(self):
-        self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
-                          self.rescue_id, 'HARD')
-
-    @attr(type=['negative', 'gate'])
-    def test_rescue_non_existent_server(self):
-        # Rescue a non-existing server
-        self.assertRaises(exceptions.NotFound,
-                          self.servers_client.rescue_server,
-                          '999erra43')
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_rebuild(self):
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.rebuild,
-                          self.rescue_id,
-                          self.image_ref_alt)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_attach_volume(self):
-        # Rescue the server
-        self.servers_client.rescue_server(self.server_id,
-                                          admin_password=self.password)
-        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
-        self.addCleanup(self._unrescue, self.server_id)
-
-        # Attach the volume to the server
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.attach_volume,
-                          self.server_id,
-                          self.volume['id'],
-                          device='/dev/%s' % self.device)
-
-    @attr(type=['negative', 'gate'])
-    def test_rescued_vm_detach_volume(self):
-        # Attach the volume to the server
-        self.servers_client.attach_volume(self.server_id,
-                                          self.volume['id'],
-                                          device='/dev/%s' % self.device)
-        self.volumes_client.wait_for_volume_status(self.volume['id'], 'in-use')
-
-        # Rescue the server
-        self.servers_client.rescue_server(self.server_id,
-                                          admin_password=self.password)
-        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
-        # addCleanup is a LIFO queue
-        self.addCleanup(self._detach, self.server_id, self.volume['id'])
-        self.addCleanup(self._unrescue, self.server_id)
-
-        # Detach the volume from the server expecting failure
-        self.assertRaises(exceptions.Conflict,
-                          self.servers_client.detach_volume,
-                          self.server_id,
-                          self.volume['id'])
diff --git a/tempest/api/compute/v3/servers/test_server_rescue_negative.py b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
new file mode 100644
index 0000000..6e09376
--- /dev/null
+++ b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
@@ -0,0 +1,133 @@
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import exceptions
+from tempest import test
+
+
+class ServerRescueNegativeV3Test(base.BaseV3ComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(ServerRescueNegativeV3Test, cls).setUpClass()
+        cls.device = 'vdf'
+
+        # Create a volume and wait for it to become ready for attach
+        resp, cls.volume = cls.volumes_client.create_volume(
+            1, display_name=data_utils.rand_name(cls.__name__ + '_volume'))
+        cls.volumes_client.wait_for_volume_status(
+            cls.volume['id'], 'available')
+
+        # Server for negative tests
+        resp, server = cls.create_test_server(wait_until='BUILD')
+        resp, resc_server = cls.create_test_server(wait_until='ACTIVE')
+        cls.server_id = server['id']
+        cls.password = server['admin_password']
+        cls.rescue_id = resc_server['id']
+        cls.rescue_password = resc_server['admin_password']
+
+        cls.servers_client.rescue_server(
+            cls.rescue_id, admin_password=cls.rescue_password)
+        cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.delete_volume(cls.volume['id'])
+        super(ServerRescueNegativeV3Test, cls).tearDownClass()
+
+    def _detach(self, server_id, volume_id):
+        self.servers_client.detach_volume(server_id, volume_id)
+        self.volumes_client.wait_for_volume_status(volume_id,
+                                                   'available')
+
+    def _unrescue(self, server_id):
+        resp, body = self.servers_client.unrescue_server(server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+
+    def _unpause(self, server_id):
+        resp, body = self.servers_client.unpause_server(server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescue_paused_instance(self):
+        # Rescue a paused server
+        resp, body = self.servers_client.pause_server(
+            self.server_id)
+        self.addCleanup(self._unpause, self.server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(self.server_id, 'PAUSED')
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.rescue_server,
+                          self.server_id)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_reboot(self):
+        self.assertRaises(exceptions.Conflict, self.servers_client.reboot,
+                          self.rescue_id, 'HARD')
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescue_non_existent_server(self):
+        # Rescue a non-existing server
+        self.assertRaises(exceptions.NotFound,
+                          self.servers_client.rescue_server,
+                          data_utils.rand_uuid())
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_rebuild(self):
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.rebuild,
+                          self.rescue_id,
+                          self.image_ref_alt)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_attach_volume(self):
+        # Rescue the server
+        self.servers_client.rescue_server(self.server_id,
+                                          admin_password=self.password)
+        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        self.addCleanup(self._unrescue, self.server_id)
+
+        # Attach the volume to the server
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.attach_volume,
+                          self.server_id,
+                          self.volume['id'],
+                          device='/dev/%s' % self.device)
+
+    @test.attr(type=['negative', 'gate'])
+    def test_rescued_vm_detach_volume(self):
+        # Attach the volume to the server
+        self.servers_client.attach_volume(self.server_id,
+                                          self.volume['id'],
+                                          device='/dev/%s' % self.device)
+        self.volumes_client.wait_for_volume_status(self.volume['id'], 'in-use')
+
+        # Rescue the server
+        self.servers_client.rescue_server(self.server_id,
+                                          admin_password=self.password)
+        self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+        # addCleanup is a LIFO queue
+        self.addCleanup(self._detach, self.server_id, self.volume['id'])
+        self.addCleanup(self._unrescue, self.server_id)
+
+        # Detach the volume from the server expecting failure
+        self.assertRaises(exceptions.Conflict,
+                          self.servers_client.detach_volume,
+                          self.server_id,
+                          self.volume['id'])
diff --git a/tempest/api/database/__init__.py b/tempest/api/database/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/database/__init__.py
diff --git a/tempest/api/database/base.py b/tempest/api/database/base.py
new file mode 100644
index 0000000..8add9ba
--- /dev/null
+++ b/tempest/api/database/base.py
@@ -0,0 +1,42 @@
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest import config
+from tempest.openstack.common import log as logging
+import tempest.test
+
+CONF = config.CONF
+LOG = logging.getLogger(__name__)
+
+
+class BaseDatabaseTest(tempest.test.BaseTestCase):
+    """Base test case class for all Database API tests."""
+
+    _interface = 'json'
+    force_tenant_isolation = False
+
+    @classmethod
+    def setUpClass(cls):
+        super(BaseDatabaseTest, cls).setUpClass()
+        if not CONF.service_available.trove:
+            skip_msg = ("%s skipped as trove is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+
+        cls.catalog_type = CONF.database.catalog_type
+        cls.db_flavor_ref = CONF.database.db_flavor_ref
+
+        os = cls.get_client_manager()
+        cls.os = os
+        cls.database_flavors_client = cls.os.database_flavors_client
diff --git a/tempest/api/database/flavors/__init__.py b/tempest/api/database/flavors/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/database/flavors/__init__.py
diff --git a/tempest/api/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
new file mode 100644
index 0000000..a591e8e
--- /dev/null
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -0,0 +1,41 @@
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.database import base
+from tempest import test
+
+
+class DatabaseFlavorsTest(base.BaseDatabaseTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(DatabaseFlavorsTest, cls).setUpClass()
+        cls.client = cls.database_flavors_client
+
+    @test.attr(type='smoke')
+    def test_get_db_flavor(self):
+        # The expected flavor details should be returned
+        resp, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+        self.assertEqual(self.db_flavor_ref, str(flavor['id']))
+        self.assertIn('ram', flavor)
+        self.assertIn('links', flavor)
+        self.assertIn('name', flavor)
+
+    @test.attr(type='smoke')
+    def test_list_db_flavors(self):
+        resp, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+        # List of all flavors should contain the expected flavor
+        resp, flavors = self.client.list_db_flavors()
+        self.assertIn(flavor, flavors)
diff --git a/tempest/api/database/flavors/test_flavors_negative.py b/tempest/api/database/flavors/test_flavors_negative.py
new file mode 100644
index 0000000..202dc48
--- /dev/null
+++ b/tempest/api/database/flavors/test_flavors_negative.py
@@ -0,0 +1,32 @@
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.database import base
+from tempest import exceptions
+from tempest import test
+
+
+class DatabaseFlavorsNegativeTest(base.BaseDatabaseTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(DatabaseFlavorsNegativeTest, cls).setUpClass()
+        cls.client = cls.database_flavors_client
+
+    @test.attr(type=['negative', 'gate'])
+    def test_get_non_existent_db_flavor(self):
+        # flavor details are not returned for non-existent flavors
+        self.assertRaises(exceptions.NotFound,
+                          self.client.get_db_flavor_details, -1)
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 8720985..93335e7 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -59,7 +59,6 @@
         # Create no network resources for these test.
         cls.set_network_resources()
         super(BaseNetworkTest, cls).setUpClass()
-        os = clients.Manager(interface=cls._interface)
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron support is required")
 
@@ -152,8 +151,6 @@
             cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
             mask_bits = CONF.network.tenant_network_v6_mask_bits
         # Find a cidr that is not in use yet and create a subnet with it
-        body = None
-        failure = None
         for subnet_cidr in cidr.subnet(mask_bits):
             try:
                 resp, body = cls.client.create_subnet(
@@ -165,12 +162,9 @@
                 is_overlapping_cidr = 'overlaps with another subnet' in str(e)
                 if not is_overlapping_cidr:
                     raise
-                # save the failure in case all of the CIDRs are overlapping
-                failure = e
-
-        if not body and failure:
-            raise failure
-
+        else:
+            message = 'Available CIDR for subnet creation could not be found'
+            raise exceptions.BuildErrorException(message)
         subnet = body['subnet']
         cls.subnets.append(subnet)
         return subnet
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 654552d..1155257 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -18,7 +18,6 @@
 from tempest.api.network import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest import exceptions
 from tempest.test import attr
 
 CONF = config.CONF
@@ -85,25 +84,7 @@
         updated_net = body['network']
         self.assertEqual(updated_net['name'], new_name)
         # Find a cidr that is not in use yet and create a subnet with it
-        if self._ip_version == 4:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
-            mask_bits = CONF.network.tenant_network_mask_bits
-        elif self._ip_version == 6:
-            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
-            mask_bits = CONF.network.tenant_network_v6_mask_bits
-        for subnet_cidr in cidr.subnet(mask_bits):
-            try:
-                resp, body = self.client.create_subnet(
-                    network_id=net_id,
-                    cidr=str(subnet_cidr),
-                    ip_version=self._ip_version)
-                break
-            except exceptions.BadRequest as e:
-                is_overlapping_cidr = 'overlaps with another subnet' in str(e)
-                if not is_overlapping_cidr:
-                    raise
-        self.assertEqual('201', resp['status'])
-        subnet = body['subnet']
+        subnet = self.create_subnet(network)
         subnet_id = subnet['id']
         # Verification of subnet update
         new_subnet = "New_subnet"
@@ -115,6 +96,8 @@
         # Delete subnet and network
         resp, body = self.client.delete_subnet(subnet_id)
         self.assertEqual('204', resp['status'])
+        # Remove subnet from cleanup list
+        self.subnets.pop()
         resp, body = self.client.delete_network(net_id)
         self.assertEqual('204', resp['status'])
 
@@ -472,7 +455,7 @@
     @classmethod
     def setUpClass(cls):
         super(NetworksIpV6TestJSON, cls).setUpClass()
-        if not CONF.network.ipv6_enabled:
+        if not CONF.network_feature_enabled.ipv6:
             cls.tearDownClass()
             skip_msg = "IPv6 Tests are disabled."
             raise cls.skipException(skip_msg)
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 1d41cc9..3e26f46 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.api.network import base_security_groups as base
+from tempest.common.utils import data_utils
 from tempest import test
 
 
@@ -41,15 +42,9 @@
         self.assertIsNotNone(found, msg)
 
     @test.attr(type='smoke')
-    def test_create_show_delete_security_group(self):
+    def test_create_list_update_show_delete_security_group(self):
         group_create_body, name = self._create_security_group()
 
-        # Show details of the created security group
-        resp, show_body = self.client.show_security_group(
-            group_create_body['security_group']['id'])
-        self.assertEqual('200', resp['status'])
-        self.assertEqual(show_body['security_group']['name'], name)
-
         # List security groups and verify if created group is there in response
         resp, list_body = self.client.list_security_groups()
         self.assertEqual('200', resp['status'])
@@ -57,6 +52,24 @@
         for secgroup in list_body['security_groups']:
             secgroup_list.append(secgroup['id'])
         self.assertIn(group_create_body['security_group']['id'], secgroup_list)
+        # Update the security group
+        new_name = data_utils.rand_name('security-')
+        new_description = data_utils.rand_name('security-description')
+        resp, update_body = self.client.update_security_group(
+            group_create_body['security_group']['id'],
+            name=new_name,
+            description=new_description)
+        # Verify if security group is updated
+        self.assertEqual('200', resp['status'])
+        self.assertEqual(update_body['security_group']['name'], new_name)
+        self.assertEqual(update_body['security_group']['description'],
+                         new_description)
+        # Show details of the updated security group
+        resp, show_body = self.client.show_security_group(
+            group_create_body['security_group']['id'])
+        self.assertEqual(show_body['security_group']['name'], new_name)
+        self.assertEqual(show_body['security_group']['description'],
+                         new_description)
 
     @test.attr(type='smoke')
     def test_create_show_delete_security_group_rule(self):
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 7542ea1..4b895d8 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -18,10 +18,15 @@
 from six import moves
 
 from tempest.api.object_storage import base
+from tempest import clients
 from tempest.common import custom_matchers
 from tempest.common.utils import data_utils
+from tempest import config
+from tempest import exceptions
 from tempest import test
 
+CONF = config.CONF
+
 
 class AccountTest(base.BaseObjectTest):
     @classmethod
@@ -37,20 +42,109 @@
     @classmethod
     def tearDownClass(cls):
         cls.delete_containers(cls.containers)
+        cls.data.teardown_all()
         super(AccountTest, cls).tearDownClass()
 
     @test.attr(type='smoke')
     def test_list_containers(self):
         # list of all containers should not be empty
-        params = {'format': 'json'}
-        resp, container_list = \
-            self.account_client.list_account_containers(params=params)
+        resp, container_list = self.account_client.list_account_containers()
         self.assertHeaders(resp, 'Account', 'GET')
 
         self.assertIsNotNone(container_list)
-        container_names = [c['name'] for c in container_list]
         for container_name in self.containers:
-            self.assertIn(container_name, container_names)
+            self.assertIn(container_name, container_list)
+
+    @test.attr(type='smoke')
+    def test_list_no_containers(self):
+        # List request to empty account
+
+        # To test listing no containers, create new user other than
+        # the base user of this instance.
+        self.data.setup_test_user()
+
+        os_test_user = clients.Manager(
+            self.data.test_user,
+            self.data.test_password,
+            self.data.test_tenant)
+
+        # Retrieve the id of an operator role of object storage
+        test_role_id = None
+        swift_role = CONF.object_storage.operator_role
+        try:
+            _, roles = self.os_admin.identity_client.list_roles()
+            test_role_id = next(r['id'] for r in roles if r['name']
+                                == swift_role)
+        except StopIteration:
+            msg = "%s role found" % swift_role
+            raise exceptions.NotFound(msg)
+
+        # Retrieve the test_user id
+        _, users = self.os_admin.identity_client.get_users()
+        test_user_id = next(usr['id'] for usr in users if usr['name']
+                            == self.data.test_user)
+
+        # Retrieve the test_tenant id
+        _, tenants = self.os_admin.identity_client.list_tenants()
+        test_tenant_id = next(tnt['id'] for tnt in tenants if tnt['name']
+                              == self.data.test_tenant)
+
+        # Assign the newly created user the appropriate operator role
+        self.os_admin.identity_client.assign_user_role(
+            test_tenant_id,
+            test_user_id,
+            test_role_id)
+
+        resp, container_list = \
+            os_test_user.account_client.list_account_containers()
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+
+        # When sending a request to an account which has not received a PUT
+        # container request, the response does not contain 'accept-ranges'
+        # header. This is a special case, therefore the existence of response
+        # headers is checked without custom matcher.
+        self.assertIn('content-length', resp)
+        self.assertIn('x-timestamp', resp)
+        self.assertIn('x-account-bytes-used', resp)
+        self.assertIn('x-account-container-count', resp)
+        self.assertIn('x-account-object-count', resp)
+        self.assertIn('content-type', resp)
+        self.assertIn('x-trans-id', resp)
+        self.assertIn('date', resp)
+
+        # Check only the format of common headers with custom matcher
+        self.assertThat(resp, custom_matchers.AreAllWellFormatted())
+
+        self.assertEqual(len(container_list), 0)
+
+    @test.attr(type='smoke')
+    def test_list_containers_with_format_json(self):
+        # list containers setting format parameter to 'json'
+        params = {'format': 'json'}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertIsNotNone(container_list)
+        self.assertTrue([c['name'] for c in container_list])
+        self.assertTrue([c['count'] for c in container_list])
+        self.assertTrue([c['bytes'] for c in container_list])
+
+    @test.attr(type='smoke')
+    def test_list_containers_with_format_xml(self):
+        # list containers setting format parameter to 'xml'
+        params = {'format': 'xml'}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertIsNotNone(container_list)
+        self.assertEqual(container_list.tag, 'account')
+        self.assertTrue('name' in container_list.keys())
+        self.assertEqual(container_list.find(".//container").tag, 'container')
+        self.assertEqual(container_list.find(".//name").tag, 'name')
+        self.assertEqual(container_list.find(".//count").tag, 'count')
+        self.assertEqual(container_list.find(".//bytes").tag, 'bytes')
 
     @test.attr(type='smoke')
     def test_list_extensions(self):
@@ -109,6 +203,17 @@
         self.assertEqual(len(container_list), self.containers_count / 2)
 
     @test.attr(type='smoke')
+    def test_list_containers_with_marker_and_end_marker(self):
+        # list containers combining marker and end_marker param
+        params = {'marker': self.containers[0],
+                  'end_marker': self.containers[self.containers_count - 1]}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertEqual(len(container_list), self.containers_count - 2)
+
+    @test.attr(type='smoke')
     def test_list_containers_with_limit_and_marker(self):
         # list containers combining marker and limit param
         # result are always limitated by the limit whatever the marker
@@ -123,34 +228,125 @@
             self.assertTrue(len(container_list) <= limit, str(container_list))
 
     @test.attr(type='smoke')
-    def test_list_account_metadata(self):
-        # list all account metadata
-        resp, metadata = self.account_client.list_account_metadata()
+    def test_list_containers_with_limit_and_end_marker(self):
+        # list containers combining limit and end_marker param
+        limit = random.randint(1, self.containers_count)
+        params = {'limit': limit,
+                  'end_marker': self.containers[self.containers_count / 2]}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
         self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
-        self.assertHeaders(resp, 'Account', 'HEAD')
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertEqual(len(container_list),
+                         min(limit, self.containers_count / 2))
 
     @test.attr(type='smoke')
-    def test_create_and_delete_account_metadata(self):
-        header = 'test-account-meta'
-        data = 'Meta!'
+    def test_list_containers_with_limit_and_marker_and_end_marker(self):
+        # list containers combining limit, marker and end_marker param
+        limit = random.randint(1, self.containers_count)
+        params = {'limit': limit,
+                  'marker': self.containers[0],
+                  'end_marker': self.containers[self.containers_count - 1]}
+        resp, container_list = self.account_client.list_account_containers(
+            params=params)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'GET')
+        self.assertEqual(len(container_list),
+                         min(limit, self.containers_count - 2))
+
+    @test.attr(type='smoke')
+    def test_list_account_metadata(self):
+        # list all account metadata
+
+        # set metadata to account
+        metadata = {'test-account-meta1': 'Meta1',
+                    'test-account-meta2': 'Meta2'}
+        resp, _ = self.account_client.create_account_metadata(metadata)
+
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'HEAD')
+        self.assertIn('x-account-meta-test-account-meta1', resp)
+        self.assertIn('x-account-meta-test-account-meta2', resp)
+        self.account_client.delete_account_metadata(metadata)
+
+    @test.attr(type='smoke')
+    def test_list_no_account_metadata(self):
+        # list no account metadata
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'HEAD')
+        self.assertNotIn('x-account-meta-', str(resp))
+
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_create_metadata(self):
         # add metadata to account
-        resp, _ = self.account_client.create_account_metadata(
-            metadata={header: data})
+        metadata = {'test-account-meta1': 'Meta1'}
+        resp, _ = self.account_client.create_account_metadata(metadata)
         self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
         self.assertHeaders(resp, 'Account', 'POST')
 
-        resp, _ = self.account_client.list_account_metadata()
-        self.assertHeaders(resp, 'Account', 'HEAD')
+        resp, body = self.account_client.list_account_metadata()
+        self.assertIn('x-account-meta-test-account-meta1', resp)
+        self.assertEqual(resp['x-account-meta-test-account-meta1'],
+                         metadata['test-account-meta1'])
 
-        self.assertIn('x-account-meta-' + header, resp)
-        self.assertEqual(resp['x-account-meta-' + header], data)
+        self.account_client.delete_account_metadata(metadata)
 
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_delete_matadata(self):
         # delete metadata from account
-        resp, _ = \
-            self.account_client.delete_account_metadata(metadata=[header])
+        metadata = {'test-account-meta1': 'Meta1'}
+        self.account_client.create_account_metadata(metadata)
+        resp, _ = self.account_client.delete_account_metadata(metadata)
         self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
         self.assertHeaders(resp, 'Account', 'POST')
 
         resp, _ = self.account_client.list_account_metadata()
-        self.assertHeaders(resp, 'Account', 'HEAD')
-        self.assertNotIn('x-account-meta-' + header, resp)
+        self.assertNotIn('x-account-meta-test-account-meta1', resp)
+
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_create_matadata_key(self):
+        # if the value of metadata is not set, the metadata is not
+        # registered at a server
+        metadata = {'test-account-meta1': ''}
+        resp, _ = self.account_client.create_account_metadata(metadata)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'POST')
+
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertNotIn('x-account-meta-test-account-meta1', resp)
+
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_delete_matadata_key(self):
+        # Although the value of metadata is not set, the feature of
+        # deleting metadata is valid
+        metadata_1 = {'test-account-meta1': 'Meta1'}
+        self.account_client.create_account_metadata(metadata_1)
+        metadata_2 = {'test-account-meta1': ''}
+        resp, _ = self.account_client.delete_account_metadata(metadata_2)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'POST')
+
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertNotIn('x-account-meta-test-account-meta1', resp)
+
+    @test.attr(type='smoke')
+    def test_update_account_metadata_with_create_and_delete_metadata(self):
+        # Send a request adding and deleting metadata requests simultaneously
+        metadata_1 = {'test-account-meta1': 'Meta1'}
+        self.account_client.create_account_metadata(metadata_1)
+        metadata_2 = {'test-account-meta2': 'Meta2'}
+        resp, body = self.account_client.create_and_delete_account_metadata(
+            metadata_2,
+            metadata_1)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Account', 'POST')
+
+        resp, _ = self.account_client.list_account_metadata()
+        self.assertNotIn('x-account-meta-test-account-meta1', resp)
+        self.assertIn('x-account-meta-test-account-meta2', resp)
+        self.assertEqual(resp['x-account-meta-test-account-meta2'],
+                         metadata_2['test-account-meta2'])
+
+        self.account_client.delete_account_metadata(metadata_2)
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index 47c270e..c597255 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -40,9 +40,9 @@
         # update account metadata
         cls.key = 'Meta'
         cls.metadatas = []
-        cls.metadata = {'Temp-URL-Key': cls.key}
-        cls.metadatas.append(cls.metadata)
-        cls.account_client.create_account_metadata(metadata=cls.metadata)
+        metadata = {'Temp-URL-Key': cls.key}
+        cls.metadatas.append(metadata)
+        cls.account_client.create_account_metadata(metadata=metadata)
 
         # create an object
         cls.object_name = data_utils.rand_name(name='ObjectTemp')
@@ -53,7 +53,7 @@
 
     @classmethod
     def tearDownClass(cls):
-        for metadata in cls.metadata:
+        for metadata in cls.metadatas:
             cls.account_client.delete_account_metadata(
                 metadata=metadata)
 
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 291f0d1..18ba37b 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -73,7 +73,7 @@
       subnet_id: {get_resource: Subnet}
   Server:
     type: AWS::EC2::Instance
-    Metadata:
+    metadata:
       Name: SmokeServerNeutron
     properties:
       ImageId: {get_param: ImageId}
@@ -93,7 +93,7 @@
     type: AWS::CloudFormation::WaitConditionHandle
   WaitCondition:
     type: AWS::CloudFormation::WaitCondition
-    DependsOn: Server
+    depends_on: Server
     properties:
       Handle: {get_resource: WaitHandleNeutron}
       Timeout: '600'
diff --git a/tempest/api/orchestration/stacks/test_server_cfn_init.py b/tempest/api/orchestration/stacks/test_server_cfn_init.py
index 5130f87..7e8bc2d 100644
--- a/tempest/api/orchestration/stacks/test_server_cfn_init.py
+++ b/tempest/api/orchestration/stacks/test_server_cfn_init.py
@@ -154,8 +154,8 @@
         sid = self.stack_identifier
         rid = 'SmokeServer'
 
-        # wait for server resource create to complete.
-        self.client.wait_for_resource_status(sid, rid, 'CREATE_COMPLETE')
+        # wait for create to complete.
+        self.client.wait_for_stack_status(sid, 'CREATE_COMPLETE')
 
         resp, body = self.client.get_resource(sid, rid)
         self.assertEqual('CREATE_COMPLETE', body['resource_status'])
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
index 5921a7a..713cfd4 100644
--- a/tempest/api/orchestration/stacks/test_swift_resources.py
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -27,20 +27,20 @@
     _interface = 'json'
     template = """
 heat_template_version: 2013-05-23
-description: Template which creates a Swift container ressource
+description: Template which creates a Swift container resource
 
 resources:
   SwiftContainerWebsite:
-    DeletionPolicy: "Delete"
-    Type: OS::Swift::Container
-    Properties:
+    deletion_policy: "Delete"
+    type: OS::Swift::Container
+    properties:
       X-Container-Read: ".r:*"
       X-Container-Meta:
         web-index: "index.html"
         web-error: "error.html"
 
   SwiftContainer:
-    Type: OS::Swift::Container
+    type: OS::Swift::Container
 
 outputs:
   WebsiteURL:
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index b0c878b..6178a1c 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -14,7 +14,7 @@
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log as logging
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -86,7 +86,7 @@
 
         super(VolumeMultiBackendTest, cls).tearDownClass()
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_backend_name_reporting(self):
         # this test checks if os-vol-attr:host is populated correctly after
         # the multi backend feature has been enabled
@@ -100,7 +100,7 @@
                self.volume1['id'])
         self.assertTrue(len(volume1_host.split("@")) > 1, msg)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_backend_name_distinction(self):
         # this test checks that the two volumes created at setUp don't
         # belong to the same backend (if they are, than the
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 12fda92..e140ad0 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -15,7 +15,7 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
 class SnapshotsActionsTest(base.BaseVolumeV1AdminTest):
@@ -80,7 +80,7 @@
     def _get_progress_alias(self):
         return 'os-extended-snapshot-attributes:progress'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_reset_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
@@ -92,7 +92,7 @@
         self.assertEqual(200, resp_get.status)
         self.assertEqual(status, snapshot_get['status'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
@@ -112,22 +112,22 @@
         self.assertEqual(status, snapshot_get['status'])
         self.assertEqual(progress, snapshot_get[progress_alias])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_force_delete_when_snapshot_is_creating(self):
         # test force delete when status of snapshot is creating
         self._create_reset_and_force_delete_temp_snapshot('creating')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_force_delete_when_snapshot_is_deleting(self):
         # test force delete when status of snapshot is deleting
         self._create_reset_and_force_delete_temp_snapshot('deleting')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_force_delete_when_snapshot_is_error(self):
         # test force delete when status of snapshot is error
         self._create_reset_and_force_delete_temp_snapshot('error')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_force_delete_when_snapshot_is_error_deleting(self):
         # test force delete when status of snapshot is error_deleting
         self._create_reset_and_force_delete_temp_snapshot('error_deleting')
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index 5c311e1..01ba915 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -14,13 +14,13 @@
 #    under the License.
 
 from tempest.api.volume import base
-from tempest.test import attr
+from tempest import test
 
 
 class VolumeHostsAdminTestsJSON(base.BaseVolumeV1AdminTest):
     _interface = "json"
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_hosts(self):
         resp, hosts = self.hosts_client.list_hosts()
         self.assertEqual(200, resp.status)
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index d481251..8183999 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -16,7 +16,7 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -33,14 +33,14 @@
         resp, _ = self.client.delete_volume_type(volume_type_id)
         self.assertEqual(202, resp.status)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_type_list(self):
         # List Volume types.
         resp, body = self.client.list_volume_types()
         self.assertEqual(200, resp.status)
         self.assertIsInstance(body, list)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_create_get_delete_volume_with_volume_type_and_extra_specs(self):
         # Create/get/delete volume with volume_type and extra spec.
         volume = {}
@@ -84,7 +84,7 @@
                          'The fetched Volume is different '
                          'from the created Volume')
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_type_create_get_delete(self):
         # Create/get volume type.
         body = {}
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 99a0826..06a0b34 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -15,7 +15,7 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
-from tempest.test import attr
+from tempest import test
 
 
 class VolumeTypesExtraSpecsTest(base.BaseVolumeV1AdminTest):
@@ -32,7 +32,7 @@
         cls.client.delete_volume_type(cls.volume_type['id'])
         super(VolumeTypesExtraSpecsTest, cls).tearDownClass()
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_type_extra_specs_list(self):
         # List Volume types extra specs.
         extra_specs = {"spec1": "val1"}
@@ -47,7 +47,7 @@
         self.assertIsInstance(body, dict)
         self.assertIn('spec1', body)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_type_extra_specs_update(self):
         # Update volume type extra specs
         extra_specs = {"spec2": "val1"}
@@ -67,7 +67,7 @@
         self.assertEqual(extra_spec['spec2'], body['spec2'],
                          "Volume type extra spec incorrectly updated")
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_type_extra_spec_create_get_delete(self):
         # Create/Get/Delete volume type extra spec.
         extra_specs = {"spec3": "val1"}
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index 5a1a2cd..d3a052e 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -18,7 +18,7 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class ExtraSpecsNegativeTest(base.BaseVolumeV1AdminTest):
@@ -38,7 +38,7 @@
         cls.client.delete_volume_type(cls.volume_type['id'])
         super(ExtraSpecsNegativeTest, cls).tearDownClass()
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_no_body(self):
         # Should not update volume type extra specs with no body
         extra_spec = {"spec1": "val2"}
@@ -46,7 +46,7 @@
                           self.client.update_volume_type_extra_specs,
                           self.volume_type['id'], extra_spec.keys()[0], None)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_nonexistent_extra_spec_id(self):
         # Should not update volume type extra specs with nonexistent id.
         extra_spec = {"spec1": "val2"}
@@ -55,7 +55,7 @@
                           self.volume_type['id'], str(uuid.uuid4()),
                           extra_spec)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_none_extra_spec_id(self):
         # Should not update volume type extra specs with none id.
         extra_spec = {"spec1": "val2"}
@@ -63,7 +63,7 @@
                           self.client.update_volume_type_extra_specs,
                           self.volume_type['id'], None, extra_spec)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_update_multiple_extra_spec(self):
         # Should not update volume type extra specs with multiple specs as
             # body.
@@ -73,7 +73,7 @@
                           self.volume_type['id'], extra_spec.keys()[0],
                           extra_spec)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_nonexistent_type_id(self):
         # Should not create volume type extra spec for nonexistent volume
             # type id.
@@ -82,21 +82,21 @@
                           self.client.create_volume_type_extra_specs,
                           str(uuid.uuid4()), extra_specs)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_none_body(self):
         # Should not create volume type extra spec for none POST body.
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_volume_type_extra_specs,
                           self.volume_type['id'], None)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_invalid_body(self):
         # Should not create volume type extra spec for invalid POST body.
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_volume_type_extra_specs,
                           self.volume_type['id'], ['invalid'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_nonexistent_volume_type_id(self):
         # Should not delete volume type extra spec for nonexistent
             # type id.
@@ -105,14 +105,14 @@
                           self.client.delete_volume_type_extra_specs,
                           str(uuid.uuid4()), extra_specs.keys()[0])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_nonexistent_volume_type_id(self):
         # Should not list volume type extra spec for nonexistent type id.
         self.assertRaises(exceptions.NotFound,
                           self.client.list_volume_types_extra_specs,
                           str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_nonexistent_volume_type_id(self):
         # Should not get volume type extra spec for nonexistent type id.
         extra_specs = {"spec1": "val1"}
@@ -120,7 +120,7 @@
                           self.client.get_volume_type_extra_specs,
                           str(uuid.uuid4()), extra_specs.keys()[0])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_nonexistent_extra_spec_id(self):
         # Should not get volume type extra spec for nonexistent extra spec
             # id.
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index 56ad227..c18e15d 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -17,13 +17,13 @@
 
 from tempest.api.volume import base
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class VolumeTypesNegativeTest(base.BaseVolumeV1AdminTest):
     _interface = 'json'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_with_nonexistent_volume_type(self):
         # Should not be able to create volume with nonexistent volume_type.
         self.assertRaises(exceptions.NotFound,
@@ -31,19 +31,19 @@
                           display_name=str(uuid.uuid4()),
                           volume_type=str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_with_empty_name(self):
         # Should not be able to create volume type with an empty name.
         self.assertRaises(exceptions.BadRequest,
                           self.client.create_volume_type, '')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_get_nonexistent_type_id(self):
         # Should not be able to get volume type with nonexistent type id.
         self.assertRaises(exceptions.NotFound, self.client.get_volume_type,
                           str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_delete_nonexistent_type_id(self):
         # Should not be able to delete volume type with nonexistent type id.
         self.assertRaises(exceptions.NotFound, self.client.delete_volume_type,
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 9274fce..aa00700 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -15,7 +15,7 @@
 
 from tempest.api.volume import base
 from tempest.common.utils import data_utils as utils
-from tempest.test import attr
+from tempest import test
 
 
 class VolumesActionsTest(base.BaseVolumeV1AdminTest):
@@ -75,7 +75,7 @@
         self.assertEqual(202, resp_delete.status)
         self.client.wait_for_resource_deletion(temp_volume['id'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_reset_status(self):
         # test volume reset status : available->error->available
         resp, body = self._reset_volume_status(self.volume['id'], 'error')
@@ -84,7 +84,7 @@
             self.volume['id'])
         self.assertEqual('error', volume_get['status'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_begin_detaching(self):
         # test volume begin detaching : available -> detaching -> available
         resp, body = self.client.volume_begin_detaching(self.volume['id'])
@@ -92,7 +92,7 @@
         resp_get, volume_get = self.client.get_volume(self.volume['id'])
         self.assertEqual('detaching', volume_get['status'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_roll_detaching(self):
         # test volume roll detaching : detaching -> in-use -> available
         resp, body = self.client.volume_begin_detaching(self.volume['id'])
@@ -110,7 +110,7 @@
         # test force delete when status of volume is attaching
         self._create_reset_and_force_delete_temp_volume('attaching')
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_force_delete_when_volume_is_error(self):
         # test force delete when status of volume is error
         self._create_reset_and_force_delete_temp_volume('error')
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index 47094f0..cd6d7a8 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -13,7 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.volume.base import BaseVolumeV1AdminTest
+from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log as logging
@@ -23,7 +23,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class VolumesBackupsTest(BaseVolumeV1AdminTest):
+class VolumesBackupsTest(base.BaseVolumeV1AdminTest):
     _interface = "json"
 
     @classmethod
@@ -38,7 +38,8 @@
         cls.volume = cls.create_volume()
 
     @test.attr(type='smoke')
-    def test_volume_backup_create_get_restore_delete(self):
+    def test_volume_backup_create_get_detailed_list_restore_delete(self):
+        # Create backup
         backup_name = data_utils.rand_name('Backup')
         create_backup = self.backups_adm_client.create_backup
         resp, backup = create_backup(self.volume['id'],
@@ -46,21 +47,31 @@
         self.assertEqual(202, resp.status)
         self.addCleanup(self.backups_adm_client.delete_backup,
                         backup['id'])
-        self.assertEqual(backup['name'], backup_name)
+        self.assertEqual(backup_name, backup['name'])
         self.volumes_adm_client.wait_for_volume_status(self.volume['id'],
                                                        'available')
         self.backups_adm_client.wait_for_backup_status(backup['id'],
                                                        'available')
 
+        # Get a given backup
         resp, backup = self.backups_adm_client.get_backup(backup['id'])
         self.assertEqual(200, resp.status)
-        self.assertEqual(backup['name'], backup_name)
+        self.assertEqual(backup_name, backup['name'])
 
+        # Get all backups with detail
+        resp, backups = self.backups_adm_client.list_backups_with_detail()
+        self.assertEqual(200, resp.status)
+        self.assertIn((backup['name'], backup['id']),
+                      [(m['name'], m['id']) for m in backups])
+
+        # Restore backup
         resp, restore = self.backups_adm_client.restore_backup(backup['id'])
         self.assertEqual(202, resp.status)
+
+        # Delete backup
         self.addCleanup(self.volumes_adm_client.delete_volume,
                         restore['volume_id'])
-        self.assertEqual(restore['backup_id'], backup['id'])
+        self.assertEqual(backup['id'], restore['backup_id'])
         self.backups_adm_client.wait_for_backup_status(backup['id'],
                                                        'available')
         self.volumes_adm_client.wait_for_volume_status(restore['volume_id'],
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
index cceffd6..ce019a2 100644
--- a/tempest/api/volume/test_extensions.py
+++ b/tempest/api/volume/test_extensions.py
@@ -17,7 +17,7 @@
 from tempest.api.volume import base
 from tempest import config
 from tempest.openstack.common import log as logging
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -28,7 +28,7 @@
 class ExtensionsTestJSON(base.BaseVolumeV1Test):
     _interface = 'json'
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_list_extensions(self):
         # List of all extensions
         resp, extensions = self.volumes_extension_client.list_extensions()
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index f4b2d4c..55a72c1 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -18,7 +18,7 @@
 from tempest.api.volume import base
 from tempest import clients
 from tempest import config
-from tempest.test import attr
+from tempest import test
 
 CONF = config.CONF
 
@@ -66,7 +66,7 @@
         self.assertEqual(202, resp.status)
         self.adm_client.wait_for_resource_deletion(volume_id)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_create_get_list_accept_volume_transfer(self):
         # Create a volume first
         volume = self.create_volume()
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 284c321..82924a5 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -18,7 +18,7 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class VolumesNegativeTest(base.BaseVolumeV1Test):
@@ -33,19 +33,19 @@
         cls.volume = cls.create_volume()
         cls.mountpoint = "/dev/vdc"
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_get_nonexistent_volume_id(self):
         # Should not be able to get a non-existent volume
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_delete_nonexistent_volume_id(self):
         # Should not be able to delete a non-existent Volume
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_invalid_size(self):
         # Should not be able to create volume with invalid size
         # in request
@@ -54,7 +54,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='#$%', display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_out_passing_size(self):
         # Should not be able to create volume without passing size
         # in request
@@ -63,7 +63,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='', display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_size_zero(self):
         # Should not be able to create volume with size zero
         v_name = data_utils.rand_name('Volume-')
@@ -71,7 +71,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='0', display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_size_negative(self):
         # Should not be able to create volume with size negative
         v_name = data_utils.rand_name('Volume-')
@@ -79,7 +79,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='-1', display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_nonexistent_volume_type(self):
         # Should not be able to create volume with non-existent volume type
         v_name = data_utils.rand_name('Volume-')
@@ -88,7 +88,7 @@
                           size='1', volume_type=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_nonexistent_snapshot_id(self):
         # Should not be able to create volume with non-existent snapshot
         v_name = data_utils.rand_name('Volume-')
@@ -97,7 +97,7 @@
                           size='1', snapshot_id=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_volume_with_nonexistent_source_volid(self):
         # Should not be able to create volume with non-existent source volume
         v_name = data_utils.rand_name('Volume-')
@@ -106,7 +106,7 @@
                           size='1', source_volid=str(uuid.uuid4()),
                           display_name=v_name, metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_update_volume_with_nonexistent_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -114,7 +114,7 @@
                           volume_id=str(uuid.uuid4()), display_name=v_name,
                           metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_update_volume_with_invalid_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -122,7 +122,7 @@
                           volume_id='#$%%&^&^', display_name=v_name,
                           metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_update_volume_with_empty_volume_id(self):
         v_name = data_utils.rand_name('Volume-')
         metadata = {'Type': 'work'}
@@ -130,29 +130,29 @@
                           volume_id='', display_name=v_name,
                           metadata=metadata)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_invalid_volume_id(self):
         # Should not be able to get volume with invalid id
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
                           '#$%%&^&^')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_get_volume_without_passing_volume_id(self):
         # Should not be able to get volume when empty ID is passed
         self.assertRaises(exceptions.NotFound, self.client.get_volume, '')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_invalid_volume_id(self):
         # Should not be able to delete volume when invalid ID is passed
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
                           '!@#$%^&*()')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_delete_volume_without_passing_volume_id(self):
         # Should not be able to delete volume when empty ID is passed
         self.assertRaises(exceptions.NotFound, self.client.delete_volume, '')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_attach_volumes_with_nonexistent_volume_id(self):
         srv_name = data_utils.rand_name('Instance-')
         resp, server = self.servers_client.create_server(srv_name,
@@ -166,60 +166,60 @@
                           server['id'],
                           self.mountpoint)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_detach_volumes_with_invalid_volume_id(self):
         self.assertRaises(exceptions.NotFound,
                           self.client.detach_volume,
                           'xxx')
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_with_size_smaller_than_original_size(self):
         # Extend volume with smaller size than original size.
         extend_size = 0
         self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_with_non_number_size(self):
         # Extend volume when size is non number.
         extend_size = 'abc'
         self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_with_None_size(self):
         # Extend volume with None size.
         extend_size = None
         self.assertRaises(exceptions.BadRequest, self.client.extend_volume,
                           self.volume['id'], extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_with_nonexistent_volume_id(self):
         # Extend volume size when volume is nonexistent.
         extend_size = int(self.volume['size']) + 1
         self.assertRaises(exceptions.NotFound, self.client.extend_volume,
                           str(uuid.uuid4()), extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_volume_extend_without_passing_volume_id(self):
         # Extend volume size when passing volume id is None.
         extend_size = int(self.volume['size']) + 1
         self.assertRaises(exceptions.NotFound, self.client.extend_volume,
                           None, extend_size)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_reserve_volume_with_nonexistent_volume_id(self):
         self.assertRaises(exceptions.NotFound,
                           self.client.reserve_volume,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_unreserve_volume_with_nonexistent_volume_id(self):
         self.assertRaises(exceptions.NotFound,
                           self.client.unreserve_volume,
                           str(uuid.uuid4()))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_reserve_volume_with_negative_volume_status(self):
         # Mark volume as reserved.
         resp, body = self.client.reserve_volume(self.volume['id'])
@@ -232,7 +232,7 @@
         resp, body = self.client.unreserve_volume(self.volume['id'])
         self.assertEqual(202, resp.status)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_volumes_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {'display_name': v_name}
@@ -240,7 +240,7 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(0, len(fetched_volume))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_volumes_detail_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {'display_name': v_name}
@@ -248,14 +248,14 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(0, len(fetched_volume))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_volumes_with_invalid_status(self):
         params = {'status': 'null'}
         resp, fetched_volume = self.client.list_volumes(params)
         self.assertEqual(200, resp.status)
         self.assertEqual(0, len(fetched_volume))
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_list_volumes_detail_with_invalid_status(self):
         params = {'status': 'null'}
         resp, fetched_volume = self.client.list_volumes_with_detail(params)
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 56915e6..2701e84 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -14,7 +14,7 @@
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log as logging
-from tempest.test import attr
+from tempest import test
 
 LOG = logging.getLogger(__name__)
 CONF = config.CONF
@@ -63,7 +63,7 @@
                       ('details' if with_detail else '', key)
                 self.assertEqual(params[key], snap[key], msg)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_create_with_volume_in_use(self):
         # Create a snapshot when volume status is in-use
         # Create a test instance
@@ -89,7 +89,7 @@
         self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
         self.snapshots.remove(snapshot)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshot_create_get_list_update_delete(self):
         # Create a snapshot
         s_name = data_utils.rand_name('snap')
@@ -134,7 +134,7 @@
         self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
         self.snapshots.remove(snapshot)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshots_list_with_params(self):
         """list snapshots with params."""
         # Create a snapshot
@@ -155,7 +155,7 @@
                   'display_name': snapshot['display_name']}
         self._list_by_param_values_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_snapshots_list_details_with_params(self):
         """list snapshot details with params."""
         # Create a snapshot
@@ -174,7 +174,7 @@
                   'display_name': snapshot['display_name']}
         self._list_by_param_values_and_assert(params, with_detail=True)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_from_snapshot(self):
         # Create a temporary snap using wrapper method from base, then
         # create a snap based volume, check resp code and deletes it
diff --git a/tempest/api/volume/test_volumes_snapshots_negative.py b/tempest/api/volume/test_volumes_snapshots_negative.py
index b24b597..9e47c03 100644
--- a/tempest/api/volume/test_volumes_snapshots_negative.py
+++ b/tempest/api/volume/test_volumes_snapshots_negative.py
@@ -15,13 +15,13 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import exceptions
-from tempest.test import attr
+from tempest import test
 
 
 class VolumesSnapshotNegativeTest(base.BaseVolumeV1Test):
     _interface = "json"
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_snapshot_with_nonexistent_volume_id(self):
         # Create a snapshot with nonexistent volume id
         s_name = data_utils.rand_name('snap')
@@ -29,7 +29,7 @@
                           self.snapshots_client.create_snapshot,
                           str(uuid.uuid4()), display_name=s_name)
 
-    @attr(type=['negative', 'gate'])
+    @test.attr(type=['negative', 'gate'])
     def test_create_snapshot_without_passing_volume_id(self):
         # Create a snapshot without passing volume id
         s_name = data_utils.rand_name('snap')
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index d0e8b99..0e91371 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -18,8 +18,8 @@
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest.openstack.common import log as logging
-from tempest.test import attr
-from testtools.matchers import ContainsAll
+from tempest import test
+from testtools import matchers
 
 LOG = logging.getLogger(__name__)
 
@@ -116,12 +116,12 @@
                           ('details' if with_detail else '', key)
                     if key == 'metadata':
                         self.assertThat(volume[key].items(),
-                                        ContainsAll(params[key].items()),
-                                        msg)
+                                        matchers.ContainsAll(params[key]
+                                        .items()), msg)
                     else:
                         self.assertEqual(params[key], volume[key], msg)
 
-    @attr(type='smoke')
+    @test.attr(type='smoke')
     def test_volume_list(self):
         # Get a list of Volumes
         # Fetch all volumes
@@ -130,7 +130,7 @@
         self.assertVolumesIn(fetched_list, self.volume_list,
                              fields=VOLUME_FIELDS)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_with_details(self):
         # Get a list of Volumes with details
         # Fetch all Volumes
@@ -138,7 +138,7 @@
         self.assertEqual(200, resp.status)
         self.assertVolumesIn(fetched_list, self.volume_list)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {'name': volume['name']}
@@ -147,7 +147,7 @@
         self.assertEqual(1, len(fetched_vol), str(fetched_vol))
         self.assertEqual(fetched_vol[0]['name'], volume['name'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_details_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {'name': volume['name']}
@@ -156,43 +156,43 @@
         self.assertEqual(1, len(fetched_vol), str(fetched_vol))
         self.assertEqual(fetched_vol[0]['name'], volume['name'])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volumes_list_by_status(self):
         params = {'status': 'available'}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volumes_list_details_by_status(self):
         params = {'status': 'available'}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volumes_list_by_availability_zone(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volumes_list_details_by_availability_zone(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_with_param_metadata(self):
         # Test to list volumes when metadata param is given
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_with_detail_param_metadata(self):
         # Test to list volumes details when metadata param is given
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_param_display_name_and_status(self):
         # Test to list volume when display name and status param is given
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
@@ -200,7 +200,7 @@
                   'status': 'available'}
         self._list_by_param_value_and_assert(params, expected_list=[volume])
 
-    @attr(type='gate')
+    @test.attr(type='gate')
     def test_volume_list_with_detail_param_display_name_and_status(self):
         # Test to list volume when name and status param is given
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
diff --git a/tempest/auth.py b/tempest/auth.py
index 8cb3b2c..0e45161 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -14,11 +14,11 @@
 #    under the License.
 
 import copy
+import datetime
 import exceptions
 import re
 import urlparse
 
-from datetime import datetime
 from tempest import config
 from tempest.services.identity.json import identity_client as json_id
 from tempest.services.identity.v3.json import identity_client as json_v3id
@@ -291,9 +291,9 @@
 
     def is_expired(self, auth_data):
         _, access = auth_data
-        expiry = datetime.strptime(access['token']['expires'],
-                                   self.EXPIRY_DATE_FORMAT)
-        return expiry <= datetime.now()
+        expiry = datetime.datetime.strptime(access['token']['expires'],
+                                            self.EXPIRY_DATE_FORMAT)
+        return expiry <= datetime.datetime.now()
 
 
 class KeystoneV3AuthProvider(KeystoneAuthProvider):
@@ -391,6 +391,6 @@
 
     def is_expired(self, auth_data):
         _, access = auth_data
-        expiry = datetime.strptime(access['expires_at'],
-                                   self.EXPIRY_DATE_FORMAT)
-        return expiry <= datetime.now()
+        expiry = datetime.datetime.strptime(access['expires_at'],
+                                            self.EXPIRY_DATE_FORMAT)
+        return expiry <= datetime.datetime.now()
diff --git a/tempest/cli/simple_read_only/test_nova.py b/tempest/cli/simple_read_only/test_nova.py
index b0264d0..d0b6028 100644
--- a/tempest/cli/simple_read_only/test_nova.py
+++ b/tempest/cli/simple_read_only/test_nova.py
@@ -154,12 +154,18 @@
     def test_admin_usage_list(self):
         self.nova('usage-list')
 
+    @testtools.skipIf(not CONF.service_available.cinder,
+                      "Skipped as Cinder is not available")
     def test_admin_volume_list(self):
         self.nova('volume-list')
 
+    @testtools.skipIf(not CONF.service_available.cinder,
+                      "Skipped as Cinder is not available")
     def test_admin_volume_snapshot_list(self):
         self.nova('volume-snapshot-list')
 
+    @testtools.skipIf(not CONF.service_available.cinder,
+                      "Skipped as Cinder is not available")
     def test_admin_volume_type_list(self):
         self.nova('volume-type-list')
 
diff --git a/tempest/clients.py b/tempest/clients.py
index 8db399a..e16d0f4 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -114,6 +114,8 @@
 from tempest.services.compute.xml.volumes_extensions_client import \
     VolumesExtensionsClientXML
 from tempest.services.data_processing.v1_1.client import DataProcessingClient
+from tempest.services.database.json.flavors_client import \
+    DatabaseFlavorsClientJSON
 from tempest.services.identity.json.identity_client import IdentityClientJSON
 from tempest.services.identity.json.identity_client import TokenClientJSON
 from tempest.services.identity.v3.json.credentials_client import \
@@ -330,6 +332,8 @@
             self.volumes_extension_client = VolumeExtensionClientJSON(
                 self.auth_provider)
             self.hosts_v3_client = HostsV3ClientJSON(self.auth_provider)
+            self.database_flavors_client = DatabaseFlavorsClientJSON(
+                self.auth_provider)
             if CONF.service_available.ceilometer:
                 self.telemetry_client = TelemetryClientJSON(
                     self.auth_provider)
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 03dccd4..66b6fe7 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -25,7 +25,7 @@
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -299,11 +299,11 @@
                 # Parse list-like xmls (users, roles, etc)
                 array = []
                 for child in element.getchildren():
-                    array.append(xml_to_json(child))
+                    array.append(common.xml_to_json(child))
                 return array
 
             # Parse one-item-like xmls (user, role, etc)
-            return xml_to_json(element)
+            return common.xml_to_json(element)
 
     def response_checker(self, method, url, headers, body, resp, resp_body):
         if (resp.status in set((204, 205, 304)) or resp.status < 200 or
diff --git a/tempest/config.py b/tempest/config.py
index 26b3bf1..db81f6e 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -348,9 +348,6 @@
     cfg.IntOpt('tenant_network_mask_bits',
                default=28,
                help="The mask bits for tenant ipv4 subnets"),
-    cfg.BoolOpt('ipv6_enabled',
-                default=True,
-                help="Allow the execution of IPv6 tests"),
     cfg.StrOpt('tenant_network_v6_cidr',
                default="2003::/64",
                help="The cidr block to allocate tenant ipv6 subnets from"),
@@ -375,6 +372,9 @@
                                      title='Enabled network service features')
 
 NetworkFeaturesGroup = [
+    cfg.BoolOpt('ipv6',
+                default=True,
+                help="Allow the execution of IPv6 tests"),
     cfg.ListOpt('api_extensions',
                 default=['all'],
                 help='A list of enabled network extensions with a special '
@@ -493,6 +493,17 @@
                      "features are expected to be enabled"),
 ]
 
+database_group = cfg.OptGroup(name='database',
+                              title='Database Service Options')
+
+DatabaseGroup = [
+    cfg.StrOpt('catalog_type',
+               default='database',
+               help="Catalog type of the Database service."),
+    cfg.StrOpt('db_flavor_ref',
+               default="1",
+               help="Valid primary flavor to use in database tests."),
+]
 
 orchestration_group = cfg.OptGroup(name='orchestration',
                                    title='Orchestration Service Options')
@@ -522,7 +533,7 @@
                default=1,
                help="Time in seconds between build status checks."),
     cfg.IntOpt('build_timeout',
-               default=300,
+               default=600,
                help="Timeout in seconds to wait for a stack to build."),
     cfg.StrOpt('instance_type',
                default='m1.micro',
@@ -739,6 +750,9 @@
     cfg.BoolOpt('ironic',
                 default=False,
                 help="Whether or not Ironic is expected to be available"),
+    cfg.BoolOpt('trove',
+                default=False,
+                help="Whether or not Trove is expected to be available"),
 ]
 
 debug_group = cfg.OptGroup(name="debug",
@@ -834,6 +848,7 @@
     register_opt_group(cfg.CONF, object_storage_group, ObjectStoreGroup)
     register_opt_group(cfg.CONF, object_storage_feature_group,
                        ObjectStoreFeaturesGroup)
+    register_opt_group(cfg.CONF, database_group, DatabaseGroup)
     register_opt_group(cfg.CONF, orchestration_group, OrchestrationGroup)
     register_opt_group(cfg.CONF, telemetry_group, TelemetryGroup)
     register_opt_group(cfg.CONF, dashboard_group, DashboardGroup)
@@ -876,6 +891,7 @@
         self.object_storage = cfg.CONF['object-storage']
         self.object_storage_feature_enabled = cfg.CONF[
             'object-storage-feature-enabled']
+        self.database = cfg.CONF.database
         self.orchestration = cfg.CONF.orchestration
         self.telemetry = cfg.CONF.telemetry
         self.dashboard = cfg.CONF.dashboard
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 5bcdacd..ce2c66f 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -17,7 +17,6 @@
 import urllib
 
 from tempest.api.network import common as net_common
-from tempest.common import ssh
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -64,6 +63,8 @@
         cls.servers_keypairs = {}
         cls.members = []
         cls.floating_ips = {}
+        cls.server_ip = None
+        cls.vip_ip = None
         cls.port1 = 80
         cls.port2 = 88
 
@@ -76,12 +77,10 @@
         name = data_utils.rand_name("smoke_server-")
         keypair = self.create_keypair(name='keypair-%s' % name)
         security_groups = [self.security_groups[tenant_id].name]
-        net = self.list_networks(tenant_id=self.tenant_id)[0]
-        self.network = net_common.DeletableNetwork(client=self.network_client,
-                                                   **net['network'])
+        net = self._list_networks(tenant_id=self.tenant_id)[0]
         create_kwargs = {
             'nics': [
-                {'net-id': self.network.id},
+                {'net-id': net['id']},
             ],
             'key_name': keypair.name,
             'security_groups': security_groups,
@@ -89,30 +88,36 @@
         server = self.create_server(name=name,
                                     create_kwargs=create_kwargs)
         self.servers_keypairs[server] = keypair
+        if (config.network.public_network_id and not
+                config.network.tenant_networks_reachable):
+            public_network_id = config.network.public_network_id
+            floating_ip = self._create_floating_ip(
+                server, public_network_id)
+            self.floating_ips[floating_ip] = server
+            self.server_ip = floating_ip.floating_ip_address
+        else:
+            self.server_ip = server.networks[net['name']][0]
         self.assertTrue(self.servers_keypairs)
+        return server
 
-    def _start_servers(self):
+    def _start_servers(self, server):
         """
         1. SSH to the instance
-        2. Start two servers listening on ports 80 and 88 respectively
+        2. Start two http backends listening on ports 80 and 88 respectively
         """
-        for server in self.servers_keypairs.keys():
-            ssh_login = config.compute.image_ssh_user
-            private_key = self.servers_keypairs[server].private_key
-            network_name = self.network.name
 
-            ip_address = server.networks[network_name][0]
-            ssh_client = ssh.Client(ip_address, ssh_login,
-                                    pkey=private_key,
-                                    timeout=100)
-            start_server = "while true; do echo -e 'HTTP/1.0 200 OK\r\n\r\n" \
-                           "%(server)s' | sudo nc -l -p %(port)s ; done &"
-            cmd = start_server % {'server': 'server1',
-                                  'port': self.port1}
-            ssh_client.exec_command(cmd)
-            cmd = start_server % {'server': 'server2',
-                                  'port': self.port2}
-            ssh_client.exec_command(cmd)
+        private_key = self.servers_keypairs[server].private_key
+        ssh_client = self.get_remote_client(
+            server_or_ip=self.server_ip,
+            private_key=private_key).ssh_client
+        start_server = "while true; do echo -e 'HTTP/1.0 200 OK\r\n\r\n" \
+                       "%(server)s' | sudo nc -l -p %(port)s ; done &"
+        cmd = start_server % {'server': 'server1',
+                              'port': self.port1}
+        ssh_client.exec_command(cmd)
+        cmd = start_server % {'server': 'server2',
+                              'port': self.port2}
+        ssh_client.exec_command(cmd)
 
     def _check_connection(self, check_ip):
         def try_connect(ip):
@@ -135,14 +140,14 @@
         # get tenant subnet and verify there's only one
         subnet = self._list_subnets(tenant_id=self.tenant_id)[0]
         self.subnet = net_common.DeletableSubnet(client=self.network_client,
-                                                 **subnet['subnet'])
+                                                 **subnet)
         self.pool = super(TestLoadBalancerBasic, self)._create_pool(
             'ROUND_ROBIN',
             'HTTP',
             self.subnet.id)
         self.assertTrue(self.pool)
 
-    def _create_members(self, network_name, server_ids):
+    def _create_members(self, server_ids):
         """
         Create two members.
 
@@ -152,7 +157,7 @@
         servers = self.compute_client.servers.list()
         for server in servers:
             if server.id in server_ids:
-                ip = server.networks[network_name][0]
+                ip = self.server_ip
                 pool_id = self.pool.id
                 if len(set(server_ids)) == 1 or len(servers) == 1:
                     member1 = self._create_member(ip, self.port1, pool_id)
@@ -173,8 +178,7 @@
 
     def _create_load_balancer(self):
         self._create_pool()
-        self._create_members(self.network.name,
-                             [self.servers_keypairs.keys()[0].id])
+        self._create_members([self.servers_keypairs.keys()[0].id])
         subnet_id = self.subnet.id
         pool_id = self.pool.id
         self.vip = super(TestLoadBalancerBasic, self)._create_vip('HTTP', 80,
@@ -185,7 +189,13 @@
                                               net_common.DeletableVip),
                              self.vip.id,
                              expected_status='ACTIVE')
-        self._assign_floating_ip_to_vip(self.vip)
+        if (config.network.public_network_id and not
+                config.network.tenant_networks_reachable):
+            self._assign_floating_ip_to_vip(self.vip)
+            self.vip_ip = self.floating_ips[
+                self.vip.id][0]['floating_ip_address']
+        else:
+            self.vip_ip = self.vip.address
 
     def _check_load_balancing(self):
         """
@@ -195,25 +205,22 @@
            of the requests
         """
 
-        vip = self.vip
-        floating_ip_vip = self.floating_ips[vip.id][0]['floating_ip_address']
-        self._check_connection(floating_ip_vip)
+        self._check_connection(self.vip_ip)
         resp = []
         for count in range(10):
             resp.append(
                 urllib.urlopen(
-                    "http://{0}/".format(floating_ip_vip)).read())
+                    "http://{0}/".format(self.vip_ip)).read())
         self.assertEqual(set(["server1\n", "server2\n"]), set(resp))
         self.assertEqual(5, resp.count("server1\n"))
         self.assertEqual(5, resp.count("server2\n"))
 
-    @test.skip_because(bug="1277381")
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_load_balancer_basic(self):
         self._create_security_groups()
-        self._create_server()
-        self._start_servers()
+        server = self._create_server()
+        self._start_servers(server)
         self._create_load_balancer()
         self._check_load_balancing()
 
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 819e366..389e6a4 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -435,3 +435,11 @@
                                post_body)
         body = json.loads(body)
         return resp, body['console']
+
+    def reset_network(self, server_id, **kwargs):
+        """Resets the Network of a server"""
+        return self.action(server_id, 'reset_network', None, **kwargs)
+
+    def inject_network_info(self, server_id, **kwargs):
+        """Inject the Network Info into server"""
+        return self.action(server_id, 'inject_network_info', None, **kwargs)
diff --git a/tempest/services/database/__init__.py b/tempest/services/database/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/database/__init__.py
diff --git a/tempest/services/database/json/__init__.py b/tempest/services/database/json/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/database/json/__init__.py
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
new file mode 100644
index 0000000..1a8a4c1
--- /dev/null
+++ b/tempest/services/database/json/flavors_client.py
@@ -0,0 +1,39 @@
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import rest_client
+from tempest import config
+import urllib
+
+CONF = config.CONF
+
+
+class DatabaseFlavorsClientJSON(rest_client.RestClient):
+
+    def __init__(self, auth_provider):
+        super(DatabaseFlavorsClientJSON, self).__init__(auth_provider)
+        self.service = CONF.database.catalog_type
+
+    def list_db_flavors(self, params=None):
+        url = 'flavors'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        return resp, self._parse_resp(body)
+
+    def get_db_flavor_details(self, db_flavor_id):
+        resp, body = self.get("flavors/%s" % str(db_flavor_id))
+        return resp, self._parse_resp(body)
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/services/identity/v3/json/credentials_client.py
index 5d6632a..f795c7b 100644
--- a/tempest/services/identity/v3/json/credentials_client.py
+++ b/tempest/services/identity/v3/json/credentials_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class CredentialsClientJSON(RestClient):
+class CredentialsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(CredentialsClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
index 652c345..c3c1e15 100644
--- a/tempest/services/identity/v3/json/endpoints_client.py
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class EndPointClientJSON(RestClient):
+class EndPointClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(EndPointClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index b044e4d..65f3355 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -15,14 +15,14 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
 
 CONF = config.CONF
 
 
-class IdentityV3ClientJSON(RestClient):
+class IdentityV3ClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(IdentityV3ClientJSON, self).__init__(auth_provider)
@@ -439,7 +439,7 @@
         return resp, body
 
 
-class V3TokenClientJSON(RestClient):
+class V3TokenClientJSON(rest_client.RestClient):
 
     def __init__(self):
         super(V3TokenClientJSON, self).__init__(None)
diff --git a/tempest/services/identity/v3/json/policy_client.py b/tempest/services/identity/v3/json/policy_client.py
index 5a3f891..3c90fa1 100644
--- a/tempest/services/identity/v3/json/policy_client.py
+++ b/tempest/services/identity/v3/json/policy_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class PolicyClientJSON(RestClient):
+class PolicyClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(PolicyClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/identity/v3/json/service_client.py b/tempest/services/identity/v3/json/service_client.py
index c1faebb..b66fb4a 100644
--- a/tempest/services/identity/v3/json/service_client.py
+++ b/tempest/services/identity/v3/json/service_client.py
@@ -15,13 +15,13 @@
 
 import json
 
-from tempest.common.rest_client import RestClient
+from tempest.common import rest_client
 from tempest import config
 
 CONF = config.CONF
 
 
-class ServiceClientJSON(RestClient):
+class ServiceClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
         super(ServiceClientJSON, self).__init__(auth_provider)
diff --git a/tempest/services/identity/v3/xml/credentials_client.py b/tempest/services/identity/v3/xml/credentials_client.py
index 22ed44d..70f85a1 100644
--- a/tempest/services/identity/v3/xml/credentials_client.py
+++ b/tempest/services/identity/v3/xml/credentials_client.py
@@ -19,10 +19,7 @@
 
 from tempest.common import rest_client
 from tempest import config
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import Text
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -39,7 +36,7 @@
         self.api_version = "v3"
 
     def _parse_body(self, body):
-        data = xml_to_json(body)
+        data = common.xml_to_json(body)
         return data
 
     def _parse_creds(self, node):
@@ -47,7 +44,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "credential":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def create_credential(self, access_key, secret_key, user_id, project_id):
@@ -55,14 +52,14 @@
         cred_type = 'ec2'
         access = "&quot;access&quot;: &quot;%s&quot;" % access_key
         secret = "&quot;secret&quot;: &quot;%s&quot;" % secret_key
-        blob = Element('blob',
-                       xmlns=XMLNS)
-        blob.append(Text("{%s , %s}"
-                         % (access, secret)))
-        credential = Element('credential', project_id=project_id,
-                             type=cred_type, user_id=user_id)
+        blob = common.Element('blob',
+                              xmlns=XMLNS)
+        blob.append(common.Text("{%s , %s}"
+                                % (access, secret)))
+        credential = common.Element('credential', project_id=project_id,
+                                    type=cred_type, user_id=user_id)
         credential.append(blob)
-        resp, body = self.post('credentials', str(Document(credential)))
+        resp, body = self.post('credentials', str(common.Document(credential)))
         body = self._parse_body(etree.fromstring(body))
         body['blob'] = json.loads(body['blob'])
         return resp, body
@@ -77,15 +74,15 @@
         user_id = kwargs.get('user_id', body['user_id'])
         access = "&quot;access&quot;: &quot;%s&quot;" % access_key
         secret = "&quot;secret&quot;: &quot;%s&quot;" % secret_key
-        blob = Element('blob',
-                       xmlns=XMLNS)
-        blob.append(Text("{%s , %s}"
-                         % (access, secret)))
-        credential = Element('credential', project_id=project_id,
-                             type=cred_type, user_id=user_id)
+        blob = common.Element('blob',
+                              xmlns=XMLNS)
+        blob.append(common.Text("{%s , %s}"
+                                % (access, secret)))
+        credential = common.Element('credential', project_id=project_id,
+                                    type=cred_type, user_id=user_id)
         credential.append(blob)
         resp, body = self.patch('credentials/%s' % credential_id,
-                                str(Document(credential)))
+                                str(common.Document(credential)))
         body = self._parse_body(etree.fromstring(body))
         body['blob'] = json.loads(body['blob'])
         return resp, body
diff --git a/tempest/services/identity/v3/xml/endpoints_client.py b/tempest/services/identity/v3/xml/endpoints_client.py
index d79ea92..cc9aa65 100644
--- a/tempest/services/identity/v3/xml/endpoints_client.py
+++ b/tempest/services/identity/v3/xml/endpoints_client.py
@@ -18,9 +18,7 @@
 from tempest.common import http
 from tempest.common import rest_client
 from tempest import config
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -41,11 +39,11 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "endpoint":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_body(self, body):
-        json = xml_to_json(body)
+        json = common.xml_to_json(body)
         return json
 
     def request(self, method, url, headers=None, body=None, wait=None):
@@ -69,21 +67,22 @@
         enabled = kwargs.get('enabled', None)
         if enabled is not None:
             enabled = str(enabled).lower()
-        create_endpoint = Element("endpoint",
-                                  xmlns=XMLNS,
-                                  service_id=service_id,
-                                  interface=interface,
-                                  url=url, region=region,
-                                  enabled=enabled)
-        resp, body = self.post('endpoints', str(Document(create_endpoint)))
+        create_endpoint = common.Element("endpoint",
+                                         xmlns=XMLNS,
+                                         service_id=service_id,
+                                         interface=interface,
+                                         url=url, region=region,
+                                         enabled=enabled)
+        resp, body = self.post('endpoints',
+                               str(common.Document(create_endpoint)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def update_endpoint(self, endpoint_id, service_id=None, interface=None,
                         url=None, region=None, enabled=None):
         """Updates an endpoint with given parameters."""
-        doc = Document()
-        endpoint = Element("endpoint")
+        doc = common.Document()
+        endpoint = common.Element("endpoint")
         doc.append(endpoint)
 
         if service_id:
diff --git a/tempest/services/identity/v3/xml/identity_client.py b/tempest/services/identity/v3/xml/identity_client.py
index e8e70d8..6ff6d56 100644
--- a/tempest/services/identity/v3/xml/identity_client.py
+++ b/tempest/services/identity/v3/xml/identity_client.py
@@ -20,10 +20,7 @@
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import Text
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -44,7 +41,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "project":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_domains(self, node):
@@ -52,7 +49,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "domain":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_group_users(self, node):
@@ -60,7 +57,7 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "user":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_roles(self, node):
@@ -68,17 +65,17 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "role":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_array(self, node):
         array = []
         for child in node.getchildren():
-            array.append(xml_to_json(child))
+            array.append(common.xml_to_json(child))
         return array
 
     def _parse_body(self, body):
-        _json = xml_to_json(body)
+        _json = common.xml_to_json(body)
         return _json
 
     def create_user(self, user_name, **kwargs):
@@ -89,16 +86,16 @@
         project_id = kwargs.get('project_id', None)
         description = kwargs.get('description', None)
         domain_id = kwargs.get('domain_id', 'default')
-        post_body = Element("user",
-                            xmlns=XMLNS,
-                            name=user_name,
-                            password=password,
-                            description=description,
-                            email=email,
-                            enabled=str(en).lower(),
-                            project_id=project_id,
-                            domain_id=domain_id)
-        resp, body = self.post('users', str(Document(post_body)))
+        post_body = common.Element("user",
+                                   xmlns=XMLNS,
+                                   name=user_name,
+                                   password=password,
+                                   description=description,
+                                   email=email,
+                                   enabled=str(en).lower(),
+                                   project_id=project_id,
+                                   domain_id=domain_id)
+        resp, body = self.post('users', str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -110,16 +107,16 @@
         project_id = kwargs.get('project_id', body['project_id'])
         description = kwargs.get('description', body['description'])
         domain_id = kwargs.get('domain_id', body['domain_id'])
-        update_user = Element("user",
-                              xmlns=XMLNS,
-                              name=name,
-                              email=email,
-                              project_id=project_id,
-                              domain_id=domain_id,
-                              description=description,
-                              enabled=str(en).lower())
+        update_user = common.Element("user",
+                                     xmlns=XMLNS,
+                                     name=name,
+                                     email=email,
+                                     project_id=project_id,
+                                     domain_id=domain_id,
+                                     description=description,
+                                     enabled=str(en).lower())
         resp, body = self.patch('users/%s' % user_id,
-                                str(Document(update_user)))
+                                str(common.Document(update_user)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -151,14 +148,14 @@
         description = kwargs.get('description', None)
         en = kwargs.get('enabled', 'true')
         domain_id = kwargs.get('domain_id', 'default')
-        post_body = Element("project",
-                            xmlns=XMLNS,
-                            description=description,
-                            domain_id=domain_id,
-                            enabled=str(en).lower(),
-                            name=name)
+        post_body = common.Element("project",
+                                   xmlns=XMLNS,
+                                   description=description,
+                                   domain_id=domain_id,
+                                   enabled=str(en).lower(),
+                                   name=name)
         resp, body = self.post('projects',
-                               str(Document(post_body)))
+                               str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -175,14 +172,14 @@
         desc = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
         domain_id = kwargs.get('domain_id', body['domain_id'])
-        post_body = Element("project",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=desc,
-                            enabled=str(en).lower(),
-                            domain_id=domain_id)
+        post_body = common.Element("project",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=desc,
+                                   enabled=str(en).lower(),
+                                   domain_id=domain_id)
         resp, body = self.patch('projects/%s' % project_id,
-                                str(Document(post_body)))
+                                str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -199,10 +196,10 @@
 
     def create_role(self, name):
         """Create a Role."""
-        post_body = Element("role",
-                            xmlns=XMLNS,
-                            name=name)
-        resp, body = self.post('roles', str(Document(post_body)))
+        post_body = common.Element("role",
+                                   xmlns=XMLNS,
+                                   name=name)
+        resp, body = self.post('roles', str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -214,11 +211,11 @@
 
     def update_role(self, name, role_id):
         """Updates a Role."""
-        post_body = Element("role",
-                            xmlns=XMLNS,
-                            name=name)
+        post_body = common.Element("role",
+                                   xmlns=XMLNS,
+                                   name=name)
         resp, body = self.patch('roles/%s' % str(role_id),
-                                str(Document(post_body)))
+                                str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -237,12 +234,12 @@
         """Creates a domain."""
         description = kwargs.get('description', None)
         en = kwargs.get('enabled', True)
-        post_body = Element("domain",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description,
-                            enabled=str(en).lower())
-        resp, body = self.post('domains', str(Document(post_body)))
+        post_body = common.Element("domain",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description,
+                                   enabled=str(en).lower())
+        resp, body = self.post('domains', str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -263,13 +260,13 @@
         description = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
         name = kwargs.get('name', body['name'])
-        post_body = Element("domain",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description,
-                            enabled=str(en).lower())
+        post_body = common.Element("domain",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description,
+                                   enabled=str(en).lower())
         resp, body = self.patch('domains/%s' % domain_id,
-                                str(Document(post_body)))
+                                str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -299,13 +296,13 @@
         description = kwargs.get('description', None)
         domain_id = kwargs.get('domain_id', 'default')
         project_id = kwargs.get('project_id', None)
-        post_body = Element("group",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description,
-                            domain_id=domain_id,
-                            project_id=project_id)
-        resp, body = self.post('groups', str(Document(post_body)))
+        post_body = common.Element("group",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description,
+                                   domain_id=domain_id,
+                                   project_id=project_id)
+        resp, body = self.post('groups', str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -320,12 +317,12 @@
         resp, body = self.get_group(group_id)
         name = kwargs.get('name', body['name'])
         description = kwargs.get('description', body['description'])
-        post_body = Element("group",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description)
+        post_body = common.Element("group",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description)
         resp, body = self.patch('groups/%s' % group_id,
-                                str(Document(post_body)))
+                                str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -456,35 +453,35 @@
         Validation is left to the server side.
         """
         if user_type == 'id':
-            _user = Element('user', id=user, password=password)
+            _user = common.Element('user', id=user, password=password)
         else:
-            _user = Element('user', name=user, password=password)
+            _user = common.Element('user', name=user, password=password)
         if domain is not None:
-            _domain = Element('domain', name=domain)
+            _domain = common.Element('domain', name=domain)
             _user.append(_domain)
 
-        password = Element('password')
+        password = common.Element('password')
         password.append(_user)
 
-        method = Element('method')
-        method.append(Text('password'))
-        methods = Element('methods')
+        method = common.Element('method')
+        method.append(common.Text('password'))
+        methods = common.Element('methods')
         methods.append(method)
-        identity = Element('identity')
+        identity = common.Element('identity')
         identity.append(methods)
         identity.append(password)
 
-        auth = Element('auth')
+        auth = common.Element('auth')
         auth.append(identity)
 
         if tenant is not None:
-            project = Element('project', name=tenant)
+            project = common.Element('project', name=tenant)
             project.append(_domain)
-            scope = Element('scope')
+            scope = common.Element('scope')
             scope.append(project)
             auth.append(scope)
 
-        resp, body = self.post(self.auth_url, body=str(Document(auth)))
+        resp, body = self.post(self.auth_url, body=str(common.Document(auth)))
         return resp, body
 
     def request(self, method, url, headers=None, body=None):
diff --git a/tempest/services/identity/v3/xml/policy_client.py b/tempest/services/identity/v3/xml/policy_client.py
index c12018a..bf4cce7 100644
--- a/tempest/services/identity/v3/xml/policy_client.py
+++ b/tempest/services/identity/v3/xml/policy_client.py
@@ -18,9 +18,7 @@
 from tempest.common import http
 from tempest.common import rest_client
 from tempest import config
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -41,11 +39,11 @@
         for child in node.getchildren():
             tag_list = child.tag.split('}', 1)
             if tag_list[1] == "policy":
-                array.append(xml_to_json(child))
+                array.append(common.xml_to_json(child))
         return array
 
     def _parse_body(self, body):
-        json = xml_to_json(body)
+        json = common.xml_to_json(body)
         return json
 
     def request(self, method, url, headers=None, body=None, wait=None):
@@ -59,8 +57,9 @@
 
     def create_policy(self, blob, type):
         """Creates a Policy."""
-        create_policy = Element("policy", xmlns=XMLNS, blob=blob, type=type)
-        resp, body = self.post('policies', str(Document(create_policy)))
+        create_policy = common.Element("policy", xmlns=XMLNS,
+                                       blob=blob, type=type)
+        resp, body = self.post('policies', str(common.Document(create_policy)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -81,9 +80,9 @@
         """Updates a policy."""
         resp, body = self.get_policy(policy_id)
         type = kwargs.get('type')
-        update_policy = Element("policy", xmlns=XMLNS, type=type)
+        update_policy = common.Element("policy", xmlns=XMLNS, type=type)
         url = 'policies/%s' % policy_id
-        resp, body = self.patch(url, str(Document(update_policy)))
+        resp, body = self.patch(url, str(common.Document(update_policy)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
diff --git a/tempest/services/identity/v3/xml/service_client.py b/tempest/services/identity/v3/xml/service_client.py
index d4a5877..966d7f7 100644
--- a/tempest/services/identity/v3/xml/service_client.py
+++ b/tempest/services/identity/v3/xml/service_client.py
@@ -17,9 +17,7 @@
 
 from tempest.common import rest_client
 from tempest import config
-from tempest.services.compute.xml.common import Document
-from tempest.services.compute.xml.common import Element
-from tempest.services.compute.xml.common import xml_to_json
+from tempest.services.compute.xml import common
 
 CONF = config.CONF
 
@@ -36,7 +34,7 @@
         self.api_version = "v3"
 
     def _parse_body(self, body):
-        data = xml_to_json(body)
+        data = common.xml_to_json(body)
         return data
 
     def update_service(self, service_id, **kwargs):
@@ -45,14 +43,14 @@
         name = kwargs.get('name', body['name'])
         description = kwargs.get('description', body['description'])
         type = kwargs.get('type', body['type'])
-        update_service = Element("service",
-                                 xmlns=XMLNS,
-                                 id=service_id,
-                                 name=name,
-                                 description=description,
-                                 type=type)
+        update_service = common.Element("service",
+                                        xmlns=XMLNS,
+                                        id=service_id,
+                                        name=name,
+                                        description=description,
+                                        type=type)
         resp, body = self.patch('services/%s' % service_id,
-                                str(Document(update_service)))
+                                str(common.Document(update_service)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -64,12 +62,12 @@
         return resp, body
 
     def create_service(self, serv_type, name=None, description=None):
-        post_body = Element("service",
-                            xmlns=XMLNS,
-                            name=name,
-                            description=description,
-                            type=serv_type)
-        resp, body = self.post("services", str(Document(post_body)))
+        post_body = common.Element("service",
+                                   xmlns=XMLNS,
+                                   name=name,
+                                   description=description,
+                                   type=serv_type)
+        resp, body = self.post("services", str(common.Document(post_body)))
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index efac5f5..be314cc 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -20,6 +20,7 @@
 from tempest.common.rest_client import RestClient
 from tempest import config
 from tempest import exceptions
+from xml.etree import ElementTree as etree
 
 CONF = config.CONF
 
@@ -28,7 +29,6 @@
     def __init__(self, auth_provider):
         super(AccountClient, self).__init__(auth_provider)
         self.service = CONF.object_storage.catalog_type
-        self.format = 'json'
 
     def create_account(self, data=None,
                        params=None,
@@ -87,7 +87,25 @@
 
         headers = {}
         for item in metadata:
-            headers[metadata_prefix + item] = 'x'
+            headers[metadata_prefix + item] = metadata[item]
+        resp, body = self.post('', headers=headers, body=None)
+        return resp, body
+
+    def create_and_delete_account_metadata(
+            self,
+            create_metadata=None,
+            delete_metadata=None,
+            create_metadata_prefix='X-Account-Meta-',
+            delete_metadata_prefix='X-Remove-Account-Meta-'):
+        """
+        Creates and deletes an account metadata entry.
+        """
+        headers = {}
+        for key in create_metadata:
+            headers[create_metadata_prefix + key] = create_metadata[key]
+        for key in delete_metadata:
+            headers[delete_metadata_prefix + key] = delete_metadata[key]
+
         resp, body = self.post('', headers=headers, body=None)
         return resp, body
 
@@ -112,24 +130,23 @@
             response.
             DEFAULT:  Python-List returned in response body
         """
+        url = '?%s' % urllib.urlencode(params) if params else ''
 
-        if params:
-            if 'format' not in params:
-                params['format'] = self.format
-        else:
-            params = {'format': self.format}
-
-        url = '?' + urllib.urlencode(params)
-        resp, body = self.get(url)
-
+        resp, body = self.get(url, headers={})
         if params and params.get('format') == 'json':
             body = json.loads(body)
+        elif params and params.get('format') == 'xml':
+            body = etree.fromstring(body)
+        else:
+            body = body.strip().splitlines()
         return resp, body
 
     def list_extensions(self):
         self.skip_path()
-        resp, body = self.get('info')
-        self.reset_path()
+        try:
+            resp, body = self.get('info')
+        finally:
+            self.reset_path()
         body = json.loads(body)
         return resp, body
 
diff --git a/tempest/services/volume/json/backups_client.py b/tempest/services/volume/json/backups_client.py
index baaf5a0..183d06b 100644
--- a/tempest/services/volume/json/backups_client.py
+++ b/tempest/services/volume/json/backups_client.py
@@ -69,6 +69,13 @@
         body = json.loads(body)
         return resp, body['backup']
 
+    def list_backups_with_detail(self):
+        """Information for all the tenant's backups."""
+        url = "backups/detail"
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body['backups']
+
     def wait_for_backup_status(self, backup_id, status):
         """Waits for a Backup to reach a given status."""
         resp, body = self.get_backup(backup_id)