1515from tempest .api .object_storage import base
1616from tempest .common import utils
1717from tempest import config
18+ from tempest .lib .common import api_version_request
1819from tempest .lib .common .utils import data_utils
1920from tempest .lib import decorators
2021from tempest .lib import exceptions as lib_exc
@@ -45,20 +46,38 @@ def resource_setup(cls):
4546
4647 def setUp (self ):
4748 super (AccountQuotasTest , self ).setUp ()
49+ self ._set_quota ()
4850
51+ def _set_quota (self , quota_bytes = 20 , quota_count = 5 ):
4952 # Set the reselleradmin auth in headers for next account_client
5053 # request
5154 self .account_client .auth_provider .set_alt_auth_data (
5255 request_part = 'headers' ,
5356 auth_data = self .reselleradmin_auth_data
5457 )
55- # Set a quota of 20 bytes on the user's account before each test
56- self .set_quota = 20
57- headers = {"X-Account-Meta-Quota-Bytes" : self .set_quota }
58+
59+ self .quota_bytes = quota_bytes
60+ self .quota_count = quota_count
61+
62+ headers = {
63+ "X-Account-Meta-Quota-Bytes" : str (self .quota_bytes ),
64+ "X-Account-Quota-Count" : str (self .quota_count )
65+ }
5866
5967 self .os_roles_operator .account_client .request (
6068 "POST" , url = "" , headers = headers , body = "" )
6169
70+ def _get_version (self ):
71+ swift_version = "latest"
72+
73+ if CONF .object_storage_feature_enabled .discoverability :
74+ body = self .capabilities_client .list_capabilities ()
75+ _version = body .get ('swift' , {}).get ('version' , "latest" )
76+ swift_version = "." .join (_version .split ('.' )[:2 ])
77+
78+ self .swift_version = api_version_request .APIVersionRequest (
79+ swift_version )
80+
6281 def tearDown (self ):
6382 # Set the reselleradmin auth in headers for next account_client
6483 # request
@@ -67,7 +86,10 @@ def tearDown(self):
6786 auth_data = self .reselleradmin_auth_data
6887 )
6988 # remove the quota from the container
70- headers = {"X-Remove-Account-Meta-Quota-Bytes" : "x" }
89+ headers = {
90+ "X-Remove-Account-Meta-Quota-Bytes" : "x" ,
91+ "X-Remove-Account-Quota-Count" : "x"
92+ }
7193
7294 self .os_roles_operator .account_client .request (
7395 "POST" , url = "" , headers = headers , body = "" )
@@ -98,7 +120,7 @@ def test_overlimit_upload(self):
98120 """Test uploading an oversized object raises an OverLimit exception"""
99121 object_name = data_utils .rand_name (
100122 prefix = CONF .resource_name_prefix , name = "TestObject" )
101- data = data_utils .arbitrary_string (self .set_quota + 1 )
123+ data = data_utils .arbitrary_string (self .quota_bytes + 1 )
102124
103125 nbefore = self ._get_bytes_used ()
104126
@@ -160,6 +182,30 @@ def test_storage_policy_quota_limit(self):
160182 )
161183 self .assertHeaders (resp , 'Object' , 'PUT' )
162184
185+ @decorators .idempotent_id ('b1e73f75-6905-4021-9d0b-796cd42ce279' )
186+ @utils .requires_ext (extension = 'account_quotas' , service = 'object' )
187+ def test_upload_too_many_objects (self ):
188+ """Test that uploading objects is blocked when the account object
189+ count quota is exceeded.
190+
191+ Skipped if Swift version < 2.34 as the feature is not supported.
192+ """
193+ self ._get_version ()
194+
195+ if self .swift_version < api_version_request .APIVersionRequest ('2.34' ):
196+ raise self .skipException (
197+ 'Account object count quota not supported' )
198+
199+ self ._set_quota (quota_count = 0 )
200+
201+ # Try uploading one more object to exceed the quota
202+ self .assertRaises (lib_exc .OverLimit ,
203+ self .object_client .create_object ,
204+ self .container_name , "OverQuotaObject" , "" )
205+
206+ nafter = self ._get_object_count ()
207+ self .assertEqual (0 , nafter )
208+
163209 @decorators .attr (type = ["smoke" ])
164210 @decorators .idempotent_id ('63f51f9f-5f1d-4fc6-b5be-d454d70949d6' )
165211 @utils .requires_ext (extension = 'account_quotas' , service = 'object' )
@@ -191,6 +237,10 @@ def _get_account_metadata(self):
191237 resp , _ = self .account_client .list_account_metadata ()
192238 return resp
193239
240+ def _get_object_count (self ):
241+ resp = self ._get_account_metadata ()
242+ return int (resp ["x-account-object-count" ])
243+
194244 def _get_bytes_used (self ):
195245 resp = self ._get_account_metadata ()
196246 return int (resp ["x-account-bytes-used" ])
0 commit comments