diff --git a/nova/quota.py b/nova/quota.py index a94498644280..deba89ec7fbe 100644 --- a/nova/quota.py +++ b/nova/quota.py @@ -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) diff --git a/nova/tests/unit/test_quota.py b/nova/tests/unit/test_quota.py index f0ed60c39f02..12a19a6207d3 100644 --- a/nova/tests/unit/test_quota.py +++ b/nova/tests/unit/test_quota.py @@ -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,