summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFerenc Cserepkei <ferenc.cserepkei@ericsson.com>2017-08-25 19:53:42 +0200
committerKeithMnemonic <keith.berger@suse.com>2019-11-26 12:48:32 -0500
commit44a098abcf287dfa67db6aede0d63dc58df80b07 (patch)
treed57677d3ae0f175f2ce83aecf8d52e0d31aa7ba2
parent7f218c8e7d0ac78d066e397952ae8c8a9b7df985 (diff)
downloadhorizon-44a098abcf287dfa67db6aede0d63dc58df80b07.tar.gz
Add "prev" link to instance page list pagination
Currently there is no link to previous page at paginated instances table. This patch resolves that issue by re-using the pagination code for flavors. It also supports Ying Zuo's scenario: After I set only 1 item per page and deleted the instance on the first page, the expected behavior is showing the next instance in the table after one is deleted. xxxIndexView uses PagedTableMixin's _get_marker() from now instead of GET()- ing the markers Closes-Bug: #1274427 Co-Authored-By: Dmitry Ratushnyy <dratushn@cisco.com> Co-Authored-By: Akihiro Motoki <amotoki@gmail.com> Change-Id: Id8eaae6bf1b5d6f42291291655e14b8715c08bc8 Signed-off-by: Ferenc Cserepkei <ferenc.cserepkei@ericsson.com> (cherry picked from commit 467669417979ec7443d5195d4b4635d5596cdc08)
-rw-r--r--openstack_dashboard/api/nova.py94
-rw-r--r--openstack_dashboard/dashboards/admin/instances/tests.py184
-rw-r--r--openstack_dashboard/dashboards/admin/instances/views.py19
-rw-r--r--openstack_dashboard/dashboards/project/instances/tests.py386
-rw-r--r--openstack_dashboard/dashboards/project/instances/views.py19
-rw-r--r--openstack_dashboard/test/integration_tests/tests/test_instances.py2
-rw-r--r--openstack_dashboard/test/unit/api/test_nova.py6
7 files changed, 489 insertions, 221 deletions
diff --git a/openstack_dashboard/api/nova.py b/openstack_dashboard/api/nova.py
index 2e2e11d5f..bb04b0bd6 100644
--- a/openstack_dashboard/api/nova.py
+++ b/openstack_dashboard/api/nova.py
@@ -372,8 +372,7 @@ def flavor_list(request, is_public=True, get_extras=False):
@profiler.trace
-def update_pagination(entities, page_size, marker, sort_dir, sort_key,
- reversed_order):
+def update_pagination(entities, page_size, marker, reversed_order=False):
has_more_data = has_prev_data = False
if len(entities) > page_size:
has_more_data = True
@@ -389,9 +388,7 @@ def update_pagination(entities, page_size, marker, sort_dir, sort_key,
# restore the original ordering here
if reversed_order:
- entities = sorted(entities, key=lambda entity:
- (getattr(entity, sort_key) or '').lower(),
- reverse=(sort_dir == 'asc'))
+ entities.reverse()
return entities, has_more_data, has_prev_data
@@ -415,7 +412,7 @@ def flavor_list_paged(request, is_public=True, get_extras=False, marker=None,
sort_key=sort_key,
sort_dir=sort_dir)
flavors, has_more_data, has_prev_data = update_pagination(
- flavors, page_size, marker, sort_dir, sort_key, reversed_order)
+ flavors, page_size, marker, reversed_order)
else:
flavors = novaclient(request).flavors.list(is_public=is_public)
@@ -546,6 +543,14 @@ def server_create(request, name, image, flavor, key_name, user_data,
@profiler.trace
def server_delete(request, instance_id):
novaclient(request).servers.delete(instance_id)
+ # Session is available and consistent for the current view
+ # among Horizon django servers even in load-balancing setup,
+ # so only the view listing the servers will recognize it as
+ # own DeleteInstance action performed. Note that dict is passed
+ # by reference in python. Quote from django's developer manual:
+ # " You can read it and write to request.session at any point
+ # in your view. You can edit it multiple times."
+ request.session['server_deleted'] = instance_id
def get_novaclient_with_locked_status(request):
@@ -565,33 +570,66 @@ def server_get(request, instance_id):
@profiler.trace
-def server_list(request, search_opts=None, detailed=True):
+def server_list_paged(request,
+ search_opts=None,
+ detailed=True,
+ sort_dir="desc"):
+ has_more_data = False
+ has_prev_data = False
nova_client = get_novaclient_with_locked_status(request)
page_size = utils.get_page_size(request)
- 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
-
- all_tenants = search_opts.get('all_tenants', False)
- if all_tenants:
- search_opts['all_tenants'] = True
- else:
+ search_opts = {} if search_opts is None else search_opts
+ marker = search_opts.get('marker', None)
+
+ if not search_opts.get('all_tenants', False):
search_opts['project_id'] = request.user.tenant_id
- servers = [Server(s, request)
- for s in nova_client.servers.list(detailed, search_opts)]
+ if search_opts.pop('paginate', False):
+ reversed_order = sort_dir is "asc"
+ LOG.debug("Notify received on deleted server: %r",
+ ('server_deleted' in request.session))
+ deleted = request.session.pop('server_deleted',
+ None)
+ view_marker = 'possibly_deleted' if deleted and marker else 'ok'
+ search_opts['marker'] = deleted if deleted else marker
+ search_opts['limit'] = page_size + 1
+ search_opts['sort_dir'] = sort_dir
+ servers = [Server(s, request)
+ for s in nova_client.servers.list(detailed, search_opts)]
+ if view_marker == 'possibly_deleted':
+ if len(servers) == 0:
+ view_marker = 'head_deleted'
+ search_opts['sort_dir'] = 'desc'
+ reversed_order = False
+ servers = [Server(s, request)
+ for s in nova_client.servers.list(detailed,
+ search_opts)]
+ if len(servers) == 0:
+ view_marker = 'tail_deleted'
+ search_opts['sort_dir'] = 'asc'
+ reversed_order = True
+ servers = [Server(s, request)
+ for s in nova_client.servers.list(detailed,
+ search_opts)]
+ (servers, has_more_data, has_prev_data) = update_pagination(
+ servers, page_size, marker, reversed_order)
+ has_prev_data = (False
+ if view_marker == 'head_deleted'
+ else has_prev_data)
+ has_more_data = (False
+ if view_marker == 'tail_deleted'
+ else has_more_data)
+ else:
+ servers = [Server(s, request)
+ for s in nova_client.servers.list(detailed, search_opts)]
+ return (servers, has_more_data, has_prev_data)
+
- has_more_data = False
- if paginate and len(servers) > page_size:
- servers.pop(-1)
- has_more_data = True
- elif paginate and len(servers) == getattr(settings, 'API_RESULT_LIMIT',
- 1000):
- has_more_data = True
+@profiler.trace
+def server_list(request, search_opts=None, detailed=True):
+ (servers, has_more_data, _) = server_list_paged(request,
+ search_opts,
+ detailed)
return (servers, has_more_data)
diff --git a/openstack_dashboard/dashboards/admin/instances/tests.py b/openstack_dashboard/dashboards/admin/instances/tests.py
index d994cd18f..a67cf4aa1 100644
--- a/openstack_dashboard/dashboards/admin/instances/tests.py
+++ b/openstack_dashboard/dashboards/admin/instances/tests.py
@@ -13,10 +13,13 @@
# under the License.
from collections import OrderedDict
+
import uuid
import mock
+from django.conf import settings
+from django.test import override_settings
from django.urls import reverse
from openstack_dashboard import api
@@ -29,7 +32,7 @@ INDEX_TEMPLATE = 'horizon/common/_data_table_view.html'
class InstanceViewTest(test.BaseAdminViewTests):
@test.create_mocks({
- api.nova: ['flavor_list', 'server_list', 'extension_supported'],
+ api.nova: ['flavor_list', 'server_list_paged', 'extension_supported'],
api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'],
})
@@ -42,7 +45,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_tenant_list.return_value = [self.tenants.list(), False]
self.mock_image_list_detailed_by_ids.return_value = self.images.list()
self.mock_flavor_list.return_value = self.flavors.list()
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
res = self.client.get(INDEX_URL)
self.assertTemplateUsed(res, INDEX_TEMPLATE)
@@ -59,11 +62,13 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), instances_img_ids)
self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True, 'all_tenants': True}
- self.mock_server_list.assert_called_once_with(
- test.IsHttpRequest(), search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ test.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
@test.create_mocks({
- api.nova: ['flavor_list', 'flavor_get', 'server_list',
+ api.nova: ['flavor_list', 'flavor_get', 'server_list_paged',
'extension_supported'],
api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'],
@@ -74,7 +79,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
instances_img_ids = [instance.image.get('id') for instance in
servers if hasattr(instance, 'image')]
full_flavors = OrderedDict([(f.id, f) for f in flavors])
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_extension_supported.return_value = True
self.mock_flavor_list.side_effect = self.exceptions.nova
self.mock_tenant_list.return_value = [self.tenants.list(), False]
@@ -92,8 +97,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertItemsEqual(instances, servers)
search_opts = {'marker': None, 'paginate': True, 'all_tenants': True}
- self.mock_server_list.assert_called_once_with(
- test.IsHttpRequest(), search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ test.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
@@ -108,7 +115,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), instances_img_ids)
@test.create_mocks({
- api.nova: ['flavor_list', 'flavor_get', 'server_list',
+ api.nova: ['flavor_list', 'flavor_get', 'server_list_paged',
'extension_supported'],
api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'],
@@ -124,7 +131,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_image_list_detailed_by_ids.return_value = self.images.list()
self.mock_flavor_list.return_value = self.flavors.list()
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_extension_supported.return_value = True
self.mock_tenant_list.return_value = [self.tenants.list(), False]
self.mock_flavor_get.side_effect = self.exceptions.nova
@@ -142,8 +149,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), instances_img_ids)
self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True, 'all_tenants': True}
- self.mock_server_list.assert_called_once_with(
- test.IsHttpRequest(), search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ test.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
@@ -155,12 +164,12 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertEqual(len(servers), self.mock_flavor_get.call_count)
@test.create_mocks({
- api.nova: ['server_list', 'flavor_list'],
+ api.nova: ['server_list_paged', 'flavor_list'],
api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'],
})
def test_index_server_list_exception(self):
- self.mock_server_list.side_effect = self.exceptions.nova
+ self.mock_server_list_paged.side_effect = self.exceptions.nova
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_tenant_list.return_value = [self.tenants.list(), False]
self.mock_image_list_detailed_by_ids.return_value = self.images.list()
@@ -170,8 +179,9 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertEqual(len(res.context['instances_table'].data), 0)
search_opts = {'marker': None, 'paginate': True, 'all_tenants': True}
- self.mock_server_list.assert_called_once_with(
+ self.mock_server_list_paged.assert_called_once_with(
test.IsHttpRequest(),
+ sort_dir='desc',
search_opts=search_opts)
self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
self.mock_image_list_detailed_by_ids.assert_called_once_with(
@@ -223,7 +233,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), [server])
@test.create_mocks({
- api.nova: ['flavor_list', 'server_list', 'extension_supported'],
+ api.nova: ['flavor_list', 'server_list_paged', 'extension_supported'],
api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'],
})
@@ -234,9 +244,9 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_tenant_list.return_value = [self.tenants.list(), False]
self.mock_image_list_detailed_by_ids.return_value = self.images.list()
self.mock_flavor_list.return_value = self.flavors.list()
- self.mock_server_list.return_value = [self.servers.list(), False]
+ self.mock_server_list_paged.return_value = [
+ self.servers.list(), False, False]
self.mock_extension_supported.return_value = True
-
res = self.client.get(INDEX_URL)
self.assertContains(res, "instances__migrate")
self.assertNotContains(res, "instances__confirm")
@@ -247,8 +257,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
test.IsHttpRequest(), instances_img_ids)
self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True, 'all_tenants': True}
- self.mock_server_list.assert_called_once_with(
- test.IsHttpRequest(), search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ test.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_extension_supported.assert_has_calls([
mock.call('AdminActions', test.IsHttpRequest()),
mock.call('AdminActions', test.IsHttpRequest()),
@@ -256,7 +268,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertEqual(12, self.mock_extension_supported.call_count)
@test.create_mocks({
- api.nova: ['flavor_list', 'server_list', 'extension_supported'],
+ api.nova: ['flavor_list', 'server_list_paged', 'extension_supported'],
api.keystone: ['tenant_list'],
api.glance: ['image_list_detailed_by_ids'],
})
@@ -272,7 +284,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.mock_image_list_detailed_by_ids.return_value = self.images.list()
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_extension_supported.return_value = True
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
res = self.client.get(INDEX_URL)
self.assertContains(res, "instances__confirm")
@@ -289,8 +301,10 @@ class InstanceViewTest(test.BaseAdminViewTests):
mock.call('Shelve', test.IsHttpRequest())] * 4)
self.assertEqual(12, self.mock_extension_supported.call_count)
search_opts = {'marker': None, 'paginate': True, 'all_tenants': True}
- self.mock_server_list.assert_called_once_with(
- test.IsHttpRequest(), search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ test.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
@test.create_mocks({api.nova: ['service_list',
'server_get']})
@@ -474,3 +488,125 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertTemplateUsed(res, INDEX_TEMPLATE)
instances = res.context['table'].data
self.assertItemsEqual(instances, [])
+
+ @test.create_mocks({
+ api.nova: ['flavor_list',
+ 'flavor_get',
+ 'server_list_paged',
+ 'extension_supported'],
+ api.keystone: ['tenant_list'],
+ api.glance: ['image_list_detailed_by_ids'],
+ })
+ def _test_servers_paginate_do(self,
+ marker,
+ servers,
+ has_more,
+ has_prev):
+ flavors = self.flavors.list()
+ tenants = self.tenants.list()
+ images = self.images.list()
+ # UUID indices are unique and are guaranteed being deterministic.
+ for i, server in enumerate(servers):
+ server.flavor['id'] = str(uuid.UUID(int=i))
+
+ self.mock_server_list_paged.return_value = [
+ servers, has_more, has_prev]
+ self.mock_extension_supported.return_value = True
+ self.mock_flavor_list.return_value = flavors
+ self.mock_image_list_detailed_by_ids.return_value = images
+ self.mock_tenant_list.return_value = [tenants, False]
+ self.mock_flavor_get.side_effect = self.exceptions.nova
+
+ if marker:
+ url = "?".join([INDEX_URL, "marker={}".format(marker)])
+ else:
+ url = INDEX_URL
+ res = self.client.get(url)
+ self.assertTemplateUsed(res, INDEX_TEMPLATE)
+ self.assertEqual(res.status_code, 200)
+
+ self.mock_extension_supported.assert_has_calls([
+ mock.call('AdminActions', test.IsHttpRequest()),
+ mock.call('AdminActions', test.IsHttpRequest()),
+ mock.call('Shelve', test.IsHttpRequest())])
+ self.assertEqual(3, self.mock_extension_supported.call_count)
+ self.mock_tenant_list.assert_called_once_with(test.IsHttpRequest())
+ self.mock_image_list_detailed_by_ids.assert_called_once_with(
+ test.IsHttpRequest(),
+ [server.image.id for server in servers])
+ self.mock_flavor_list.assert_called_once_with(test.IsHttpRequest())
+ search_opts = {'marker': marker, 'paginate': True, 'all_tenants': True}
+ self.mock_server_list_paged.assert_called_once_with(
+ test.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
+ self.mock_flavor_get.assert_has_calls(
+ [mock.call(test.IsHttpRequest(), s.flavor['id']) for s in servers])
+ self.assertEqual(len(servers), self.mock_flavor_get.call_count)
+
+ return res
+
+ @override_settings(API_RESULT_PAGE_SIZE=1)
+ def test_severs_index_paginated(self):
+ size = settings.API_RESULT_PAGE_SIZE
+ mox_servers = self.servers.list()
+
+ # get first page
+ expected_servers = mox_servers[:size]
+ res = self._test_servers_paginate_do(
+ marker=None,
+ servers=expected_servers,
+ has_more=True,
+ has_prev=False)
+ servers = res.context['table'].data
+ self.assertItemsEqual(servers, expected_servers)
+
+ # get second page
+ expected_servers = mox_servers[size:2 * size]
+ marker = expected_servers[0].id
+ res = self._test_servers_paginate_do(
+ marker=marker,
+ servers=expected_servers,
+ has_more=True,
+ has_prev=True)
+ servers = res.context['table'].data
+ self.assertItemsEqual(servers, expected_servers)
+
+ # get last page
+ expected_servers = mox_servers[-size:]
+ marker = expected_servers[0].id
+ res = self._test_servers_paginate_do(
+ marker=marker,
+ servers=expected_servers,
+ has_more=False,
+ has_prev=True)
+ servers = res.context['table'].data
+ self.assertItemsEqual(servers, expected_servers)
+
+ @override_settings(API_RESULT_PAGE_SIZE=1)
+ def test_servers_index_paginated_prev(self):
+ size = settings.API_RESULT_PAGE_SIZE
+ mox_servers = self.servers.list()
+
+ # prev from some page
+ expected_servers = mox_servers[size:2 * size]
+ marker = mox_servers[0].id
+
+ res = self._test_servers_paginate_do(
+ marker=marker,
+ servers=expected_servers,
+ has_more=False,
+ has_prev=True)
+ servers = res.context['table'].data
+ self.assertItemsEqual(servers, expected_servers)
+
+ # back to first page
+ expected_servers = mox_servers[:size]
+ marker = mox_servers[0].id
+ res = self._test_servers_paginate_do(
+ marker=marker,
+ servers=expected_servers,
+ has_more=True,
+ has_prev=False)
+ servers = res.context['table'].data
+ self.assertItemsEqual(servers, expected_servers)
diff --git a/openstack_dashboard/dashboards/admin/instances/views.py b/openstack_dashboard/dashboards/admin/instances/views.py
index 63454d89c..0bba73fb1 100644
--- a/openstack_dashboard/dashboards/admin/instances/views.py
+++ b/openstack_dashboard/dashboards/admin/instances/views.py
@@ -70,10 +70,13 @@ class AdminUpdateView(views.UpdateView):
success_url = reverse_lazy("horizon:admin:instances:index")
-class AdminIndexView(tables.DataTableView):
+class AdminIndexView(tables.PagedTableMixin, tables.DataTableView):
table_class = project_tables.AdminInstancesTable
page_title = _("Instances")
+ def has_prev_data(self, table):
+ return getattr(self, "_prev", False)
+
def has_more_data(self, table):
return self._more
@@ -115,21 +118,21 @@ class AdminIndexView(tables.DataTableView):
exceptions.handle(self.request, msg)
return {}
- def _get_instances(self, search_opts):
+ def _get_instances(self, search_opts, sort_dir):
try:
- instances, self._more = api.nova.server_list(
+ instances, self._more, self._prev = api.nova.server_list_paged(
self.request,
- search_opts=search_opts)
+ search_opts=search_opts,
+ sort_dir=sort_dir)
except Exception:
- self._more = False
+ self._more = self._prev = False
instances = []
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))
return instances
def get_data(self):
- marker = self.request.GET.get(
- project_tables.AdminInstancesTable._meta.pagination_param, None)
+ marker, sort_dir = self._get_marker()
default_search_opts = {'marker': marker,
'paginate': True,
'all_tenants': True}
@@ -148,7 +151,7 @@ class AdminIndexView(tables.DataTableView):
self._needs_filter_first = False
- instances = self._get_instances(search_opts)
+ instances = self._get_instances(search_opts, sort_dir)
results = futurist_utils.call_functions_parallel(
(self._get_images, [tuple(instances)]),
self._get_flavors,
diff --git a/openstack_dashboard/dashboards/project/instances/tests.py b/openstack_dashboard/dashboards/project/instances/tests.py
index 2ab3ab13c..cc9c3032e 100644
--- a/openstack_dashboard/dashboards/project/instances/tests.py
+++ b/openstack_dashboard/dashboards/project/instances/tests.py
@@ -170,7 +170,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
@helpers.create_mocks({
api.nova: (
'flavor_list',
- 'server_list',
+ 'server_list_paged',
'tenant_absolute_limits',
'extension_supported',
'is_feature_available',
@@ -192,13 +192,12 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = \
(self.images.list(), False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_tenant_absolute_limits.return_value = \
self.limits['absolute']
self.mock_floating_ip_supported.return_value = True
self.mock_floating_ip_simple_associate_supported.return_value = True
-
return self.client.get(INDEX_URL)
def _check_get_index(self, use_servers_update_address=True,
@@ -217,8 +216,10 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(
- helpers.IsHttpRequest(), search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
if use_servers_update_address:
servers = self.servers.list()
self.mock_servers_update_addresses.assert_called_once_with(
@@ -261,17 +262,18 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self._check_get_index(use_servers_update_address=False)
@helpers.create_mocks({
- api.nova: ('server_list', 'tenant_absolute_limits', 'flavor_list'),
+ api.nova: ('server_list_paged',
+ 'tenant_absolute_limits',
+ 'flavor_list'),
api.glance: ('image_list_detailed',),
})
def test_index_server_list_exception(self):
search_opts = {'marker': None, 'paginate': True}
flavors = self.flavors.list()
images = self.images.list()
-
self.mock_flavor_list.return_value = flavors
self.mock_image_list_detailed.return_value = (images, False, False)
- self.mock_server_list.side_effect = self.exceptions.nova
+ self.mock_server_list_paged.side_effect = self.exceptions.nova
self.mock_tenant_absolute_limits.return_value = self.limits['absolute']
res = self.client.get(INDEX_URL)
@@ -283,15 +285,20 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_tenant_absolute_limits, 2,
mock.call(helpers.IsHttpRequest(), reserved=True))
@helpers.create_mocks({
- api.nova: ('flavor_list', 'server_list', 'flavor_get',
- 'tenant_absolute_limits', 'extension_supported',
+ api.nova: ('flavor_list',
+ 'server_list_paged',
+ 'flavor_get',
+ 'tenant_absolute_limits',
+ 'extension_supported',
'is_feature_available',),
api.glance: ('image_list_detailed',),
api.neutron: ('floating_ip_simple_associate_supported',
@@ -305,7 +312,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self._mock_extension_supported({'AdminActions': True,
'Shelve': True})
self.mock_is_feature_available.return_value = True
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_flavor_list.side_effect = self.exceptions.nova
self.mock_image_list_detailed.return_value = (self.images.list(),
@@ -326,8 +333,10 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.assert_mock_multiple_calls_with_same_arguments(
self.mock_is_feature_available, 8,
mock.call(helpers.IsHttpRequest(), 'locked_attribute'))
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
@@ -344,8 +353,11 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
mock.call(helpers.IsHttpRequest()))
@helpers.create_mocks({
- api.nova: ('flavor_list', 'server_list', 'tenant_absolute_limits',
- 'extension_supported', 'is_feature_available',),
+ api.nova: ('flavor_list',
+ 'server_list_paged',
+ 'tenant_absolute_limits',
+ 'extension_supported',
+ 'is_feature_available',),
api.glance: ('image_list_detailed',),
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
@@ -361,7 +373,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self._mock_extension_supported({'AdminActions': True,
'Shelve': True})
self.mock_is_feature_available.return_value = True
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
@@ -386,8 +398,10 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.assert_mock_multiple_calls_with_same_arguments(
@@ -427,7 +441,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.assertNotIsInstance(action, tables.ConsoleLink)
self._check_get_index(multiplier=8)
- @helpers.create_mocks({api.nova: ('server_list',
+ @helpers.create_mocks({api.nova: ('server_list_paged',
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
@@ -436,21 +450,22 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
servers = self.servers.list()
server = servers[0]
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
self.mock_server_delete.return_value = None
-
formData = {'action': 'instances__delete__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
self.assertRedirectsNoFollow(res, INDEX_URL)
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
@@ -459,7 +474,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_server_delete.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
- @helpers.create_mocks({api.nova: ('server_list',
+ @helpers.create_mocks({api.nova: ('server_list_paged',
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
@@ -469,7 +484,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
server = servers[0]
server.status = 'ERROR'
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
@@ -482,8 +497,10 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.assertRedirectsNoFollow(res, INDEX_URL)
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
@@ -492,7 +509,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_server_delete.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
- @helpers.create_mocks({api.nova: ('server_list',
+ @helpers.create_mocks({api.nova: ('server_list_paged',
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
@@ -501,7 +518,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
servers = self.servers.list()
server = servers[0]
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
@@ -514,8 +531,10 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.assertRedirectsNoFollow(res, INDEX_URL)
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
@@ -525,7 +544,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_pause',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -539,7 +558,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_pause.return_value = None
@@ -554,15 +573,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_pause.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_pause',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -576,7 +597,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_pause.side_effect = self.exceptions.nova
@@ -591,15 +612,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_pause.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_unpause',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -613,7 +636,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_unpause.return_value = None
@@ -628,15 +651,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_unpause.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_unpause',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -651,7 +676,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_unpause.side_effect = self.exceptions.nova
@@ -666,15 +691,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_unpause.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_reboot',
- 'server_list',
+ 'server_list_paged',
'flavor_list',),
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
@@ -685,7 +712,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_reboot.return_value = None
@@ -698,15 +725,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_reboot.assert_called_once_with(
helpers.IsHttpRequest(), server.id, soft_reboot=False)
@helpers.create_mocks({api.nova: ('server_reboot',
- 'server_list',
+ 'server_list_paged',
'flavor_list',),
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
@@ -717,7 +746,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_reboot.side_effect = self.exceptions.nova
@@ -730,15 +759,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_reboot.assert_called_once_with(
helpers.IsHttpRequest(), server.id, soft_reboot=False)
@helpers.create_mocks({api.nova: ('server_reboot',
- 'server_list',
+ 'server_list_paged',
'flavor_list',),
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
@@ -749,7 +780,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_reboot.return_value = None
@@ -762,15 +793,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_reboot.assert_called_once_with(
helpers.IsHttpRequest(), server.id, soft_reboot=True)
@helpers.create_mocks({api.nova: ('server_suspend',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -784,7 +817,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_suspend.return_value = None
@@ -797,12 +830,15 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_extension_supported.assert_called_once_with(
'AdminActions', helpers.IsHttpRequest())
- self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
+ self.mock_flavor_list.assert_called_once_with(
+ helpers.IsHttpRequest())
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_suspend.assert_called_once_with(
@@ -810,7 +846,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
@django.test.utils.override_settings(API_RESULT_PAGE_SIZE=2)
@helpers.create_mocks({api.nova: ('server_suspend',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -824,7 +860,8 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers[page_size:], False]
+ self.mock_server_list_paged.return_value = [
+ servers[page_size:], False, True]
self.mock_servers_update_addresses.return_value = None
self.mock_server_suspend.return_value = None
@@ -842,8 +879,9 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
- self.mock_server_list.assert_called_once_with(
+ self.mock_server_list_paged.assert_called_once_with(
helpers.IsHttpRequest(),
+ sort_dir='desc',
search_opts={'marker': servers[page_size - 1].id,
'paginate': True})
self.mock_servers_update_addresses.assert_called_once_with(
@@ -852,7 +890,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
helpers.IsHttpRequest(), servers[-1].id)
@helpers.create_mocks({api.nova: ('server_suspend',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -866,7 +904,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_suspend.side_effect = self.exceptions.nova
@@ -881,15 +919,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_suspend.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_resume',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -904,7 +944,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_resume.return_value = None
@@ -919,15 +959,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_resume.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_resume',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available'),
@@ -942,7 +984,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_resume.side_effect = self.exceptions.nova
@@ -957,15 +999,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_resume.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_shelve',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -979,10 +1023,9 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_shelve.return_value = None
-
formData = {'action': 'instances__shelve__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
@@ -994,15 +1037,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_shelve.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_shelve',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -1016,7 +1061,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_shelve.side_effect = self.exceptions.nova
@@ -1031,15 +1076,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_shelve.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_unshelve',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -1054,7 +1101,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_unshelve.return_value = None
@@ -1069,15 +1116,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_unshelve.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_unshelve',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -1092,7 +1141,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_unshelve.side_effect = self.exceptions.nova
@@ -1107,15 +1156,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_unshelve.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_lock',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -1130,10 +1181,9 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_lock.return_value = None
-
formData = {'action': 'instances__lock__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
@@ -1147,15 +1197,17 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_lock.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_lock',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available',),
@@ -1170,7 +1222,7 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_lock.side_effect = self.exceptions.nova
@@ -1183,19 +1235,22 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'AdminActions', helpers.IsHttpRequest())
self.mock_is_feature_available.assert_called_once_with(
helpers.IsHttpRequest(), 'locked_attribute')
- self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
+ self.mock_flavor_list.assert_called_once_with(
+ helpers.IsHttpRequest())
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_lock.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_unlock',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available'),
@@ -1209,10 +1264,9 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_unlock.return_value = None
-
formData = {'action': 'instances__unlock__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
@@ -1222,19 +1276,22 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
'AdminActions', helpers.IsHttpRequest())
self.mock_is_feature_available.assert_called_once_with(
helpers.IsHttpRequest(), 'locked_attribute')
- self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
+ self.mock_flavor_list.assert_called_once_with(
+ helpers.IsHttpRequest())
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_unlock.assert_called_once_with(
helpers.IsHttpRequest(), server.id)
@helpers.create_mocks({api.nova: ('server_unlock',
- 'server_list',
+ 'server_list_paged',
'flavor_list',
'extension_supported',
'is_feature_available'),
@@ -1243,13 +1300,12 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
def test_unlock_instance_exception(self):
servers = self.servers.list()
server = servers[0]
-
self.mock_extension_supported.return_value = True
self.mock_is_feature_available.return_value = True
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_server_unlock.side_effect = self.exceptions.nova
@@ -1266,8 +1322,10 @@ class InstanceTableTests(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.mock_server_unlock.assert_called_once_with(
@@ -1743,8 +1801,11 @@ class InstanceTests(InstanceTestBase):
self._test_instances_index_retrieve_password_action()
@helpers.create_mocks({
- api.nova: ('flavor_list', 'server_list', 'tenant_absolute_limits',
- 'extension_supported', 'is_feature_available',),
+ api.nova: ('flavor_list',
+ 'server_list_paged',
+ 'tenant_absolute_limits',
+ 'extension_supported',
+ 'is_feature_available',),
api.glance: ('image_list_detailed',),
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
@@ -1759,7 +1820,7 @@ class InstanceTests(InstanceTestBase):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_tenant_absolute_limits.return_value = self.limits['absolute']
self.mock_floating_ip_supported.return_value = True
@@ -1787,8 +1848,10 @@ class InstanceTests(InstanceTestBase):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.assert_mock_multiple_calls_with_same_arguments(
@@ -3923,8 +3986,11 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
msg, 0)
@helpers.create_mocks({
- api.nova: ('flavor_list', 'server_list', 'tenant_absolute_limits',
- 'extension_supported', 'is_feature_available',),
+ api.nova: ('flavor_list',
+ 'server_list_paged',
+ 'tenant_absolute_limits',
+ 'extension_supported',
+ 'is_feature_available',),
api.glance: ('image_list_detailed',),
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
@@ -3940,7 +4006,7 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_tenant_absolute_limits.return_value = limits
self.mock_floating_ip_supported.return_value = True
@@ -3967,8 +4033,10 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.assert_mock_multiple_calls_with_same_arguments(
@@ -3982,8 +4050,11 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
mock.call(helpers.IsHttpRequest()))
@helpers.create_mocks({
- api.nova: ('flavor_list', 'server_list', 'tenant_absolute_limits',
- 'extension_supported', 'is_feature_available',),
+ api.nova: ('flavor_list',
+ 'server_list_paged',
+ 'tenant_absolute_limits',
+ 'extension_supported',
+ 'is_feature_available',),
api.glance: ('image_list_detailed',),
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
@@ -4000,7 +4071,7 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_tenant_absolute_limits.return_value = limits
self.mock_floating_ip_supported.return_value = True
@@ -4026,8 +4097,10 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(helpers.IsHttpRequest(),
- search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.assert_mock_multiple_calls_with_same_arguments(
@@ -4166,8 +4239,11 @@ class InstanceLaunchInstanceTests(InstanceTestBase,
class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
@helpers.create_mocks({
- api.nova: ('flavor_list', 'server_list', 'tenant_absolute_limits',
- 'extension_supported', 'is_feature_available',),
+ api.nova: ('flavor_list',
+ 'server_list_paged',
+ 'tenant_absolute_limits',
+ 'extension_supported',
+ 'is_feature_available',),
api.glance: ('image_list_detailed',),
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
@@ -4184,7 +4260,7 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.return_value = [servers, False]
+ self.mock_server_list_paged.return_value = [servers, False, False]
self.mock_servers_update_addresses.return_value = None
self.mock_tenant_absolute_limits.return_value = self.limits['absolute']
self.mock_floating_ip_supported.return_value = True
@@ -4203,8 +4279,10 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.assert_called_once_with(
helpers.IsHttpRequest())
search_opts = {'marker': None, 'paginate': True}
- self.mock_server_list.assert_called_once_with(
- helpers.IsHttpRequest(), search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers)
self.assert_mock_multiple_calls_with_same_arguments(
@@ -4737,8 +4815,11 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
@django.test.utils.override_settings(API_RESULT_PAGE_SIZE=2)
@helpers.create_mocks({
- api.nova: ('flavor_list', 'server_list', 'tenant_absolute_limits',
- 'extension_supported', 'is_feature_available',),
+ api.nova: ('flavor_list',
+ 'server_list_paged',
+ 'tenant_absolute_limits',
+ 'extension_supported',
+ 'is_feature_available',),
api.glance: ('image_list_detailed',),
api.neutron: ('floating_ip_simple_associate_supported',
'floating_ip_supported',),
@@ -4758,9 +4839,9 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed.return_value = (self.images.list(),
False, False)
- self.mock_server_list.side_effect = [
- [servers[:page_size], True],
- [servers[page_size:], False]
+ self.mock_server_list_paged.side_effect = [
+ [servers[:page_size], True, False],
+ [servers[page_size:], False, False]
]
self.mock_servers_update_addresses.return_value = None
@@ -4798,14 +4879,16 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
self.mock_image_list_detailed, 2,
mock.call(helpers.IsHttpRequest()))
- self.mock_server_list.assert_has_calls([
+ self.mock_server_list_paged.assert_has_calls([
mock.call(helpers.IsHttpRequest(),
+ sort_dir='desc',
search_opts={'marker': None, 'paginate': True}),
mock.call(helpers.IsHttpRequest(),
+ sort_dir='desc',
search_opts={'marker': servers[page_size - 1].id,
'paginate': True}),
])
- self.assertEqual(2, self.mock_server_list.call_count)
+ self.assertEqual(2, self.mock_server_list_paged.call_count)
self.mock_servers_update_addresses.assert_has_calls([
mock.call(helpers.IsHttpRequest(), servers[:page_size]),
mock.call(helpers.IsHttpRequest(), servers[page_size:]),
@@ -4823,7 +4906,7 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
mock.call(helpers.IsHttpRequest()))
@django.test.utils.override_settings(API_RESULT_PAGE_SIZE=2)
- @helpers.create_mocks({api.nova: ('server_list',
+ @helpers.create_mocks({api.nova: ('server_list_paged',
'flavor_list',
'server_delete',),
api.glance: ('image_list_detailed',),
@@ -4835,7 +4918,8 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
servers = self.servers.list()[:3]
server = servers[-1]
- self.mock_server_list.return_value = [servers[page_size:], False]
+ self.mock_server_list_paged.return_value = [
+ servers[page_size:], False, True]
self.mock_servers_update_addresses.return_value = None
self.mock_flavor_list.return_value = self.flavors.list()
self.mock_image_list_detailed.return_value = (self.images.list(),
@@ -4854,8 +4938,10 @@ class InstanceTests2(InstanceTestBase, InstanceTableTestMixin):
self.assertMessageCount(success=1)
search_opts = {'marker': servers[page_size - 1].id, 'paginate': True}
- self.mock_server_list.assert_called_once_with(
- helpers.IsHttpRequest(), search_opts=search_opts)
+ self.mock_server_list_paged.assert_called_once_with(
+ helpers.IsHttpRequest(),
+ sort_dir='desc',
+ search_opts=search_opts)
self.mock_servers_update_addresses.assert_called_once_with(
helpers.IsHttpRequest(), servers[page_size:])
self.mock_flavor_list.assert_called_once_with(helpers.IsHttpRequest())
diff --git a/openstack_dashboard/dashboards/project/instances/views.py b/openstack_dashboard/dashboards/project/instances/views.py
index 9d39f43c6..8ee4c2bb7 100644
--- a/openstack_dashboard/dashboards/project/instances/views.py
+++ b/openstack_dashboard/dashboards/project/instances/views.py
@@ -59,10 +59,13 @@ from openstack_dashboard.views import get_url_with_pagination
LOG = logging.getLogger(__name__)
-class IndexView(tables.DataTableView):
+class IndexView(tables.PagedTableMixin, tables.DataTableView):
table_class = project_tables.InstancesTable
page_title = _("Instances")
+ def has_prev_data(self, table):
+ return getattr(self, "_prev", False)
+
def has_more_data(self, table):
return self._more
@@ -85,13 +88,14 @@ class IndexView(tables.DataTableView):
exceptions.handle(self.request, ignore=True)
return {}
- def _get_instances(self, search_opts):
+ def _get_instances(self, search_opts, sort_dir):
try:
- instances, self._more = api.nova.server_list(
+ instances, self._more, self._prev = api.nova.server_list_paged(
self.request,
- search_opts=search_opts)
+ search_opts=search_opts,
+ sort_dir=sort_dir)
except Exception:
- self._more = False
+ self._more = self._prev = False
instances = []
exceptions.handle(self.request,
_('Unable to retrieve instances.'))
@@ -122,8 +126,7 @@ class IndexView(tables.DataTableView):
return instances
def get_data(self):
- marker = self.request.GET.get(
- project_tables.InstancesTable._meta.pagination_param, None)
+ marker, sort_dir = self._get_marker()
search_opts = self.get_filters({'marker': marker, 'paginate': True})
image_dict, flavor_dict = futurist_utils.call_functions_parallel(
@@ -137,7 +140,7 @@ class IndexView(tables.DataTableView):
self._more = False
return []
- instances = self._get_instances(search_opts)
+ instances = self._get_instances(search_opts, sort_dir)
# Loop through instances to get flavor info.
for instance in instances:
diff --git a/openstack_dashboard/test/integration_tests/tests/test_instances.py b/openstack_dashboard/test/integration_tests/tests/test_instances.py
index ec8521782..603e525d4 100644
--- a/openstack_dashboard/test/integration_tests/tests/test_instances.py
+++ b/openstack_dashboard/test/integration_tests/tests/test_instances.py
@@ -73,7 +73,7 @@ class TestInstances(helpers.TestCase):
first_page_definition = {'Next': True, 'Prev': False,
'Count': items_per_page,
'Names': [instance_list[1]]}
- second_page_definition = {'Next': False, 'Prev': False,
+ second_page_definition = {'Next': False, 'Prev': True,
'Count': items_per_page,
'Names': [instance_list[0]]}
settings_page = self.home_pg.go_to_settings_usersettingspage()
diff --git a/openstack_dashboard/test/unit/api/test_nova.py b/openstack_dashboard/test/unit/api/test_nova.py
index 59903bbf6..9adcb3de0 100644
--- a/openstack_dashboard/test/unit/api/test_nova.py
+++ b/openstack_dashboard/test/unit/api/test_nova.py
@@ -204,7 +204,8 @@ class ComputeApiTests(test.APIMockTestCase):
True,
{'all_tenants': True,
'marker': None,
- 'limit': page_size + 1})
+ 'limit': page_size + 1,
+ 'sort_dir': 'desc'})
@override_settings(API_RESULT_PAGE_SIZE=1)
@mock.patch.object(api.nova, 'novaclient')
@@ -229,7 +230,8 @@ class ComputeApiTests(test.APIMockTestCase):
True,
{'all_tenants': True,
'marker': None,
- 'limit': page_size + 1})
+ 'limit': page_size + 1,
+ 'sort_dir': 'desc'})
@mock.patch.object(api.nova, 'novaclient')
def test_usage_get(self, mock_novaclient):