Adds tests covering Swift's Account Quota middleware

The execution of the tests is conditional to a setting declared
in the config file.

There are 2 tests:
 + User uploads an object smaller than the quota successfully
 + User fails to upload an object larger than the quota

Note that this test assumes that the admin account has the
ResellerAdmin role.

Change-Id: I00dd1b88d4d9b65b4c6f5b9cc6b1c8704bdc9d8b
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 825965f..6cc7179 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -259,6 +259,8 @@
 # Number of seconds to wait while looping to check the status of a
 # container to container synchronization
 container_sync_interval = 5
+# Set to True if the Account Quota middleware is enabled
+accounts_quotas_available = True
 
 [boto]
 # This section contains configuration options used when executing tests
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
new file mode 100644
index 0000000..bc050dc
--- /dev/null
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -0,0 +1,115 @@
+# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
+#
+# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
+#
+# 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 testtools
+
+from tempest.api.object_storage import base
+from tempest import clients
+from tempest.common.utils.data_utils import arbitrary_string
+from tempest.common.utils.data_utils import rand_name
+import tempest.config
+from tempest import exceptions
+from tempest.test import attr
+
+
+class AccountQuotasTest(base.BaseObjectTest):
+    accounts_quotas_available = \
+        tempest.config.TempestConfig().object_storage.accounts_quotas_available
+
+    @classmethod
+    def setUpClass(cls):
+        super(AccountQuotasTest, cls).setUpClass()
+        cls.container_name = rand_name(name="TestContainer")
+        cls.container_client.create_container(cls.container_name)
+
+        cls.data.setup_test_user()
+
+        cls.os_reselleradmin = clients.Manager(
+            cls.data.test_user,
+            cls.data.test_password,
+            cls.data.test_tenant)
+
+        # Retrieve the ResellerAdmin role id
+        reseller_role_id = None
+        try:
+            _, roles = cls.os_admin.identity_client.list_roles()
+            reseller_role_id = next(r['id'] for r in roles if r['name']
+                                    == 'ResellerAdmin')
+        except StopIteration:
+            msg = "No ResellerAdmin role found"
+            raise exceptions.NotFound(msg)
+
+        # Retrieve the ResellerAdmin tenant id
+        _, users = cls.os_admin.identity_client.get_users()
+        reseller_user_id = next(usr['id'] for usr in users if usr['name']
+                                == cls.data.test_user)
+
+        # Retrieve the ResellerAdmin tenant id
+        _, tenants = cls.os_admin.identity_client.list_tenants()
+        reseller_tenant_id = next(tnt['id'] for tnt in tenants if tnt['name']
+                                  == cls.data.test_tenant)
+
+        # Assign the newly created user the appropriate ResellerAdmin role
+        cls.os_admin.identity_client.assign_user_role(
+            reseller_tenant_id,
+            reseller_user_id,
+            reseller_role_id)
+
+        # Retrieve a ResellerAdmin auth token and use it to set a quota
+        # on the client's account
+        cls.reselleradmin_token = cls.token_client.get_token(
+            cls.data.test_user,
+            cls.data.test_password,
+            cls.data.test_tenant)
+
+        headers = {"X-Auth-Token": cls.reselleradmin_token,
+                   "X-Account-Meta-Quota-Bytes": "20"}
+
+        cls.os.custom_account_client.request("POST", "", headers, "")
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.delete_containers([cls.container_name])
+        cls.data.teardown_all()
+
+        # remove the quota from the container
+        headers = {"X-Auth-Token": cls.reselleradmin_token,
+                   "X-Remove-Account-Meta-Quota-Bytes": "x"}
+
+        cls.os.custom_account_client.request("POST", "", headers, "")
+
+        super(AccountQuotasTest, cls).tearDownClass()
+
+    @testtools.skipIf(not accounts_quotas_available,
+                      "Account Quotas middleware not available")
+    @attr(type="smoke")
+    def test_upload_valid_object(self):
+        object_name = rand_name(name="TestObject")
+        data = arbitrary_string()
+        resp, _ = self.object_client.create_object(self.container_name,
+                                                   object_name, data)
+
+        self.assertEqual(resp["status"], "201")
+
+    @testtools.skipIf(not accounts_quotas_available,
+                      "Account Quotas middleware not available")
+    @attr(type=["negative", "smoke"])
+    def test_upload_large_object(self):
+        object_name = rand_name(name="TestObject")
+        data = arbitrary_string(30)
+        self.assertRaises(exceptions.OverLimit,
+                          self.object_client.create_object,
+                          self.container_name, object_name, data)
diff --git a/tempest/config.py b/tempest/config.py
index 19170ae..9b1a91e 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -366,6 +366,9 @@
                default=5,
                help="Number of seconds to wait while looping to check the"
                     "status of a container to container synchronization"),
+    cfg.BoolOpt('accounts_quotas_available',
+                default=True,
+                help="Set to True if the Account Quota middleware is enabled"),
 ]