quota: Move targets argument to get_disabled_quotas

In addition, unnecessary API calls determined by 'targets'
are now removed.

blueprint make-quotas-great-again
Change-Id: I77b1335c25f2e2f3952e0d3c59f8c89a2bad3195
This commit is contained in:
Akihiro Motoki 2017-12-09 19:59:27 +09:00
parent 0e0db28969
commit 06ca3c811b
3 changed files with 77 additions and 60 deletions

View File

@ -339,13 +339,11 @@ class FloatingIpViewTests(test.TestCase):
'is_extension_supported',
'is_router_enabled',
'tenant_quota_get'),
api.base: ('is_service_enabled',),
api.cinder: ('is_volume_service_enabled',)})
api.base: ('is_service_enabled',)})
@test.update_settings(OPENSTACK_NEUTRON_NETWORK={'enable_quotas': True})
def test_correct_quotas_displayed(self):
self.mock_is_volume_service_enabled.return_value = False
self.mock_is_service_enabled.side_effect = [True, True]
self.mock_is_extension_supported.side_effect = [True, True, False]
self.mock_is_service_enabled.return_value = True
self.mock_is_extension_supported.side_effect = [True, False]
self.mock_is_router_enabled.return_value = True
self.mock_tenant_quota_get.return_value = self.neutron_quotas.first()
self.mock_tenant_floating_ip_list.return_value = \
@ -357,16 +355,10 @@ class FloatingIpViewTests(test.TestCase):
self.assertEqual(res.context['usages']['floatingip']['quota'],
self.neutron_quotas.first().get('floatingip').limit)
self.mock_is_volume_service_enabled.assert_called_once_with(
test.IsHttpRequest())
self.assertEqual(2, self.mock_is_service_enabled.call_count)
self.mock_is_service_enabled.assert_has_calls([
mock.call(test.IsHttpRequest(), 'network'),
mock.call(test.IsHttpRequest(), 'compute'),
])
self.assertEqual(3, self.mock_is_extension_supported.call_count)
self.mock_is_service_enabled.assert_called_once_with(
test.IsHttpRequest(), 'network')
self.assertEqual(2, self.mock_is_extension_supported.call_count)
self.mock_is_extension_supported.assert_has_calls([
mock.call(test.IsHttpRequest(), 'security-group'),
mock.call(test.IsHttpRequest(), 'quotas'),
mock.call(test.IsHttpRequest(), 'quota_details'),
])

View File

@ -50,8 +50,10 @@ class QuotaTests(test.APITestCase):
self.mock_is_volume_service_enabled.return_value = volume_enabled
def _check_service_enabled(self, expected_count):
self.mock_is_volume_service_enabled.assert_called_once_with(
test.IsHttpRequest())
expected_volume_count = expected_count.pop('volume', 0)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_is_volume_service_enabled, expected_volume_count,
mock.call(test.IsHttpRequest()))
self.assertEqual(expected_count, self._service_call_count)
total_count = sum(expected_count.values())
self.assertEqual(total_count, self.mock_is_service_enabled.call_count)
@ -144,7 +146,7 @@ class QuotaTests(test.APITestCase):
# Compare available resources
self.assertAvailableQuotasEqual(expected_output, quota_usages.usages)
self._check_service_enabled({'compute': 2, 'network': 1})
self._check_service_enabled({'compute': 2, 'network': 1, 'volume': 1})
self.mock_nova_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest(), reserved=True, tenant_id=tenant_id)
self.mock_cinder_tenant_absolute_limits.assert_called_once_with(
@ -183,11 +185,13 @@ class QuotaTests(test.APITestCase):
self.assertAvailableQuotasEqual(expected_output, quota_usages.usages)
if with_compute and nova_quotas_enabled:
self._check_service_enabled({'compute': 2, 'network': 1})
self._check_service_enabled({'compute': 2, 'network': 1,
'volume': 1})
self.mock_nova_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest(), reserved=True, tenant_id=tenant_id)
else:
self._check_service_enabled({'compute': 1, 'network': 1})
self._check_service_enabled({'compute': 1, 'network': 1,
'volume': 1})
self.mock_nova_tenant_absolute_limits.assert_not_called()
if with_volume:
self.mock_cinder_tenant_absolute_limits.assert_called_once_with(
@ -220,7 +224,7 @@ class QuotaTests(test.APITestCase):
quotas.NOVA_QUOTA_FIELDS)
self.assertItemsEqual(result_quotas, expected_quotas)
self._check_service_enabled({'compute': 1, 'network': 1})
self._check_service_enabled({'compute': 1, 'network': 1, 'volume': 1})
@test.create_mocks({api.nova: ('tenant_absolute_limits',),
api.base: ('is_service_enabled',),
@ -242,7 +246,7 @@ class QuotaTests(test.APITestCase):
self.assertIn('ram', quota_usages)
self.assertIsNotNone(quota_usages.get('ram'))
self._check_service_enabled({'compute': 2, 'network': 1})
self._check_service_enabled({'compute': 2, 'network': 1, 'volume': 1})
self.mock_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest(), reserved=True, tenant_id=tenant_id)
@ -264,7 +268,7 @@ class QuotaTests(test.APITestCase):
# Compare internal structure of usages to expected.
self.assertItemsEqual(expected_output, quota_usages.usages)
self._check_service_enabled({'compute': 2, 'network': 1})
self._check_service_enabled({'compute': 2, 'network': 1, 'volume': 1})
self.mock_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest(), reserved=True, tenant_id='1')
@ -293,7 +297,7 @@ class QuotaTests(test.APITestCase):
# Compare internal structure of usages to expected.
self.assertItemsEqual(expected_output, quota_usages.usages)
self._check_service_enabled({'compute': 2, 'network': 1})
self._check_service_enabled({'compute': 2, 'network': 1, 'volume': 1})
self.mock_nova_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest(), reserved=True, tenant_id=tenant_id)
self.mock_cinder_tenant_absolute_limits.assert_called_once_with(
@ -319,7 +323,7 @@ class QuotaTests(test.APITestCase):
# Compare internal structure of usages to expected.
self.assertItemsEqual(expected_output, quota_usages.usages)
self._check_service_enabled({'compute': 2, 'network': 1})
self._check_service_enabled({'compute': 2, 'network': 1, 'volume': 1})
self.mock_nova_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest(), reserved=True, tenant_id=tenant_id)
self.mock_cinder_tenant_absolute_limits.assert_called_once_with(
@ -336,7 +340,7 @@ class QuotaTests(test.APITestCase):
quotas.get_tenant_quota_data(self.request)
self._check_service_enabled({'compute': 1, 'network': 1})
self._check_service_enabled({'compute': 1, 'network': 1, 'volume': 1})
self.mock_tenant_quota_get.assert_called_once_with(
test.IsHttpRequest(), '1')
self.mock_handle.assert_called_once_with(
@ -384,7 +388,7 @@ class QuotaTests(test.APITestCase):
expected = set(['router', 'floatingip'])
self.assertEqual(expected, disabled_quotas)
self._check_service_enabled({'compute': 1, 'network': 1})
self._check_service_enabled({'compute': 1, 'network': 1, 'volume': 1})
self.mock_is_extension_supported.assert_called_once_with(
test.IsHttpRequest(), 'security-group')
self.mock_is_router_enabled.assert_called_once_with(
@ -393,11 +397,12 @@ class QuotaTests(test.APITestCase):
test.IsHttpRequest())
def test_tenant_quota_usages_with_target_instances(self):
self._test_tenant_quota_usages_with_target(targets=('instances', ))
self._test_tenant_quota_usages_with_target(
targets=('instances', ), use_cinder_call=False)
def test_tenant_quota_usages_with_target_ram(self):
self._test_tenant_quota_usages_with_target(
targets=('ram', ), use_flavor_list=True)
targets=('ram', ), use_flavor_list=True, use_cinder_call=False)
def test_tenant_quota_usages_with_target_volume(self):
self._test_tenant_quota_usages_with_target(
@ -439,12 +444,16 @@ class QuotaTests(test.APITestCase):
# Compare available resources
self.assertAvailableQuotasEqual(expected, quota_usages.usages)
expected_count = {}
if use_compute_call:
expected_count['compute'] = 2
if use_cinder_call:
expected_count['volume'] = 1
self._check_service_enabled(expected_count)
if use_compute_call:
self._check_service_enabled({'compute': 2, 'network': 1})
self.mock_nova_tenant_absolute_limits.assert_called_once_with(
test.IsHttpRequest(), reserved=True, tenant_id=tenant_id)
else:
self._check_service_enabled({'compute': 1, 'network': 1})
self.mock_nova_tenant_absolute_limits.assert_not_called()
if use_cinder_call:
self.mock_cinder_tenant_absolute_limits.assert_called_once_with(
@ -478,10 +487,10 @@ class QuotaTests(test.APITestCase):
'router_list')})
def _test_tenant_quota_usages_neutron_with_target(self, targets):
self._mock_service_enabled(network_enabled=True)
self.mock_is_extension_supported.side_effect = [
True, # security-group
False, # quota_details
]
if 'security_group' in targets:
self.mock_is_extension_supported.side_effect = [True, False]
else:
self.mock_is_extension_supported.side_effect = [False]
self.mock_is_router_enabled.return_value = True
self.mock_is_quotas_extension_supported.return_value = True
self.mock_tenant_quota_get.return_value = self.neutron_quotas.first()
@ -526,14 +535,21 @@ class QuotaTests(test.APITestCase):
# Compare available resources
self.assertAvailableQuotasEqual(expected, quota_usages.usages)
self._check_service_enabled({'compute': 1, 'network': 1})
self.mock_is_extension_supported.assert_has_calls([
mock.call(test.IsHttpRequest(), 'security-group'),
mock.call(test.IsHttpRequest(), 'quota_details'),
])
self.assertEqual(2, self.mock_is_extension_supported.call_count)
self.mock_is_router_enabled.assert_called_once_with(
test.IsHttpRequest())
self._check_service_enabled({'network': 1})
if 'security_group' in targets:
self.mock_is_extension_supported.assert_has_calls([
mock.call(test.IsHttpRequest(), 'security-group'),
mock.call(test.IsHttpRequest(), 'quota_details'),
])
self.assertEqual(2, self.mock_is_extension_supported.call_count)
else:
self.mock_is_extension_supported.assert_called_once_with(
test.IsHttpRequest(), 'quota_details')
if 'floatingip' in targets or 'router' in targets:
self.mock_is_router_enabled.assert_called_once_with(
test.IsHttpRequest())
else:
self.mock_is_router_enabled.assert_not_called()
self.mock_is_quotas_extension_supported.assert_called_once_with(
test.IsHttpRequest())
self.mock_tenant_quota_get.assert_called_once_with(

View File

@ -234,23 +234,36 @@ def get_tenant_quota_data(request, disabled_quotas=None, tenant_id=None):
# It is confusing and makes the code complicated. They should be push away.
# Check Identity Project panel and System Defaults panel too.
@profiler.trace
def get_disabled_quotas(request):
def get_disabled_quotas(request, targets=None):
if targets:
if set(targets) - QUOTA_FIELDS:
raise ValueError('Unknown quota field names are included: %s'
% set(targets) - QUOTA_FIELDS)
candidates = set(targets)
else:
candidates = QUOTA_FIELDS
# We no longer supports nova network, so we always disable
# network related nova quota fields.
disabled_quotas = set()
# Cinder
if not cinder.is_volume_service_enabled(request):
disabled_quotas.update(CINDER_QUOTA_FIELDS)
if candidates & CINDER_QUOTA_FIELDS:
if not cinder.is_volume_service_enabled(request):
disabled_quotas.update(CINDER_QUOTA_FIELDS)
# Neutron
if not base.is_service_enabled(request, 'network'):
if not (candidates & NEUTRON_QUOTA_FIELDS):
pass
elif not base.is_service_enabled(request, 'network'):
disabled_quotas.update(NEUTRON_QUOTA_FIELDS)
else:
if not neutron.is_extension_supported(request, 'security-group'):
if ({'security_group', 'security_group_rule'} & candidates and
not neutron.is_extension_supported(request, 'security-group')):
disabled_quotas.update(['security_group', 'security_group_rule'])
if not neutron.is_router_enabled(request):
if ({'router', 'floatingip'} & candidates and
not neutron.is_router_enabled(request)):
disabled_quotas.update(['router', 'floatingip'])
try:
@ -261,9 +274,13 @@ def get_disabled_quotas(request):
"quotas extension is enabled.")
# Nova
if not (base.is_service_enabled(request, 'compute') and
nova.can_set_quotas()):
disabled_quotas.update(NOVA_QUOTA_FIELDS)
if candidates & NOVA_QUOTA_FIELDS:
if not (base.is_service_enabled(request, 'compute') and
nova.can_set_quotas()):
disabled_quotas.update(NOVA_QUOTA_FIELDS)
enabled_quotas = candidates - disabled_quotas
disabled_quotas = set(QUOTA_FIELDS) - enabled_quotas
# There appear to be no glance quota fields currently
return disabled_quotas
@ -405,17 +422,9 @@ def tenant_quota_usages(request, tenant_id=None, targets=None):
if not tenant_id:
tenant_id = request.user.project_id
disabled_quotas = get_disabled_quotas(request)
disabled_quotas = get_disabled_quotas(request, targets)
usages = QuotaUsage()
if targets:
if set(targets) - QUOTA_FIELDS:
raise ValueError('Unknown quota field names are included: %s'
% set(targets) - QUOTA_FIELDS)
enabled_quotas = set(QUOTA_FIELDS) - disabled_quotas
enabled_quotas &= set(targets)
disabled_quotas = set(QUOTA_FIELDS) - enabled_quotas
futurist_utils.call_functions_parallel(
(_get_tenant_compute_usages,
[request, usages, disabled_quotas, tenant_id]),