New test case for Swift Policy quota limit added

This test verifies that quota limits are enforced per storage policy. It
sets a 10-byte quota on the "silver" policy and creates a container
using that policy. It then tries to upload an object larger than the
quota, expecting an OverLimit exception. Next, it creates a default
(non-policy) container and successfully uploads the same large object,
confirming that the quota enforcement is specific to the storage policy.
The test also ensures the response headers are correct after a
successful upload.

Closes-Bug: #2122673

Depends-On: https://review.opendev.org/c/openstack/devstack/+/955473

Change-Id: I3fb85118af7f62074556eaaf619dab3ddcc9be5b
Signed-off-by: Tanvi Nautiyal <tnautiya@redhat.com>
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index 37783b8..6c472a6 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -109,6 +109,57 @@
         nafter = self._get_bytes_used()
         self.assertEqual(nbefore, nafter)
 
+    @decorators.idempotent_id('aab68903-cc9f-493a-b17e-b387db3e4e44')
+    @utils.requires_ext(extension='account_quotas', service='object')
+    def test_storage_policy_quota_limit(self):
+        """Verify quota limits are enforced per storage policy"""
+        policy_names = [p["name"] for p in self.policies]
+        if 'silver' not in policy_names:
+            raise self.skipException("Missing storage policy 'silver'")
+
+        policy_quota = 10
+        policy_quota_header = {
+            "X-Account-Quota-Bytes-Policy-silver": str(policy_quota)
+        }
+        self.account_client.auth_provider.set_alt_auth_data(
+            request_part='headers',
+            auth_data=self.reselleradmin_auth_data
+        )
+        self.os_roles_operator.account_client.request(
+            "POST", url="", headers=policy_quota_header, body=""
+        )
+
+        # Create a new container using the "silver" storage policy
+        silver_container = data_utils.rand_name("silver-container")
+        headers = {'X-Storage-Policy': 'silver'}
+        self.container_client.create_container(
+            silver_container, **headers
+        )
+
+        # Try uploading an object larger than the quota
+        large_data = data_utils.arbitrary_string(size=policy_quota + 1)
+        object_name = data_utils.rand_name(name='large_object')
+        self.assertRaises(
+            lib_exc.OverLimit,
+            self.object_client.create_object,
+            silver_container,
+            object_name,
+            large_data
+            )
+
+        # Upload same large object to default container
+        default_container = data_utils.rand_name(
+            "default_container"
+        )
+        self.container_client.create_container(default_container)
+        default_object = data_utils.rand_name(name='default_object')
+        resp, _ = self.object_client.create_object(
+            default_container,
+            default_object,
+            large_data
+        )
+        self.assertHeaders(resp, 'Object', 'PUT')
+
     @decorators.attr(type=["smoke"])
     @decorators.idempotent_id('63f51f9f-5f1d-4fc6-b5be-d454d70949d6')
     @utils.requires_ext(extension='account_quotas', service='object')