Add snapshot gigabytes quota

Manila has used single gigabytes quota for shares and snapshots.
Config opt 'no_snapshot_gb_quota' is set to False by default, that has been
used for enabling/disabling of snapshot gigabytes quota considerations.

Add separate snapshot gigabyte quota and remove opt 'no_snapshot_gb_quota' that
is not needed anymore. To be able to set infinite quota for snapshot gigabytes,
just set value for new config option 'quota_snapshot_gigabytes' to '-1'.

Change-Id: I43cb95ff3d0d3e6191f520b52edb67a0a44e9c2c
Implements BP add-snapshot-gb-quota
This commit is contained in:
Valeriy Ponomaryov 2015-02-24 15:45:15 +02:00
parent 98a6c6621b
commit c0019bce6b
14 changed files with 180 additions and 65 deletions

View File

@ -40,6 +40,7 @@ class SharesAdminQuotasTest(base.BaseSharesAdminTest):
resp, quotas = self.shares_client.default_quotas(self.tenant["id"]) resp, quotas = self.shares_client.default_quotas(self.tenant["id"])
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertGreater(int(quotas["gigabytes"]), -2) self.assertGreater(int(quotas["gigabytes"]), -2)
self.assertGreater(int(quotas["snapshot_gigabytes"]), -2)
self.assertGreater(int(quotas["shares"]), -2) self.assertGreater(int(quotas["shares"]), -2)
self.assertGreater(int(quotas["snapshots"]), -2) self.assertGreater(int(quotas["snapshots"]), -2)
self.assertGreater(int(quotas["share_networks"]), -2) self.assertGreater(int(quotas["share_networks"]), -2)
@ -49,6 +50,7 @@ class SharesAdminQuotasTest(base.BaseSharesAdminTest):
resp, quotas = self.shares_client.show_quotas(self.tenant["id"]) resp, quotas = self.shares_client.show_quotas(self.tenant["id"])
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertGreater(int(quotas["gigabytes"]), -2) self.assertGreater(int(quotas["gigabytes"]), -2)
self.assertGreater(int(quotas["snapshot_gigabytes"]), -2)
self.assertGreater(int(quotas["shares"]), -2) self.assertGreater(int(quotas["shares"]), -2)
self.assertGreater(int(quotas["snapshots"]), -2) self.assertGreater(int(quotas["snapshots"]), -2)
self.assertGreater(int(quotas["share_networks"]), -2) self.assertGreater(int(quotas["share_networks"]), -2)
@ -59,6 +61,7 @@ class SharesAdminQuotasTest(base.BaseSharesAdminTest):
self.user["id"]) self.user["id"])
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertGreater(int(quotas["gigabytes"]), -2) self.assertGreater(int(quotas["gigabytes"]), -2)
self.assertGreater(int(quotas["snapshot_gigabytes"]), -2)
self.assertGreater(int(quotas["shares"]), -2) self.assertGreater(int(quotas["shares"]), -2)
self.assertGreater(int(quotas["snapshots"]), -2) self.assertGreater(int(quotas["snapshots"]), -2)
self.assertGreater(int(quotas["share_networks"]), -2) self.assertGreater(int(quotas["share_networks"]), -2)
@ -149,6 +152,25 @@ class SharesAdminQuotasUpdateTest(base.BaseSharesAdminTest):
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertEqual(int(updated["gigabytes"]), gigabytes) self.assertEqual(int(updated["gigabytes"]), gigabytes)
@test.attr(type=["gate", "smoke", ])
def test_update_tenant_quota_snapshot_gigabytes(self):
client = self.get_client_with_isolated_creds()
# get current quotas
resp, custom = client.show_quotas(client.creds["tenant"]["id"])
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
# make quotas for update
snapshot_gigabytes = int(custom["snapshot_gigabytes"]) + 2
# set new quota for shares
resp, updated = client.update_quotas(
client.creds["tenant"]["id"],
snapshot_gigabytes=snapshot_gigabytes)
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertEqual(
int(updated["snapshot_gigabytes"]), snapshot_gigabytes)
@test.attr(type=["gate", "smoke", ]) @test.attr(type=["gate", "smoke", ])
def test_update_user_quota_gigabytes(self): def test_update_user_quota_gigabytes(self):
client = self.get_client_with_isolated_creds() client = self.get_client_with_isolated_creds()
@ -169,6 +191,27 @@ class SharesAdminQuotasUpdateTest(base.BaseSharesAdminTest):
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertEqual(int(updated["gigabytes"]), gigabytes) self.assertEqual(int(updated["gigabytes"]), gigabytes)
@test.attr(type=["gate", "smoke", ])
def test_update_user_quota_snapshot_gigabytes(self):
client = self.get_client_with_isolated_creds()
# get current quotas
resp, custom = client.show_quotas(client.creds["tenant"]["id"],
client.creds["user"]["id"])
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
# make quotas for update
snapshot_gigabytes = int(custom["snapshot_gigabytes"]) - 1
# set new quota for shares
resp, updated = client.update_quotas(
client.creds["tenant"]["id"], client.creds["user"]["id"],
snapshot_gigabytes=snapshot_gigabytes)
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertEqual(
int(updated["snapshot_gigabytes"]), snapshot_gigabytes)
@test.attr(type=["gate", "smoke", ]) @test.attr(type=["gate", "smoke", ])
def test_update_tenant_quota_share_networks(self): def test_update_tenant_quota_share_networks(self):
client = self.get_client_with_isolated_creds() client = self.get_client_with_isolated_creds()
@ -217,18 +260,23 @@ class SharesAdminQuotasUpdateTest(base.BaseSharesAdminTest):
shares = int(custom["shares"]) + 2 shares = int(custom["shares"]) + 2
snapshots = int(custom["snapshots"]) + 2 snapshots = int(custom["snapshots"]) + 2
gigabytes = int(custom["gigabytes"]) + 2 gigabytes = int(custom["gigabytes"]) + 2
snapshot_gigabytes = int(custom["snapshot_gigabytes"]) + 2
share_networks = int(custom["share_networks"]) + 2 share_networks = int(custom["share_networks"]) + 2
# set new quota # set new quota
resp, updated = client.update_quotas(client.creds["tenant"]["id"], resp, updated = client.update_quotas(
shares=shares, client.creds["tenant"]["id"],
snapshots=snapshots, shares=shares,
gigabytes=gigabytes, snapshots=snapshots,
share_networks=share_networks) gigabytes=gigabytes,
snapshot_gigabytes=snapshot_gigabytes,
share_networks=share_networks)
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertEqual(int(updated["shares"]), shares) self.assertEqual(int(updated["shares"]), shares)
self.assertEqual(int(updated["snapshots"]), snapshots) self.assertEqual(int(updated["snapshots"]), snapshots)
self.assertEqual(int(updated["gigabytes"]), gigabytes) self.assertEqual(int(updated["gigabytes"]), gigabytes)
self.assertEqual(
int(updated["snapshot_gigabytes"]), snapshot_gigabytes)
self.assertEqual(int(updated["share_networks"]), share_networks) self.assertEqual(int(updated["share_networks"]), share_networks)
# reset customized quotas # reset customized quotas
@ -281,6 +329,13 @@ class SharesAdminQuotasUpdateTest(base.BaseSharesAdminTest):
gigabytes=-1) gigabytes=-1)
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
@test.attr(type=["gate", "smoke", ])
def test_unlimited_quota_for_snapshot_gigabytes(self):
client = self.get_client_with_isolated_creds()
resp, __ = client.update_quotas(client.creds["tenant"]["id"],
snapshot_gigabytes=-1)
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
@test.attr(type=["gate", "smoke", ]) @test.attr(type=["gate", "smoke", ])
def test_unlimited_user_quota_for_gigabytes(self): def test_unlimited_user_quota_for_gigabytes(self):
client = self.get_client_with_isolated_creds() client = self.get_client_with_isolated_creds()
@ -289,6 +344,14 @@ class SharesAdminQuotasUpdateTest(base.BaseSharesAdminTest):
gigabytes=-1) gigabytes=-1)
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
@test.attr(type=["gate", "smoke", ])
def test_unlimited_user_quota_for_snapshot_gigabytes(self):
client = self.get_client_with_isolated_creds()
resp, __ = client.update_quotas(client.creds["tenant"]["id"],
client.creds["user"]["id"],
snapshot_gigabytes=-1)
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
@test.attr(type=["gate", "smoke", ]) @test.attr(type=["gate", "smoke", ])
def test_unlimited_quota_for_share_networks(self): def test_unlimited_quota_for_share_networks(self):
client = self.get_client_with_isolated_creds() client = self.get_client_with_isolated_creds()

View File

@ -79,6 +79,15 @@ class SharesAdminQuotasNegativeTest(base.BaseSharesAdminTest):
client.creds["tenant"]["id"], client.creds["tenant"]["id"],
gigabytes=-2) gigabytes=-2)
@test.attr(type=["gate", "smoke", "negative"])
def test_update_snapshot_gigabytes_quota_with_wrong_data(self):
# -1 is acceptable value as unlimited
client = self.get_client_with_isolated_creds()
self.assertRaises(exceptions.BadRequest,
client.update_quotas,
client.creds["tenant"]["id"],
snapshot_gigabytes=-2)
@test.attr(type=["gate", "smoke", "negative"]) @test.attr(type=["gate", "smoke", "negative"])
def test_update_share_networks_quota_with_wrong_data(self): def test_update_share_networks_quota_with_wrong_data(self):
# -1 is acceptable value as unlimited # -1 is acceptable value as unlimited
@ -145,6 +154,21 @@ class SharesAdminQuotasNegativeTest(base.BaseSharesAdminTest):
client.creds["user"]["id"], client.creds["user"]["id"],
gigabytes=bigger_value) gigabytes=bigger_value)
@test.attr(type=["gate", "smoke", "negative"])
def test_try_set_user_quota_snap_gigabytes_bigger_than_tenant_quota(self):
client = self.get_client_with_isolated_creds()
# get current quotas for tenant
__, tenant_quotas = client.show_quotas(client.creds["tenant"]["id"])
# try set user quota for snapshot gigabytes bigger than tenant quota
bigger_value = int(tenant_quotas["snapshot_gigabytes"]) + 2
self.assertRaises(exceptions.BadRequest,
client.update_quotas,
client.creds["tenant"]["id"],
client.creds["user"]["id"],
snapshot_gigabytes=bigger_value)
@test.attr(type=["gate", "smoke", "negative"]) @test.attr(type=["gate", "smoke", "negative"])
def test_try_set_user_quota_share_networks_bigger_than_tenant_quota(self): def test_try_set_user_quota_share_networks_bigger_than_tenant_quota(self):
client = self.get_client_with_isolated_creds() client = self.get_client_with_isolated_creds()

View File

@ -35,6 +35,7 @@ class SharesQuotasTest(base.BaseSharesTest):
resp, quotas = self.shares_client.default_quotas(self.tenant["id"]) resp, quotas = self.shares_client.default_quotas(self.tenant["id"])
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertGreater(int(quotas["gigabytes"]), -2) self.assertGreater(int(quotas["gigabytes"]), -2)
self.assertGreater(int(quotas["snapshot_gigabytes"]), -2)
self.assertGreater(int(quotas["shares"]), -2) self.assertGreater(int(quotas["shares"]), -2)
self.assertGreater(int(quotas["snapshots"]), -2) self.assertGreater(int(quotas["snapshots"]), -2)
self.assertGreater(int(quotas["share_networks"]), -2) self.assertGreater(int(quotas["share_networks"]), -2)
@ -44,6 +45,7 @@ class SharesQuotasTest(base.BaseSharesTest):
resp, quotas = self.shares_client.show_quotas(self.tenant["id"]) resp, quotas = self.shares_client.show_quotas(self.tenant["id"])
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertGreater(int(quotas["gigabytes"]), -2) self.assertGreater(int(quotas["gigabytes"]), -2)
self.assertGreater(int(quotas["snapshot_gigabytes"]), -2)
self.assertGreater(int(quotas["shares"]), -2) self.assertGreater(int(quotas["shares"]), -2)
self.assertGreater(int(quotas["snapshots"]), -2) self.assertGreater(int(quotas["snapshots"]), -2)
self.assertGreater(int(quotas["share_networks"]), -2) self.assertGreater(int(quotas["share_networks"]), -2)
@ -54,6 +56,7 @@ class SharesQuotasTest(base.BaseSharesTest):
self.user["id"]) self.user["id"])
self.assertIn(int(resp["status"]), self.HTTP_SUCCESS) self.assertIn(int(resp["status"]), self.HTTP_SUCCESS)
self.assertGreater(int(quotas["gigabytes"]), -2) self.assertGreater(int(quotas["gigabytes"]), -2)
self.assertGreater(int(quotas["snapshot_gigabytes"]), -2)
self.assertGreater(int(quotas["shares"]), -2) self.assertGreater(int(quotas["shares"]), -2)
self.assertGreater(int(quotas["snapshots"]), -2) self.assertGreater(int(quotas["snapshots"]), -2)
self.assertGreater(int(quotas["share_networks"]), -2) self.assertGreater(int(quotas["share_networks"]), -2)

View File

@ -245,8 +245,8 @@ class SharesClient(service_client.ServiceClient):
return self.delete(uri) return self.delete(uri)
def update_quotas(self, tenant_id, user_id=None, shares=None, def update_quotas(self, tenant_id, user_id=None, shares=None,
snapshots=None, gigabytes=None, share_networks=None, snapshots=None, gigabytes=None, snapshot_gigabytes=None,
force=True): share_networks=None, force=True):
uri = "os-quota-sets/%s" % tenant_id uri = "os-quota-sets/%s" % tenant_id
if user_id is not None: if user_id is not None:
uri += "?user_id=%s" % user_id uri += "?user_id=%s" % user_id
@ -260,6 +260,8 @@ class SharesClient(service_client.ServiceClient):
put_body["snapshots"] = snapshots put_body["snapshots"] = snapshots
if gigabytes is not None: if gigabytes is not None:
put_body["gigabytes"] = gigabytes put_body["gigabytes"] = gigabytes
if snapshot_gigabytes is not None:
put_body["snapshot_gigabytes"] = snapshot_gigabytes
if share_networks is not None: if share_networks is not None:
put_body["share_networks"] = share_networks put_body["share_networks"] = share_networks
put_body = json.dumps({"quota_set": put_body}) put_body = json.dumps({"quota_set": put_body})

View File

@ -39,6 +39,7 @@ class UsedLimitsController(wsgi.Controller):
'totalShareSnapshotsUsed': 'snapshots', 'totalShareSnapshotsUsed': 'snapshots',
'totalShareNetworksUsed': 'share_networks', 'totalShareNetworksUsed': 'share_networks',
'totalShareGigabytesUsed': 'gigabytes', 'totalShareGigabytesUsed': 'gigabytes',
'totalSnapshotGigabytesUsed': 'snapshot_gigabytes',
} }
used_limits = {} used_limits = {}

View File

@ -44,6 +44,7 @@ class ViewBuilder(object):
""" """
limit_names = { limit_names = {
"gigabytes": ["maxTotalShareGigabytes"], "gigabytes": ["maxTotalShareGigabytes"],
"snapshot_gigabytes": ["maxTotalSnapshotGigabytes"],
"shares": ["maxTotalShares"], "shares": ["maxTotalShares"],
"snapshots": ["maxTotalShareSnapshots"], "snapshots": ["maxTotalShareSnapshots"],
"share_networks": ["maxTotalShareNetworks"], "share_networks": ["maxTotalShareNetworks"],

View File

@ -174,9 +174,7 @@ global_opts = [
help="Specify list of protocols to be allowed for share " help="Specify list of protocols to be allowed for share "
"creation. Available values are '%s'" % six.text_type( "creation. Available values are '%s'" % six.text_type(
constants.SUPPORTED_SHARE_PROTOCOLS)), constants.SUPPORTED_SHARE_PROTOCOLS)),
cfg.BoolOpt('no_snapshot_gb_quota', ]
default=False,
help='Whether snapshots count against Gigabyte quota.'), ]
CONF.register_opts(global_opts) CONF.register_opts(global_opts)

View File

@ -263,18 +263,15 @@ def _sync_snapshots(context, project_id, user_id, session):
def _sync_gigabytes(context, project_id, user_id, session): def _sync_gigabytes(context, project_id, user_id, session):
(_junk, share_gigs) = share_data_get_for_project(context, _junk, share_gigs = share_data_get_for_project(
project_id, context, project_id, user_id, session=session)
user_id, return dict(gigabytes=share_gigs)
session=session)
if CONF.no_snapshot_gb_quota:
return {'gigabytes': share_gigs}
(_junk, snap_gigs) = snapshot_data_get_for_project(context,
project_id, def _sync_snapshot_gigabytes(context, project_id, user_id, session):
user_id, _junk, snapshot_gigs = snapshot_data_get_for_project(
session=session) context, project_id, user_id, session=session)
return {'gigabytes': share_gigs + snap_gigs} return dict(snapshot_gigabytes=snapshot_gigs)
def _sync_share_networks(context, project_id, user_id, session): def _sync_share_networks(context, project_id, user_id, session):
@ -289,6 +286,7 @@ QUOTA_SYNC_FUNCTIONS = {
'_sync_shares': _sync_shares, '_sync_shares': _sync_shares,
'_sync_snapshots': _sync_snapshots, '_sync_snapshots': _sync_snapshots,
'_sync_gigabytes': _sync_gigabytes, '_sync_gigabytes': _sync_gigabytes,
'_sync_snapshot_gigabytes': _sync_snapshot_gigabytes,
'_sync_share_networks': _sync_share_networks, '_sync_share_networks': _sync_share_networks,
} }

View File

@ -306,8 +306,11 @@ class QuotaError(ManilaException):
class ShareSizeExceedsAvailableQuota(QuotaError): class ShareSizeExceedsAvailableQuota(QuotaError):
message = _("Requested share or snapshot exceeds " message = _("Requested share exceeds allowed gigabytes quota.")
"allowed gigabytes quota.")
class SnapshotSizeExceedsAvailableQuota(QuotaError):
message = _("Requested snapshot exceeds allowed gigabytes quota.")
class ShareLimitExceeded(QuotaError): class ShareLimitExceeded(QuotaError):

View File

@ -39,8 +39,10 @@ quota_opts = [
help='Number of share snapshots allowed per project.'), help='Number of share snapshots allowed per project.'),
cfg.IntOpt('quota_gigabytes', cfg.IntOpt('quota_gigabytes',
default=1000, default=1000,
help='Number of share gigabytes (snapshots are also included) ' help='Number of share gigabytes allowed per project.'),
'allowed per project.'), cfg.IntOpt('quota_snapshot_gigabytes',
default=1000,
help='Number of snapshot gigabytes allowed per project.'),
cfg.IntOpt('quota_share_networks', cfg.IntOpt('quota_share_networks',
default=10, default=10,
help='Number of share-networks allowed per project.'), help='Number of share-networks allowed per project.'),
@ -1076,6 +1078,8 @@ resources = [
ReservableResource('shares', '_sync_shares', 'quota_shares'), ReservableResource('shares', '_sync_shares', 'quota_shares'),
ReservableResource('snapshots', '_sync_snapshots', 'quota_snapshots'), ReservableResource('snapshots', '_sync_snapshots', 'quota_snapshots'),
ReservableResource('gigabytes', '_sync_gigabytes', 'quota_gigabytes'), ReservableResource('gigabytes', '_sync_gigabytes', 'quota_gigabytes'),
ReservableResource('snapshot_gigabytes', '_sync_snapshot_gigabytes',
'quota_snapshot_gigabytes'),
ReservableResource('share_networks', '_sync_share_networks', ReservableResource('share_networks', '_sync_share_networks',
'quota_share_networks'), 'quota_share_networks'),
] ]

View File

@ -272,7 +272,8 @@ class API(base.Base):
size = share['size'] size = share['size']
try: try:
reservations = QUOTAS.reserve(context, snapshots=1, gigabytes=size) reservations = QUOTAS.reserve(
context, snapshots=1, snapshot_gigabytes=size)
except exception.OverQuota as e: except exception.OverQuota as e:
overs = e.kwargs['overs'] overs = e.kwargs['overs']
usages = e.kwargs['usages'] usages = e.kwargs['usages']
@ -281,15 +282,15 @@ class API(base.Base):
def _consumed(name): def _consumed(name):
return (usages[name]['reserved'] + usages[name]['in_use']) return (usages[name]['reserved'] + usages[name]['in_use'])
if 'gigabytes' in overs: if 'snapshot_gigabytes' in overs:
msg = _LW("Quota exceeded for %(s_pid)s, tried to create " msg = _LW("Quota exceeded for %(s_pid)s, tried to create "
"%(s_size)sG snapshot (%(d_consumed)dG of " "%(s_size)sG snapshot (%(d_consumed)dG of "
"%(d_quota)dG already consumed)") "%(d_quota)dG already consumed)")
LOG.warn(msg, {'s_pid': context.project_id, LOG.warn(msg, {'s_pid': context.project_id,
's_size': size, 's_size': size,
'd_consumed': _consumed('gigabytes'), 'd_consumed': _consumed('gigabytes'),
'd_quota': quotas['gigabytes']}) 'd_quota': quotas['snapshot_gigabytes']})
raise exception.ShareSizeExceedsAvailableQuota() raise exception.SnapshotSizeExceedsAvailableQuota()
elif 'snapshots' in overs: elif 'snapshots' in overs:
msg = _LW("Quota exceeded for %(s_pid)s, tried to create " msg = _LW("Quota exceeded for %(s_pid)s, tried to create "
"snapshot (%(d_consumed)d snapshots " "snapshot (%(d_consumed)d snapshots "

View File

@ -399,10 +399,9 @@ class ShareManager(manager.SchedulerDependentManager):
else: else:
self.db.share_snapshot_destroy(context, snapshot_id) self.db.share_snapshot_destroy(context, snapshot_id)
try: try:
reservations = QUOTAS.reserve(context, reservations = QUOTAS.reserve(
project_id=project_id, context, project_id=project_id, snapshots=-1,
snapshots=-1, snapshot_gigabytes=-snapshot_ref['size'])
gigabytes=-snapshot_ref['size'])
except Exception: except Exception:
reservations = None reservations = None
LOG.exception(_LE("Failed to update usages deleting snapshot")) LOG.exception(_LE("Failed to update usages deleting snapshot"))

View File

@ -498,7 +498,7 @@ class ShareAPITestCase(test.TestCase):
share_api.policy.check_policy.assert_called_once_with( share_api.policy.check_policy.assert_called_once_with(
self.context, 'share', 'create_snapshot', share) self.context, 'share', 'create_snapshot', share)
quota.QUOTAS.reserve.assert_called_once_with( quota.QUOTAS.reserve.assert_called_once_with(
self.context, snapshots=1, gigabytes=1) self.context, snapshots=1, snapshot_gigabytes=1)
quota.QUOTAS.commit.assert_called_once_with( quota.QUOTAS.commit.assert_called_once_with(
self.context, 'reservation') self.context, 'reservation')
db_driver.share_snapshot_create.assert_called_once_with( db_driver.share_snapshot_create.assert_called_once_with(

View File

@ -616,20 +616,17 @@ class DbQuotaDriverTestCase(test.TestCase):
expected_all_context = { expected_all_context = {
"shares": {"limit": 10, "in_use": 2, "reserved": 0, }, "shares": {"limit": 10, "in_use": 2, "reserved": 0, },
"gigabytes": {"limit": 50, "in_use": 10, "reserved": 0, }, "gigabytes": {"limit": 50, "in_use": 10, "reserved": 0, },
"snapshots": {"limit": 10, "in_use": 0, "reserved": 0, }, "snapshot_gigabytes": {"limit": 50, "in_use": 20, "reserved": 0, },
"snapshots": {"limit": 10, "in_use": 4, "reserved": 0, },
"share_networks": {"limit": 10, "in_use": 0, "reserved": 0, }, "share_networks": {"limit": 10, "in_use": 0, "reserved": 0, },
} }
def setUp(self): def setUp(self):
super(DbQuotaDriverTestCase, self).setUp() super(DbQuotaDriverTestCase, self).setUp()
self.flags(
self.flags(quota_shares=10, quota_shares=10, quota_snapshots=10, quota_gigabytes=1000,
quota_snapshots=10, quota_snapshot_gigabytes=1000, reservation_expire=86400,
quota_gigabytes=1000, until_refresh=0, max_age=0)
reservation_expire=86400,
until_refresh=0,
max_age=0,
)
self.driver = quota.DbQuotaDriver() self.driver = quota.DbQuotaDriver()
@ -649,17 +646,18 @@ class DbQuotaDriverTestCase(test.TestCase):
expected = { expected = {
"shares": 10, "shares": 10,
"gigabytes": 1000, "gigabytes": 1000,
"snapshot_gigabytes": 1000,
"snapshots": 10, "snapshots": 10,
"share_networks": 10, "share_networks": 10,
} }
self.assertEqual(result, expected) self.assertEqual(expected, result)
def _stub_quota_class_get_all_by_name(self): def _stub_quota_class_get_all_by_name(self):
# Stub out quota_class_get_all_by_name # Stub out quota_class_get_all_by_name
def fake_qcgabn(context, quota_class): def fake_qcgabn(context, quota_class):
self.calls.append('quota_class_get_all_by_name') self.calls.append('quota_class_get_all_by_name')
self.assertEqual(quota_class, 'test_class') self.assertEqual(quota_class, 'test_class')
return dict(gigabytes=500, shares=10, ) return dict(gigabytes=500, shares=10, snapshot_gigabytes=50)
self.mock_object(db, 'quota_class_get_all_by_name', fake_qcgabn) self.mock_object(db, 'quota_class_get_all_by_name', fake_qcgabn)
def test_get_class_quotas(self): def test_get_class_quotas(self):
@ -671,10 +669,11 @@ class DbQuotaDriverTestCase(test.TestCase):
expected = { expected = {
"shares": 10, "shares": 10,
"gigabytes": 500, "gigabytes": 500,
"snapshot_gigabytes": 50,
"snapshots": 10, "snapshots": 10,
"share_networks": 10, "share_networks": 10,
} }
self.assertEqual(result, expected) self.assertEqual(expected, result)
def test_get_class_quotas_no_defaults(self): def test_get_class_quotas_no_defaults(self):
self._stub_quota_class_get_all_by_name() self._stub_quota_class_get_all_by_name()
@ -682,27 +681,35 @@ class DbQuotaDriverTestCase(test.TestCase):
'test_class', False) 'test_class', False)
self.assertEqual(self.calls, ['quota_class_get_all_by_name']) self.assertEqual(self.calls, ['quota_class_get_all_by_name'])
self.assertEqual(result, dict(shares=10, self.assertEqual(
gigabytes=500)) dict(shares=10, gigabytes=500, snapshot_gigabytes=50), result)
def _stub_get_by_project_and_user(self): def _stub_get_by_project_and_user(self):
def fake_qgabpu(context, project_id, user_id): def fake_qgabpu(context, project_id, user_id):
self.calls.append('quota_get_all_by_project_and_user') self.calls.append('quota_get_all_by_project_and_user')
self.assertEqual(project_id, 'test_project') self.assertEqual(project_id, 'test_project')
self.assertEqual(user_id, 'fake_user') self.assertEqual(user_id, 'fake_user')
return dict(shares=10, gigabytes=50, reserved=0) return dict(
shares=10, gigabytes=50, snapshots=10, snapshot_gigabytes=50,
reserved=0)
def fake_qgabp(context, project_id): def fake_qgabp(context, project_id):
self.calls.append('quota_get_all_by_project') self.calls.append('quota_get_all_by_project')
self.assertEqual(project_id, 'test_project') self.assertEqual(project_id, 'test_project')
return dict(shares=10, gigabytes=50, reserved=0) return dict(
shares=10, gigabytes=50, snapshots=10, snapshot_gigabytes=50,
reserved=0)
def fake_qugabpu(context, project_id, user_id): def fake_qugabpu(context, project_id, user_id):
self.calls.append('quota_usage_get_all_by_project_and_user') self.calls.append('quota_usage_get_all_by_project_and_user')
self.assertEqual(project_id, 'test_project') self.assertEqual(project_id, 'test_project')
self.assertEqual(user_id, 'fake_user') self.assertEqual(user_id, 'fake_user')
return dict(shares=dict(in_use=2, reserved=0), return dict(
gigabytes=dict(in_use=10, reserved=0), ) shares=dict(in_use=2, reserved=0),
gigabytes=dict(in_use=10, reserved=0),
snapshots=dict(in_use=4, reserved=0),
snapshot_gigabytes=dict(in_use=20, reserved=0),
)
self.mock_object(db, 'quota_get_all_by_project_and_user', fake_qgabpu) self.mock_object(db, 'quota_get_all_by_project_and_user', fake_qgabpu)
self.mock_object(db, 'quota_get_all_by_project', fake_qgabp) self.mock_object(db, 'quota_get_all_by_project', fake_qgabp)
@ -723,19 +730,23 @@ class DbQuotaDriverTestCase(test.TestCase):
'quota_usage_get_all_by_project_and_user', 'quota_usage_get_all_by_project_and_user',
'quota_class_get_all_by_name', 'quota_class_get_all_by_name',
]) ])
self.assertEqual(result, self.expected_all_context) self.assertEqual(self.expected_all_context, result)
def _stub_get_by_project(self): def _stub_get_by_project(self):
def fake_qgabp(context, project_id): def fake_qgabp(context, project_id):
self.calls.append('quota_get_all_by_project') self.calls.append('quota_get_all_by_project')
self.assertEqual(project_id, 'test_project') self.assertEqual(project_id, 'test_project')
return dict(shares=10, gigabytes=50, reserved=0) return dict(
shares=10, gigabytes=50, snapshot_gigabytes=50, reserved=0)
def fake_qugabp(context, project_id): def fake_qugabp(context, project_id):
self.calls.append('quota_usage_get_all_by_project') self.calls.append('quota_usage_get_all_by_project')
self.assertEqual(project_id, 'test_project') self.assertEqual(project_id, 'test_project')
return dict(shares=dict(in_use=2, reserved=0), return dict(
gigabytes=dict(in_use=10, reserved=0), ) shares=dict(in_use=2, reserved=0),
snapshots=dict(in_use=4, reserved=0),
snapshot_gigabytes=dict(in_use=20, reserved=0),
gigabytes=dict(in_use=10, reserved=0))
self.mock_object(db, 'quota_get_all_by_project', fake_qgabp) self.mock_object(db, 'quota_get_all_by_project', fake_qgabp)
self.mock_object(db, 'quota_usage_get_all_by_project', fake_qugabp) self.mock_object(db, 'quota_usage_get_all_by_project', fake_qugabp)
@ -751,7 +762,7 @@ class DbQuotaDriverTestCase(test.TestCase):
self.assertEqual(self.calls, ['quota_get_all_by_project', self.assertEqual(self.calls, ['quota_get_all_by_project',
'quota_usage_get_all_by_project', 'quota_usage_get_all_by_project',
'quota_class_get_all_by_name', ]) 'quota_class_get_all_by_name', ])
self.assertEqual(result, self.expected_all_context) self.assertEqual(self.expected_all_context, result)
def test_get_project_quotas_with_remains(self): def test_get_project_quotas_with_remains(self):
self._stub_get_by_project() self._stub_get_by_project()
@ -772,7 +783,7 @@ class DbQuotaDriverTestCase(test.TestCase):
'quota_get_all_by_project', 'quota_get_all_by_project',
'quota_usage_get_all_by_project_and_user', 'quota_usage_get_all_by_project_and_user',
]) ])
self.assertEqual(result, self.expected_all_context) self.assertEqual(self.expected_all_context, result)
def test_get_project_quotas_alt_context_no_class(self): def test_get_project_quotas_alt_context_no_class(self):
self._stub_get_by_project() self._stub_get_by_project()
@ -782,7 +793,7 @@ class DbQuotaDriverTestCase(test.TestCase):
self.assertEqual(self.calls, ['quota_get_all_by_project', self.assertEqual(self.calls, ['quota_get_all_by_project',
'quota_usage_get_all_by_project', ]) 'quota_usage_get_all_by_project', ])
self.assertEqual(result, self.expected_all_context) self.assertEqual(self.expected_all_context, result)
def test_get_user_quotas_alt_context_with_class(self): def test_get_user_quotas_alt_context_with_class(self):
self._stub_get_by_project_and_user() self._stub_get_by_project_and_user()
@ -797,7 +808,7 @@ class DbQuotaDriverTestCase(test.TestCase):
'quota_usage_get_all_by_project_and_user', 'quota_usage_get_all_by_project_and_user',
'quota_class_get_all_by_name', 'quota_class_get_all_by_name',
]) ])
self.assertEqual(result, self.expected_all_context) self.assertEqual(self.expected_all_context, result)
def test_get_project_quotas_alt_context_with_class(self): def test_get_project_quotas_alt_context_with_class(self):
self._stub_get_by_project() self._stub_get_by_project()
@ -808,7 +819,7 @@ class DbQuotaDriverTestCase(test.TestCase):
self.assertEqual(self.calls, ['quota_get_all_by_project', self.assertEqual(self.calls, ['quota_get_all_by_project',
'quota_usage_get_all_by_project', 'quota_usage_get_all_by_project',
'quota_class_get_all_by_name', ]) 'quota_class_get_all_by_name', ])
self.assertEqual(result, self.expected_all_context) self.assertEqual(self.expected_all_context, result)
def test_get_user_quotas_no_defaults(self): def test_get_user_quotas_no_defaults(self):
self._stub_get_by_project_and_user() self._stub_get_by_project_and_user()
@ -826,8 +837,10 @@ class DbQuotaDriverTestCase(test.TestCase):
expected = { expected = {
"shares": {"limit": 10, "in_use": 2, "reserved": 0, }, "shares": {"limit": 10, "in_use": 2, "reserved": 0, },
"gigabytes": {"limit": 50, "in_use": 10, "reserved": 0, }, "gigabytes": {"limit": 50, "in_use": 10, "reserved": 0, },
"snapshot_gigabytes": {"limit": 50, "in_use": 20, "reserved": 0, },
"snapshots": {"limit": 10, "in_use": 4, "reserved": 0, },
} }
self.assertEqual(result, expected) self.assertEqual(expected, result)
def test_get_project_quotas_no_defaults(self): def test_get_project_quotas_no_defaults(self):
self._stub_get_by_project() self._stub_get_by_project()
@ -841,8 +854,9 @@ class DbQuotaDriverTestCase(test.TestCase):
expected = { expected = {
"shares": {"limit": 10, "in_use": 2, "reserved": 0, }, "shares": {"limit": 10, "in_use": 2, "reserved": 0, },
"gigabytes": {"limit": 50, "in_use": 10, "reserved": 0, }, "gigabytes": {"limit": 50, "in_use": 10, "reserved": 0, },
"snapshot_gigabytes": {"limit": 50, "in_use": 20, "reserved": 0, },
} }
self.assertEqual(result, expected) self.assertEqual(expected, result)
def test_get_user_quotas_no_usages(self): def test_get_user_quotas_no_usages(self):
self._stub_get_by_project_and_user() self._stub_get_by_project_and_user()
@ -858,10 +872,11 @@ class DbQuotaDriverTestCase(test.TestCase):
expected = { expected = {
"shares": {"limit": 10, }, "shares": {"limit": 10, },
"gigabytes": {"limit": 50, }, "gigabytes": {"limit": 50, },
"snapshot_gigabytes": {"limit": 50, },
"snapshots": {"limit": 10, }, "snapshots": {"limit": 10, },
"share_networks": {"limit": 10, }, "share_networks": {"limit": 10, },
} }
self.assertEqual(result, expected) self.assertEqual(result, expected, result)
def test_get_project_quotas_no_usages(self): def test_get_project_quotas_no_usages(self):
self._stub_get_by_project() self._stub_get_by_project()
@ -874,10 +889,11 @@ class DbQuotaDriverTestCase(test.TestCase):
expected = { expected = {
"shares": {"limit": 10, }, "shares": {"limit": 10, },
"gigabytes": {"limit": 50, }, "gigabytes": {"limit": 50, },
"snapshot_gigabytes": {"limit": 50, },
"snapshots": {"limit": 10, }, "snapshots": {"limit": 10, },
"share_networks": {"limit": 10, }, "share_networks": {"limit": 10, },
} }
self.assertEqual(result, expected) self.assertEqual(expected, result)
def _stub_get_settable_quotas(self): def _stub_get_settable_quotas(self):
def fake_get_project_quotas(context, resources, project_id, def fake_get_project_quotas(context, resources, project_id,
@ -928,6 +944,7 @@ class DbQuotaDriverTestCase(test.TestCase):
expected = { expected = {
"shares": {"minimum": 0, "maximum": 12, }, "shares": {"minimum": 0, "maximum": 12, },
"gigabytes": {"minimum": 0, "maximum": 1000, }, "gigabytes": {"minimum": 0, "maximum": 1000, },
"snapshot_gigabytes": {"minimum": 0, "maximum": 1000, },
"snapshots": {"minimum": 0, "maximum": 10, }, "snapshots": {"minimum": 0, "maximum": 10, },
"share_networks": {"minimum": 0, "maximum": 10, }, "share_networks": {"minimum": 0, "maximum": 10, },
} }
@ -945,6 +962,7 @@ class DbQuotaDriverTestCase(test.TestCase):
expected = { expected = {
"shares": {"minimum": 0, "maximum": -1, }, "shares": {"minimum": 0, "maximum": -1, },
"gigabytes": {"minimum": 0, "maximum": -1, }, "gigabytes": {"minimum": 0, "maximum": -1, },
"snapshot_gigabytes": {"minimum": 0, "maximum": -1, },
"snapshots": {"minimum": 0, "maximum": -1, }, "snapshots": {"minimum": 0, "maximum": -1, },
"share_networks": {"minimum": 0, "maximum": -1, }, "share_networks": {"minimum": 0, "maximum": -1, },
} }