CSV Summary not working inside Admin panel.
When browsing Project usages from 'Admin->Projects->More->View Usages' an AttributeError exception is thrown due to missing csv_render_class attribute. Also, project_id instead of tenant_id in BaseUsage were expected, so any request to /admin/projects/[id]/usage/ will always return the current tenant from session. This fix reuse logic from project/overview/ into this view. Change-Id: I7d762569a7de176fdb8545a226e563afac34adae Closes-Bug: #1255667
This commit is contained in:
parent
059b75625c
commit
340bf16be0
@ -15,11 +15,13 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.core.urlresolvers import reverse # noqa
|
from django.core.urlresolvers import reverse # noqa
|
||||||
from django import http
|
from django import http
|
||||||
from django.test.utils import override_settings # noqa
|
from django.test.utils import override_settings # noqa
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from mox import IgnoreArg # noqa
|
from mox import IgnoreArg # noqa
|
||||||
from mox import IsA # noqa
|
from mox import IsA # noqa
|
||||||
@ -30,6 +32,7 @@ from horizon.workflows import views
|
|||||||
from openstack_dashboard import api
|
from openstack_dashboard import api
|
||||||
from openstack_dashboard.dashboards.admin.projects import workflows
|
from openstack_dashboard.dashboards.admin.projects import workflows
|
||||||
from openstack_dashboard.test import helpers as test
|
from openstack_dashboard.test import helpers as test
|
||||||
|
from openstack_dashboard import usage
|
||||||
from openstack_dashboard.usage import quotas
|
from openstack_dashboard.usage import quotas
|
||||||
|
|
||||||
from selenium.webdriver import ActionChains # noqa
|
from selenium.webdriver import ActionChains # noqa
|
||||||
@ -1446,6 +1449,66 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
|
|||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
|
||||||
|
class UsageViewTests(test.BaseAdminViewTests):
|
||||||
|
def _stub_nova_api_calls(self, nova_stu_enabled=True):
|
||||||
|
self.mox.StubOutWithMock(api.nova, 'usage_get')
|
||||||
|
self.mox.StubOutWithMock(api.nova, 'tenant_absolute_limits')
|
||||||
|
self.mox.StubOutWithMock(api.nova, 'extension_supported')
|
||||||
|
api.nova.extension_supported(
|
||||||
|
'SimpleTenantUsage', IsA(http.HttpRequest)) \
|
||||||
|
.AndReturn(nova_stu_enabled)
|
||||||
|
|
||||||
|
def _stub_neutron_api_calls(self, neutron_sg_enabled=True):
|
||||||
|
self.mox.StubOutWithMock(api.neutron, 'is_extension_supported')
|
||||||
|
self.mox.StubOutWithMock(api.network, 'tenant_floating_ip_list')
|
||||||
|
if neutron_sg_enabled:
|
||||||
|
self.mox.StubOutWithMock(api.network, 'security_group_list')
|
||||||
|
api.neutron.is_extension_supported(
|
||||||
|
IsA(http.HttpRequest),
|
||||||
|
'security-group').AndReturn(neutron_sg_enabled)
|
||||||
|
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
|
||||||
|
.AndReturn(self.floating_ips.list())
|
||||||
|
if neutron_sg_enabled:
|
||||||
|
api.network.security_group_list(IsA(http.HttpRequest)) \
|
||||||
|
.AndReturn(self.q_secgroups.list())
|
||||||
|
|
||||||
|
def test_usage_csv(self):
|
||||||
|
self._test_usage_csv(nova_stu_enabled=True)
|
||||||
|
|
||||||
|
def test_usage_csv_disabled(self):
|
||||||
|
self._test_usage_csv(nova_stu_enabled=False)
|
||||||
|
|
||||||
|
def _test_usage_csv(self, nova_stu_enabled=True):
|
||||||
|
now = timezone.now()
|
||||||
|
usage_obj = api.nova.NovaUsage(self.usages.first())
|
||||||
|
self._stub_nova_api_calls(nova_stu_enabled)
|
||||||
|
api.nova.extension_supported(
|
||||||
|
'SimpleTenantUsage', IsA(http.HttpRequest)) \
|
||||||
|
.AndReturn(nova_stu_enabled)
|
||||||
|
start = datetime.datetime(now.year, now.month, now.day, 0, 0, 0, 0)
|
||||||
|
end = datetime.datetime(now.year, now.month, now.day, 23, 59, 59, 0)
|
||||||
|
|
||||||
|
if nova_stu_enabled:
|
||||||
|
api.nova.usage_get(IsA(http.HttpRequest),
|
||||||
|
self.tenant.id,
|
||||||
|
start, end).AndReturn(usage_obj)
|
||||||
|
api.nova.tenant_absolute_limits(IsA(http.HttpRequest))\
|
||||||
|
.AndReturn(self.limits['absolute'])
|
||||||
|
self._stub_neutron_api_calls()
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
project_id = self.tenants.first().id
|
||||||
|
csv_url = reverse('horizon:admin:projects:usage',
|
||||||
|
args=[project_id]) + "?format=csv"
|
||||||
|
res = self.client.get(csv_url)
|
||||||
|
self.assertTemplateUsed(res, 'project/overview/usage.csv')
|
||||||
|
|
||||||
|
self.assertTrue(isinstance(res.context['usage'], usage.ProjectUsage))
|
||||||
|
hdr = ('Instance Name,VCPUs,Ram (MB),Disk (GB),Usage (Hours),'
|
||||||
|
'Uptime(Seconds),State')
|
||||||
|
self.assertContains(res, '%s\r\n' % hdr)
|
||||||
|
|
||||||
|
|
||||||
class SeleniumTests(test.SeleniumAdminTestCase):
|
class SeleniumTests(test.SeleniumAdminTestCase):
|
||||||
@test.create_stubs(
|
@test.create_stubs(
|
||||||
{api.keystone: ('tenant_list', 'tenant_get', 'tenant_update')})
|
{api.keystone: ('tenant_list', 'tenant_get', 'tenant_update')})
|
||||||
|
@ -29,6 +29,6 @@ urlpatterns = patterns('',
|
|||||||
url(r'^create$', views.CreateProjectView.as_view(), name='create'),
|
url(r'^create$', views.CreateProjectView.as_view(), name='create'),
|
||||||
url(r'^(?P<tenant_id>[^/]+)/update/$',
|
url(r'^(?P<tenant_id>[^/]+)/update/$',
|
||||||
views.UpdateProjectView.as_view(), name='update'),
|
views.UpdateProjectView.as_view(), name='update'),
|
||||||
url(r'^(?P<tenant_id>[^/]+)/usage/$',
|
url(r'^(?P<project_id>[^/]+)/usage/$',
|
||||||
views.ProjectUsageView.as_view(), name='usage'),
|
views.ProjectUsageView.as_view(), name='usage'),
|
||||||
)
|
)
|
||||||
|
@ -34,7 +34,8 @@ from openstack_dashboard.dashboards.admin.projects \
|
|||||||
import tables as project_tables
|
import tables as project_tables
|
||||||
from openstack_dashboard.dashboards.admin.projects \
|
from openstack_dashboard.dashboards.admin.projects \
|
||||||
import workflows as project_workflows
|
import workflows as project_workflows
|
||||||
|
from openstack_dashboard.dashboards.project.overview \
|
||||||
|
import views as project_views
|
||||||
|
|
||||||
PROJECT_INFO_FIELDS = ("domain_id",
|
PROJECT_INFO_FIELDS = ("domain_id",
|
||||||
"domain_name",
|
"domain_name",
|
||||||
@ -94,6 +95,8 @@ class ProjectUsageView(usage.UsageView):
|
|||||||
table_class = usage.ProjectUsageTable
|
table_class = usage.ProjectUsageTable
|
||||||
usage_class = usage.ProjectUsage
|
usage_class = usage.ProjectUsage
|
||||||
template_name = 'admin/projects/usage.html'
|
template_name = 'admin/projects/usage.html'
|
||||||
|
csv_response_class = project_views.ProjectUsageCsvRenderer
|
||||||
|
csv_template_name = 'project/overview/usage.csv'
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
super(ProjectUsageView, self).get_data()
|
super(ProjectUsageView, self).get_data()
|
||||||
|
@ -18,6 +18,7 @@ from openstack_dashboard.usage import base
|
|||||||
class UsageView(tables.DataTableView):
|
class UsageView(tables.DataTableView):
|
||||||
usage_class = None
|
usage_class = None
|
||||||
show_terminated = True
|
show_terminated = True
|
||||||
|
csv_template_name = None
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(UsageView, self).__init__(*args, **kwargs)
|
super(UsageView, self).__init__(*args, **kwargs)
|
||||||
@ -27,7 +28,8 @@ class UsageView(tables.DataTableView):
|
|||||||
|
|
||||||
def get_template_names(self):
|
def get_template_names(self):
|
||||||
if self.request.GET.get('format', 'html') == 'csv':
|
if self.request.GET.get('format', 'html') == 'csv':
|
||||||
return ".".join((self.template_name.rsplit('.', 1)[0], 'csv'))
|
return (self.csv_template_name or
|
||||||
|
".".join((self.template_name.rsplit('.', 1)[0], 'csv')))
|
||||||
return self.template_name
|
return self.template_name
|
||||||
|
|
||||||
def get_content_type(self):
|
def get_content_type(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user