Merge "Fix and simplify arbitrary_string. lp#1085048"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 053c36e..ed3cf6c 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -193,7 +193,7 @@
 tenant_name = admin
 
 [volume]
-# This section contains the configuration options used when executng tests
+# This section contains the configuration options used when executing tests
 # against the OpenStack Block Storage API service
 
 # The type of endpoint for a Cinder or Block Storage API service.
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 52ed6bc..8311365 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -162,8 +162,8 @@
     def post(self, url, body, headers):
         return self.request('POST', url, headers, body)
 
-    def get(self, url, headers=None):
-        return self.request('GET', url, headers)
+    def get(self, url, headers=None, wait=None):
+        return self.request('GET', url, headers, wait=wait)
 
     def delete(self, url, headers=None):
         return self.request('DELETE', url, headers)
@@ -186,7 +186,8 @@
     def _parse_resp(self, body):
         return json.loads(body)
 
-    def request(self, method, url, headers=None, body=None, depth=0):
+    def request(self, method, url,
+                headers=None, body=None, depth=0, wait=None):
         """A simple HTTP request interface."""
 
         if (self.token is None) or (self.base_url is None):
@@ -205,7 +206,8 @@
             raise exceptions.Unauthorized()
 
         if resp.status == 404:
-            self._log(req_url, body, resp, resp_body)
+            if not wait:
+                self._log(req_url, body, resp, resp_body)
             raise exceptions.NotFound(resp_body)
 
         if resp.status == 400:
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index 9d422e1..22e4742 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -60,9 +60,7 @@
 
 def parse_image_id(image_ref):
     """Return the image id from a given image ref"""
-    temp = image_ref.rsplit('/')
-    #Return the last item, which is the image id
-    return temp[len(temp) - 1]
+    return  image_ref.rsplit('/')[-1]
 
 
 def arbitrary_string(size=4, base_text=None):
diff --git a/tempest/manager.py b/tempest/manager.py
index fda887c..59743e5 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -41,6 +41,7 @@
 from tempest.services.compute.json import keypairs_client
 from tempest.services.compute.json import volumes_extensions_client
 from tempest.services.compute.json import console_output_client
+from tempest.services.compute.json import quotas_client
 
 NetworkClient = network_client.NetworkClient
 ImagesClient = images_client.ImagesClientJSON
@@ -54,6 +55,7 @@
 VolumesExtensionsClient = volumes_extensions_client.VolumesExtensionsClientJSON
 VolumesClient = volumes_client.VolumesClientJSON
 ConsoleOutputsClient = console_output_client.ConsoleOutputsClient
+QuotasClient = quotas_client.QuotasClient
 
 LOG = logging.getLogger(__name__)
 
@@ -233,6 +235,7 @@
         self.volumes_extensions_client = VolumesExtensionsClient(*client_args)
         self.volumes_client = VolumesClient(*client_args)
         self.console_outputs_client = ConsoleOutputsClient(*client_args)
+        self.quotas_client = QuotasClient(*client_args)
         self.network_client = NetworkClient(*client_args)
 
 
diff --git a/tempest/openstack.py b/tempest/openstack.py
index dc73bd7..fbd2f00 100644
--- a/tempest/openstack.py
+++ b/tempest/openstack.py
@@ -59,7 +59,7 @@
 from tempest.services.object_storage.object_client import ObjectClient
 from tempest.services.boto.clients import APIClientEC2
 from tempest.services.boto.clients import ObjectClientS3
-
+from tempest.services.compute.json.quotas_client import QuotasClient
 
 LOG = logging.getLogger(__name__)
 
@@ -184,6 +184,7 @@
             msg = "Unsupported interface type `%s'" % interface
             raise exceptions.InvalidConfiguration(msg)
         self.console_outputs_client = ConsoleOutputsClient(*client_args)
+        self.quotas_client = QuotasClient(*client_args)
         self.network_client = NetworkClient(*client_args)
         self.account_client = AccountClient(*client_args)
         self.container_client = ContainerClient(*client_args)
diff --git a/tempest/services/compute/admin/__init__.py b/tempest/services/compute/admin/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/compute/admin/__init__.py
diff --git a/tempest/services/compute/admin/json/__init__.py b/tempest/services/compute/admin/json/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/services/compute/admin/json/__init__.py
diff --git a/tempest/services/compute/admin/json/quotas_client.py b/tempest/services/compute/admin/json/quotas_client.py
new file mode 100644
index 0000000..625d4d4
--- /dev/null
+++ b/tempest/services/compute/admin/json/quotas_client.py
@@ -0,0 +1,79 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2012 NTT Data
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import json
+
+from tempest.services.compute.json.quotas_client import QuotasClient
+
+
+class AdminQuotasClient(QuotasClient):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(AdminQuotasClient, self).__init__(config, username, password,
+                                                auth_url, tenant_name)
+
+    def update_quota_set(self, tenant_id, injected_file_content_bytes=None,
+                         metadata_items=None, ram=None, floating_ips=None,
+                         key_pairs=None, instances=None,
+                         security_group_rules=None, injected_files=None,
+                         cores=None, injected_file_path_bytes=None,
+                         security_groups=None):
+        """
+        Updates the tenant's quota limits for one or more resources
+        """
+        post_body = {}
+
+        if injected_file_content_bytes >= 0:
+            post_body['injected_file_content_bytes'] = \
+                injected_file_content_bytes
+
+        if metadata_items >= 0:
+            post_body['metadata_items'] = metadata_items
+
+        if ram >= 0:
+            post_body['ram'] = ram
+
+        if floating_ips >= 0:
+            post_body['floating_ips'] = floating_ips
+
+        if key_pairs >= 0:
+            post_body['key_pairs'] = key_pairs
+
+        if instances >= 0:
+            post_body['instances'] = instances
+
+        if security_group_rules >= 0:
+            post_body['security_group_rules'] = security_group_rules
+
+        if injected_files >= 0:
+            post_body['injected_files'] = injected_files
+
+        if cores >= 0:
+            post_body['cores'] = cores
+
+        if injected_file_path_bytes >= 0:
+            post_body['injected_file_path_bytes'] = injected_file_path_bytes
+
+        if security_groups >= 0:
+            post_body['security_groups'] = security_groups
+
+        post_body = json.dumps({'quota_set': post_body})
+        resp, body = self.put('os-quota-sets/%s' % str(tenant_id), post_body,
+                              self.headers)
+
+        body = json.loads(body)
+        return resp, body['quota_set']
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index f363bf7..945477a 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -26,19 +26,15 @@
                                                auth_url, tenant_name)
         self.service = self.config.compute.catalog_type
 
-    def get_limits(self):
+    def get_absolute_limits(self):
         resp, body = self.get("limits")
         body = json.loads(body)
-        return resp, body['limits']
+        return resp, body['limits']['absolute']
 
-    def get_max_server_meta(self):
-        resp, limits_dict = self.get_limits()
-        return resp, limits_dict['absolute']['maxServerMeta']
-
-    def get_personality_file_limit(self):
-        resp, limits_dict = self.get_limits()
-        return resp, limits_dict['absolute']['maxPersonality']
-
-    def get_personality_size_limit(self):
-        resp, limits_dict = self.get_limits()
-        return resp, limits_dict['absolute']['maxPersonalitySize']
+    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/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
new file mode 100644
index 0000000..2cc417f
--- /dev/null
+++ b/tempest/services/compute/json/quotas_client.py
@@ -0,0 +1,36 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2012 NTT Data
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import json
+
+from tempest.common.rest_client import RestClient
+
+
+class QuotasClient(RestClient):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(QuotasClient, self).__init__(config, username, password,
+                                           auth_url, tenant_name)
+        self.service = self.config.compute.catalog_type
+
+    def get_quota_set(self, tenant_id):
+        """List the quota set for a tenant"""
+
+        url = 'os-quota-sets/%s' % str(tenant_id)
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body['quota_set']
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 5ac1124..240bcfe 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -59,10 +59,10 @@
         body = json.loads(body)
         return resp, body['volumes']
 
-    def get_volume(self, volume_id):
+    def get_volume(self, volume_id, wait=None):
         """Returns the details of a single volume"""
         url = "os-volumes/%s" % str(volume_id)
-        resp, body = self.get(url)
+        resp, body = self.get(url, wait=wait)
         body = json.loads(body)
         return resp, body['volume']
 
@@ -111,7 +111,7 @@
 
     def is_resource_deleted(self, id):
         try:
-            self.get_volume(id)
+            self.get_volume(id, wait=True)
         except exceptions.NotFound:
             return True
         return False
diff --git a/tempest/services/compute/xml/limits_client.py b/tempest/services/compute/xml/limits_client.py
index 75142a9..229dbee 100644
--- a/tempest/services/compute/xml/limits_client.py
+++ b/tempest/services/compute/xml/limits_client.py
@@ -29,7 +29,7 @@
                                               auth_url, tenant_name)
         self.service = self.config.compute.catalog_type
 
-    def get_limits(self):
+    def get_absolute_limits(self):
         resp, body = self.get("limits", self.headers)
         body = objectify.fromstring(body)
         lim = NS + 'absolute'
@@ -37,23 +37,19 @@
 
         for el in body[lim].iterchildren():
             attributes = el.attrib
-            if attributes['name'] == 'maxServerMeta':
-                ret['maxServerMeta'] = int(attributes['value'])
-            elif attributes['name'] == 'maxPersonality':
-                ret['maxPersonality'] = int(attributes['value'])
-            elif attributes['name'] == 'maxPersonalitySize':
-                ret['maxPersonalitySize'] = int(attributes['value'])
-
+            ret[attributes['name']] = attributes['value']
         return resp, ret
 
-    def get_max_server_meta(self):
-        resp, limits_dict = self.get_limits()
-        return resp, limits_dict['maxServerMeta']
+    def get_specific_absolute_limit(self, absolute_limit):
+        resp, body = self.get("limits", self.headers)
+        body = objectify.fromstring(body)
+        lim = NS + 'absolute'
+        ret = {}
 
-    def get_personality_file_limit(self):
-        resp, limits_dict = self.get_limits()
-        return resp, limits_dict['maxPersonality']
-
-    def get_personality_size_limit(self):
-        resp, limits_dict = self.get_limits()
-        return resp, limits_dict['maxPersonalitySize']
+        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/xml/volumes_extensions_client.py b/tempest/services/compute/xml/volumes_extensions_client.py
index 6869360..0fbc070 100644
--- a/tempest/services/compute/xml/volumes_extensions_client.py
+++ b/tempest/services/compute/xml/volumes_extensions_client.py
@@ -79,10 +79,10 @@
             volumes += [self._parse_volume(vol) for vol in list(body)]
         return resp, volumes
 
-    def get_volume(self, volume_id):
+    def get_volume(self, volume_id, wait=None):
         """Returns the details of a single volume"""
         url = "os-volumes/%s" % str(volume_id)
-        resp, body = self.get(url, self.headers)
+        resp, body = self.get(url, self.headers, wait=wait)
         body = etree.fromstring(body)
         return resp, self._parse_volume(body)
 
@@ -139,7 +139,7 @@
 
     def is_resource_deleted(self, id):
         try:
-            self.get_volume(id)
+            self.get_volume(id, wait=True)
         except exceptions.NotFound:
             return True
         return False
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 6f04e5e..28dae4e 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -62,10 +62,10 @@
         body = json.loads(body)
         return resp, body['volumes']
 
-    def get_volume(self, volume_id):
+    def get_volume(self, volume_id, wait=None):
         """Returns the details of a single volume"""
         url = "volumes/%s" % str(volume_id)
-        resp, body = self.get(url)
+        resp, body = self.get(url, wait=wait)
         body = json.loads(body)
         return resp, body['volume']
 
@@ -133,7 +133,7 @@
 
     def is_resource_deleted(self, id):
         try:
-            self.get_volume(id)
+            self.get_volume(id, wait=True)
         except exceptions.NotFound:
             return True
         return False
diff --git a/tempest/services/volume/xml/volumes_client.py b/tempest/services/volume/xml/volumes_client.py
index ef5f3e9..9d2f159 100644
--- a/tempest/services/volume/xml/volumes_client.py
+++ b/tempest/services/volume/xml/volumes_client.py
@@ -82,10 +82,10 @@
             volumes += [self._parse_volume(vol) for vol in list(body)]
         return resp, volumes
 
-    def get_volume(self, volume_id):
+    def get_volume(self, volume_id, wait=None):
         """Returns the details of a single volume"""
         url = "volumes/%s" % str(volume_id)
-        resp, body = self.get(url, self.headers)
+        resp, body = self.get(url, self.headers, wait=wait)
         body = etree.fromstring(body)
         return resp, self._parse_volume(body)
 
@@ -140,7 +140,7 @@
 
     def is_resource_deleted(self, id):
         try:
-            self.get_volume(id)
+            self.get_volume(id, wait=True)
         except exceptions.NotFound:
             return True
         return False
diff --git a/tempest/tests/boto/__init__.py b/tempest/tests/boto/__init__.py
index 3d5ea6c..11fa077 100644
--- a/tempest/tests/boto/__init__.py
+++ b/tempest/tests/boto/__init__.py
@@ -73,7 +73,6 @@
         EC2_CAN_CONNECT_ERROR = "AWS credentials not set," +\
                                 " faild to get them even by keystoneclient"
     except Exception as exc:
-        logging.exception(exc)
         EC2_CAN_CONNECT_ERROR = str(exc)
     else:
         EC2_CAN_CONNECT_ERROR = None
@@ -88,7 +87,6 @@
             if exc.status == 403:
                 _cred_sub_check(s3client.connection_data)
     except Exception as exc:
-        logging.exception(exc)
         S3_CAN_CONNECT_ERROR = str(exc)
     except keystoneclient.exceptions.Unauthorized:
         S3_CAN_CONNECT_ERROR = "AWS credentials not set," +\
diff --git a/tempest/tests/boto/test_ec2_security_groups.py b/tempest/tests/boto/test_ec2_security_groups.py
index 4e978e1..3d50e8b 100644
--- a/tempest/tests/boto/test_ec2_security_groups.py
+++ b/tempest/tests/boto/test_ec2_security_groups.py
@@ -39,8 +39,8 @@
         group = self.client.create_security_group(group_name,
                                                   group_description)
         self.addResourceCleanUp(self.client.delete_security_group, group_name)
-        groups_get = self.client.get_all_security_groups(groupnames=
-                                                         (group_name,))
+        groups_get = self.client.get_all_security_groups(
+                                                  groupnames=(group_name,))
         self.assertEqual(len(groups_get), 1)
         group_get = groups_get[0]
         self.assertEqual(group.name, group_get.name)
@@ -61,8 +61,8 @@
                                                        to_port=22)
         self.assertTrue(success)
         #TODO(afazekas): Duplicate tests
-        group_get = self.client.get_all_security_groups(groupnames=
-                                                        (group_name,))[0]
+        group_get = self.client.get_all_security_groups(
+                                                 groupnames=(group_name,))[0]
         #remove listed rules
         for ip_permission in group_get.rules:
             for cidr in ip_permission.grants:
@@ -72,7 +72,7 @@
                                 from_port=ip_permission.from_port,
                                 to_port=ip_permission.to_port))
 
-        group_get = self.client.get_all_security_groups(groupnames=
-                                                        (group_name,))[0]
+        group_get = self.client.get_all_security_groups(
+                                                 groupnames=(group_name,))[0]
         #all rules shuld be removed now
         self.assertEqual(0, len(group_get.rules))
diff --git a/tempest/tests/compute/admin/test_quotas.py b/tempest/tests/compute/admin/test_quotas.py
new file mode 100644
index 0000000..98ca169
--- /dev/null
+++ b/tempest/tests/compute/admin/test_quotas.py
@@ -0,0 +1,156 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack, LLC
+# 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 nose.plugins.attrib import attr
+
+from tempest.tests.compute.base import BaseComputeTest
+from tempest.services.compute.admin.json import quotas_client as adm_quotas
+from tempest import exceptions
+
+
+class QuotasTest(BaseComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(QuotasTest, cls).setUpClass()
+        adm_user = cls.config.compute_admin.username
+        adm_pass = cls.config.compute_admin.password
+        adm_tenant = cls.config.compute_admin.tenant_name
+        auth_url = cls.config.identity.auth_url
+
+        cls.adm_client = adm_quotas.AdminQuotasClient(cls.config, adm_user,
+                                                      adm_pass, auth_url,
+                                                      adm_tenant)
+        cls.client = cls.os.quotas_client
+        cls.identity_admin_client = cls._get_identity_admin_client()
+        resp, tenants = cls.identity_admin_client.list_tenants()
+
+        if cls.config.compute.allow_tenant_isolation:
+            cls.demo_tenant_id = cls.isolated_creds[0][0]['tenantId']
+        else:
+            cls.demo_tenant_id = [tnt['id'] for tnt in tenants if tnt['name']
+                                  == cls.config.compute.tenant_name][0]
+
+        cls.adm_tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
+                             cls.config.compute_admin.tenant_name][0]
+
+        cls.default_quota_set = {'injected_file_content_bytes': 10240,
+                                 'metadata_items': 128, 'injected_files': 5,
+                                 'ram': 51200, 'floating_ips': 10,
+                                 'key_pairs': 100,
+                                 'injected_file_path_bytes': 255,
+                                 'instances': 10, 'security_group_rules': 20,
+                                 'cores': 20, 'security_groups': 10}
+
+    @classmethod
+    def tearDown(cls):
+        for server in cls.servers:
+            try:
+                cls.servers_client.delete_server(server['id'])
+            except exceptions.NotFound:
+                continue
+
+    @attr(type='smoke')
+    def test_get_default_quotas(self):
+        """Admin can get the default resource quota set for a tenant"""
+        expected_quota_set = self.default_quota_set.copy()
+        expected_quota_set['id'] = self.demo_tenant_id
+        try:
+            resp, quota_set = self.client.get_quota_set(self.demo_tenant_id)
+            self.assertEqual(200, resp.status)
+            self.assertSequenceEqual(expected_quota_set, quota_set)
+        except:
+            self.fail("Admin could not get the default quota set for a tenant")
+
+    def test_update_all_quota_resources_for_tenant(self):
+        """Admin can update all the resource quota limits for a tenant"""
+        new_quota_set = {'injected_file_content_bytes': 20480,
+                         'metadata_items': 256, 'injected_files': 10,
+                         'ram': 10240, 'floating_ips': 20, 'key_pairs': 200,
+                         'injected_file_path_bytes': 512, 'instances': 20,
+                         'security_group_rules': 20, 'cores': 2,
+                         'security_groups': 20}
+        try:
+            # Update limits for all quota resources
+            resp, quota_set = self.adm_client.update_quota_set(
+                self.demo_tenant_id,
+                **new_quota_set)
+            self.assertEqual(200, resp.status)
+            self.assertSequenceEqual(new_quota_set, quota_set)
+        except:
+            self.fail("Admin could not update quota set for the tenant")
+        finally:
+            # Reset quota resource limits to default values
+            resp, quota_set = self.adm_client.update_quota_set(
+                self.demo_tenant_id,
+                **self.default_quota_set)
+            self.assertEqual(200, resp.status, "Failed to reset quota "
+                             "defaults")
+
+    def test_get_updated_quotas(self):
+        """Verify that GET shows the updated quota set"""
+        self.adm_client.update_quota_set(self.demo_tenant_id,
+                                         ram='5120')
+        try:
+            resp, quota_set = self.client.get_quota_set(self.demo_tenant_id)
+            self.assertEqual(200, resp.status)
+            self.assertEqual(quota_set['ram'], 5120)
+        except:
+            self.fail("Could not get the update quota limit for resource")
+        finally:
+            # Reset quota resource limits to default values
+            resp, quota_set = self.adm_client.update_quota_set(
+                self.demo_tenant_id,
+                **self.default_quota_set)
+            self.assertEqual(200, resp.status, "Failed to reset quota "
+                             "defaults")
+
+    def test_create_server_when_cpu_quota_is_full(self):
+        """Disallow server creation when tenant's vcpu quota is full"""
+        resp, quota_set = self.client.get_quota_set(self.demo_tenant_id)
+        default_vcpu_quota = quota_set['cores']
+        vcpu_quota = 0  # Set the quota to zero to conserve resources
+
+        resp, quota_set = self.adm_client.update_quota_set(self.demo_tenant_id,
+                                                           cores=vcpu_quota)
+        try:
+            self.create_server()
+        except exceptions.OverLimit:
+            pass
+        else:
+            self.fail("Could create servers over the VCPU quota limit")
+        finally:
+            self.adm_client.update_quota_set(self.demo_tenant_id,
+                                             cores=default_vcpu_quota)
+
+    def test_create_server_when_memory_quota_is_full(self):
+        """Disallow server creation when tenant's memory quota is full"""
+        resp, quota_set = self.client.get_quota_set(self.demo_tenant_id)
+        default_mem_quota = quota_set['ram']
+        mem_quota = 0  # Set the quota to zero to conserve resources
+
+        self.adm_client.update_quota_set(self.demo_tenant_id,
+                                         ram=mem_quota)
+        try:
+            self.create_server()
+        except exceptions.OverLimit:
+            pass
+        else:
+            self.fail("Could create servers over the memory quota limit")
+        finally:
+            self.adm_client.update_quota_set(self.demo_tenant_id,
+                                             ram=default_mem_quota)
diff --git a/tempest/tests/compute/base.py b/tempest/tests/compute/base.py
index ebf3b54..bb2ff8b 100644
--- a/tempest/tests/compute/base.py
+++ b/tempest/tests/compute/base.py
@@ -17,14 +17,13 @@
 
 import logging
 import time
-import nose
 
 import unittest2 as unittest
 import nose
 
 from tempest import config
-from tempest import openstack
 from tempest import exceptions
+from tempest import openstack
 from tempest.common.utils.data_utils import rand_name
 
 __all__ = ['BaseComputeTest', 'BaseComputeTestJSON', 'BaseComputeTestXML',
@@ -61,6 +60,7 @@
         cls.keypairs_client = os.keypairs_client
         cls.security_groups_client = os.security_groups_client
         cls.console_outputs_client = os.console_outputs_client
+        cls.quotas_client = os.quotas_client
         cls.limits_client = os.limits_client
         cls.volumes_extensions_client = os.volumes_extensions_client
         cls.volumes_client = os.volumes_client
@@ -178,10 +178,12 @@
         cls.clear_isolated_creds()
 
     @classmethod
-    def create_server(cls, image_id=None):
+    def create_server(cls, image_id=None, flavor=None):
         """Wrapper utility that returns a test server"""
         server_name = rand_name(cls.__name__ + "-instance")
-        flavor = cls.flavor_ref
+
+        if not flavor:
+            flavor = cls.flavor_ref
         if not image_id:
             image_id = cls.image_ref
 
diff --git a/tempest/tests/compute/limits/__init__.py b/tempest/tests/compute/limits/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/compute/limits/__init__.py
diff --git a/tempest/tests/compute/limits/test_absolute_limits.py b/tempest/tests/compute/limits/test_absolute_limits.py
new file mode 100644
index 0000000..ede0dc2
--- /dev/null
+++ b/tempest/tests/compute/limits/test_absolute_limits.py
@@ -0,0 +1,68 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack, LLC
+# 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 unittest2 as unittest
+
+from tempest.tests.compute import base
+
+
+class AbsoluteLimitsTest(object):
+
+    @staticmethod
+    def setUpClass(cls):
+        cls.client = cls.limits_client
+
+    @unittest.skip("Skipped until the Bug #1025294 is resolved")
+    def test_absLimits_get(self):
+        """
+        To check if all limits are present in the response
+        """
+        resp, absolute_limits = self.client.get_absolute_limits()
+        expected_elements = ['maxImageMeta', 'maxPersonality',
+                             'maxPersonalitySize',
+                             'maxPersonalityFilePathSize',
+                             'maxServerMeta', 'maxTotalCores',
+                             'maxTotalFloatingIps', 'maxSecurityGroups',
+                             'maxSecurityGroupRules', 'maxTotalInstances',
+                             'maxTotalKeypairs', 'maxTotalRAMSize',
+                             'maxTotalVolumeGigabytes', 'maxTotalVolumes',
+                             'totalCoresUsed', 'totalFloatingIpsUsed',
+                             'totalSecurityGroupsUsed', 'totalInstancesUsed',
+                             'totalKeyPairsUsed', 'totalRAMUsed',
+                             'totalVolumeGigabytesUsed', 'totalVolumesUsed']
+        # check whether all expected elements exist
+        missing_elements =\
+            [ele for ele in expected_elements if ele not in absolute_limits]
+        self.assertEqual(0, len(missing_elements),
+                         "Failed to find element %s in absolute limits list"
+                         % ', '.join(ele for ele in missing_elements))
+
+
+class AbsoluteLimitsTestJSON(base.BaseComputeTestJSON,
+                             AbsoluteLimitsTest):
+    @classmethod
+    def setUpClass(cls):
+        super(AbsoluteLimitsTestJSON, cls).setUpClass()
+        AbsoluteLimitsTest.setUpClass(cls)
+
+
+class AbsoluteLimitsTestXML(base.BaseComputeTestXML,
+                            AbsoluteLimitsTest):
+    @classmethod
+    def setUpClass(cls):
+        super(AbsoluteLimitsTestXML, cls).setUpClass()
+        AbsoluteLimitsTest.setUpClass(cls)
diff --git a/tempest/tests/compute/servers/test_server_personality.py b/tempest/tests/compute/servers/test_server_personality.py
index a570aec..75457d1 100644
--- a/tempest/tests/compute/servers/test_server_personality.py
+++ b/tempest/tests/compute/servers/test_server_personality.py
@@ -34,8 +34,9 @@
         name = rand_name('server')
         file_contents = 'This is a test file.'
         personality = []
-        _, max_file_limit = self.user_client.get_personality_file_limit()
-        for i in range(0, max_file_limit + 1):
+        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)})
@@ -57,18 +58,16 @@
             name = rand_name('server')
             file_contents = 'This is a test file.'
 
-            cli_resp = self.user_client.get_personality_file_limit()
-            resp, max_file_limit = cli_resp
-            self.assertEqual(200, resp.status)
+            max_file_limit = \
+                self.user_client.get_specific_absolute_limit("maxPersonality")
 
             personality = []
-            for i in range(0, max_file_limit):
+            for i in range(0, int(max_file_limit)):
                 path = 'etc/test' + str(i) + '.txt'
                 personality.append({
                     'path': path,
                     'contents': base64.b64encode(file_contents),
                 })
-
             resp, server = self.client.create_server(name, self.image_ref,
                                                      self.flavor_ref,
                                                      personality=personality)
diff --git a/tempest/tests/compute/test_quotas.py b/tempest/tests/compute/test_quotas.py
new file mode 100644
index 0000000..d07064f
--- /dev/null
+++ b/tempest/tests/compute/test_quotas.py
@@ -0,0 +1,49 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack, LLC
+# 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 nose.plugins.attrib import attr
+
+from tempest.tests.compute.base import BaseComputeTest
+
+
+class QuotasTest(BaseComputeTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(QuotasTest, cls).setUpClass()
+        cls.client = cls.quotas_client
+        cls.admin_client = cls._get_identity_admin_client()
+        resp, tenants = cls.admin_client.list_tenants()
+        cls.tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
+                         cls.client.tenant_name][0]
+
+    @attr(type='smoke')
+    def test_get_default_quotas(self):
+        """User can get the default quota set for it's tenant"""
+        expected_quota_set = {'injected_file_content_bytes': 10240,
+                              'metadata_items': 128, 'injected_files': 5,
+                              'ram': 51200, 'floating_ips': 10,
+                              'key_pairs': 100,
+                              'injected_file_path_bytes': 255, 'instances': 10,
+                              'security_group_rules': 20, 'cores': 20,
+                              'id': self.tenant_id, 'security_groups': 10}
+        try:
+            resp, quota_set = self.client.get_quota_set(self.tenant_id)
+            self.assertEqual(200, resp.status)
+            self.assertSequenceEqual(expected_quota_set, quota_set)
+        except:
+            self.fail("Quota set for tenant did not have default limits")
diff --git a/tempest/tests/compute/volumes/test_volumes_get.py b/tempest/tests/compute/volumes/test_volumes_get.py
index e80e5b9..0a207b9 100644
--- a/tempest/tests/compute/volumes/test_volumes_get.py
+++ b/tempest/tests/compute/volumes/test_volumes_get.py
@@ -26,6 +26,7 @@
     @attr(type='smoke')
     def test_volume_create_get_delete(self):
         """CREATE, GET, DELETE Volume"""
+        volume = None
         try:
             v_name = rand_name('Volume-%s-') % self._interface
             metadata = {'Type': 'work'}
@@ -61,11 +62,12 @@
                              'from the created Volume')
 
         finally:
-            #Delete the Volume created in this method
-            resp, _ = self.client.delete_volume(volume['id'])
-            self.assertEqual(202, resp.status)
-            #Checking if the deleted Volume still exists
-            self.client.wait_for_resource_deletion(volume['id'])
+            if volume:
+                #Delete the Volume created in this method
+                resp, _ = self.client.delete_volume(volume['id'])
+                self.assertEqual(202, resp.status)
+                #Checking if the deleted Volume still exists
+                self.client.wait_for_resource_deletion(volume['id'])
 
     @attr(type='positive')
     def test_volume_get_metadata_none(self):