glare/glare/tests/unit/test_quotas.py

799 lines
33 KiB
Python

# 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.
import mock
from six import BytesIO
from glare.common import exception
from glare.common import store_api
from glare.tests.unit import base
class TestStaticQuotas(base.BaseTestArtifactAPI):
"""Test static quota limits."""
def test_count_artifact_number(self):
user1_req = self.get_fake_request(self.users['user1'])
user2_req = self.get_fake_request(self.users['user2'])
# initially there are no artifacts
self.assertEqual(
0, len(self.controller.list(user1_req, 'all')['artifacts']))
self.assertEqual(
0, len(self.controller.list(user2_req, 'all')['artifacts']))
# set global limit on 10 artifacts
self.config(max_artifact_number=10)
# 3 images, 15 heat templates, 10 murano packages
self.config(max_artifact_number=3,
group='artifact_type:images')
self.config(max_artifact_number=15,
group='artifact_type:heat_templates')
self.config(max_artifact_number=10,
group='artifact_type:murano_packages')
# create 3 images for user1
for i in range(3):
img = self.controller.create(
user1_req, 'images', {'name': 'img%d' % i})
# creation of another image fails because of artifact type limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'images', {'name': 'img4'})
# create 7 murano packages
for i in range(7):
self.controller.create(
user1_req, 'murano_packages', {'name': 'mp%d' % i})
# creation of another package fails because of global limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'murano_packages', {'name': 'mp8'})
# delete an image and create another murano package work
self.controller.delete(user1_req, 'images', img['id'])
self.controller.create(user1_req, 'murano_packages', {'name': 'mp8'})
# user2 can create his own artifacts
for i in range(10):
self.controller.create(
user2_req, 'heat_templates', {'name': 'ht%d' % i})
# creation of another heat template fails because of global limit
self.assertRaises(exception.Forbidden, self.controller.create,
user2_req, 'heat_templates', {'name': 'ht11'})
# disable global limit and try to create 15 heat templates
self.config(max_artifact_number=-1)
for i in range(15):
self.controller.create(
user1_req, 'heat_templates', {'name': 'ht%d' % i})
# creation of another heat template fails because of type limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'heat_templates', {'name': 'ht16'})
# disable type limit for heat templates and create 1 heat templates
self.config(max_artifact_number=-1,
group='artifact_type:heat_templates')
self.controller.create(
user1_req, 'heat_templates', {'name': 'ht16'})
def test_calculate_uploaded_data(self):
user1_req = self.get_fake_request(self.users['user1'])
user2_req = self.get_fake_request(self.users['user2'])
# initially there are no artifacts
self.assertEqual(
0, len(self.controller.list(user1_req, 'all')['artifacts']))
self.assertEqual(
0, len(self.controller.list(user2_req, 'all')['artifacts']))
# set global limit on 1000 bytes
self.config(max_uploaded_data=1000)
# 300 for sample artifact, 1500 for images, 1000 for murano packages
self.config(max_uploaded_data=300,
group='artifact_type:sample_artifact')
self.config(max_uploaded_data=1500,
group='artifact_type:images')
self.config(max_uploaded_data=1000,
group='artifact_type:murano_packages')
# create 2 sample artifacts for user 1
art1 = self.controller.create(
user1_req, 'sample_artifact', {'name': 'art1'})
art2 = self.controller.create(
user1_req, 'sample_artifact', {'name': 'art2'})
# create 3 images for user1
img1 = self.controller.create(
user1_req, 'images', {'name': 'img1'})
img2 = self.controller.create(
user1_req, 'images', {'name': 'img2'})
img3 = self.controller.create(
user1_req, 'images', {'name': 'img3'})
# upload to art1 fails now because of type limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'sample_artifact', art1['id'], 'blob',
BytesIO(b'a' * 301), 'application/octet-stream', 301)
# upload to img1 fails now because of global limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', img1['id'], 'image',
BytesIO(b'a' * 1001), 'application/octet-stream', 1001)
# upload 300 bytes to 'blob' of art1
self.controller.upload_blob(
user1_req, 'sample_artifact', art1['id'], 'blob',
BytesIO(b'a' * 300), 'application/octet-stream',
content_length=300)
# upload another blob to art1 fails because of type limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'sample_artifact', art1['id'],
'dict_of_blobs/blob', BytesIO(b'a'),
'application/octet-stream', 1)
# upload to art2 fails now because of type limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'sample_artifact', art2['id'], 'blob',
BytesIO(b'a'), 'application/octet-stream', 1)
# delete art1 and check that upload to art2 works
self.controller.delete(user1_req, 'sample_artifact', art1['id'])
self.controller.upload_blob(
user1_req, 'sample_artifact', art2['id'], 'blob',
BytesIO(b'a' * 300), 'application/octet-stream', 300)
# upload 700 bytes to img1 works
self.controller.upload_blob(
user1_req, 'images', img1['id'], 'image',
BytesIO(b'a' * 700), 'application/octet-stream', 700)
# upload to img2 fails because of global limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', img2['id'], 'image',
BytesIO(b'a'), 'application/octet-stream', 1)
# user2 can upload data to images
img1 = self.controller.create(
user2_req, 'images', {'name': 'img1'})
self.controller.upload_blob(
user2_req, 'images', img1['id'], 'image',
BytesIO(b'a' * 1000), 'application/octet-stream', 1000)
# disable global limit and try upload data from user1 again
self.config(max_uploaded_data=-1)
self.controller.upload_blob(
user1_req, 'images', img2['id'], 'image',
BytesIO(b'a' * 800), 'application/octet-stream', 800)
# uploading more fails because of image type limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', img3['id'], 'image',
BytesIO(b'a'), 'application/octet-stream', 1)
# disable type limit and try upload data from user1 again
self.config(max_uploaded_data=-1, group='artifact_type:images')
self.controller.upload_blob(
user1_req, 'images', img3['id'], 'image',
BytesIO(b'a' * 1000), 'application/octet-stream', 1000)
def test_max_artifact_number_change_global_config_values(self):
user1_req = self.get_fake_request(self.users['user1'])
# initially there are no artifacts
self.assertEqual(
0, len(self.controller.list(user1_req, 'all')['artifacts']))
arts = []
# set global limit on 5 artifacts
self.config(max_artifact_number=5)
# create 5 artifacts for user1
for i in range(5):
arts.append(self.controller.create(
user1_req, 'images', {'name': 'img%d' % i}))
# creation of another image fails because of the limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'images', {'name': 'failed_img'})
# increase the global limit to 10 artifacts
self.config(max_artifact_number=10)
# now user can create 5 new artifacts
for i in range(5, 10):
arts.append(self.controller.create(
user1_req, 'images', {'name': 'img%d' % i}))
# creation of another image fails because of the limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'images', {'name': 'failed_img'})
# decrease the global limit to 5 artifacts again
self.config(max_artifact_number=5)
# delete 5 artifacts
for i in range(5):
self.controller.delete(user1_req, 'images', arts[i]['id'])
self.assertEqual(
5, len(self.controller.list(user1_req, 'all')['artifacts']))
# creation of another image still fails because of the limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'images', {'name': 'failed_img'})
# deletion of another artifact should unblock image creation
self.controller.delete(user1_req, 'images', arts[5]['id'])
self.controller.create(user1_req, 'images', {'name': 'okay_img'})
def test_max_artifact_number_change_type_config_values(self):
user1_req = self.get_fake_request(self.users['user1'])
# initially there are no artifacts
self.assertEqual(
0, len(self.controller.list(user1_req, 'all')['artifacts']))
arts = []
# set type limit on 5 artifacts
self.config(max_artifact_number=5,
group='artifact_type:images')
# create 5 artifacts for user1
for i in range(5):
arts.append(self.controller.create(
user1_req, 'images', {'name': 'img%d' % i}))
# creation of another image fails because of the limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'images', {'name': 'failed_img'})
# increase the type limit to 10 artifacts
self.config(max_artifact_number=10,
group='artifact_type:images')
# create 5 new artifacts
for i in range(5, 10):
arts.append(self.controller.create(
user1_req, 'images', {'name': 'img%d' % i}))
# creation of another image fails because of the limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'images', {'name': 'failed_img'})
# decrease the global limit to 5 artifacts again
self.config(max_artifact_number=5,
group='artifact_type:images')
# delete 5 artifacts
for i in range(5):
self.controller.delete(user1_req, 'images', arts[i]['id'])
self.assertEqual(
5, len(self.controller.list(user1_req, 'all')['artifacts']))
# creation of another image still fails because of the limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'images', {'name': 'failed_img'})
# deletion of another artifact should unblock image creation
self.controller.delete(user1_req, 'images', arts[5]['id'])
self.controller.create(user1_req, 'images', {'name': 'okay_img'})
def test_max_uploaded_data_change_global_config_values(self):
user1_req = self.get_fake_request(self.users['user1'])
# set global limit on 1000 bytes
self.config(max_uploaded_data=1000)
arts = []
# create 5 images for user1 and upload 200 bytes to each
for i in range(5):
art = self.controller.create(
user1_req, 'images', {'name': 'img%d' % i})
art = self.controller.upload_blob(
user1_req, 'images', art['id'], 'image',
BytesIO(b'a' * 200), 'application/octet-stream', 200)
arts.append(art)
# now all uploads fail
new_art = self.controller.create(
user1_req, 'images', {'name': 'new_img'})
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', new_art['id'], 'image',
BytesIO(b'a'), 'application/octet-stream', 1)
# increase the global limit to 2000 bytes
self.config(max_uploaded_data=2000)
# now user can 5 new artifacts and upload 200 bytes to each
for i in range(5, 10):
art = self.controller.create(
user1_req, 'images', {'name': 'img%d' % i})
art = self.controller.upload_blob(
user1_req, 'images', art['id'], 'image',
BytesIO(b'a' * 200), 'application/octet-stream', 200)
arts.append(art)
# new uploads still fail, because we reached the new limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', new_art['id'], 'image',
BytesIO(b'a'), 'application/octet-stream', 1)
# decrease the global limit to 1000 bytes again
self.config(max_uploaded_data=1000)
# delete 6 artifacts
for i in range(6):
self.controller.delete(user1_req, 'images', arts[i]['id'])
self.assertEqual(
5, len(self.controller.list(user1_req, 'all')['artifacts']))
# now we can upload data to new_art
self.controller.upload_blob(
user1_req, 'images', new_art['id'], 'image',
BytesIO(b'a' * 200), 'application/octet-stream', 200)
def test_max_max_uploaded_data_change_type_config_values(self):
user1_req = self.get_fake_request(self.users['user1'])
# set type limit on 1000 bytes
self.config(max_uploaded_data=1000,
group='artifact_type:images')
arts = []
# create 5 images for user1 and upload 200 bytes to each
for i in range(5):
art = self.controller.create(
user1_req, 'images', {'name': 'img%d' % i})
art = self.controller.upload_blob(
user1_req, 'images', art['id'], 'image',
BytesIO(b'a' * 200), 'application/octet-stream', 200)
arts.append(art)
# now all uploads fail
new_art = self.controller.create(
user1_req, 'images', {'name': 'new_img'})
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', new_art['id'], 'image',
BytesIO(b'a'), 'application/octet-stream', 1)
# increase the type limit to 2000 bytes
self.config(max_uploaded_data=2000,
group='artifact_type:images')
# now user can 5 new artifacts and upload 200 bytes to each
for i in range(5, 10):
art = self.controller.create(
user1_req, 'images', {'name': 'img%d' % i})
art = self.controller.upload_blob(
user1_req, 'images', art['id'], 'image',
BytesIO(b'a' * 200), 'application/octet-stream', 200)
arts.append(art)
# new uploads still fail, because we reached the new limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', new_art['id'], 'image',
BytesIO(b'a'), 'application/octet-stream', 1)
# decrease the type limit to 1000 bytes again
self.config(max_uploaded_data=1000,
group='artifact_type:images')
# delete 6 artifacts
for i in range(6):
self.controller.delete(user1_req, 'images', arts[i]['id'])
self.assertEqual(
5, len(self.controller.list(user1_req, 'all')['artifacts']))
# now we can upload data to new_art
self.controller.upload_blob(
user1_req, 'images', new_art['id'], 'image',
BytesIO(b'a' * 200), 'application/octet-stream', 200)
class TestDynamicQuotas(base.BaseTestArtifactAPI):
"""Test dynamic quota limits."""
def test_count_artifact_number(self):
user1_req = self.get_fake_request(self.users['user1'])
user2_req = self.get_fake_request(self.users['user2'])
# initially there are no artifacts
self.assertEqual(
0, len(self.controller.list(user1_req, 'all')['artifacts']))
self.assertEqual(
0, len(self.controller.list(user2_req, 'all')['artifacts']))
values = {
user1_req.context.project_id: {
"max_artifact_number:images": 3,
"max_artifact_number:heat_templates": 15,
"max_artifact_number:murano_packages": 10,
"max_artifact_number": 10
},
user2_req.context.project_id: {
"max_artifact_number": 10
}
}
admin_req = self.get_fake_request(self.users["admin"])
# define several quotas
self.controller.set_quotas(admin_req, values)
# create 3 images for user1
for i in range(3):
img = self.controller.create(
user1_req, 'images', {'name': 'img%d' % i})
# creation of another image fails because of artifact type limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'images', {'name': 'img4'})
# create 7 murano packages
for i in range(7):
self.controller.create(
user1_req, 'murano_packages', {'name': 'mp%d' % i})
# creation of another package fails because of global limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'murano_packages', {'name': 'mp8'})
# delete an image and create another murano package work
self.controller.delete(user1_req, 'images', img['id'])
self.controller.create(user1_req, 'murano_packages', {'name': 'mp8'})
# user2 can create his own artifacts
for i in range(10):
self.controller.create(
user2_req, 'heat_templates', {'name': 'ht%d' % i})
# creation of another heat template fails because of global limit
self.assertRaises(exception.Forbidden, self.controller.create,
user2_req, 'heat_templates', {'name': 'ht11'})
# disable global limit for user1 and try to create 15 heat templates
values = {
user1_req.context.project_id: {
"max_artifact_number:images": 3,
"max_artifact_number:heat_templates": 15,
"max_artifact_number:murano_packages": 10,
"max_artifact_number": -1
}
}
self.controller.set_quotas(admin_req, values)
for i in range(15):
self.controller.create(
user1_req, 'heat_templates', {'name': 'ht%d' % i})
# creation of another heat template fails because of type limit
self.assertRaises(exception.Forbidden, self.controller.create,
user1_req, 'heat_templates', {'name': 'ht16'})
# disable type limit for heat templates and create 1 heat templates
values = {
user1_req.context.project_id: {
"max_artifact_number:images": 3,
"max_artifact_number:heat_templates": -1,
"max_artifact_number:murano_packages": 10,
"max_artifact_number": -1
}
}
self.controller.set_quotas(admin_req, values)
# now user1 can create another heat template
self.controller.create(
user1_req, 'heat_templates', {'name': 'ht16'})
def test_calculate_uploaded_data(self):
user1_req = self.get_fake_request(self.users['user1'])
user2_req = self.get_fake_request(self.users['user2'])
# initially there are no artifacts
self.assertEqual(
0, len(self.controller.list(user1_req, 'all')['artifacts']))
self.assertEqual(
0, len(self.controller.list(user2_req, 'all')['artifacts']))
values = {
user1_req.context.project_id: {
"max_uploaded_data:images": 1500,
"max_uploaded_data:sample_artifact": 300,
"max_uploaded_data:murano_packages": 1000,
"max_uploaded_data": 1000
},
user2_req.context.project_id: {
"max_uploaded_data": 1000
}
}
admin_req = self.get_fake_request(self.users["admin"])
# define several quotas
self.controller.set_quotas(admin_req, values)
# create 2 sample artifacts for user 1
art1 = self.controller.create(
user1_req, 'sample_artifact', {'name': 'art1'})
art2 = self.controller.create(
user1_req, 'sample_artifact', {'name': 'art2'})
# create 3 images for user1
img1 = self.controller.create(
user1_req, 'images', {'name': 'img1'})
img2 = self.controller.create(
user1_req, 'images', {'name': 'img2'})
img3 = self.controller.create(
user1_req, 'images', {'name': 'img3'})
# upload to art1 fails now because of type limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'sample_artifact', art1['id'], 'blob',
BytesIO(b'a' * 301), 'application/octet-stream', 301)
# upload to img1 fails now because of global limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', img1['id'], 'image',
BytesIO(b'a' * 1001), 'application/octet-stream', 1001)
# upload 300 bytes to 'blob' of art1
self.controller.upload_blob(
user1_req, 'sample_artifact', art1['id'], 'blob',
BytesIO(b'a' * 300), 'application/octet-stream',
content_length=300)
# upload another blob to art1 fails because of type limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'sample_artifact', art1['id'],
'dict_of_blobs/blob', BytesIO(b'a'),
'application/octet-stream', 1)
# upload to art2 fails now because of type limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'sample_artifact', art2['id'], 'blob',
BytesIO(b'a'), 'application/octet-stream', 1)
# delete art1 and check that upload to art2 works
self.controller.delete(user1_req, 'sample_artifact', art1['id'])
self.controller.upload_blob(
user1_req, 'sample_artifact', art2['id'], 'blob',
BytesIO(b'a' * 300), 'application/octet-stream', 300)
# upload 700 bytes to img1 works
self.controller.upload_blob(
user1_req, 'images', img1['id'], 'image',
BytesIO(b'a' * 700), 'application/octet-stream', 700)
# upload to img2 fails because of global limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', img2['id'], 'image',
BytesIO(b'a'), 'application/octet-stream', 1)
# user2 can upload data to images
img1 = self.controller.create(
user2_req, 'images', {'name': 'img1'})
self.controller.upload_blob(
user2_req, 'images', img1['id'], 'image',
BytesIO(b'a' * 1000), 'application/octet-stream', 1000)
# disable global limit and try upload data from user1 again
values = {
user1_req.context.project_id: {
"max_uploaded_data:images": 1500,
"max_uploaded_data:sample_artifact": 300,
"max_uploaded_data:murano_packages": 1000,
"max_uploaded_data": -1
}
}
self.controller.set_quotas(admin_req, values)
self.controller.upload_blob(
user1_req, 'images', img2['id'], 'image',
BytesIO(b'a' * 800), 'application/octet-stream', 800)
# uploading more fails because of image type limit
self.assertRaises(
exception.RequestEntityTooLarge, self.controller.upload_blob,
user1_req, 'images', img3['id'], 'image',
BytesIO(b'a'), 'application/octet-stream', 1)
# disable type limit and try upload data from user1 again
values = {
user1_req.context.project_id: {
"max_uploaded_data:images": -1,
"max_uploaded_data:sample_artifact": 300,
"max_uploaded_data:murano_packages": 1000,
"max_uploaded_data": -1
}
}
self.controller.set_quotas(admin_req, values)
self.controller.upload_blob(
user1_req, 'images', img3['id'], 'image',
BytesIO(b'a' * 1000), 'application/octet-stream', 1000)
def test_quota_upload_no_content_length(self):
user1_req = self.get_fake_request(self.users['user1'])
user2_req = self.get_fake_request(self.users['user2'])
admin_req = self.get_fake_request(self.users['admin'])
values = {
user1_req.context.project_id: {
"max_uploaded_data:sample_artifact": 20,
"max_uploaded_data": 5
},
user2_req.context.project_id: {
"max_uploaded_data:sample_artifact": 7,
"max_uploaded_data": -1
},
admin_req.context.project_id: {
"max_uploaded_data:sample_artifact": -1,
"max_uploaded_data": -1
}
}
# define several quotas
self.controller.set_quotas(admin_req, values)
# create a sample artifacts for user 1
art1 = self.controller.create(
user1_req, 'sample_artifact', {'name': 'art1'})
# Max small_blob size is 10. User1 global quota is 5.
# Since user doesn't specify how many bytes he wants to upload,
# engine can't verify it before upload. Therefore it allocates
# 5 available bytes for user and begins upload. If uploaded data
# amount exceeds this limit RequestEntityTooLarge is raised and
# upload fails.
with mock.patch(
'glare.common.store_api.save_blob_to_store',
side_effect=store_api.save_blob_to_store) as mocked_save:
data = BytesIO(b'a' * 10)
self.assertRaises(
exception.RequestEntityTooLarge,
self.controller.upload_blob,
user1_req, 'sample_artifact', art1['id'], 'small_blob',
data, 'application/octet-stream',
content_length=None)
mocked_save.assert_called_once_with(
mock.ANY, data, user1_req.context, 5, store_type='database')
# check that blob wasn't uploaded
self.assertIsNone(
self.controller.show(
user1_req, 'sample_artifact', art1['id'])['small_blob'])
# try to upload with smaller amount that doesn't exceeds quota
with mock.patch(
'glare.common.store_api.save_blob_to_store',
side_effect=store_api.save_blob_to_store) as mocked_save:
data = BytesIO(b'a' * 4)
self.controller.upload_blob(
user1_req, 'sample_artifact', art1['id'], 'small_blob',
data, 'application/octet-stream',
content_length=None)
mocked_save.assert_called_once_with(
mock.ANY, data, user1_req.context, 5, store_type='database')
# check that blob was uploaded
blob = self.controller.show(
user1_req, 'sample_artifact', art1['id'])['small_blob']
self.assertEqual(4, blob['size'])
self.assertEqual('active', blob['status'])
# create a sample artifacts for user 2
art2 = self.controller.create(
user2_req, 'sample_artifact', {'name': 'art2'})
# Max small_blob size is 10. User1 has no global quota, but his
# type quota is 7.
# Since user doesn't specify how many bytes he wants to upload,
# engine can't verify it before upload. Therefore it allocates
# 7 available bytes for user and begins upload. If uploaded data
# amount exceeds this limit RequestEntityTooLarge is raised and
# upload fails.
with mock.patch(
'glare.common.store_api.save_blob_to_store',
side_effect=store_api.save_blob_to_store) as mocked_save:
data = BytesIO(b'a' * 10)
self.assertRaises(
exception.RequestEntityTooLarge,
self.controller.upload_blob,
user2_req, 'sample_artifact', art2['id'], 'small_blob',
data, 'application/octet-stream',
content_length=None)
mocked_save.assert_called_once_with(
mock.ANY, data, user2_req.context, 7, store_type='database')
# check that blob wasn't uploaded
self.assertIsNone(
self.controller.show(
user2_req, 'sample_artifact', art2['id'])['small_blob'])
# try to upload with smaller amount that doesn't exceeds quota
with mock.patch(
'glare.common.store_api.save_blob_to_store',
side_effect=store_api.save_blob_to_store) as mocked_save:
data = BytesIO(b'a' * 7)
self.controller.upload_blob(
user2_req, 'sample_artifact', art2['id'], 'small_blob',
data, 'application/octet-stream',
content_length=None)
mocked_save.assert_called_once_with(
mock.ANY, data, user2_req.context, 7, store_type='database')
# check that blob was uploaded
blob = self.controller.show(
user2_req, 'sample_artifact', art2['id'])['small_blob']
self.assertEqual(7, blob['size'])
self.assertEqual('active', blob['status'])
# create a sample artifacts for admin
arta = self.controller.create(
user2_req, 'sample_artifact', {'name': 'arta'})
# Max small_blob size is 10. Admin has no quotas at all.
# Since admin doesn't specify how many bytes he wants to upload,
# engine can't verify it before upload. Therefore it allocates
# 10 available bytes (max allowed small_blob size) for him and begins
# upload. If uploaded data amount exceeds this limit
# RequestEntityTooLarge is raised and upload fails.
with mock.patch(
'glare.common.store_api.save_blob_to_store',
side_effect=store_api.save_blob_to_store) as mocked_save:
data = BytesIO(b'a' * 11)
self.assertRaises(
exception.RequestEntityTooLarge,
self.controller.upload_blob,
admin_req, 'sample_artifact', arta['id'], 'small_blob',
data, 'application/octet-stream',
content_length=None)
mocked_save.assert_called_once_with(
mock.ANY, data, admin_req.context, 10, store_type='database')
# check that blob wasn't uploaded
self.assertIsNone(
self.controller.show(
admin_req, 'sample_artifact', arta['id'])['small_blob'])
# try to upload with smaller amount that doesn't exceeds quota
with mock.patch(
'glare.common.store_api.save_blob_to_store',
side_effect=store_api.save_blob_to_store) as mocked_save:
data = BytesIO(b'a' * 10)
self.controller.upload_blob(
admin_req, 'sample_artifact', arta['id'], 'small_blob',
data, 'application/octet-stream',
content_length=None)
mocked_save.assert_called_once_with(
mock.ANY, data, admin_req.context, 10, store_type='database')
# check that blob was uploaded
blob = self.controller.show(
admin_req, 'sample_artifact', arta['id'])['small_blob']
self.assertEqual(10, blob['size'])
self.assertEqual('active', blob['status'])