Lazy load a project quotas's default values
A project quotas's default values should only be retrieved once we know they are going to be used. This becomes more important with nested quotas where a get_defaults call may require calling get_project in Keystone. As part of this change, code was re-arranged to be more readable by removing three layers of a.get('x', b.get('y', c.get('z'))), but the underlying behavior has not been changed. Change-Id: I3ea3f6810f2834ae8283449d58642e82189671a7 Depends-On: Ibbd6f47c370d8f10c08cba358574b55e3059dcd1
This commit is contained in:
parent
a63bfeac76
commit
199162ed07
@ -188,6 +188,7 @@ class DbQuotaDriver(object):
|
||||
quotas = {}
|
||||
project_quotas = db.quota_get_all_by_project(context, project_id)
|
||||
allocated_quotas = None
|
||||
default_quotas = None
|
||||
if usages:
|
||||
project_usages = db.quota_usage_get_all_by_project(context,
|
||||
project_id)
|
||||
@ -206,20 +207,22 @@ class DbQuotaDriver(object):
|
||||
else:
|
||||
class_quotas = {}
|
||||
|
||||
# TODO(mc_nair): change this to be lazy loaded
|
||||
default_quotas = self.get_defaults(context, resources, project_id)
|
||||
|
||||
for resource in resources.values():
|
||||
# Omit default/quota class values
|
||||
if not defaults and resource.name not in project_quotas:
|
||||
continue
|
||||
|
||||
quotas[resource.name] = dict(
|
||||
limit=project_quotas.get(
|
||||
resource.name,
|
||||
class_quotas.get(resource.name,
|
||||
default_quotas[resource.name])),
|
||||
)
|
||||
quota_val = project_quotas.get(resource.name)
|
||||
if quota_val is None:
|
||||
quota_val = class_quotas.get(resource.name)
|
||||
if quota_val is None:
|
||||
# Lazy load the default quotas
|
||||
if default_quotas is None:
|
||||
default_quotas = self.get_defaults(
|
||||
context, resources, project_id)
|
||||
quota_val = default_quotas[resource.name]
|
||||
|
||||
quotas[resource.name] = {'limit': quota_val}
|
||||
|
||||
# Include usages if desired. This is optional because one
|
||||
# internal consumer of this interface wants to access the
|
||||
|
@ -1062,6 +1062,24 @@ class DbQuotaDriverTestCase(DbQuotaDriverBaseTestCase):
|
||||
reserved= 0)
|
||||
), result)
|
||||
|
||||
@mock.patch('cinder.quota.db.quota_get_all_by_project')
|
||||
@mock.patch('cinder.quota.db.quota_class_get_default')
|
||||
def test_get_project_quotas_lazy_load_defaults(
|
||||
self, mock_defaults, mock_quotas):
|
||||
mock_quotas.return_value = self._default_quotas_non_child
|
||||
self.driver.get_project_quotas(
|
||||
FakeContext('test_project', None),
|
||||
quota.QUOTAS.resources, 'test_project', usages=False)
|
||||
# Shouldn't load a project's defaults if all the quotas are already
|
||||
# defined in the DB
|
||||
self.assertFalse(mock_defaults.called)
|
||||
|
||||
mock_quotas.return_value = {}
|
||||
self.driver.get_project_quotas(
|
||||
FakeContext('test_project', None),
|
||||
quota.QUOTAS.resources, 'test_project', usages=False)
|
||||
self.assertTrue(mock_defaults.called)
|
||||
|
||||
def test_get_root_project_with_subprojects_quotas(self):
|
||||
self._stub_get_by_project()
|
||||
self._stub_volume_type_get_all()
|
||||
@ -1170,8 +1188,7 @@ class DbQuotaDriverTestCase(DbQuotaDriverBaseTestCase):
|
||||
|
||||
self.assertEqual(['quota_get_all_by_project',
|
||||
'quota_usage_get_all_by_project',
|
||||
'quota_class_get_all_by_name',
|
||||
'quota_class_get_default', ], self.calls)
|
||||
'quota_class_get_all_by_name'], self.calls)
|
||||
self.assertEqual(dict(backups=dict(limit=10,
|
||||
in_use=2,
|
||||
reserved=0, ),
|
||||
|
Loading…
x
Reference in New Issue
Block a user