Added 'page_size' param to image list

Added a new query param called 'page_size' to
accepted_query_params list in image list call.
This param is passed on to glance-client which will
be used to paginate the result set.

Fixes bug 1200233

Change-Id: I1c804c74c153e80bb572ec45283ebd9b6b7b41c5
This commit is contained in:
Sumanth Nagadavalli 2013-08-29 10:27:08 +05:30
parent 91de035005
commit d3aa5c59e0
6 changed files with 61 additions and 13 deletions

View File

@ -150,23 +150,25 @@ def get_pagination_params(request):
"""
params = {}
if 'limit' in request.GET:
params['limit'] = _get_limit_param(request)
params['limit'] = _get_int_param(request, 'limit')
if 'page_size' in request.GET:
params['page_size'] = _get_int_param(request, 'page_size')
if 'marker' in request.GET:
params['marker'] = _get_marker_param(request)
return params
def _get_limit_param(request):
"""Extract integer limit from request or fail."""
def _get_int_param(request, param):
"""Extract integer param from request or fail."""
try:
limit = int(request.GET['limit'])
int_param = int(request.GET[param])
except ValueError:
msg = _('limit param must be an integer')
msg = _('%s param must be an integer') % param
raise webob.exc.HTTPBadRequest(explanation=msg)
if limit < 0:
msg = _('limit param must be positive')
if int_param < 0:
msg = _('%s param must be positive') % param
raise webob.exc.HTTPBadRequest(explanation=msg)
return limit
return int_param
def _get_marker_param(request):

View File

@ -270,7 +270,7 @@ class GlanceImageService(object):
def _extract_query_params(self, params):
_params = {}
accepted_params = ('filters', 'marker', 'limit',
'sort_key', 'sort_dir')
'page_size', 'sort_key', 'sort_dir')
for param in accepted_params:
if params.get(param):
_params[param] = params.get(param)

View File

@ -275,6 +275,25 @@ class ImagesControllerTest(test.TestCase):
self.assertThat({'limit': ['2'], 'marker': ['124']},
matchers.DictMatches(params))
def test_get_image_details_with_limit_and_page_size(self):
request = fakes.HTTPRequest.blank(
'/v2/fake/images/detail?limit=2&page_size=1')
response = self.controller.detail(request)
response_list = response["images"]
response_links = response["images_links"]
expected = [self.expected_image_123["image"],
self.expected_image_124["image"]]
self.assertThat(expected, matchers.DictListMatches(response_list))
href_parts = urlparse.urlparse(response_links[0]['href'])
self.assertEqual('/v2/fake/images', href_parts.path)
params = urlparse.parse_qs(href_parts.query)
self.assertThat({'limit': ['2'], 'page_size': ['1'],
'marker': ['124']}, matchers.DictMatches(params))
def _detail_request(self, filters, request):
context = request.environ['nova.context']
self.image_service.detail(context, filters=filters).AndReturn([])

View File

@ -196,6 +196,24 @@ class PaginationParamsTest(test.TestCase):
self.assertEqual(common.get_pagination_params(req),
{'marker': marker, 'limit': 20})
def test_valid_page_size(self):
# Test valid page_size param.
req = webob.Request.blank('/?page_size=10')
self.assertEqual(common.get_pagination_params(req),
{'page_size': 10})
def test_invalid_page_size(self):
# Test invalid page_size param.
req = webob.Request.blank('/?page_size=-2')
self.assertRaises(
webob.exc.HTTPBadRequest, common.get_pagination_params, req)
def test_valid_limit_and_page_size(self):
# Test valid limit and page_size parameters.
req = webob.Request.blank('/?limit=20&page_size=5')
self.assertEqual(common.get_pagination_params(req),
{'page_size': 5, 'limit': 20})
class MiscFunctionsTest(test.TestCase):

View File

@ -40,7 +40,7 @@ class StubGlanceClient(object):
setattr(self.images, fn, getattr(self, fn))
#TODO(bcwaldon): implement filters
def list(self, filters=None, marker=None, limit=30):
def list(self, filters=None, marker=None, limit=30, page_size=20):
if marker is None:
index = 0
else:
@ -50,7 +50,6 @@ class StubGlanceClient(object):
break
else:
raise glanceclient.exc.BadRequest('Marker not found')
return self._images[index:index + limit]
def get(self, image_id):

View File

@ -26,6 +26,7 @@ import time
import sys
import testtools
from mock import patch
import mox
import glanceclient.exc
@ -34,6 +35,7 @@ from oslo.config import cfg
from nova import context
from nova import exception
from nova.image import glance
from nova.image.glance import GlanceClientWrapper
from nova import test
from nova.tests.api.openstack import fakes
from nova.tests.glance import stubs as glance_stubs
@ -115,8 +117,8 @@ class TestGlanceImageService(test.TestCase):
super(TestGlanceImageService, self).setUp()
fakes.stub_out_compute_api_snapshot(self.stubs)
client = glance_stubs.StubGlanceClient()
self.service = self._create_image_service(client)
self.client = glance_stubs.StubGlanceClient()
self.service = self._create_image_service(self.client)
self.context = context.RequestContext('fake', 'fake', auth_token=True)
self.mox = mox.Mox()
self.files_to_clean = []
@ -304,6 +306,14 @@ class TestGlanceImageService(test.TestCase):
image_metas = self.service.detail(self.context, limit=5)
self.assertEquals(len(image_metas), 5)
def test_page_size(self):
with patch.object(GlanceClientWrapper, 'call') as a_mock:
self.service.detail(self.context, page_size=5)
self.assertEquals(a_mock.called, True)
a_mock.assert_called_with(self.context, 1, 'list',
filters={'is_public': 'none'},
page_size=5)
def test_detail_default_limit(self):
fixtures = []
ids = []