1616from tempest .common import object_storage
1717from tempest .common import utils
1818from tempest import config
19+ from tempest .lib .common import api_version_request
1920from tempest .lib .common .utils import data_utils
2021from tempest .lib import decorators
2122from tempest .lib import exceptions as lib_exc
@@ -46,20 +47,38 @@ def resource_setup(cls):
4647
4748 def setUp (self ):
4849 super (AccountQuotasTest , self ).setUp ()
50+ self ._set_quota ()
4951
52+ def _set_quota (self , quota_bytes = 20 , quota_count = 5 ):
5053 # Set the reselleradmin auth in headers for next account_client
5154 # request
5255 self .account_client .auth_provider .set_alt_auth_data (
5356 request_part = 'headers' ,
5457 auth_data = self .reselleradmin_auth_data
5558 )
56- # Set a quota of 20 bytes on the user's account before each test
57- self .set_quota = 20
58- headers = {"X-Account-Meta-Quota-Bytes" : self .set_quota }
59+
60+ self .quota_bytes = quota_bytes
61+ self .quota_count = quota_count
62+
63+ headers = {
64+ "X-Account-Meta-Quota-Bytes" : str (self .quota_bytes ),
65+ "X-Account-Quota-Count" : str (self .quota_count )
66+ }
5967
6068 self .os_roles_operator .account_client .request (
6169 "POST" , url = "" , headers = headers , body = "" )
6270
71+ def _get_version (self ):
72+ swift_version = "latest"
73+
74+ if CONF .object_storage_feature_enabled .discoverability :
75+ body = self .capabilities_client .list_capabilities ()
76+ _version = body .get ('swift' , {}).get ('version' , "latest" )
77+ swift_version = "." .join (_version .split ('.' )[:2 ])
78+
79+ self .swift_version = api_version_request .APIVersionRequest (
80+ swift_version )
81+
6382 def tearDown (self ):
6483 # Set the reselleradmin auth in headers for next account_client
6584 # request
@@ -68,7 +87,10 @@ def tearDown(self):
6887 auth_data = self .reselleradmin_auth_data
6988 )
7089 # remove the quota from the container
71- headers = {"X-Remove-Account-Meta-Quota-Bytes" : "x" }
90+ headers = {
91+ "X-Remove-Account-Meta-Quota-Bytes" : "x" ,
92+ "X-Remove-Account-Quota-Count" : "x"
93+ }
7294
7395 self .os_roles_operator .account_client .request (
7496 "POST" , url = "" , headers = headers , body = "" )
@@ -99,7 +121,7 @@ def test_overlimit_upload(self):
99121 """Test uploading an oversized object raises an OverLimit exception"""
100122 object_name = data_utils .rand_name (
101123 prefix = CONF .resource_name_prefix , name = "TestObject" )
102- data = data_utils .arbitrary_string (self .set_quota + 1 )
124+ data = data_utils .arbitrary_string (self .quota_bytes + 1 )
103125
104126 nbefore = self ._get_bytes_used ()
105127
@@ -169,6 +191,30 @@ def test_storage_policy_quota_limit(self):
169191 )
170192 self .assertHeaders (resp , 'Object' , 'PUT' )
171193
194+ @decorators .idempotent_id ('b1e73f75-6905-4021-9d0b-796cd42ce279' )
195+ @utils .requires_ext (extension = 'account_quotas' , service = 'object' )
196+ def test_upload_too_many_objects (self ):
197+ """Test that uploading objects is blocked when the account object
198+ count quota is exceeded.
199+
200+ Skipped if Swift version < 2.34 as the feature is not supported.
201+ """
202+ self ._get_version ()
203+
204+ if self .swift_version < api_version_request .APIVersionRequest ('2.34' ):
205+ raise self .skipException (
206+ 'Account object count quota not supported' )
207+
208+ self ._set_quota (quota_count = 0 )
209+
210+ # Try uploading one more object to exceed the quota
211+ self .assertRaises (lib_exc .OverLimit ,
212+ self .object_client .create_object ,
213+ self .container_name , "OverQuotaObject" , "" )
214+
215+ nafter = self ._get_object_count ()
216+ self .assertEqual (0 , nafter )
217+
172218 @decorators .attr (type = ["smoke" ])
173219 @decorators .idempotent_id ('63f51f9f-5f1d-4fc6-b5be-d454d70949d6' )
174220 @utils .requires_ext (extension = 'account_quotas' , service = 'object' )
@@ -200,6 +246,10 @@ def _get_account_metadata(self):
200246 resp , _ = self .account_client .list_account_metadata ()
201247 return resp
202248
249+ def _get_object_count (self ):
250+ resp = self ._get_account_metadata ()
251+ return int (resp ["x-account-object-count" ])
252+
203253 def _get_bytes_used (self ):
204254 resp = self ._get_account_metadata ()
205255 return int (resp ["x-account-bytes-used" ])
0 commit comments