Fixes Nonetype error of flavor info in intances index view

Adds unit test for the changes.

Bug#981269

Change-Id: I7e3ab027e9c11defcdd9d3d90e41462433666600
This commit is contained in:
Ke Wu
2012-06-21 10:28:48 -07:00
parent c748df7c51
commit 8d63b31204
4 changed files with 162 additions and 27 deletions

View File

@@ -20,6 +20,7 @@
from django import http
from django.core.urlresolvers import reverse
from django.utils.datastructures import SortedDict
from mox import IsA
from horizon import api
@@ -90,3 +91,63 @@ class InstancesAndVolumesViewTest(test.TestCase):
self.assertTemplateUsed(res,
'nova/instances_and_volumes/index.html')
self.assertEqual(len(res.context['instances_table'].data), 0)
@test.create_stubs({api: ('flavor_list', 'server_list',
'flavor_get', 'volume_list',)})
def test_index_flavor_list_exception(self):
servers = self.servers.list()
flavors = self.flavors.list()
volumes = self.volumes.list()
full_flavors = SortedDict([(f.id, f) for f in flavors])
api.server_list(IsA(http.HttpRequest)).AndReturn(servers)
api.flavor_list(IsA(http.HttpRequest)).AndRaise(self.exceptions.nova)
for server in servers:
api.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
AndReturn(full_flavors[server.flavor["id"]])
api.volume_list(IsA(http.HttpRequest)).AndReturn(volumes)
self.mox.ReplayAll()
res = self.client.get(
reverse('horizon:nova:instances_and_volumes:index'))
self.assertTemplateUsed(res,
'nova/instances_and_volumes/index.html')
instances = res.context['instances_table'].data
volumes = res.context['volumes_table'].data
self.assertItemsEqual(instances, self.servers.list())
self.assertItemsEqual(volumes, self.volumes.list())
@test.create_stubs({api: ('flavor_list', 'server_list',
'flavor_get', 'volume_list',)})
def test_index_flavor_get_exception(self):
servers = self.servers.list()
flavors = self.flavors.list()
volumes = self.volumes.list()
max_id = max([int(flavor.id) for flavor in flavors])
for server in servers:
max_id += 1
server.flavor["id"] = max_id
api.server_list(IsA(http.HttpRequest)).AndReturn(servers)
api.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
for server in servers:
api.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
AndRaise(self.exceptions.nova)
api.volume_list(IsA(http.HttpRequest)).AndReturn(volumes)
self.mox.ReplayAll()
res = self.client.get(
reverse('horizon:nova:instances_and_volumes:index'))
instances = res.context['instances_table'].data
volumes = res.context['volumes_table'].data
self.assertTemplateUsed(res,
'nova/instances_and_volumes/index.html')
self.assertMessageCount(res, error=len(servers))
self.assertItemsEqual(instances, self.servers.list())
self.assertItemsEqual(volumes, self.volumes.list())

View File

@@ -54,14 +54,27 @@ class IndexView(tables.MultiTableView):
if instances:
try:
flavors = api.flavor_list(self.request)
full_flavors = SortedDict([(str(flavor.id), flavor)
for flavor in flavors])
for instance in instances:
flavor_id = instance.flavor["id"]
instance.full_flavor = full_flavors[flavor_id]
except:
msg = _('Unable to retrieve instance size information.')
exceptions.handle(self.request, msg)
# If fails to retrieve flavor list, creates an empty list.
flavors = []
full_flavors = SortedDict([(str(flavor.id), flavor)
for flavor in flavors])
# Loop through instances to get flavor info.
for instance in instances:
try:
flavor_id = instance.flavor["id"]
if flavor_id in full_flavors:
instance.full_flavor = full_flavors[flavor_id]
else:
# If the flavor_id is not in full_flavors list,
# gets it via nova api.
instance.full_flavor = api.flavor_get(
self.request, flavor_id)
except:
msg = _('Unable to retrieve instance \
size information.')
exceptions.handle(self.request, msg)
self._instances = instances
return self._instances

View File

@@ -16,6 +16,7 @@
from django import http
from django.core.urlresolvers import reverse
from django.utils.datastructures import SortedDict
from mox import IsA
from novaclient import exceptions as novaclient_exceptions
@@ -24,13 +25,12 @@ from horizon import test
class InstanceViewTest(test.BaseAdminViewTests):
@test.create_stubs({api.nova: ('flavor_list', 'server_list',),
api.keystone: ('tenant_list',)})
def test_index(self):
servers = self.servers.list()
flavors = self.flavors.list()
tenants = self.tenants.list()
self.mox.StubOutWithMock(api.nova, 'server_list')
self.mox.StubOutWithMock(api.nova, 'flavor_list')
self.mox.StubOutWithMock(api.keystone, 'tenant_list')
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True).\
AndReturn(tenants)
api.nova.server_list(IsA(http.HttpRequest),
@@ -43,9 +43,63 @@ class InstanceViewTest(test.BaseAdminViewTests):
instances = res.context['table'].data
self.assertItemsEqual(instances, servers)
@test.create_stubs({api.nova: ('flavor_list', 'flavor_get',
'server_list',),
api.keystone: ('tenant_list',)})
def test_index_flavor_list_exception(self):
servers = self.servers.list()
tenants = self.tenants.list()
flavors = self.flavors.list()
full_flavors = SortedDict([(f.id, f) for f in flavors])
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(servers)
api.nova.flavor_list(IsA(http.HttpRequest)). \
AndRaise(self.exceptions.nova)
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True).\
AndReturn(tenants)
for server in servers:
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
AndReturn(full_flavors[server.flavor["id"]])
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:syspanel:instances:index'))
self.assertTemplateUsed(res, 'syspanel/instances/index.html')
instances = res.context['table'].data
self.assertItemsEqual(instances, servers)
@test.create_stubs({api.nova: ('flavor_list', 'flavor_get',
'server_list',),
api.keystone: ('tenant_list',)})
def test_index_flavor_get_exception(self):
servers = self.servers.list()
flavors = self.flavors.list()
tenants = self.tenants.list()
max_id = max([int(flavor.id) for flavor in flavors])
for server in servers:
max_id += 1
server.flavor["id"] = max_id
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(servers)
api.nova.flavor_list(IsA(http.HttpRequest)). \
AndReturn(flavors)
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True).\
AndReturn(tenants)
for server in servers:
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
AndRaise(self.exceptions.nova)
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:syspanel:instances:index'))
instances = res.context['table'].data
self.assertTemplateUsed(res, 'syspanel/instances/index.html')
self.assertMessageCount(res, error=len(servers))
self.assertItemsEqual(instances, servers)
@test.create_stubs({api.nova: ('server_list',)})
def test_index_server_list_exception(self):
self.mox.StubOutWithMock(api.nova, 'server_list')
self.mox.StubOutWithMock(api.nova, 'flavor_list')
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndRaise(self.exceptions.nova)
@@ -55,14 +109,13 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertTemplateUsed(res, 'syspanel/instances/index.html')
self.assertEqual(len(res.context['instances_table'].data), 0)
@test.create_stubs({api: ('server_get', 'flavor_get',),
api.keystone: ('tenant_get',)})
def test_ajax_loading_instances(self):
server = self.servers.first()
flavor = self.flavors.list()[0]
tenant = self.tenants.list()[0]
self.mox.StubOutWithMock(api, 'server_get')
self.mox.StubOutWithMock(api, 'flavor_get')
self.mox.StubOutWithMock(api.keystone, 'tenant_get')
api.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
api.flavor_get(IsA(http.HttpRequest),
server.flavor['id']).AndReturn(flavor)
@@ -86,6 +139,11 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertContains(res, "Active", 1, 200)
self.assertContains(res, "Running", 1, 200)
@test.create_stubs({api.nova: ('flavor_list', 'keypair_list',
'security_group_list', 'volume_list',
'volume_snapshot_list',
'tenant_quota_usages', 'server_create'),
api.glance: ('image_list_detailed',)})
def test_launch_post(self):
flavor = self.flavors.first()
image = self.images.first()
@@ -98,15 +156,6 @@ class InstanceViewTest(test.BaseAdminViewTests):
volume_choice = "%s:vol" % volume.id
block_device_mapping = {device_name: u"%s::0" % volume_choice}
self.mox.StubOutWithMock(api.glance, 'image_list_detailed')
self.mox.StubOutWithMock(api.nova, 'flavor_list')
self.mox.StubOutWithMock(api.nova, 'keypair_list')
self.mox.StubOutWithMock(api.nova, 'security_group_list')
self.mox.StubOutWithMock(api.nova, 'volume_list')
self.mox.StubOutWithMock(api.nova, 'volume_snapshot_list')
self.mox.StubOutWithMock(api.nova, 'tenant_quota_usages')
self.mox.StubOutWithMock(api.nova, 'server_create')
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.keypair_list(IsA(http.HttpRequest)) \

View File

@@ -61,9 +61,9 @@ class AdminIndexView(tables.DataTableView):
try:
flavors = api.nova.flavor_list(self.request)
except:
# If fails to retrieve flavor list, creates an empty list.
flavors = []
msg = _('Unable to retrieve instance size information.')
exceptions.handle(self.request, msg)
# Gather our tenants to correlate against IDs
try:
tenants = api.keystone.tenant_list(self.request, admin=True)
@@ -74,8 +74,20 @@ class AdminIndexView(tables.DataTableView):
full_flavors = SortedDict([(f.id, f) for f in flavors])
tenant_dict = SortedDict([(t.id, t) for t in tenants])
# Loop through instances to get flavor and tenant info.
for inst in instances:
inst.full_flavor = full_flavors.get(inst.flavor["id"], None)
flavor_id = inst.flavor["id"]
try:
if flavor_id in full_flavors:
inst.full_flavor = full_flavors[flavor_id]
else:
# If the flavor_id is not in full_flavors list,
# gets it via nova api.
inst.full_flavor = api.nova.flavor_get(
self.request, flavor_id)
except:
msg = _('Unable to retrieve instance size information.')
exceptions.handle(self.request, msg)
tenant = tenant_dict.get(inst.tenant_id, None)
inst.tenant_name = getattr(tenant, "name", None)
return instances