Handle negative values in total*Used for Cinder absolute limits

In some cases negative values can be returned for resources currently
in use. When this occurs, the project overview page fails with an
error 500 due to an OverflowError, "cannot convert float infinity to
integer". Handle this case more gracefully.

Change-Id: Id1ad16eafdde906dc74bfafc7f72ea8d3bdcdc8f
Closes-Bug: #1386687
This commit is contained in:
Julie Pichon 2014-10-28 13:02:15 +00:00
parent 4a9424781e
commit 53c7dc022e
2 changed files with 33 additions and 3 deletions

View File

@ -482,9 +482,16 @@ def tenant_absolute_limits(request):
limits = cinderclient(request).limits.get().absolute
limits_dict = {}
for limit in limits:
# -1 is used to represent unlimited quotas
if limit.value == -1:
limits_dict[limit.name] = float("inf")
if limit.value < 0:
# In some cases, the absolute limits data in Cinder can get
# out of sync causing the total.*Used limits to return
# negative values instead of 0. For such cases, replace
# negative values with 0.
if limit.name.startswith('total') and limit.name.endswith('Used'):
limits_dict[limit.name] = 0
else:
# -1 is used to represent unlimited quotas
limits_dict[limit.name] = float("inf")
else:
limits_dict[limit.name] = limit.value
return limits_dict

View File

@ -13,6 +13,7 @@
# under the License.
from django.test.utils import override_settings
import six
import cinderclient as cinder_client
@ -86,6 +87,28 @@ class CinderApiTests(test.APITestCase):
associate_spec = assoc_vol_types[0].associated_qos_spec
self.assertTrue(associate_spec, qos_specs_only_one[0].name)
def test_absolute_limits_with_negative_values(self):
values = {"maxTotalVolumes": -1, "totalVolumesUsed": -1}
expected_results = {"maxTotalVolumes": float("inf"),
"totalVolumesUsed": 0}
limits = self.mox.CreateMockAnything()
limits.absolute = []
for key, val in six.iteritems(values):
limit = self.mox.CreateMockAnything()
limit.name = key
limit.value = val
limits.absolute.append(limit)
cinderclient = self.stub_cinderclient()
cinderclient.limits = self.mox.CreateMockAnything()
cinderclient.limits.get().AndReturn(limits)
self.mox.ReplayAll()
ret_val = api.cinder.tenant_absolute_limits(self.request)
for key in expected_results.keys():
self.assertEqual(expected_results[key], ret_val[key])
class CinderApiVersionTests(test.TestCase):