Merge "Add pagination to stack list"

This commit is contained in:
Jenkins 2014-04-08 09:59:24 +00:00 committed by Gerrit Code Review
commit c0fb123953
6 changed files with 129 additions and 47 deletions

View File

@ -16,6 +16,7 @@ import logging
from django.conf import settings
from heatclient import client as heat_client
from horizon.utils import functions as utils
from openstack_dashboard.api import base
LOG = logging.getLogger(__name__)
@ -52,8 +53,29 @@ def heatclient(request, password=None):
return client
def stacks_list(request):
return [stack for stack in heatclient(request).stacks.list()]
def stacks_list(request, marker=None, paginate=False):
limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
page_size = utils.get_page_size(request)
if paginate:
request_size = page_size + 1
else:
request_size = limit
kwargs = {}
if marker:
kwargs['marker'] = marker
stacks_iter = heatclient(request).stacks.list(limit=request_size,
**kwargs)
has_more_data = False
stacks = list(stacks_iter)
if paginate:
if len(stacks) > page_size:
stacks.pop()
has_more_data = True
return (stacks, has_more_data)
def stack_delete(request, stack_id):

View File

@ -109,6 +109,7 @@ class StacksTable(tables.DataTable):
class Meta:
name = "stacks"
verbose_name = _("Stacks")
pagination_param = 'stack_marker'
status_columns = ["status", ]
row_class = StacksUpdateRow
table_actions = (LaunchStack, DeleteStack,)

View File

@ -14,9 +14,11 @@
import json
from django.conf import settings
from django.core import exceptions
from django.core.urlresolvers import reverse
from django import http
from django.test.utils import override_settings # noqa
from mox import IsA # noqa
@ -25,6 +27,7 @@ from openstack_dashboard.test import helpers as test
from openstack_dashboard.dashboards.project.stacks import forms
from openstack_dashboard.dashboards.project.stacks import mappings
from openstack_dashboard.dashboards.project.stacks import tables
INDEX_URL = reverse('horizon:project:stacks:index')
@ -93,20 +96,59 @@ class MappingsTests(test.TestCase):
class StackTests(test.TestCase):
@override_settings(API_RESULT_PAGE_SIZE=2)
@test.create_stubs({api.heat: ('stacks_list',)})
def test_index(self):
stacks = self.stacks.list()
def test_index_paginated(self):
stacks = self.stacks.list()[:5]
# import pdb; pdb.set_trace()
api.heat.stacks_list(IsA(http.HttpRequest)) \
.AndReturn(stacks)
api.heat.stacks_list(IsA(http.HttpRequest),
marker=None,
paginate=True) \
.AndReturn([stacks,
True])
api.heat.stacks_list(IsA(http.HttpRequest),
marker=None,
paginate=True) \
.AndReturn([stacks[:2],
True])
api.heat.stacks_list(IsA(http.HttpRequest),
marker=stacks[2].id,
paginate=True) \
.AndReturn([stacks[2:4],
True])
api.heat.stacks_list(IsA(http.HttpRequest),
marker=stacks[4].id,
paginate=True) \
.AndReturn([stacks[4:],
True])
self.mox.ReplayAll()
res = self.client.get(INDEX_URL)
url = reverse('horizon:project:stacks:index')
res = self.client.get(url)
# get all
self.assertEqual(len(res.context['stacks_table'].data),
len(stacks))
self.assertTemplateUsed(res, 'project/stacks/index.html')
self.assertIn('table', res.context)
resp_stacks = res.context['table'].data
self.assertEqual(len(resp_stacks), len(stacks))
res = self.client.get(url)
# get first page with 2 items
self.assertEqual(len(res.context['stacks_table'].data),
settings.API_RESULT_PAGE_SIZE)
url = "%s?%s=%s" % (reverse('horizon:project:stacks:index'),
tables.StacksTable._meta.pagination_param, stacks[2].id)
res = self.client.get(url)
# get second page (items 2-4)
self.assertEqual(len(res.context['stacks_table'].data),
settings.API_RESULT_PAGE_SIZE)
url = "%s?%s=%s" % (reverse('horizon:project:stacks:index'),
tables.StacksTable._meta.pagination_param, stacks[4].id)
res = self.client.get(url)
# get third page (item 5)
self.assertEqual(len(res.context['stacks_table'].data),
1)
@test.create_stubs({api.heat: ('stack_create', 'template_validate')})
def test_launch_stack(self):

View File

@ -46,13 +46,25 @@ class IndexView(tables.DataTableView):
table_class = project_tables.StacksTable
template_name = 'project/stacks/index.html'
def __init__(self, *args, **kwargs):
super(IndexView, self).__init__(*args, **kwargs)
self._more = None
def has_more_data(self, table):
return self._more
def get_data(self):
request = self.request
stacks = []
marker = self.request.GET.get(
project_tables.StacksTable._meta.pagination_param)
try:
stacks = api.heat.stacks_list(self.request)
stacks, self._more = api.heat.stacks_list(self.request,
marker=marker,
paginate=True)
except Exception:
exceptions.handle(request, _('Unable to retrieve stack list.'))
stacks = []
self._more = False
msg = _('Unable to retrieve stack list.')
exceptions.handle(self.request, msg)
return stacks

View File

@ -12,6 +12,9 @@
# License for the specific language governing permissions and limitations
# under the License.
from django.conf import settings
from django.test.utils import override_settings # noqa
from openstack_dashboard import api
from openstack_dashboard.test import helpers as test
@ -19,13 +22,15 @@ from openstack_dashboard.test import helpers as test
class HeatApiTests(test.APITestCase):
def test_stack_list(self):
api_stacks = self.stacks.list()
limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
heatclient = self.stub_heatclient()
heatclient.stacks = self.mox.CreateMockAnything()
heatclient.stacks.list().AndReturn(iter(api_stacks))
heatclient.stacks.list(limit=limit).AndReturn(iter(api_stacks))
self.mox.ReplayAll()
stacks = api.heat.stacks_list(self.request)
stacks, has_more = api.heat.stacks_list(self.request)
self.assertItemsEqual(stacks, api_stacks)
self.assertFalse(has_more)
def test_template_get(self):
api_stacks = self.stacks.list()

View File

@ -329,36 +329,36 @@ def data(TEST):
TEST.stack_templates = utils.TestDataContainer()
TEST.stack_environments = utils.TestDataContainer()
# Stacks
stack1 = {
"description": "No description",
"links": [{
"href": "http://192.168.1.70:8004/v1/"
"051c727ee67040d6a7b7812708485a97/"
"stacks/stack-1211-38/"
"05b4f39f-ea96-4d91-910c-e758c078a089",
"rel": "self"
}],
"parameters": {
'DBUsername': '******',
'InstanceType': 'm1.small',
'AWS::StackId':
'arn:openstack:heat::2ce287:stacks/teststack/88553ec',
'DBRootPassword': '******',
'AWS::StackName': 'teststack',
'DBPassword': '******',
'AWS::Region': 'ap-southeast-1',
'DBName': u'wordpress'
},
"stack_status_reason": "Stack successfully created",
"stack_name": "stack-test",
"creation_time": "2013-04-22T00:11:39Z",
"updated_time": "null",
"stack_status": "CREATE_COMPLETE",
"id": "05b4f39f-ea96-4d91-910c-e758c078a089"
}
stack = stacks.Stack(stacks.StackManager(None), stack1)
TEST.stacks.add(stack)
for i in range(10):
stack_data = {
"description": "No description",
"links": [{
"href": "http://192.168.1.70:8004/v1/"
"051c727ee67040d6a7b7812708485a97/"
"stacks/stack-1211-38/"
"05b4f39f-ea96-4d91-910c-e758c078a089",
"rel": "self"
}],
"parameters": {
'DBUsername': '******',
'InstanceType': 'm1.small',
'AWS::StackId':
'arn:openstack:heat::2ce287:stacks/teststack/88553ec',
'DBRootPassword': '******',
'AWS::StackName': "teststack{0}".format(i),
'DBPassword': '******',
'AWS::Region': 'ap-southeast-1',
'DBName': u'wordpress'
},
"stack_status_reason": "Stack successfully created",
"stack_name": "stack-test{0}".format(i),
"creation_time": "2013-04-22T00:11:39Z",
"updated_time": "2013-04-22T00:11:39Z",
"stack_status": "CREATE_COMPLETE",
"id": "05b4f39f-ea96-4d91-910c-e758c078a089{0}".format(i)
}
stack = stacks.Stack(stacks.StackManager(None), stack_data)
TEST.stacks.add(stack)
TEST.stack_templates.add(Template(TEMPLATE, VALIDATE))
TEST.stack_environments.add(Environment(ENVIRONMENT))