manila/manila/tests/api/v2/test_quota_sets.py

421 lines
15 KiB
Python

# Copyright 2013 OpenStack Foundation
# Copyright (c) 2015 Mirantis inc.
# All Rights Reserved.
#
# 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.
"""
Tests for manila.api.v1.quota_sets.py
"""
import copy
import ddt
import mock
from oslo_config import cfg
import webob.exc
import webob.response
from manila.api.openstack import api_version_request as api_version
from manila.api.v2 import quota_sets
from manila import context
from manila import exception
from manila import policy
from manila import test
from manila.tests.api import fakes
from manila import utils
CONF = cfg.CONF
REQ = mock.MagicMock()
REQ.environ = {'manila.context': context.get_admin_context()}
REQ.environ['manila.context'].is_admin = True
REQ.environ['manila.context'].auth_token = 'foo_auth_token'
REQ.environ['manila.context'].project_id = 'foo_project_id'
REQ_WITH_USER = copy.deepcopy(REQ)
REQ_WITH_USER.environ['manila.context'].user_id = 'foo_user_id'
REQ_WITH_USER.environ['QUERY_STRING'] = 'user_id=foo_user_id'
REQ_MEMBER = copy.deepcopy(REQ)
REQ_MEMBER.environ['manila.context'].is_admin = False
@ddt.ddt
class QuotaSetsControllerTest(test.TestCase):
def setUp(self):
super(self.__class__, self).setUp()
self.controller = quota_sets.QuotaSetsController()
self.resource_name = self.controller.resource_name
self.project_id = 'foo_project_id'
self.mock_policy_check = self.mock_object(
policy, 'check_policy', mock.Mock(return_value=True))
@ddt.data(
{"shares": 3, "snapshots": 4, "gigabytes": 5,
"snapshot_gigabytes": 6, "share_networks": 7},
{"shares": -1, "snapshots": -1, "gigabytes": -1,
"snapshot_gigabytes": -1, "share_networks": -1},
{"shares": 13},
{"snapshots": 24},
{"gigabytes": 7},
{"snapshot_gigabytes": 10001},
{"share_networks": 12345},
)
def test_defaults(self, quotas):
for k, v in quotas.items():
CONF.set_default('quota_' + k, v)
expected = {
'quota_set': {
'id': self.project_id,
'shares': quotas.get('shares', 50),
'gigabytes': quotas.get('gigabytes', 1000),
'snapshots': quotas.get('snapshots', 50),
'snapshot_gigabytes': quotas.get('snapshot_gigabytes', 1000),
'share_networks': quotas.get('share_networks', 10),
}
}
result = self.controller.defaults(REQ, self.project_id)
self.assertEqual(expected, result)
self.mock_policy_check.assert_called_once_with(
REQ.environ['manila.context'], self.resource_name, 'show')
@ddt.data(
('os-', '1.0', quota_sets.QuotaSetsControllerLegacy, 'defaults'),
('os-', '2.6', quota_sets.QuotaSetsControllerLegacy, 'defaults'),
('', '2.7', quota_sets.QuotaSetsController, 'defaults'),
('os-', '1.0', quota_sets.QuotaSetsControllerLegacy, 'show'),
('os-', '2.6', quota_sets.QuotaSetsControllerLegacy, 'show'),
('', '2.7', quota_sets.QuotaSetsController, 'show'),
)
@ddt.unpack
def test_get_quotas_with_different_api_versions(self, url, version,
controller, method_name):
expected = {
'quota_set': {
'id': self.project_id,
'shares': 50,
'gigabytes': 1000,
'snapshots': 50,
'snapshot_gigabytes': 1000,
'share_networks': 10,
}
}
req = fakes.HTTPRequest.blank(
'/fooproject/%squota-sets' % url,
version=version, use_admin_context=True)
result = getattr(controller(), method_name)(req, self.project_id)
self.assertEqual(expected, result)
@ddt.data(REQ, REQ_WITH_USER)
def test_quota_detail(self, request):
request.api_version_request = api_version.APIVersionRequest('2.25')
quotas = {
"shares": 23,
"snapshots": 34,
"gigabytes": 45,
"snapshot_gigabytes": 56,
"share_networks": 67,
}
expected = {
'quota_set': {
'id': self.project_id,
'shares': {'in_use': 0,
'limit': quotas['shares'],
'reserved': 0},
'gigabytes': {'in_use': 0,
'limit': quotas['gigabytes'], 'reserved': 0},
'snapshots': {'in_use': 0,
'limit': quotas['snapshots'], 'reserved': 0},
'snapshot_gigabytes': {
'in_use': 0,
'limit': quotas['snapshot_gigabytes'],
'reserved': 0,
},
'share_networks': {
'in_use': 0,
'limit': quotas['share_networks'],
'reserved': 0
},
}
}
for k, v in quotas.items():
CONF.set_default('quota_' + k, v)
result = self.controller.detail(request, self.project_id)
self.assertEqual(expected, result)
self.mock_policy_check.assert_called_once_with(
request.environ['manila.context'], self.resource_name, 'show')
@ddt.data(REQ, REQ_WITH_USER)
def test_show_quota(self, request):
quotas = {
"shares": 23,
"snapshots": 34,
"gigabytes": 45,
"snapshot_gigabytes": 56,
"share_networks": 67,
}
expected = {
'quota_set': {
'id': self.project_id,
'shares': quotas.get('shares', 50),
'gigabytes': quotas.get('gigabytes', 1000),
'snapshots': quotas.get('snapshots', 50),
'snapshot_gigabytes': quotas.get('snapshot_gigabytes', 1000),
'share_networks': quotas.get('share_networks', 10),
}
}
for k, v in quotas.items():
CONF.set_default('quota_' + k, v)
result = self.controller.show(request, self.project_id)
self.assertEqual(expected, result)
self.mock_policy_check.assert_called_once_with(
request.environ['manila.context'], self.resource_name, 'show')
def test_show_quota_not_authorized(self):
self.mock_object(
quota_sets.db,
'authorize_project_context',
mock.Mock(side_effect=exception.NotAuthorized))
self.assertRaises(
webob.exc.HTTPForbidden,
self.controller.show,
REQ, self.project_id)
self.mock_policy_check.assert_called_once_with(
REQ.environ['manila.context'], self.resource_name, 'show')
@ddt.data(REQ, REQ_WITH_USER)
def test_update_quota(self, request):
CONF.set_default('quota_shares', 789)
body = {'quota_set': {'tenant_id': self.project_id, 'shares': 788}}
expected = {
'quota_set': {
'shares': body['quota_set']['shares'],
'gigabytes': 1000,
'snapshots': 50,
'snapshot_gigabytes': 1000,
'share_networks': 10,
}
}
mock_policy_update_check_call = mock.call(
request.environ['manila.context'], self.resource_name, 'update')
mock_policy_show_check_call = mock.call(
request.environ['manila.context'], self.resource_name, 'show')
update_result = self.controller.update(
request, self.project_id, body=body)
self.assertEqual(expected, update_result)
show_result = self.controller.show(request, self.project_id)
expected['quota_set']['id'] = self.project_id
self.assertEqual(expected, show_result)
self.mock_policy_check.assert_has_calls([
mock_policy_update_check_call, mock_policy_show_check_call])
@ddt.data(-2, 'foo', {1: 2}, [1])
def test_update_quota_with_invalid_value(self, value):
body = {'quota_set': {'tenant_id': self.project_id, 'shares': value}}
self.assertRaises(
webob.exc.HTTPBadRequest,
self.controller.update,
REQ, self.project_id, body=body)
self.mock_policy_check.assert_called_once_with(
REQ.environ['manila.context'], self.resource_name, 'update')
def test_user_quota_can_not_be_bigger_than_tenant_quota(self):
value = 777
CONF.set_default('quota_shares', value)
body = {
'quota_set': {
'tenant_id': self.project_id,
'shares': value + 1,
}
}
self.assertRaises(
webob.exc.HTTPBadRequest,
self.controller.update,
REQ_WITH_USER, self.project_id, body=body)
self.mock_policy_check.assert_called_once_with(
REQ_WITH_USER.environ['manila.context'], self.resource_name,
'update')
def test_update_inexistent_quota(self):
body = {
'quota_set': {
'tenant_id': self.project_id,
'fake_quota': 13,
}
}
self.assertRaises(
webob.exc.HTTPBadRequest,
self.controller.update,
REQ, self.project_id, body=body)
self.mock_policy_check.assert_called_once_with(
REQ.environ['manila.context'], self.resource_name, 'update')
def test_update_quota_not_authorized(self):
body = {'quota_set': {'tenant_id': self.project_id, 'shares': 13}}
self.assertRaises(
webob.exc.HTTPForbidden,
self.controller.update,
REQ_MEMBER, self.project_id, body=body)
self.mock_policy_check.assert_called_once_with(
REQ_MEMBER.environ['manila.context'], self.resource_name, 'update')
@ddt.data(
('os-quota-sets', '1.0', quota_sets.QuotaSetsControllerLegacy),
('os-quota-sets', '2.6', quota_sets.QuotaSetsControllerLegacy),
('quota-sets', '2.7', quota_sets.QuotaSetsController),
)
@ddt.unpack
def test_update_all_quotas_with_force(self, url, version, controller):
req = fakes.HTTPRequest.blank(
'/fooproject/%s' % url, version=version, use_admin_context=True)
quotas = (
('quota_shares', 13),
('quota_gigabytes', 14),
('quota_snapshots', 15),
('quota_snapshot_gigabytes', 16),
('quota_share_networks', 17),
)
for quota, value in quotas:
CONF.set_default(quota, value)
expected = {
'quota_set': {
'tenant_id': self.project_id,
'shares': quotas[0][1],
'gigabytes': quotas[1][1],
'snapshots': quotas[2][1],
'snapshot_gigabytes': quotas[3][1],
'share_networks': quotas[4][1],
'force': True,
}
}
update_result = controller().update(
req, self.project_id, body=expected)
expected['quota_set'].pop('force')
expected['quota_set'].pop('tenant_id')
self.assertEqual(expected, update_result)
show_result = controller().show(req, self.project_id)
expected['quota_set']['id'] = self.project_id
self.assertEqual(expected, show_result)
self.mock_policy_check.assert_has_calls([
mock.call(req.environ['manila.context'],
self.resource_name, action)
for action in ('update', 'show')
])
@ddt.data(
('os-quota-sets', '1.0', quota_sets.QuotaSetsControllerLegacy),
('os-quota-sets', '2.6', quota_sets.QuotaSetsControllerLegacy),
('quota-sets', '2.7', quota_sets.QuotaSetsController),
)
@ddt.unpack
def test_delete_tenant_quota(self, url, version, controller):
self.mock_object(quota_sets.QUOTAS, 'destroy_all_by_project_and_user')
self.mock_object(quota_sets.QUOTAS, 'destroy_all_by_project')
req = fakes.HTTPRequest.blank(
'/fooproject/%s' % url, version=version, use_admin_context=True)
result = controller().delete(req, self.project_id)
self.assertTrue(
utils.IsAMatcher(webob.response.Response) == result
)
self.assertTrue(hasattr(result, 'status_code'))
self.assertEqual(202, result.status_code)
self.assertFalse(
quota_sets.QUOTAS.destroy_all_by_project_and_user.called)
quota_sets.QUOTAS.destroy_all_by_project.assert_called_once_with(
req.environ['manila.context'], self.project_id)
self.mock_policy_check.assert_called_once_with(
req.environ['manila.context'], self.resource_name, 'delete')
def test_delete_user_quota(self):
project_id = 'foo_project_id'
self.mock_object(quota_sets.QUOTAS, 'destroy_all_by_project_and_user')
self.mock_object(quota_sets.QUOTAS, 'destroy_all_by_project')
result = self.controller.delete(REQ_WITH_USER, project_id)
self.assertTrue(
utils.IsAMatcher(webob.response.Response) == result
)
self.assertTrue(hasattr(result, 'status_code'))
self.assertEqual(202, result.status_code)
quota_sets.QUOTAS.destroy_all_by_project_and_user. \
assert_called_once_with(
REQ_WITH_USER.environ['manila.context'],
project_id,
REQ_WITH_USER.environ['manila.context'].user_id)
self.assertFalse(quota_sets.QUOTAS.destroy_all_by_project.called)
self.mock_policy_check.assert_called_once_with(
REQ_WITH_USER.environ['manila.context'], self.resource_name,
'delete')
def test_delete_not_authorized(self):
self.assertRaises(
webob.exc.HTTPForbidden,
self.controller.delete,
REQ_MEMBER, self.project_id)
self.mock_policy_check.assert_called_once_with(
REQ_MEMBER.environ['manila.context'], self.resource_name, 'delete')
@ddt.data(
('os-quota-sets', '2.7', quota_sets.QuotaSetsControllerLegacy),
('quota-sets', '2.6', quota_sets.QuotaSetsController),
('quota-sets', '2.0', quota_sets.QuotaSetsController),
)
@ddt.unpack
def test_api_not_found(self, url, version, controller):
req = fakes.HTTPRequest.blank('/fooproject/%s' % url, version=version)
for method_name in ('show', 'defaults', 'delete'):
self.assertRaises(
exception.VersionNotFoundForAPIMethod,
getattr(controller(), method_name),
req, self.project_id)
@ddt.data(
('os-quota-sets', '2.7', quota_sets.QuotaSetsControllerLegacy),
('quota-sets', '2.6', quota_sets.QuotaSetsController),
('quota-sets', '2.0', quota_sets.QuotaSetsController),
)
@ddt.unpack
def test_update_api_not_found(self, url, version, controller):
req = fakes.HTTPRequest.blank('/fooproject/%s' % url, version=version)
self.assertRaises(
exception.VersionNotFoundForAPIMethod,
controller().update,
req, self.project_id)