Merge "Test server create with ephemeral disk"
diff --git a/tempest/api/__init__.py b/tempest/api/__init__.py
index 0b3d2db..e69de29 100644
--- a/tempest/api/__init__.py
+++ b/tempest/api/__init__.py
@@ -1,16 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 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.
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 6fe3186..2160949 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -44,6 +44,7 @@
         cls.s2_name = data_utils.rand_name('server')
         resp, server = cls.create_test_server(name=cls.s2_name,
                                               wait_until='ACTIVE')
+        cls.s2_id = server['id']
 
     def _get_unused_flavor_id(self):
         flavor_id = data_utils.rand_int_id(start=1000)
@@ -64,6 +65,22 @@
         self.assertEqual([], servers)
 
     @attr(type='gate')
+    def test_list_servers_filter_by_error_status(self):
+        # Filter the list of servers by server error status
+        params = {'status': 'error'}
+        resp, server = self.client.reset_state(self.s1_id, state='error')
+        resp, body = self.non_admin_client.list_servers(params)
+        # Reset server's state to 'active'
+        resp, server = self.client.reset_state(self.s1_id, state='active')
+        # Verify server's state
+        resp, server = self.client.get_server(self.s1_id)
+        self.assertEqual(server['status'], 'ACTIVE')
+        servers = body['servers']
+        # Verify error server in list result
+        self.assertIn(self.s1_id, map(lambda x: x['id'], servers))
+        self.assertNotIn(self.s2_id, map(lambda x: x['id'], servers))
+
+    @attr(type='gate')
     def test_list_servers_by_admin_with_all_tenants(self):
         # Listing servers by admin user with all tenants parameter
         # Here should be listed all servers
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 3748e37..f3863b3 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -121,6 +121,23 @@
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
 
     @attr(type='gate')
+    def test_list_servers_filter_by_shutoff_status(self):
+        # Filter the list of servers by server shutoff status
+        params = {'status': 'shutoff'}
+        self.client.stop(self.s1['id'])
+        self.client.wait_for_server_status(self.s1['id'],
+                                           'SHUTOFF')
+        resp, body = self.client.list_servers(params)
+        self.client.start(self.s1['id'])
+        self.client.wait_for_server_status(self.s1['id'],
+                                           'ACTIVE')
+        servers = body['servers']
+
+        self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
+        self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
+        self.assertNotIn(self.s3['id'], map(lambda x: x['id'], servers))
+
+    @attr(type='gate')
     def test_list_servers_filter_by_limit(self):
         # Verify only the expected number of servers are returned
         params = {'limit': 1}
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index f195562..e4af2e1 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -174,7 +174,7 @@
 
     def _detect_server_image_flavor(self, server_id):
         # Detects the current server image flavor ref.
-        resp, server = self.client.get_server(self.server_id)
+        resp, server = self.client.get_server(server_id)
         current_flavor = server['flavor']['id']
         new_flavor_ref = self.flavor_ref_alt \
             if current_flavor == self.flavor_ref else self.flavor_ref
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index f9b44d8..56929a3 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -19,7 +19,6 @@
 from tempest.api.compute import base
 from tempest.openstack.common import log as logging
 from tempest import test
-import testtools
 
 
 LOG = logging.getLogger(__name__)
@@ -28,21 +27,25 @@
 class ExtensionsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
-    @testtools.skipIf(not test.is_extension_enabled('os-consoles', 'compute'),
-                      'os-consoles extension not enabled.')
     @test.attr(type='gate')
     def test_list_extensions(self):
         # List of all extensions
+        if len(self.config.compute_feature_enabled.api_extensions) == 0:
+            raise self.skipException('There are not any extensions configured')
         resp, extensions = self.extensions_client.list_extensions()
-        self.assertIn("extensions", extensions)
-        extension_list = [extension.get('alias')
-                          for extension in extensions.get('extensions', {})]
-        LOG.debug("Nova extensions: %s" % ','.join(extension_list))
         self.assertEqual(200, resp.status)
-        self.assertTrue(self.extensions_client.is_enabled("Consoles"))
+        ext = self.config.compute_feature_enabled.api_extensions[0]
+        if ext == 'all':
+            self.assertIn('Hosts', map(lambda x: x['name'], extensions))
+        elif ext:
+            self.assertIn(ext, map(lambda x: x['name'], extensions))
+        else:
+            raise self.skipException('There are not any extensions configured')
+        # Log extensions list
+        extension_list = map(lambda x: x['name'], extensions)
+        LOG.debug("Nova extensions: %s" % ','.join(extension_list))
 
-    @testtools.skipIf(not test.is_extension_enabled('os-consoles', 'compute'),
-                      'os-consoles extension not enabled.')
+    @test.requires_ext(extension='os-consoles', service='compute')
     @test.attr(type='gate')
     def test_get_extension(self):
         # get the specified extensions
diff --git a/tempest/api/compute/v3/admin/test_servers.py b/tempest/api/compute/v3/admin/test_servers.py
index 6fe3186..becdd78 100644
--- a/tempest/api/compute/v3/admin/test_servers.py
+++ b/tempest/api/compute/v3/admin/test_servers.py
@@ -21,7 +21,7 @@
 from tempest.test import skip_because
 
 
-class ServersAdminTestJSON(base.BaseV2ComputeAdminTest):
+class ServersAdminV3TestJSON(base.BaseV3ComputeAdminTest):
 
     """
     Tests Servers API using admin privileges
@@ -31,10 +31,10 @@
 
     @classmethod
     def setUpClass(cls):
-        super(ServersAdminTestJSON, cls).setUpClass()
-        cls.client = cls.os_adm.servers_client
+        super(ServersAdminV3TestJSON, cls).setUpClass()
+        cls.client = cls.servers_admin_client
         cls.non_admin_client = cls.servers_client
-        cls.flavors_client = cls.os_adm.flavors_client
+        cls.flavors_client = cls.flavors_admin_client
 
         cls.s1_name = data_utils.rand_name('server')
         resp, server = cls.create_test_server(name=cls.s1_name,
@@ -44,6 +44,7 @@
         cls.s2_name = data_utils.rand_name('server')
         resp, server = cls.create_test_server(name=cls.s2_name,
                                               wait_until='ACTIVE')
+        cls.s2_id = server['id']
 
     def _get_unused_flavor_id(self):
         flavor_id = data_utils.rand_int_id(start=1000)
@@ -114,6 +115,22 @@
             self.assertIn(key, str(diagnostic.keys()))
 
     @attr(type='gate')
+    def test_list_servers_filter_by_error_status(self):
+        # Filter the list of servers by server error status
+        params = {'status': 'error'}
+        resp, server = self.client.reset_state(self.s1_id, state='error')
+        resp, body = self.non_admin_client.list_servers(params)
+        # Reset server's state to 'active'
+        resp, server = self.client.reset_state(self.s1_id, state='active')
+        # Verify server's state
+        resp, server = self.client.get_server(self.s1_id)
+        self.assertEqual(server['status'], 'ACTIVE')
+        servers = body['servers']
+        # Verify error server in list result
+        self.assertIn(self.s1_id, map(lambda x: x['id'], servers))
+        self.assertNotIn(self.s2_id, map(lambda x: x['id'], servers))
+
+    @attr(type='gate')
     def test_rebuild_server_in_error_state(self):
         # The server in error state should be rebuilt using the provided
         # image and changed to ACTIVE state
@@ -142,5 +159,5 @@
         self.assertEqual(self.image_ref_alt, rebuilt_image_id)
 
 
-class ServersAdminTestXML(ServersAdminTestJSON):
+class ServersAdminV3TestXML(ServersAdminV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/admin/test_servers_negative.py b/tempest/api/compute/v3/admin/test_servers_negative.py
index 77d873b..670bc2c 100644
--- a/tempest/api/compute/v3/admin/test_servers_negative.py
+++ b/tempest/api/compute/v3/admin/test_servers_negative.py
@@ -22,7 +22,7 @@
 from tempest.test import attr
 
 
-class ServersAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
+class ServersAdminNegativeV3TestJSON(base.BaseV3ComputeAdminTest):
 
     """
     Tests Servers API using admin privileges
@@ -32,10 +32,10 @@
 
     @classmethod
     def setUpClass(cls):
-        super(ServersAdminNegativeTestJSON, cls).setUpClass()
-        cls.client = cls.os_adm.servers_client
+        super(ServersAdminNegativeV3TestJSON, cls).setUpClass()
+        cls.client = cls.servers_admin_client
         cls.non_adm_client = cls.servers_client
-        cls.flavors_client = cls.os_adm.flavors_client
+        cls.flavors_client = cls.flavors_admin_client
         cls.identity_client = cls._get_identity_admin_client()
         tenant = cls.identity_client.get_tenant_by_name(
             cls.client.tenant_name)
@@ -139,5 +139,5 @@
                           server_id)
 
 
-class ServersAdminNegativeTestXML(ServersAdminNegativeTestJSON):
+class ServersAdminNegativeV3TestXML(ServersAdminNegativeV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
index 3dd7b0b..140cc2f 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -176,6 +176,23 @@
         self.assertEqual(['ACTIVE'] * 3, [x['status'] for x in servers])
 
     @attr(type='gate')
+    def test_list_servers_filter_by_shutoff_status(self):
+        # Filter the list of servers by server shutoff status
+        params = {'status': 'shutoff'}
+        self.client.stop(self.s1['id'])
+        self.client.wait_for_server_status(self.s1['id'],
+                                           'SHUTOFF')
+        resp, body = self.client.list_servers(params)
+        self.client.start(self.s1['id'])
+        self.client.wait_for_server_status(self.s1['id'],
+                                           'ACTIVE')
+        servers = body['servers']
+
+        self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
+        self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
+        self.assertNotIn(self.s3['id'], map(lambda x: x['id'], servers))
+
+    @attr(type='gate')
     def test_list_servers_filtered_by_name_wildcard(self):
         # List all servers that contains '-instance' in name
         params = {'name': '-instance'}
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index 602bd5b..f462cc2 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -15,7 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import base64
 import time
 
 import testtools
@@ -113,15 +112,11 @@
         # The server should be rebuilt using the provided image and data
         meta = {'rebuild': 'server'}
         new_name = data_utils.rand_name('server')
-        file_contents = 'Test server rebuild.'
-        personality = [{'path': 'rebuild.txt',
-                       'contents': base64.b64encode(file_contents)}]
         password = 'rebuildPassw0rd'
         resp, rebuilt_server = self.client.rebuild(self.server_id,
                                                    self.image_ref_alt,
                                                    name=new_name,
                                                    metadata=meta,
-                                                   personality=personality,
                                                    admin_password=password)
         self.addCleanup(self.client.rebuild, self.server_id, self.image_ref)
 
@@ -134,9 +129,9 @@
         # Verify the server properties after the rebuild completes
         self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
         resp, server = self.client.get_server(rebuilt_server['id'])
-        rebuilt_image_id = rebuilt_server['image']['id']
+        rebuilt_image_id = server['image']['id']
         self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
-        self.assertEqual(new_name, rebuilt_server['name'])
+        self.assertEqual(new_name, server['name'])
 
         if self.run_ssh:
             # Verify that the user can authenticate with the provided password
@@ -174,7 +169,7 @@
 
     def _detect_server_image_flavor(self, server_id):
         # Detects the current server image flavor ref.
-        resp, server = self.client.get_server(self.server_id)
+        resp, server = self.client.get_server(server_id)
         current_flavor = server['flavor']['id']
         new_flavor_ref = self.flavor_ref_alt \
             if current_flavor == self.flavor_ref else self.flavor_ref
diff --git a/tempest/api/compute/v3/servers/test_server_metadata.py b/tempest/api/compute/v3/servers/test_server_metadata.py
index ee0f4a9..f36feb3 100644
--- a/tempest/api/compute/v3/servers/test_server_metadata.py
+++ b/tempest/api/compute/v3/servers/test_server_metadata.py
@@ -20,12 +20,12 @@
 from tempest.test import attr
 
 
-class ServerMetadataTestJSON(base.BaseV2ComputeTest):
+class ServerMetadataV3TestJSON(base.BaseV3ComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(ServerMetadataTestJSON, cls).setUpClass()
+        super(ServerMetadataV3TestJSON, cls).setUpClass()
         cls.client = cls.servers_client
         cls.quotas = cls.quotas_client
         cls.admin_client = cls._get_identity_admin_client()
@@ -37,7 +37,7 @@
         cls.server_id = server['id']
 
     def setUp(self):
-        super(ServerMetadataTestJSON, self).setUp()
+        super(ServerMetadataV3TestJSON, self).setUp()
         meta = {'key1': 'value1', 'key2': 'value2'}
         resp, _ = self.client.set_server_metadata(self.server_id, meta)
         self.assertEqual(resp.status, 200)
@@ -88,7 +88,7 @@
         meta = {'key1': 'alt1', 'key3': 'value3'}
         resp, metadata = self.client.update_server_metadata(self.server_id,
                                                             meta)
-        self.assertEqual(200, resp.status)
+        self.assertEqual(201, resp.status)
 
         # Verify the values have been updated to the proper values
         resp, resp_metadata = self.client.list_server_metadata(self.server_id)
@@ -213,5 +213,5 @@
                           self.server_id, meta=meta, no_metadata_field=True)
 
 
-class ServerMetadataTestXML(ServerMetadataTestJSON):
+class ServerMetadataV3TestXML(ServerMetadataV3TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/v3/servers/test_server_personality.py b/tempest/api/compute/v3/servers/test_server_personality.py
deleted file mode 100644
index c6d2e44..0000000
--- a/tempest/api/compute/v3/servers/test_server_personality.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import base64
-
-from tempest.api.compute import base
-from tempest import exceptions
-from tempest.test import attr
-
-
-class ServerPersonalityTestJSON(base.BaseV2ComputeTest):
-    _interface = 'json'
-
-    @classmethod
-    def setUpClass(cls):
-        super(ServerPersonalityTestJSON, cls).setUpClass()
-        cls.client = cls.servers_client
-        cls.user_client = cls.limits_client
-
-    @attr(type='gate')
-    def test_personality_files_exceed_limit(self):
-        # Server creation should fail if greater than the maximum allowed
-        # number of files are injected into the server.
-        file_contents = 'This is a test file.'
-        personality = []
-        max_file_limit = \
-            self.user_client.get_specific_absolute_limit("maxPersonality")
-        for i in range(0, int(max_file_limit) + 1):
-            path = 'etc/test' + str(i) + '.txt'
-            personality.append({'path': path,
-                                'contents': base64.b64encode(file_contents)})
-        self.assertRaises(exceptions.OverLimit, self.create_test_server,
-                          personality=personality)
-
-    @attr(type='gate')
-    def test_can_create_server_with_max_number_personality_files(self):
-        # Server should be created successfully if maximum allowed number of
-        # files is injected into the server during creation.
-        file_contents = 'This is a test file.'
-        max_file_limit = \
-            self.user_client.get_specific_absolute_limit("maxPersonality")
-        person = []
-        for i in range(0, int(max_file_limit)):
-            path = 'etc/test' + str(i) + '.txt'
-            person.append({
-                'path': path,
-                'contents': base64.b64encode(file_contents),
-            })
-        resp, server = self.create_test_server(personality=person)
-        self.assertEqual('202', resp['status'])
-
-
-class ServerPersonalityTestXML(ServerPersonalityTestJSON):
-    _interface = "xml"
diff --git a/tempest/api/compute/v3/test_extensions.py b/tempest/api/compute/v3/test_extensions.py
index 72dfe14..f37ebcf 100644
--- a/tempest/api/compute/v3/test_extensions.py
+++ b/tempest/api/compute/v3/test_extensions.py
@@ -30,13 +30,20 @@
     @test.attr(type='gate')
     def test_list_extensions(self):
         # List of all extensions
+        if len(self.config.compute_feature_enabled.api_v3_extensions) == 0:
+            raise self.skipException('There are not any extensions configured')
         resp, extensions = self.extensions_client.list_extensions()
-        self.assertIn("extensions", extensions)
-        extension_list = [extension.get('alias')
-                          for extension in extensions.get('extensions', {})]
-        LOG.debug("Nova extensions: %s" % ','.join(extension_list))
         self.assertEqual(200, resp.status)
-        self.assertTrue(self.extensions_client.is_enabled("Consoles"))
+        ext = self.config.compute_feature_enabled.api_v3_extensions[0]
+        if ext == 'all':
+            self.assertIn('Hosts', map(lambda x: x['name'], extensions))
+        elif ext:
+            self.assertIn(ext, map(lambda x: x['name'], extensions))
+        else:
+            raise self.skipException('There are not any extensions configured')
+        # Log extensions list
+        extension_list = map(lambda x: x['name'], extensions)
+        LOG.debug("Nova extensions: %s" % ','.join(extension_list))
 
     @test.attr(type='gate')
     def test_get_extension(self):
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index ad5354c..c293f80 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -31,7 +31,7 @@
         url = 'extensions'
         resp, body = self.get(url)
         body = json.loads(body)
-        return resp, body
+        return resp, body['extensions']
 
     def is_enabled(self, extension):
         _, extensions = self.list_extensions()
diff --git a/tempest/services/compute/v3/json/extensions_client.py b/tempest/services/compute/v3/json/extensions_client.py
index 6e0dc9d..bd8287e 100644
--- a/tempest/services/compute/v3/json/extensions_client.py
+++ b/tempest/services/compute/v3/json/extensions_client.py
@@ -32,7 +32,7 @@
         url = 'extensions'
         resp, body = self.get(url)
         body = json.loads(body)
-        return resp, body
+        return resp, body['extensions']
 
     def is_enabled(self, extension):
         _, extensions = self.list_extensions()
diff --git a/tempest/services/compute/v3/json/limits_client.py b/tempest/services/compute/v3/json/limits_client.py
deleted file mode 100644
index 3e53e3e..0000000
--- a/tempest/services/compute/v3/json/limits_client.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import json
-from tempest.common.rest_client import RestClient
-
-
-class LimitsClientJSON(RestClient):
-
-    def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(LimitsClientJSON, self).__init__(config, username, password,
-                                               auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
-
-    def get_absolute_limits(self):
-        resp, body = self.get("limits")
-        body = json.loads(body)
-        return resp, body['limits']['absolute']
-
-    def get_specific_absolute_limit(self, absolute_limit):
-        resp, body = self.get("limits")
-        body = json.loads(body)
-        if absolute_limit not in body['limits']['absolute']:
-            return None
-        else:
-            return body['limits']['absolute'][absolute_limit]
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index da31036..3342660 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -45,8 +45,6 @@
         admin_password: Sets the initial root password.
         key_name: Key name of keypair that was created earlier.
         meta: A dictionary of values to be used as metadata.
-        personality: A list of dictionaries for files to be injected into
-        the server.
         security_groups: A list of security group dicts.
         networks: A list of network dicts with UUID and fixed_ip.
         user_data: User data for instance.
@@ -64,7 +62,7 @@
             'flavor_ref': flavor_ref
         }
 
-        for option in ['personality', 'admin_password', 'key_name', 'networks',
+        for option in ['admin_password', 'key_name', 'networks',
                        ('os-security-groups:security_groups',
                         'security_groups'),
                        ('os-user-data:user_data', 'user_data'),
@@ -103,7 +101,6 @@
         Updates the properties of an existing server.
         server_id: The id of an existing server.
         name: The name of the server.
-        personality: A list of files to be injected into the server.
         access_ip_v4: The IPv4 access address for the server.
         access_ip_v6: The IPv6 access address for the server.
         """
@@ -163,10 +160,12 @@
         body = json.loads(body)
         return resp, body
 
-    def wait_for_server_status(self, server_id, status, extra_timeout=0):
+    def wait_for_server_status(self, server_id, status, extra_timeout=0,
+                               raise_on_error=True):
         """Waits for a server to reach a given status."""
         return waiters.wait_for_server_status(self, server_id, status,
-                                              extra_timeout=extra_timeout)
+                                              extra_timeout=extra_timeout,
+                                              raise_on_error=raise_on_error)
 
     def wait_for_server_termination(self, server_id, ignore_error=False):
         """Waits for server to reach termination."""
@@ -346,19 +345,19 @@
         return self.action(server_id, 'unlock', None, **kwargs)
 
     def suspend_server(self, server_id, **kwargs):
-        """Suspends the provded server."""
+        """Suspends the provided server."""
         return self.action(server_id, 'suspend', None, **kwargs)
 
     def resume_server(self, server_id, **kwargs):
-        """Un-suspends the provded server."""
+        """Un-suspends the provided server."""
         return self.action(server_id, 'resume', None, **kwargs)
 
     def pause_server(self, server_id, **kwargs):
-        """Pauses the provded server."""
+        """Pauses the provided server."""
         return self.action(server_id, 'pause', None, **kwargs)
 
     def unpause_server(self, server_id, **kwargs):
-        """Un-pauses the provded server."""
+        """Un-pauses the provided server."""
         return self.action(server_id, 'unpause', None, **kwargs)
 
     def reset_state(self, server_id, state='error'):
diff --git a/tempest/services/compute/v3/xml/extensions_client.py b/tempest/services/compute/v3/xml/extensions_client.py
index 8f97692..926770e 100644
--- a/tempest/services/compute/v3/xml/extensions_client.py
+++ b/tempest/services/compute/v3/xml/extensions_client.py
@@ -37,7 +37,7 @@
         url = 'extensions'
         resp, body = self.get(url, self.headers)
         body = self._parse_array(etree.fromstring(body))
-        return resp, {'extensions': body}
+        return resp, body
 
     def is_enabled(self, extension):
         _, extensions = self.list_extensions()
diff --git a/tempest/services/compute/v3/xml/limits_client.py b/tempest/services/compute/v3/xml/limits_client.py
deleted file mode 100644
index 704de52..0000000
--- a/tempest/services/compute/v3/xml/limits_client.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-#
-# Copyright 2012 IBM Corp.
-# 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 lxml import objectify
-
-from tempest.common.rest_client import RestClientXML
-
-NS = "{http://docs.openstack.org/common/api/v1.0}"
-
-
-class LimitsClientXML(RestClientXML):
-
-    def __init__(self, config, username, password, auth_url, tenant_name=None):
-        super(LimitsClientXML, self).__init__(config, username, password,
-                                              auth_url, tenant_name)
-        self.service = self.config.compute.catalog_type
-
-    def get_absolute_limits(self):
-        resp, body = self.get("limits", self.headers)
-        body = objectify.fromstring(body)
-        lim = NS + 'absolute'
-        ret = {}
-
-        for el in body[lim].iterchildren():
-            attributes = el.attrib
-            ret[attributes['name']] = attributes['value']
-        return resp, ret
-
-    def get_specific_absolute_limit(self, absolute_limit):
-        resp, body = self.get("limits", self.headers)
-        body = objectify.fromstring(body)
-        lim = NS + 'absolute'
-        ret = {}
-
-        for el in body[lim].iterchildren():
-            attributes = el.attrib
-            ret[attributes['name']] = attributes['value']
-        if absolute_limit not in ret:
-            return None
-        else:
-            return ret[absolute_limit]
diff --git a/tempest/services/compute/v3/xml/servers_client.py b/tempest/services/compute/v3/xml/servers_client.py
index a5cc291..5aca7e8 100644
--- a/tempest/services/compute/v3/xml/servers_client.py
+++ b/tempest/services/compute/v3/xml/servers_client.py
@@ -194,6 +194,10 @@
         server = self._parse_server(etree.fromstring(body))
         return resp, server
 
+    def migrate_server(self, server_id, **kwargs):
+        """Migrates the given server ."""
+        return self.action(server_id, 'migrate', None, **kwargs)
+
     def lock_server(self, server_id, **kwargs):
         """Locks the given server."""
         return self.action(server_id, 'lock', None, **kwargs)
@@ -300,8 +304,6 @@
         admin_password: Sets the initial root password.
         key_name: Key name of keypair that was created earlier.
         meta: A dictionary of values to be used as metadata.
-        personality: A list of dictionaries for files to be injected into
-        the server.
         security_groups: A list of security group dicts.
         networks: A list of network dicts with UUID and fixed_ip.
         user_data: User data for instance.
@@ -400,22 +402,16 @@
                 meta.append(Text(v))
                 metadata.append(meta)
 
-        if 'personality' in kwargs:
-            personality = Element('personality')
-            server.append(personality)
-            for k in kwargs['personality']:
-                temp = Element('file', path=k['path'])
-                temp.append(Text(k['contents']))
-                personality.append(temp)
-
         resp, body = self.post('servers', str(Document(server)), self.headers)
         server = self._parse_server(etree.fromstring(body))
         return resp, server
 
-    def wait_for_server_status(self, server_id, status, extra_timeout=0):
+    def wait_for_server_status(self, server_id, status, extra_timeout=0,
+                               raise_on_error=True):
         """Waits for a server to reach a given status."""
         return waiters.wait_for_server_status(self, server_id, status,
-                                              extra_timeout=extra_timeout)
+                                              extra_timeout=extra_timeout,
+                                              raise_on_error=raise_on_error)
 
     def wait_for_server_termination(self, server_id, ignore_error=False):
         """Waits for server to reach termination."""
@@ -608,7 +604,7 @@
     def set_server_metadata_item(self, server_id, key, meta):
         doc = Document()
         for k, v in meta.items():
-            meta_element = Element("meta", key=k)
+            meta_element = Element("metadata", key=k)
             meta_element.append(Text(v))
             doc.append(meta_element)
         resp, body = self.put('servers/%s/metadata/%s' % (str(server_id), key),
diff --git a/tempest/services/compute/xml/extensions_client.py b/tempest/services/compute/xml/extensions_client.py
index b17fc4f..8b7b90a 100644
--- a/tempest/services/compute/xml/extensions_client.py
+++ b/tempest/services/compute/xml/extensions_client.py
@@ -37,7 +37,7 @@
         url = 'extensions'
         resp, body = self.get(url, self.headers)
         body = self._parse_array(etree.fromstring(body))
-        return resp, {'extensions': body}
+        return resp, body
 
     def is_enabled(self, extension):
         _, extensions = self.list_extensions()
diff --git a/tempest/stress/__init__.py b/tempest/stress/__init__.py
index 1caf74a..e69de29 100644
--- a/tempest/stress/__init__.py
+++ b/tempest/stress/__init__.py
@@ -1,13 +0,0 @@
-# Copyright 2013 Quanta Research Cambridge, Inc.
-#
-#    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.
diff --git a/tempest/stress/actions/__init__.py b/tempest/stress/actions/__init__.py
index 1caf74a..e69de29 100644
--- a/tempest/stress/actions/__init__.py
+++ b/tempest/stress/actions/__init__.py
@@ -1,13 +0,0 @@
-# Copyright 2013 Quanta Research Cambridge, Inc.
-#
-#    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.