Adding pagination to the instance views

Modifying the api.nova.server_list() method to optionally handle
pagination.  The method will also work without pagination to
support the many other place than the instance views that continue
to call the method.

Fixes: bug #1046915

Change-Id: I8195f1f2d8922e1722743d7a2d627a8645e8b3bd
This commit is contained in:
David Lyle 2013-03-14 08:43:33 -06:00
parent de1940c922
commit 81247fda00
17 changed files with 194 additions and 78 deletions

View File

@ -362,14 +362,27 @@ def server_get(request, instance_id):
def server_list(request, search_opts=None, all_tenants=False):
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 20)
paginate = False
if search_opts is None:
search_opts = {}
elif 'paginate' in search_opts:
paginate = search_opts.pop('paginate')
if paginate:
search_opts['limit'] = page_size + 1
if all_tenants:
search_opts['all_tenants'] = True
else:
search_opts['project_id'] = request.user.tenant_id
return [Server(s, request)
for s in novaclient(request).servers.list(True, search_opts)]
servers = [Server(s, request)
for s in novaclient(request).servers.list(True, search_opts)]
has_more_data = False
if paginate and len(servers) > page_size:
servers.pop(-1)
has_more_data = True
return (servers, has_more_data)
def server_console_output(request, instance_id, tail_length=None):

View File

@ -168,7 +168,7 @@ class FloatingIpManager(network.FloatingIpManager):
def list_targets(self):
ports = port_list(self.request)
servers = nova.server_list(self.request)
servers, has_more = nova.server_list(self.request)
server_dict = SortedDict([(s.id, s.name) for s in servers])
targets = []
for p in ports:

View File

@ -35,8 +35,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
tenants = self.tenants.list()
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True).\
AndReturn(tenants)
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(servers)
all_tenants=True, search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
self.mox.ReplayAll()
@ -54,8 +56,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
flavors = self.flavors.list()
full_flavors = SortedDict([(f.id, f) for f in flavors])
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(servers)
all_tenants=True, search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.flavor_list(IsA(http.HttpRequest)). \
AndRaise(self.exceptions.nova)
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True).\
@ -83,8 +87,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
for i, server in enumerate(servers):
server.flavor['id'] = str(uuid.UUID(int=i))
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(servers)
all_tenants=True, search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.flavor_list(IsA(http.HttpRequest)). \
AndReturn(flavors)
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True).\
@ -102,8 +108,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
@test.create_stubs({api.nova: ('server_list',)})
def test_index_server_list_exception(self):
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndRaise(self.exceptions.nova)
all_tenants=True, search_opts=search_opts) \
.AndRaise(self.exceptions.nova)
self.mox.ReplayAll()
@ -146,8 +154,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
def test_index_options_before_migrate(self):
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True).\
AndReturn(self.tenants.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(self.servers.list())
all_tenants=True, search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IsA(http.HttpRequest)).\
AndReturn(self.flavors.list())
self.mox.ReplayAll()
@ -164,8 +174,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
server.status = "VERIFY_RESIZE"
api.keystone.tenant_list(IsA(http.HttpRequest), admin=True).\
AndReturn(self.tenants.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(self.servers.list())
all_tenants=True, search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IsA(http.HttpRequest)).\
AndReturn(self.flavors.list())
self.mox.ReplayAll()

View File

@ -46,11 +46,21 @@ class AdminIndexView(tables.DataTableView):
table_class = AdminInstancesTable
template_name = 'admin/instances/index.html'
def has_more_data(self, table):
return self._more
def get_data(self):
instances = []
marker = self.request.GET.get(
AdminInstancesTable._meta.pagination_param, None)
try:
instances = api.nova.server_list(self.request, all_tenants=True)
instances, self._more = api.nova.server_list(
self.request,
search_opts={'marker': marker,
'paginate': True},
all_tenants=True)
except:
self._more = False
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))
if instances:

View File

@ -33,7 +33,7 @@ class VolumeTests(test.BaseAdminViewTests):
cinder.volume_list(IsA(http.HttpRequest), search_opts={
'all_tenants': 1}).AndReturn(self.volumes.list())
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
cinder.volume_type_list(IsA(http.HttpRequest)).\
AndReturn(self.volume_types.list())
keystone.tenant_list(IsA(http.HttpRequest),
@ -75,7 +75,7 @@ class VolumeTests(test.BaseAdminViewTests):
cinder.volume_list(IsA(http.HttpRequest), search_opts={
'all_tenants': 1}).AndReturn(self.volumes.list())
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
cinder.volume_type_list(IsA(http.HttpRequest)).\
AndReturn(self.volume_types.list())
cinder.volume_type_delete(IsA(http.HttpRequest),

View File

@ -132,7 +132,8 @@ class FloatingIpViewTests(test.TestCase):
self.mox.StubOutWithMock(api.nova, 'server_list')
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(self.servers.list())
all_tenants=True).AndReturn([self.servers.list(),
False])
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
api.network.floating_ip_disassociate(IsA(http.HttpRequest),
@ -154,7 +155,8 @@ class FloatingIpViewTests(test.TestCase):
self.mox.StubOutWithMock(api.nova, 'server_list')
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(self.servers.list())
all_tenants=True).AndReturn([self.servers.list(),
False])
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())

View File

@ -91,7 +91,8 @@ class FloatingIPsTab(tabs.TableTab):
instances = []
try:
instances = nova.server_list(self.request, all_tenants=True)
instances, has_more = nova.server_list(self.request,
all_tenants=True)
except:
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))

View File

@ -43,7 +43,8 @@ class AccessAndSecurityTests(test.TestCase):
self.mox.StubOutWithMock(api.nova, 'server_list')
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(self.servers.list())
all_tenants=True).AndReturn([self.servers.list(),
False])
api.nova.keypair_list(IsA(http.HttpRequest)).AndReturn(keypairs)
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(floating_ips)

View File

@ -46,8 +46,9 @@ class InstanceTests(test.TestCase):
def test_index(self):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
@ -65,7 +66,8 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_list',
'tenant_absolute_limits')})
def test_index_server_list_exception(self):
api.nova.server_list(IsA(http.HttpRequest)) \
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndRaise(self.exceptions.nova)
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
@ -86,8 +88,9 @@ class InstanceTests(test.TestCase):
servers = self.servers.list()
flavors = self.flavors.list()
full_flavors = SortedDict([(f.id, f) for f in flavors])
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(servers)
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndRaise(self.exceptions.nova)
for server in servers:
@ -117,7 +120,9 @@ class InstanceTests(test.TestCase):
for i, server in enumerate(servers):
server.flavor['id'] = str(uuid.UUID(int=i))
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(servers)
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
for server in servers:
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
@ -141,8 +146,9 @@ class InstanceTests(test.TestCase):
def test_terminate_instance(self):
server = self.servers.first()
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.nova.server_delete(IsA(http.HttpRequest), server.id)
@ -159,8 +165,9 @@ class InstanceTests(test.TestCase):
def test_terminate_instance_exception(self):
server = self.servers.first()
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.nova.server_delete(IsA(http.HttpRequest), server.id) \
.AndRaise(self.exceptions.nova)
@ -180,8 +187,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_pause(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
@ -199,8 +207,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_pause(IsA(http.HttpRequest), server.id) \
.AndRaise(self.exceptions.nova)
@ -220,8 +229,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_unpause(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
@ -240,8 +250,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_unpause(IsA(http.HttpRequest), server.id) \
.AndRaise(self.exceptions.nova)
@ -260,8 +271,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
api.nova.REBOOT_HARD)
@ -280,8 +292,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
api.nova.REBOOT_HARD) \
.AndRaise(self.exceptions.nova)
@ -301,8 +314,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
api.nova.REBOOT_SOFT)
@ -321,8 +335,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_suspend(IsA(http.HttpRequest), unicode(server.id))
self.mox.ReplayAll()
@ -340,8 +355,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_suspend(IsA(http.HttpRequest), unicode(server.id)) \
.AndRaise(self.exceptions.nova)
@ -361,8 +377,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_resume(IsA(http.HttpRequest), unicode(server.id))
self.mox.ReplayAll()
@ -381,8 +398,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_resume(IsA(http.HttpRequest),
unicode(server.id)) \
.AndRaise(self.exceptions.nova)
@ -1181,8 +1199,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(limits)
@ -1209,8 +1228,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
@ -1281,8 +1301,9 @@ class InstanceTests(test.TestCase):
server = self.servers.first()
fip = self.q_floating_ips.first()
api.nova.server_list(
IsA(http.HttpRequest)).AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.network.floating_ip_target_get_by_instance(
IsA(http.HttpRequest),
@ -1310,8 +1331,9 @@ class InstanceTests(test.TestCase):
fip = self.q_floating_ips.first()
fip.port_id = server.id
api.nova.server_list(
IsA(http.HttpRequest)).AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.network.floating_ip_target_get_by_instance(
IsA(http.HttpRequest),

View File

@ -48,11 +48,20 @@ class IndexView(tables.DataTableView):
table_class = InstancesTable
template_name = 'project/instances/index.html'
def has_more_data(self, table):
return self._more
def get_data(self):
marker = self.request.GET.get(
InstancesTable._meta.pagination_param, None)
# Gather our instances
try:
instances = api.nova.server_list(self.request)
instances, self._more = api.nova.server_list(
self.request,
search_opts={'marker': marker,
'paginate': True})
except:
self._more = False
instances = []
exceptions.handle(self.request,
_('Unable to retrieve instances.'))

View File

@ -244,8 +244,8 @@ class LoadBalancerTests(test.TestCase):
api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([server1,
server2])
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(
[[server1, server2], False])
api.quantum.port_list(IsA(http.HttpRequest),
device_id=server1.id).AndReturn([port1, ])
@ -288,8 +288,9 @@ class LoadBalancerTests(test.TestCase):
api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([server1,
server2])
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([[server1,
server2],
False])
self.mox.ReplayAll()
@ -317,7 +318,7 @@ class LoadBalancerTests(test.TestCase):
api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
api.nova.server_list(
IsA(http.HttpRequest)).AndReturn([server1, server2])
IsA(http.HttpRequest)).AndReturn([[server1, server2], False])
self.mox.ReplayAll()

View File

@ -285,7 +285,7 @@ class AddMemberAction(workflows.Action):
members_choices = []
try:
servers = api.nova.server_list(request)
servers, has_more = api.nova.server_list(request)
except:
servers = []
exceptions.handle(request,

View File

@ -314,11 +314,11 @@ class VolumeViewTests(test.TestCase):
AndReturn(self.volumes.list())
cinder.volume_delete(IsA(http.HttpRequest), volume.id)
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
AndReturn(self.volumes.list())
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
self.mox.ReplayAll()
@ -342,11 +342,11 @@ class VolumeViewTests(test.TestCase):
cinder.volume_delete(IsA(http.HttpRequest), volume.id).\
AndRaise(exc)
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
AndReturn(self.volumes.list())
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
self.mox.ReplayAll()
@ -364,7 +364,7 @@ class VolumeViewTests(test.TestCase):
servers = self.servers.list()
cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(servers)
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False])
self.mox.ReplayAll()
url = reverse('horizon:project:volumes:attach', args=[volume.id])
@ -387,7 +387,7 @@ class VolumeViewTests(test.TestCase):
servers = self.servers.list()
cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(servers)
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False])
self.mox.ReplayAll()
url = reverse('horizon:project:volumes:attach', args=[volume.id])
@ -407,7 +407,7 @@ class VolumeViewTests(test.TestCase):
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
.AndReturn(volume)
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
.AndReturn([self.servers.list(), False])
self.mox.ReplayAll()

View File

@ -50,7 +50,8 @@ class VolumeTableMixIn(object):
def _get_instances(self):
try:
return api.nova.server_list(self.request)
instances, has_more = api.nova.server_list(self.request)
return instances
except:
exceptions.handle(self.request,
_("Unable to retrieve volume/instance "
@ -145,7 +146,7 @@ class EditAttachmentsView(tables.DataTableView, forms.ModalFormView):
def get_initial(self):
try:
instances = api.nova.server_list(self.request)
instances, has_more = api.nova.server_list(self.request)
except:
instances = []
exceptions.handle(self.request,

View File

@ -22,6 +22,9 @@
from __future__ import absolute_import
from django import http
from django.conf import settings
from django.test.utils import override_settings
from mox import IsA
from novaclient.v1_1 import servers
@ -112,10 +115,51 @@ class ComputeApiTests(test.APITestCase):
novaclient.servers.list(True, {'all_tenants': True}).AndReturn(servers)
self.mox.ReplayAll()
ret_val = api.nova.server_list(self.request, all_tenants=True)
ret_val, has_more = api.nova.server_list(self.request,
all_tenants=True)
for server in ret_val:
self.assertIsInstance(server, api.nova.Server)
def test_server_list_pagination(self):
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 20)
servers = self.servers.list()
novaclient = self.stub_novaclient()
novaclient.servers = self.mox.CreateMockAnything()
novaclient.servers.list(True,
{'all_tenants': True,
'marker': None,
'limit': page_size + 1}).AndReturn(servers)
self.mox.ReplayAll()
ret_val, has_more = api.nova.server_list(self.request,
{'marker': None,
'paginate': True},
all_tenants=True)
for server in ret_val:
self.assertIsInstance(server, api.nova.Server)
self.assertFalse(has_more)
@override_settings(API_RESULT_PAGE_SIZE=1)
def test_server_list_pagination_more(self):
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 1)
servers = self.servers.list()
novaclient = self.stub_novaclient()
novaclient.servers = self.mox.CreateMockAnything()
novaclient.servers.list(True,
{'all_tenants': True,
'marker': None,
'limit': page_size + 1}).AndReturn(servers)
self.mox.ReplayAll()
ret_val, has_more = api.nova.server_list(self.request,
{'marker': None,
'paginate': True},
all_tenants=True)
for server in ret_val:
self.assertIsInstance(server, api.nova.Server)
self.assertEquals(page_size, len(ret_val))
self.assertTrue(has_more)
def test_usage_get(self):
novaclient = self.stub_novaclient()
novaclient.usage = self.mox.CreateMockAnything()

View File

@ -65,7 +65,7 @@ class QuotaTests(test.APITestCase):
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
.AndReturn([self.servers.list(), False])
cinder.volume_list(IsA(http.HttpRequest)) \
.AndReturn(self.volumes.list())
cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \
@ -94,7 +94,7 @@ class QuotaTests(test.APITestCase):
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
.AndReturn([self.servers.list(), False])
self.mox.ReplayAll()
@ -118,7 +118,7 @@ class QuotaTests(test.APITestCase):
.AndReturn(self.quotas.first())
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn([])
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([])
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([[], False])
self.mox.ReplayAll()
@ -153,7 +153,7 @@ class QuotaTests(test.APITestCase):
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
.AndReturn([self.servers.list(), False])
cinder.volume_list(IsA(http.HttpRequest)) \
.AndReturn(self.volumes.list())
cinder.tenant_quota_get(IsA(http.HttpRequest), '1') \

View File

@ -119,7 +119,7 @@ def tenant_quota_usages(request):
# Get our usages.
floating_ips = network.tenant_floating_ip_list(request)
flavors = dict([(f.id, f) for f in nova.flavor_list(request)])
instances = nova.server_list(request)
instances, has_more = nova.server_list(request)
# Fetch deleted flavors if necessary.
missing_flavors = [instance.flavor['id'] for instance in instances
if instance.flavor['id'] not in flavors]