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:
Leandro I. Costantino 2013-12-06 10:52:24 -05:00
parent 059b75625c
commit 340bf16be0
4 changed files with 71 additions and 3 deletions

View File

@ -15,11 +15,13 @@
# under the License.
import copy
import datetime
import logging
from django.core.urlresolvers import reverse # noqa
from django import http
from django.test.utils import override_settings # noqa
from django.utils import timezone
from mox import IgnoreArg # noqa
from mox import IsA # noqa
@ -30,6 +32,7 @@ from horizon.workflows import views
from openstack_dashboard import api
from openstack_dashboard.dashboards.admin.projects import workflows
from openstack_dashboard.test import helpers as test
from openstack_dashboard import usage
from openstack_dashboard.usage import quotas
from selenium.webdriver import ActionChains # noqa
@ -1446,6 +1449,66 @@ class UpdateProjectWorkflowTests(test.BaseAdminViewTests):
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):
@test.create_stubs(
{api.keystone: ('tenant_list', 'tenant_get', 'tenant_update')})

View File

@ -29,6 +29,6 @@ urlpatterns = patterns('',
url(r'^create$', views.CreateProjectView.as_view(), name='create'),
url(r'^(?P<tenant_id>[^/]+)/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'),
)

View File

@ -34,7 +34,8 @@ from openstack_dashboard.dashboards.admin.projects \
import tables as project_tables
from openstack_dashboard.dashboards.admin.projects \
import workflows as project_workflows
from openstack_dashboard.dashboards.project.overview \
import views as project_views
PROJECT_INFO_FIELDS = ("domain_id",
"domain_name",
@ -94,6 +95,8 @@ class ProjectUsageView(usage.UsageView):
table_class = usage.ProjectUsageTable
usage_class = usage.ProjectUsage
template_name = 'admin/projects/usage.html'
csv_response_class = project_views.ProjectUsageCsvRenderer
csv_template_name = 'project/overview/usage.csv'
def get_data(self):
super(ProjectUsageView, self).get_data()

View File

@ -18,6 +18,7 @@ from openstack_dashboard.usage import base
class UsageView(tables.DataTableView):
usage_class = None
show_terminated = True
csv_template_name = None
def __init__(self, *args, **kwargs):
super(UsageView, self).__init__(*args, **kwargs)
@ -27,7 +28,8 @@ class UsageView(tables.DataTableView):
def get_template_names(self):
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
def get_content_type(self):