Source code for glare.tests.functional.test_quotas

# Copyright 2017 - Nokia Networks
#
#    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 glare.tests.functional import base


[docs]class TestQuotasAPI(base.TestArtifact): """Test quotas REST API."""
[docs] def setUp(self): base.functional.FunctionalTest.setUp(self) self.glare_server.deployment_flavor = 'noauth' self.glare_server.max_uploaded_data = '10000' self.glare_server.max_artifact_number = '150' self.glare_server.enabled_artifact_types = 'images,' \ 'heat_templates,' \ 'murano_packages,' \ 'sample_artifact' self.glare_server.custom_artifact_types_modules = ( 'glare.tests.sample_artifact') self.glare_server.artifact_type_section = """ [artifact_type:sample_artifact] max_uploaded_data = 3000 [artifact_type:images] max_uploaded_data = 15000 max_artifact_number = 30 [artifact_type:heat_templates] max_artifact_number = 150 [artifact_type:murano_packages] max_uploaded_data = 10000 max_artifact_number = 100 """ self.start_servers(**self.__dict__.copy())
[docs] def test_quota_api_wrong(self): self.set_user('admin') url = '/quotas' # try to set wrong values values = [{"project1": "value1"}] self.put(url=url, data=values, status=400) # no quota name values = [ { "project_id": "project1", "project_quotas": [ { "quota_value": 10 } ] } ] self.put(url=url, data=values, status=400) # no quota value values = [ { "project_id": "project1", "project_quotas": [ { "quota_name": "max_artifact_number", } ] } ] self.put(url=url, data=values, status=400) # no project id values = [ { "project_quotas": [ { "quota_name": "max_artifact_number", "quota_value": 10 } ] } ] self.put(url=url, data=values, status=400) # no project quotas values = [ { "project_id": "project1", } ] self.put(url=url, data=values, status=400) # quota name has more than 1 : values = [ { "project_id": "project1", "project_quotas": [ { "quota_name": "max:artifact:number", "quota_value": 10 } ] } ] self.put(url=url, data=values, status=400) # too long quota name values = [ { "project_id": "project1", "project_quotas": [ { "quota_name": "a" * 256, "quota_value": 10 } ] } ] self.put(url=url, data=values, status=400) # too long project name values = [ { "project_id": "a" * 256, "project_quotas": [ { "quota_name": "max_artifact_number", "quota_value": 10 } ] } ] self.put(url=url, data=values, status=400) # negative quota value less than -1 values = [ { "project_id": "project1", "project_quotas": [ { "quota_name": "max_artifact_number", "quota_value": -2 } ] } ] self.put(url=url, data=values, status=400) # non-integer quota value values = [ { "project_id": "project1", "project_quotas": [ { "quota_name": "max_artifact_number", "quota_value": "AAA" } ] } ] self.put(url=url, data=values, status=400) values = [ { "project_id": "project1", "project_quotas": [ { "quota_name": "max_artifact_number", "quota_value": 10.5 } ] } ] self.put(url=url, data=values, status=400)
@staticmethod def _deserialize_quotas(quotas): values = {} for item in quotas: project_id = item['project_id'] values[project_id] = {} for quota in item['project_quotas']: values[project_id][quota['quota_name']] = quota['quota_value'] return values
[docs] def test_quota_api(self): self.set_user('admin') user1_tenant_id = self.users['user1']['tenant_id'] user2_tenant_id = self.users['user2']['tenant_id'] admin_tenant_id = self.users['admin']['tenant_id'] values = [ { "project_id": user1_tenant_id, "project_quotas": [ { "quota_name": "max_artifact_number:images", "quota_value": 3 }, { "quota_name": "max_artifact_number:heat_templates", "quota_value": 15 }, { "quota_name": "max_artifact_number:murano_packages", "quota_value": 10 }, { "quota_name": "max_artifact_number", "quota_value": 10 } ] }, { "project_id": user2_tenant_id, "project_quotas": [ { "quota_name": "max_artifact_number", "quota_value": 10 } ] }, { "project_id": admin_tenant_id, "project_quotas": [ { "quota_name": "max_artifact_number", "quota_value": 10 } ] } ] url = '/quotas' # define several quotas self.put(url=url, data=values) # get all quotas res = self.get(url=url) global_quotas = res['global_quotas'] self.assertEqual({ 'max_artifact_number': 150, 'max_artifact_number:heat_templates': 150, 'max_artifact_number:images': 30, 'max_artifact_number:murano_packages': 100, 'max_uploaded_data': 10000, 'max_uploaded_data:images': 15000, 'max_uploaded_data:murano_packages': 10000, 'max_uploaded_data:sample_artifact': 3000}, global_quotas) self.assertEqual(self._deserialize_quotas(values), self._deserialize_quotas(res['quotas'])) # get user1 quotas res = self._deserialize_quotas(self.get( url='/project-quotas/' + user1_tenant_id)) self.assertEqual({user1_tenant_id: { 'max_artifact_number': 10, 'max_artifact_number:heat_templates': 15, 'max_artifact_number:images': 3, 'max_artifact_number:murano_packages': 10, 'max_uploaded_data': 10000, 'max_uploaded_data:images': 15000, 'max_uploaded_data:murano_packages': 10000, 'max_uploaded_data:sample_artifact': 3000}}, res) # get admin quotas res = self._deserialize_quotas(self.get(url='/project-quotas')) self.assertEqual({admin_tenant_id: { 'max_artifact_number': 10, 'max_artifact_number:heat_templates': 150, 'max_artifact_number:images': 30, 'max_artifact_number:murano_packages': 100, 'max_uploaded_data': 10000, 'max_uploaded_data:images': 15000, 'max_uploaded_data:murano_packages': 10000, 'max_uploaded_data:sample_artifact': 3000}}, res) # user1 can't set quotas self.set_user('user1') self.put(url=url, data=values, status=403) self.get(url=url, status=403) # user1 can get his quotas res = self._deserialize_quotas(self.get(url='/project-quotas')) self.assertEqual({user1_tenant_id: { 'max_artifact_number': 10, 'max_artifact_number:heat_templates': 15, 'max_artifact_number:images': 3, 'max_artifact_number:murano_packages': 10, 'max_uploaded_data': 10000, 'max_uploaded_data:images': 15000, 'max_uploaded_data:murano_packages': 10000, 'max_uploaded_data:sample_artifact': 3000}}, res) # user1 can't get user2 quotas self.get(url='/project-quotas/' + user2_tenant_id, status=403)
[docs]class TestStaticQuotas(base.TestArtifact): """Test static quota limits."""
[docs] def setUp(self): base.functional.FunctionalTest.setUp(self) self.set_user('user1') self.glare_server.deployment_flavor = 'noauth' self.glare_server.max_uploaded_data = '1000' self.glare_server.max_artifact_number = '10' self.glare_server.enabled_artifact_types = 'images,' \ 'heat_templates,' \ 'murano_packages,' \ 'sample_artifact' self.glare_server.custom_artifact_types_modules = ( 'glare.tests.sample_artifact') self.glare_server.artifact_type_section = """ [artifact_type:sample_artifact] default_store = database max_uploaded_data = 300 [artifact_type:images] max_uploaded_data = 1500 max_artifact_number = 3 [artifact_type:heat_templates] max_artifact_number = 15 [artifact_type:murano_packages] max_uploaded_data = 1000 max_artifact_number = 10 """ self.start_servers(**self.__dict__.copy())
[docs] def test_count_artifact_number(self): # initially there are no artifacts result = self.get('/all') self.assertEqual([], result['all']) # create 3 images for user1 for i in range(3): img = self.create_artifact( data={'name': 'img%d' % i}, type_name='images') # creation of another image fails because of artifact type limit self.create_artifact( data={'name': 'img4'}, type_name='images', status=403) # create 7 murano packages for i in range(7): self.create_artifact( data={'name': 'mp%d' % i}, type_name='murano_packages') # creation of another package fails because of global limit self.create_artifact( data={'name': 'mp8'}, type_name='murano_packages', status=403) # delete an image and create another murano package work self.delete('/images/%s' % img['id']) self.create_artifact( data={'name': 'mp8'}, type_name='murano_packages') # admin can create his own artifacts self.set_user('admin') for i in range(10): self.create_artifact( data={'name': 'ht%d' % i}, type_name='heat_templates') # creation of another heat template fails because of global limit self.create_artifact( data={'name': 'ht11'}, type_name='heat_templates', status=403)
[docs] def test_calculate_uploaded_data(self): headers = {'Content-Type': 'application/octet-stream'} # initially there are no artifacts result = self.get('/all') self.assertEqual([], result['all']) # create 2 sample artifacts for user1 art1 = self.create_artifact(data={'name': 'art1'}) art2 = self.create_artifact(data={'name': 'art2'}) # create 2 images for user1 img1 = self.create_artifact(data={'name': 'img1'}, type_name='images') img2 = self.create_artifact(data={'name': 'img2'}, type_name='images') # upload to art1 fails now because of type limit data = 'a' * 301 self.put(url='/sample_artifact/%s/blob' % art1['id'], data=data, status=413, headers=headers) # upload to img1 fails now because of global limit data = 'a' * 1001 self.put(url='/images/%s/image' % img1['id'], data=data, status=413, headers=headers) # upload 300 bytes to 'blob' of art1 data = 'a' * 300 self.put(url='/sample_artifact/%s/blob' % art1['id'], data=data, headers=headers) # upload another blob to art1 fails because of type limit self.put(url='/sample_artifact/%s/dict_of_blobs/blob' % art1['id'], data='a', status=413, headers=headers) # upload to art2 fails now because of type limit self.put(url='/sample_artifact/%s/dict_of_blobs/blob' % art2['id'], data='a', status=413, headers=headers) # delete art1 and check that upload to art2 works data = 'a' * 300 self.delete('/sample_artifact/%s' % art1['id']) self.put(url='/sample_artifact/%s/dict_of_blobs/blob' % art2['id'], data=data, headers=headers) # upload 700 bytes to img1 works data = 'a' * 700 self.put(url='/images/%s/image' % img1['id'], data=data, headers=headers) # upload to img2 fails because of global limit self.put(url='/images/%s/image' % img2['id'], data='a', status=413, headers=headers) # admin can upload data to his images self.set_user('admin') img1 = self.create_artifact(data={'name': 'img1'}, type_name='images') data = 'a' * 1000 self.put(url='/images/%s/image' % img1['id'], data=data, headers=headers)
[docs]class TestDynamicQuotas(base.TestArtifact): """Test dynamic quota limits."""
[docs] def setUp(self): base.functional.FunctionalTest.setUp(self) self.glare_server.deployment_flavor = 'noauth' self.glare_server.enabled_artifact_types = 'images,' \ 'heat_templates,' \ 'murano_packages,' \ 'sample_artifact' self.glare_server.custom_artifact_types_modules = ( 'glare.tests.sample_artifact') self.start_servers(**self.__dict__.copy())
[docs] def test_count_artifact_number(self): self.set_user('admin') user1_tenant_id = self.users['user1']['tenant_id'] admin_tenant_id = self.users['admin']['tenant_id'] values = [ { "project_id": user1_tenant_id, "project_quotas": [ { "quota_name": "max_artifact_number:images", "quota_value": 3 }, { "quota_name": "max_artifact_number:heat_templates", "quota_value": 15 }, { "quota_name": "max_artifact_number:murano_packages", "quota_value": 10 }, { "quota_name": "max_artifact_number", "quota_value": 10 } ] }, { "project_id": admin_tenant_id, "project_quotas": [ { "quota_name": "max_artifact_number", "quota_value": 10 } ] } ] url = '/quotas' # define several quotas self.put(url=url, data=values) self.set_user('user1') # initially there are no artifacts result = self.get('/all') self.assertEqual([], result['all']) # create 3 images for user1 for i in range(3): img = self.create_artifact( data={'name': 'img%d' % i}, type_name='images') # creation of another image fails because of artifact type limit self.create_artifact( data={'name': 'img4'}, type_name='images', status=403) # create 7 murano packages for i in range(7): self.create_artifact( data={'name': 'mp%d' % i}, type_name='murano_packages') # creation of another package fails because of global limit self.create_artifact( data={'name': 'mp8'}, type_name='murano_packages', status=403) # delete an image and create another murano package work self.delete('/images/%s' % img['id']) self.create_artifact( data={'name': 'mp8'}, type_name='murano_packages') # admin can create his own artifacts self.set_user('admin') for i in range(10): self.create_artifact( data={'name': 'ht%d' % i}, type_name='heat_templates') # creation of another heat template fails because of global limit self.create_artifact( data={'name': 'ht11'}, type_name='heat_templates', status=403) # disable global limit for user1 and try to create 15 heat templates values = [ { "project_id": user1_tenant_id, "project_quotas": [ { "quota_name": "max_artifact_number:images", "quota_value": 3 }, { "quota_name": "max_artifact_number:heat_templates", "quota_value": 15 }, { "quota_name": "max_artifact_number:murano_packages", "quota_value": 10 }, { "quota_name": "max_artifact_number", "quota_value": -1 } ] } ] url = '/quotas' self.put(url=url, data=values) self.set_user("user1") for i in range(15): self.create_artifact( data={'name': 'ht%d' % i}, type_name='heat_templates') # creation of another heat template fails because of type limit self.create_artifact( data={'name': 'ht16'}, type_name='heat_templates', status=403) self.set_user("admin") # disable type limit for heat templates and create 1 heat templates values = [ { "project_id": user1_tenant_id, "project_quotas": [ { "quota_name": "max_artifact_number:images", "quota_value": 3 }, { "quota_name": "max_artifact_number:heat_templates", "quota_value": -1 }, { "quota_name": "max_artifact_number:murano_packages", "quota_value": 10 }, { "quota_name": "max_artifact_number", "quota_value": -1 } ] } ] url = '/quotas' self.put(url=url, data=values) # now user1 can create another heat template self.set_user("user1") self.create_artifact( data={'name': 'ht16'}, type_name='heat_templates')
[docs] def test_calculate_uploaded_data(self): self.set_user('admin') user1_tenant_id = self.users['user1']['tenant_id'] admin_tenant_id = self.users['admin']['tenant_id'] values = [ { "project_id": user1_tenant_id, "project_quotas": [ { "quota_name": "max_uploaded_data:images", "quota_value": 1500 }, { "quota_name": "max_uploaded_data:sample_artifact", "quota_value": 300 }, { "quota_name": "max_uploaded_data:murano_packages", "quota_value": 1000 }, { "quota_name": "max_uploaded_data", "quota_value": 1000 } ] }, { "project_id": admin_tenant_id, "project_quotas": [ { "quota_name": "max_uploaded_data", "quota_value": 1000 } ] } ] url = '/quotas' # define several quotas self.put(url=url, data=values) headers = {'Content-Type': 'application/octet-stream'} self.set_user('user1') # initially there are no artifacts result = self.get('/all') self.assertEqual([], result['all']) # create 2 sample artifacts for user1 art1 = self.create_artifact(data={'name': 'art1'}) art2 = self.create_artifact(data={'name': 'art2'}) # create 3 images for user1 img1 = self.create_artifact(data={'name': 'img1'}, type_name='images') img2 = self.create_artifact(data={'name': 'img2'}, type_name='images') img3 = self.create_artifact(data={'name': 'img3'}, type_name='images') # upload to art1 fails now because of type limit data = 'a' * 301 self.put(url='/sample_artifact/%s/blob' % art1['id'], data=data, status=413, headers=headers) # upload to img1 fails now because of global limit data = 'a' * 1001 self.put(url='/images/%s/image' % img1['id'], data=data, status=413, headers=headers) # upload 300 bytes to 'blob' of art1 data = 'a' * 300 self.put(url='/sample_artifact/%s/blob' % art1['id'], data=data, headers=headers) # upload another blob to art1 fails because of type limit self.put(url='/sample_artifact/%s/dict_of_blobs/blob' % art1['id'], data='a', status=413, headers=headers) # upload to art2 fails now because of type limit self.put(url='/sample_artifact/%s/dict_of_blobs/blob' % art2['id'], data='a', status=413, headers=headers) # delete art1 and check that upload to art2 works data = 'a' * 300 self.delete('/sample_artifact/%s' % art1['id']) self.put(url='/sample_artifact/%s/dict_of_blobs/blob' % art2['id'], data=data, headers=headers) # upload 700 bytes to img1 works data = 'a' * 700 self.put(url='/images/%s/image' % img1['id'], data=data, headers=headers) # upload to img2 fails because of global limit self.put(url='/images/%s/image' % img2['id'], data='a', status=413, headers=headers) # admin can upload data to his images self.set_user('admin') img1 = self.create_artifact(data={'name': 'img1'}, type_name='images') data = 'a' * 1000 self.put(url='/images/%s/image' % img1['id'], data=data, headers=headers) # disable global limit and try upload data from user1 again values = [ { "project_id": user1_tenant_id, "project_quotas": [ { "quota_name": "max_uploaded_data:images", "quota_value": 1500 }, { "quota_name": "max_uploaded_data:sample_artifact", "quota_value": 300 }, { "quota_name": "max_uploaded_data:murano_packages", "quota_value": 1000 }, { "quota_name": "max_uploaded_data", "quota_value": -1 } ] } ] url = '/quotas' self.put(url=url, data=values) self.set_user("user1") data = 'a' * 800 self.put(url='/images/%s/image' % img2['id'], data=data, headers=headers) # uploading more fails because of image type limit data = 'a' self.put(url='/images/%s/image' % img3['id'], data=data, headers=headers, status=413) # disable type limit and try upload data from user1 again self.set_user("admin") values = [ { "project_id": user1_tenant_id, "project_quotas": [ { "quota_name": "max_uploaded_data:images", "quota_value": -1 }, { "quota_name": "max_uploaded_data:sample_artifact", "quota_value": 300 }, { "quota_name": "max_uploaded_data:murano_packages", "quota_value": 1000 }, { "quota_name": "max_uploaded_data", "quota_value": -1 } ] } ] url = '/quotas' self.put(url=url, data=values) self.set_user("user1") data = 'a' * 1000 self.put(url='/images/%s/image' % img3['id'], data=data, headers=headers)