Default to 0 when merging values in limit check

When merging project_values and user_values after taking the symmetric
difference of their keys, we should use a default value of 0 for the
.get(key) calls because a default value of None will not take
precedence over 0 if 0 is the value in project_values or user_values.
In the buggy case, we end up with a merged value of None instead of 0
because: 'None or 0' is 0 but '0 or None' is None.

Closes-Bug: #1696605

Change-Id: I54a3a52cf5e9b7826dad37c6d1e053ba92cd4fd9
This commit is contained in:
melanie witt 2017-06-07 23:58:25 +00:00
parent c7afbb95e6
commit b1647af290
2 changed files with 16 additions and 3 deletions

View File

@ -609,9 +609,10 @@ class DbQuotaDriver(object):
merged_values = {}
for key in keys_to_merge:
# The key will be either in project_values or user_values based on
# the earlier symmetric_difference.
merged_values[key] = (project_values.get(key) or
user_values.get(key))
# the earlier symmetric_difference. Default to 0 in case the found
# value is 0 and won't take precedence over a None default.
merged_values[key] = (project_values.get(key, 0) or
user_values.get(key, 0))
project_values.pop(key, None)
user_values.pop(key, None)

View File

@ -2492,6 +2492,18 @@ class DbQuotaDriverTestCase(test.TestCase):
for kwarg in kwargs:
self.driver.limit_check_project_and_user(ctxt, resources, **kwarg)
def test_limit_check_project_and_user_zero_values(self):
self._stub_get_project_quotas()
ctxt = FakeContext('test_project', 'test_class')
resources = self._get_fake_countable_resources()
# Check: only project_values, only user_values, and then both.
kwargs = [{'project_values': {'fixed_ips': 0}},
{'user_values': {'key_pairs': 0}},
{'project_values': {'instances': 0},
'user_values': {'instances': 0}}]
for kwarg in kwargs:
self.driver.limit_check_project_and_user(ctxt, resources, **kwarg)
def _stub_quota_reserve(self):
def fake_quota_reserve(context, resources, quotas, user_quotas, deltas,
expire, until_refresh, max_age, project_id=None,