diff --git a/openstack_dashboard/dashboards/project/floating_ips/tests.py b/openstack_dashboard/dashboards/project/floating_ips/tests.py index 1bdfafc4fc..c317884012 100644 --- a/openstack_dashboard/dashboards/project/floating_ips/tests.py +++ b/openstack_dashboard/dashboards/project/floating_ips/tests.py @@ -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'), ]) diff --git a/openstack_dashboard/test/unit/usage/test_quotas.py b/openstack_dashboard/test/unit/usage/test_quotas.py index 5ee948f5d6..9f906648cc 100644 --- a/openstack_dashboard/test/unit/usage/test_quotas.py +++ b/openstack_dashboard/test/unit/usage/test_quotas.py @@ -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( diff --git a/openstack_dashboard/usage/quotas.py b/openstack_dashboard/usage/quotas.py index 39aab80a71..94c6e4b301 100644 --- a/openstack_dashboard/usage/quotas.py +++ b/openstack_dashboard/usage/quotas.py @@ -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]),