Merge "GET volumes API sorting REST/volume/DB updates"
This commit is contained in:
commit
0d9d8b2ca7
@ -282,8 +282,9 @@ class VolumeController(wsgi.Controller):
|
|||||||
self._get_volume_search_options())
|
self._get_volume_search_options())
|
||||||
|
|
||||||
volumes = self.volume_api.get_all(context, marker=None, limit=None,
|
volumes = self.volume_api.get_all(context, marker=None, limit=None,
|
||||||
sort_key='created_at',
|
sort_keys=['created_at'],
|
||||||
sort_dir='desc', filters=search_opts,
|
sort_dirs=['desc'],
|
||||||
|
filters=search_opts,
|
||||||
viewable_admin_meta=True)
|
viewable_admin_meta=True)
|
||||||
|
|
||||||
volumes = [dict(vol.iteritems()) for vol in volumes]
|
volumes = [dict(vol.iteritems()) for vol in volumes]
|
||||||
|
@ -216,8 +216,7 @@ class VolumeController(wsgi.Controller):
|
|||||||
params = req.params.copy()
|
params = req.params.copy()
|
||||||
marker = params.pop('marker', None)
|
marker = params.pop('marker', None)
|
||||||
limit = params.pop('limit', None)
|
limit = params.pop('limit', None)
|
||||||
sort_key = params.pop('sort_key', 'created_at')
|
sort_keys, sort_dirs = common.get_sort_params(params)
|
||||||
sort_dir = params.pop('sort_dir', 'desc')
|
|
||||||
params.pop('offset', None)
|
params.pop('offset', None)
|
||||||
filters = params
|
filters = params
|
||||||
|
|
||||||
@ -236,8 +235,10 @@ class VolumeController(wsgi.Controller):
|
|||||||
except (ValueError, SyntaxError):
|
except (ValueError, SyntaxError):
|
||||||
LOG.debug('Could not evaluate value %s, assuming string', v)
|
LOG.debug('Could not evaluate value %s, assuming string', v)
|
||||||
|
|
||||||
volumes = self.volume_api.get_all(context, marker, limit, sort_key,
|
volumes = self.volume_api.get_all(context, marker, limit,
|
||||||
sort_dir, filters,
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
filters=filters,
|
||||||
viewable_admin_meta=True)
|
viewable_admin_meta=True)
|
||||||
|
|
||||||
volumes = [dict(vol.iteritems()) for vol in volumes]
|
volumes = [dict(vol.iteritems()) for vol in volumes]
|
||||||
|
@ -179,11 +179,11 @@ def volume_get(context, volume_id):
|
|||||||
return IMPL.volume_get(context, volume_id)
|
return IMPL.volume_get(context, volume_id)
|
||||||
|
|
||||||
|
|
||||||
def volume_get_all(context, marker, limit, sort_key, sort_dir,
|
def volume_get_all(context, marker, limit, sort_keys=None, sort_dirs=None,
|
||||||
filters=None):
|
filters=None):
|
||||||
"""Get all volumes."""
|
"""Get all volumes."""
|
||||||
return IMPL.volume_get_all(context, marker, limit, sort_key, sort_dir,
|
return IMPL.volume_get_all(context, marker, limit, sort_keys=sort_keys,
|
||||||
filters=filters)
|
sort_dirs=sort_dirs, filters=filters)
|
||||||
|
|
||||||
|
|
||||||
def volume_get_all_by_host(context, host, filters=None):
|
def volume_get_all_by_host(context, host, filters=None):
|
||||||
@ -196,11 +196,13 @@ def volume_get_all_by_group(context, group_id, filters=None):
|
|||||||
return IMPL.volume_get_all_by_group(context, group_id, filters=filters)
|
return IMPL.volume_get_all_by_group(context, group_id, filters=filters)
|
||||||
|
|
||||||
|
|
||||||
def volume_get_all_by_project(context, project_id, marker, limit, sort_key,
|
def volume_get_all_by_project(context, project_id, marker, limit,
|
||||||
sort_dir, filters=None):
|
sort_keys=None, sort_dirs=None, filters=None):
|
||||||
"""Get all volumes belonging to a project."""
|
"""Get all volumes belonging to a project."""
|
||||||
return IMPL.volume_get_all_by_project(context, project_id, marker, limit,
|
return IMPL.volume_get_all_by_project(context, project_id, marker, limit,
|
||||||
sort_key, sort_dir, filters=filters)
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
filters=filters)
|
||||||
|
|
||||||
|
|
||||||
def volume_get_iscsi_target_num(context, volume_id):
|
def volume_get_iscsi_target_num(context, volume_id):
|
||||||
|
@ -1183,16 +1183,22 @@ def volume_get(context, volume_id):
|
|||||||
|
|
||||||
|
|
||||||
@require_admin_context
|
@require_admin_context
|
||||||
def volume_get_all(context, marker, limit, sort_key, sort_dir,
|
def volume_get_all(context, marker, limit, sort_keys=None, sort_dirs=None,
|
||||||
filters=None):
|
filters=None):
|
||||||
"""Retrieves all volumes.
|
"""Retrieves all volumes.
|
||||||
|
|
||||||
|
If no sort parameters are specified then the returned volumes are sorted
|
||||||
|
first by the 'created_at' key and then by the 'id' key in descending
|
||||||
|
order.
|
||||||
|
|
||||||
:param context: context to query under
|
:param context: context to query under
|
||||||
:param marker: the last item of the previous page, used to determine the
|
:param marker: the last item of the previous page, used to determine the
|
||||||
next page of results to return
|
next page of results to return
|
||||||
:param limit: maximum number of items to return
|
:param limit: maximum number of items to return
|
||||||
:param sort_key: single attributes by which results should be sorted
|
:param sort_keys: list of attributes by which results should be sorted,
|
||||||
:param sort_dir: direction in which results should be sorted (asc, desc)
|
paired with corresponding item in sort_dirs
|
||||||
|
:param sort_dirs: list of directions in which results should be sorted,
|
||||||
|
paired with corresponding item in sort_keys
|
||||||
:param filters: dictionary of filters; values that are in lists, tuples,
|
:param filters: dictionary of filters; values that are in lists, tuples,
|
||||||
or sets cause an 'IN' operation, while exact matching
|
or sets cause an 'IN' operation, while exact matching
|
||||||
is used for other values, see _process_volume_filters
|
is used for other values, see _process_volume_filters
|
||||||
@ -1203,7 +1209,7 @@ def volume_get_all(context, marker, limit, sort_key, sort_dir,
|
|||||||
with session.begin():
|
with session.begin():
|
||||||
# Generate the query
|
# Generate the query
|
||||||
query = _generate_paginate_query(context, session, marker, limit,
|
query = _generate_paginate_query(context, session, marker, limit,
|
||||||
sort_key, sort_dir, filters)
|
sort_keys, sort_dirs, filters)
|
||||||
# No volumes would match, return empty list
|
# No volumes would match, return empty list
|
||||||
if query is None:
|
if query is None:
|
||||||
return []
|
return []
|
||||||
@ -1267,17 +1273,23 @@ def volume_get_all_by_group(context, group_id, filters=None):
|
|||||||
|
|
||||||
|
|
||||||
@require_context
|
@require_context
|
||||||
def volume_get_all_by_project(context, project_id, marker, limit, sort_key,
|
def volume_get_all_by_project(context, project_id, marker, limit,
|
||||||
sort_dir, filters=None):
|
sort_keys=None, sort_dirs=None, filters=None):
|
||||||
""""Retrieves all volumes in a project.
|
""""Retrieves all volumes in a project.
|
||||||
|
|
||||||
|
If no sort parameters are specified then the returned volumes are sorted
|
||||||
|
first by the 'created_at' key and then by the 'id' key in descending
|
||||||
|
order.
|
||||||
|
|
||||||
:param context: context to query under
|
:param context: context to query under
|
||||||
:param project_id: project for all volumes being retrieved
|
:param project_id: project for all volumes being retrieved
|
||||||
:param marker: the last item of the previous page, used to determine the
|
:param marker: the last item of the previous page, used to determine the
|
||||||
next page of results to return
|
next page of results to return
|
||||||
:param limit: maximum number of items to return
|
:param limit: maximum number of items to return
|
||||||
:param sort_key: single attributes by which results should be sorted
|
:param sort_keys: list of attributes by which results should be sorted,
|
||||||
:param sort_dir: direction in which results should be sorted (asc, desc)
|
paired with corresponding item in sort_dirs
|
||||||
|
:param sort_dirs: list of directions in which results should be sorted,
|
||||||
|
paired with corresponding item in sort_keys
|
||||||
:param filters: dictionary of filters; values that are in lists, tuples,
|
:param filters: dictionary of filters; values that are in lists, tuples,
|
||||||
or sets cause an 'IN' operation, while exact matching
|
or sets cause an 'IN' operation, while exact matching
|
||||||
is used for other values, see _process_volume_filters
|
is used for other values, see _process_volume_filters
|
||||||
@ -1292,15 +1304,15 @@ def volume_get_all_by_project(context, project_id, marker, limit, sort_key,
|
|||||||
filters['project_id'] = project_id
|
filters['project_id'] = project_id
|
||||||
# Generate the query
|
# Generate the query
|
||||||
query = _generate_paginate_query(context, session, marker, limit,
|
query = _generate_paginate_query(context, session, marker, limit,
|
||||||
sort_key, sort_dir, filters)
|
sort_keys, sort_dirs, filters)
|
||||||
# No volumes would match, return empty list
|
# No volumes would match, return empty list
|
||||||
if query is None:
|
if query is None:
|
||||||
return []
|
return []
|
||||||
return query.all()
|
return query.all()
|
||||||
|
|
||||||
|
|
||||||
def _generate_paginate_query(context, session, marker, limit, sort_key,
|
def _generate_paginate_query(context, session, marker, limit, sort_keys,
|
||||||
sort_dir, filters):
|
sort_dirs, filters):
|
||||||
"""Generate the query to include the filters and the paginate options.
|
"""Generate the query to include the filters and the paginate options.
|
||||||
|
|
||||||
Returns a query with sorting / pagination criteria added or None
|
Returns a query with sorting / pagination criteria added or None
|
||||||
@ -1311,14 +1323,19 @@ def _generate_paginate_query(context, session, marker, limit, sort_key,
|
|||||||
:param marker: the last item of the previous page; we returns the next
|
:param marker: the last item of the previous page; we returns the next
|
||||||
results after this value.
|
results after this value.
|
||||||
:param limit: maximum number of items to return
|
:param limit: maximum number of items to return
|
||||||
:param sort_key: single attributes by which results should be sorted
|
:param sort_keys: list of attributes by which results should be sorted,
|
||||||
:param sort_dir: direction in which results should be sorted (asc, desc)
|
paired with corresponding item in sort_dirs
|
||||||
|
:param sort_dirs: list of directions in which results should be sorted,
|
||||||
|
paired with corresponding item in sort_keys
|
||||||
:param filters: dictionary of filters; values that are in lists, tuples,
|
:param filters: dictionary of filters; values that are in lists, tuples,
|
||||||
or sets cause an 'IN' operation, while exact matching
|
or sets cause an 'IN' operation, while exact matching
|
||||||
is used for other values, see _process_volume_filters
|
is used for other values, see _process_volume_filters
|
||||||
function for more information
|
function for more information
|
||||||
:returns: updated query or None
|
:returns: updated query or None
|
||||||
"""
|
"""
|
||||||
|
sort_keys, sort_dirs = process_sort_params(sort_keys,
|
||||||
|
sort_dirs,
|
||||||
|
default_dir='desc')
|
||||||
query = _volume_get_query(context, session=session)
|
query = _volume_get_query(context, session=session)
|
||||||
|
|
||||||
if filters:
|
if filters:
|
||||||
@ -1331,9 +1348,9 @@ def _generate_paginate_query(context, session, marker, limit, sort_key,
|
|||||||
marker_volume = _volume_get(context, marker, session)
|
marker_volume = _volume_get(context, marker, session)
|
||||||
|
|
||||||
return sqlalchemyutils.paginate_query(query, models.Volume, limit,
|
return sqlalchemyutils.paginate_query(query, models.Volume, limit,
|
||||||
[sort_key, 'created_at', 'id'],
|
sort_keys,
|
||||||
marker=marker_volume,
|
marker=marker_volume,
|
||||||
sort_dir=sort_dir)
|
sort_dirs=sort_dirs)
|
||||||
|
|
||||||
|
|
||||||
def _process_volume_filters(query, filters):
|
def _process_volume_filters(query, filters):
|
||||||
|
@ -625,8 +625,8 @@ class VolumeApiTest(test.TestCase):
|
|||||||
def test_volume_detail_limit_offset(self):
|
def test_volume_detail_limit_offset(self):
|
||||||
def volume_detail_limit_offset(is_admin):
|
def volume_detail_limit_offset(is_admin):
|
||||||
def stub_volume_get_all_by_project(context, project_id, marker,
|
def stub_volume_get_all_by_project(context, project_id, marker,
|
||||||
limit, sort_key, sort_dir,
|
limit, sort_keys=None,
|
||||||
filters=None,
|
sort_dirs=None, filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return [
|
return [
|
||||||
stubs.stub_volume(1, display_name='vol1'),
|
stubs.stub_volume(1, display_name='vol1'),
|
||||||
@ -770,8 +770,8 @@ class VolumeApiTest(test.TestCase):
|
|||||||
req.environ = {'cinder.context': context}
|
req.environ = {'cinder.context': context}
|
||||||
self.controller._items(req, mock.Mock)
|
self.controller._items(req, mock.Mock)
|
||||||
get_all.assert_called_once_with(
|
get_all.assert_called_once_with(
|
||||||
context, sort_dir='desc', viewable_admin_meta=True,
|
context, sort_dirs=['desc'], viewable_admin_meta=True,
|
||||||
sort_key='created_at', limit=None,
|
sort_keys=['created_at'], limit=None,
|
||||||
filters={'display_name': 'Volume-573108026'}, marker=None)
|
filters={'display_name': 'Volume-573108026'}, marker=None)
|
||||||
|
|
||||||
@mock.patch('cinder.volume.api.API.get_all')
|
@mock.patch('cinder.volume.api.API.get_all')
|
||||||
@ -782,8 +782,8 @@ class VolumeApiTest(test.TestCase):
|
|||||||
req.environ = {'cinder.context': context}
|
req.environ = {'cinder.context': context}
|
||||||
self.controller._items(req, mock.Mock)
|
self.controller._items(req, mock.Mock)
|
||||||
get_all.assert_called_once_with(
|
get_all.assert_called_once_with(
|
||||||
context, sort_dir='desc', viewable_admin_meta=True,
|
context, sort_dirs=['desc'], viewable_admin_meta=True,
|
||||||
sort_key='created_at', limit=None,
|
sort_keys=['created_at'], limit=None,
|
||||||
filters={'id': ['1', '2', '3']}, marker=None)
|
filters={'id': ['1', '2', '3']}, marker=None)
|
||||||
|
|
||||||
@mock.patch('cinder.volume.api.API.get_all')
|
@mock.patch('cinder.volume.api.API.get_all')
|
||||||
@ -794,8 +794,8 @@ class VolumeApiTest(test.TestCase):
|
|||||||
req.environ = {'cinder.context': context}
|
req.environ = {'cinder.context': context}
|
||||||
self.controller._items(req, mock.Mock)
|
self.controller._items(req, mock.Mock)
|
||||||
get_all.assert_called_once_with(
|
get_all.assert_called_once_with(
|
||||||
context, sort_dir='desc', viewable_admin_meta=True,
|
context, sort_dirs=['desc'], viewable_admin_meta=True,
|
||||||
sort_key='created_at', limit=None, filters={'id': 'd+'},
|
sort_keys=['created_at'], limit=None, filters={'id': 'd+'},
|
||||||
marker=None)
|
marker=None)
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,15 +124,16 @@ def stub_volume_get_db(context, volume_id):
|
|||||||
|
|
||||||
|
|
||||||
def stub_volume_get_all(context, search_opts=None, marker=None, limit=None,
|
def stub_volume_get_all(context, search_opts=None, marker=None, limit=None,
|
||||||
sort_key='created_at', sort_dir='desc', filters=None,
|
sort_keys=None, sort_dirs=None, filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return [stub_volume(100, project_id='fake'),
|
return [stub_volume(100, project_id='fake'),
|
||||||
stub_volume(101, project_id='superfake'),
|
stub_volume(101, project_id='superfake'),
|
||||||
stub_volume(102, project_id='superduperfake')]
|
stub_volume(102, project_id='superduperfake')]
|
||||||
|
|
||||||
|
|
||||||
def stub_volume_get_all_by_project(self, context, marker, limit, sort_key,
|
def stub_volume_get_all_by_project(self, context, marker, limit,
|
||||||
sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
filters = filters or {}
|
filters = filters or {}
|
||||||
return [stub_volume_get(self, context, '1')]
|
return [stub_volume_get(self, context, '1')]
|
||||||
|
@ -928,7 +928,8 @@ class VolumeApiTest(test.TestCase):
|
|||||||
|
|
||||||
def test_volume_index_with_marker(self):
|
def test_volume_index_with_marker(self):
|
||||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return [
|
return [
|
||||||
stubs.stub_volume(1, display_name='vol1'),
|
stubs.stub_volume(1, display_name='vol1'),
|
||||||
@ -950,19 +951,27 @@ class VolumeApiTest(test.TestCase):
|
|||||||
stubs.stub_volume_get_all_by_project)
|
stubs.stub_volume_get_all_by_project)
|
||||||
self.stubs.Set(volume_api.API, 'get', stubs.stub_volume_get)
|
self.stubs.Set(volume_api.API, 'get', stubs.stub_volume_get)
|
||||||
|
|
||||||
req = fakes.HTTPRequest.blank('/v2/volumes?limit=1')
|
req = fakes.HTTPRequest.blank('/v2/volumes'
|
||||||
|
'?limit=1&name=foo'
|
||||||
|
'&sort=id1:asc')
|
||||||
res_dict = self.controller.index(req)
|
res_dict = self.controller.index(req)
|
||||||
volumes = res_dict['volumes']
|
volumes = res_dict['volumes']
|
||||||
self.assertEqual(len(volumes), 1)
|
self.assertEqual(len(volumes), 1)
|
||||||
|
|
||||||
# Ensure that the next link is correctly formatted
|
# Ensure that the next link is correctly formatted, it should
|
||||||
|
# contain the same limit, filter, and sort information as the
|
||||||
|
# original request as well as a marker; this ensures that the
|
||||||
|
# caller can simply use the "next" link and that they do not
|
||||||
|
# need to manually insert the limit and sort information.
|
||||||
links = res_dict['volumes_links']
|
links = res_dict['volumes_links']
|
||||||
self.assertEqual(links[0]['rel'], 'next')
|
self.assertEqual(links[0]['rel'], 'next')
|
||||||
href_parts = urlparse.urlparse(links[0]['href'])
|
href_parts = urlparse.urlparse(links[0]['href'])
|
||||||
self.assertEqual('/v2/fakeproject/volumes', href_parts.path)
|
self.assertEqual('/v2/fakeproject/volumes', href_parts.path)
|
||||||
params = urlparse.parse_qs(href_parts.query)
|
params = urlparse.parse_qs(href_parts.query)
|
||||||
self.assertTrue('marker' in params)
|
self.assertEqual(str(volumes[0]['id']), params['marker'][0])
|
||||||
self.assertEqual('1', params['limit'][0])
|
self.assertEqual('1', params['limit'][0])
|
||||||
|
self.assertEqual('foo', params['name'][0])
|
||||||
|
self.assertEqual('id1:asc', params['sort'][0])
|
||||||
|
|
||||||
def test_volume_index_limit_negative(self):
|
def test_volume_index_limit_negative(self):
|
||||||
req = fakes.HTTPRequest.blank('/v2/volumes?limit=-1')
|
req = fakes.HTTPRequest.blank('/v2/volumes?limit=-1')
|
||||||
@ -989,7 +998,8 @@ class VolumeApiTest(test.TestCase):
|
|||||||
|
|
||||||
def test_volume_index_limit_offset(self):
|
def test_volume_index_limit_offset(self):
|
||||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return [
|
return [
|
||||||
stubs.stub_volume(1, display_name='vol1'),
|
stubs.stub_volume(1, display_name='vol1'),
|
||||||
@ -1017,7 +1027,8 @@ class VolumeApiTest(test.TestCase):
|
|||||||
|
|
||||||
def test_volume_detail_with_marker(self):
|
def test_volume_detail_with_marker(self):
|
||||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return [
|
return [
|
||||||
stubs.stub_volume(1, display_name='vol1'),
|
stubs.stub_volume(1, display_name='vol1'),
|
||||||
@ -1078,7 +1089,8 @@ class VolumeApiTest(test.TestCase):
|
|||||||
|
|
||||||
def test_volume_detail_limit_offset(self):
|
def test_volume_detail_limit_offset(self):
|
||||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return [
|
return [
|
||||||
stubs.stub_volume(1, display_name='vol1'),
|
stubs.stub_volume(1, display_name='vol1'),
|
||||||
@ -1112,8 +1124,7 @@ class VolumeApiTest(test.TestCase):
|
|||||||
req)
|
req)
|
||||||
|
|
||||||
def test_volume_with_limit_zero(self):
|
def test_volume_with_limit_zero(self):
|
||||||
def stub_volume_get_all(context, marker, limit,
|
def stub_volume_get_all(context, marker, limit, **kwargs):
|
||||||
sort_key, sort_dir, **kwargs):
|
|
||||||
return []
|
return []
|
||||||
self.stubs.Set(db, 'volume_get_all', stub_volume_get_all)
|
self.stubs.Set(db, 'volume_get_all', stub_volume_get_all)
|
||||||
req = fakes.HTTPRequest.blank('/v2/volumes?limit=0')
|
req = fakes.HTTPRequest.blank('/v2/volumes?limit=0')
|
||||||
@ -1136,7 +1147,7 @@ class VolumeApiTest(test.TestCase):
|
|||||||
|
|
||||||
# Number of volumes equals the max, include next link
|
# Number of volumes equals the max, include next link
|
||||||
def stub_volume_get_all(context, marker, limit,
|
def stub_volume_get_all(context, marker, limit,
|
||||||
sort_key, sort_dir,
|
sort_keys=None, sort_dirs=None,
|
||||||
filters=None,
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
vols = [stubs.stub_volume(i)
|
vols = [stubs.stub_volume(i)
|
||||||
@ -1155,7 +1166,7 @@ class VolumeApiTest(test.TestCase):
|
|||||||
|
|
||||||
# Number of volumes less than max, do not include
|
# Number of volumes less than max, do not include
|
||||||
def stub_volume_get_all2(context, marker, limit,
|
def stub_volume_get_all2(context, marker, limit,
|
||||||
sort_key, sort_dir,
|
sort_keys=None, sort_dirs=None,
|
||||||
filters=None,
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
vols = [stubs.stub_volume(i)
|
vols = [stubs.stub_volume(i)
|
||||||
@ -1173,7 +1184,7 @@ class VolumeApiTest(test.TestCase):
|
|||||||
|
|
||||||
# Number of volumes more than the max, include next link
|
# Number of volumes more than the max, include next link
|
||||||
def stub_volume_get_all3(context, marker, limit,
|
def stub_volume_get_all3(context, marker, limit,
|
||||||
sort_key, sort_dir,
|
sort_keys=None, sort_dirs=None,
|
||||||
filters=None,
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
vols = [stubs.stub_volume(i)
|
vols = [stubs.stub_volume(i)
|
||||||
@ -1214,14 +1225,16 @@ class VolumeApiTest(test.TestCase):
|
|||||||
"""
|
"""
|
||||||
# Non-admin, project function should be called with no_migration_status
|
# Non-admin, project function should be called with no_migration_status
|
||||||
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
def stub_volume_get_all_by_project(context, project_id, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
self.assertEqual(filters['no_migration_targets'], True)
|
self.assertEqual(filters['no_migration_targets'], True)
|
||||||
self.assertFalse('all_tenants' in filters)
|
self.assertFalse('all_tenants' in filters)
|
||||||
return [stubs.stub_volume(1, display_name='vol1')]
|
return [stubs.stub_volume(1, display_name='vol1')]
|
||||||
|
|
||||||
def stub_volume_get_all(context, marker, limit,
|
def stub_volume_get_all(context, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return []
|
return []
|
||||||
self.stubs.Set(db, 'volume_get_all_by_project',
|
self.stubs.Set(db, 'volume_get_all_by_project',
|
||||||
@ -1238,13 +1251,15 @@ class VolumeApiTest(test.TestCase):
|
|||||||
# Admin, all_tenants is not set, project function should be called
|
# Admin, all_tenants is not set, project function should be called
|
||||||
# without no_migration_status
|
# without no_migration_status
|
||||||
def stub_volume_get_all_by_project2(context, project_id, marker, limit,
|
def stub_volume_get_all_by_project2(context, project_id, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
self.assertFalse('no_migration_targets' in filters)
|
self.assertFalse('no_migration_targets' in filters)
|
||||||
return [stubs.stub_volume(1, display_name='vol2')]
|
return [stubs.stub_volume(1, display_name='vol2')]
|
||||||
|
|
||||||
def stub_volume_get_all2(context, marker, limit,
|
def stub_volume_get_all2(context, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return []
|
return []
|
||||||
self.stubs.Set(db, 'volume_get_all_by_project',
|
self.stubs.Set(db, 'volume_get_all_by_project',
|
||||||
@ -1259,12 +1274,14 @@ class VolumeApiTest(test.TestCase):
|
|||||||
# Admin, all_tenants is set, get_all function should be called
|
# Admin, all_tenants is set, get_all function should be called
|
||||||
# without no_migration_status
|
# without no_migration_status
|
||||||
def stub_volume_get_all_by_project3(context, project_id, marker, limit,
|
def stub_volume_get_all_by_project3(context, project_id, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def stub_volume_get_all3(context, marker, limit,
|
def stub_volume_get_all3(context, marker, limit,
|
||||||
sort_key, sort_dir, filters=None,
|
sort_keys=None, sort_dirs=None,
|
||||||
|
filters=None,
|
||||||
viewable_admin_meta=False):
|
viewable_admin_meta=False):
|
||||||
self.assertFalse('no_migration_targets' in filters)
|
self.assertFalse('no_migration_targets' in filters)
|
||||||
self.assertFalse('all_tenants' in filters)
|
self.assertFalse('all_tenants' in filters)
|
||||||
@ -1551,8 +1568,10 @@ class VolumeApiTest(test.TestCase):
|
|||||||
self.controller._view_builder.detail_list = mock.Mock()
|
self.controller._view_builder.detail_list = mock.Mock()
|
||||||
self.controller._get_volumes(req, True)
|
self.controller._get_volumes(req, True)
|
||||||
get_all.assert_called_once_with(
|
get_all.assert_called_once_with(
|
||||||
context, None, None, 'created_at', 'desc',
|
context, None, None,
|
||||||
{'display_name': 'Volume-573108026'}, viewable_admin_meta=True)
|
sort_keys=['created_at'], sort_dirs=['desc'],
|
||||||
|
filters={'display_name': 'Volume-573108026'},
|
||||||
|
viewable_admin_meta=True)
|
||||||
|
|
||||||
@mock.patch('cinder.volume.api.API.get_all')
|
@mock.patch('cinder.volume.api.API.get_all')
|
||||||
def test_get_volumes_filter_with_list(self, get_all):
|
def test_get_volumes_filter_with_list(self, get_all):
|
||||||
@ -1563,8 +1582,9 @@ class VolumeApiTest(test.TestCase):
|
|||||||
self.controller._view_builder.detail_list = mock.Mock()
|
self.controller._view_builder.detail_list = mock.Mock()
|
||||||
self.controller._get_volumes(req, True)
|
self.controller._get_volumes(req, True)
|
||||||
get_all.assert_called_once_with(
|
get_all.assert_called_once_with(
|
||||||
context, None, None, 'created_at', 'desc',
|
context, None, None,
|
||||||
{'id': ['1', '2', '3']}, viewable_admin_meta=True)
|
sort_keys=['created_at'], sort_dirs=['desc'],
|
||||||
|
filters={'id': ['1', '2', '3']}, viewable_admin_meta=True)
|
||||||
|
|
||||||
@mock.patch('cinder.volume.api.API.get_all')
|
@mock.patch('cinder.volume.api.API.get_all')
|
||||||
def test_get_volumes_filter_with_expression(self, get_all):
|
def test_get_volumes_filter_with_expression(self, get_all):
|
||||||
@ -1575,8 +1595,9 @@ class VolumeApiTest(test.TestCase):
|
|||||||
self.controller._view_builder.detail_list = mock.Mock()
|
self.controller._view_builder.detail_list = mock.Mock()
|
||||||
self.controller._get_volumes(req, True)
|
self.controller._get_volumes(req, True)
|
||||||
get_all.assert_called_once_with(
|
get_all.assert_called_once_with(
|
||||||
context, None, None, 'created_at', 'desc',
|
context, None, None,
|
||||||
{'display_name': 'd-'}, viewable_admin_meta=True)
|
sort_keys=['created_at'], sort_dirs=['desc'],
|
||||||
|
filters={'display_name': 'd-'}, viewable_admin_meta=True)
|
||||||
|
|
||||||
|
|
||||||
class VolumeSerializerTest(test.TestCase):
|
class VolumeSerializerTest(test.TestCase):
|
||||||
|
@ -315,7 +315,7 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
{'host': 'h%d' % i, 'size': i})
|
{'host': 'h%d' % i, 'size': i})
|
||||||
for i in xrange(3)]
|
for i in xrange(3)]
|
||||||
self._assertEqualListsOfObjects(volumes, db.volume_get_all(
|
self._assertEqualListsOfObjects(volumes, db.volume_get_all(
|
||||||
self.ctxt, None, None, 'host', None))
|
self.ctxt, None, None, ['host'], None))
|
||||||
|
|
||||||
def test_volume_get_all_marker_passed(self):
|
def test_volume_get_all_marker_passed(self):
|
||||||
volumes = [
|
volumes = [
|
||||||
@ -326,7 +326,7 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
]
|
]
|
||||||
|
|
||||||
self._assertEqualListsOfObjects(volumes[2:], db.volume_get_all(
|
self._assertEqualListsOfObjects(volumes[2:], db.volume_get_all(
|
||||||
self.ctxt, 2, 2, 'id', None))
|
self.ctxt, 2, 2, ['id'], ['asc']))
|
||||||
|
|
||||||
def test_volume_get_all_by_host(self):
|
def test_volume_get_all_by_host(self):
|
||||||
volumes = []
|
volumes = []
|
||||||
@ -433,7 +433,7 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
self._assertEqualListsOfObjects(volumes[i],
|
self._assertEqualListsOfObjects(volumes[i],
|
||||||
db.volume_get_all_by_project(
|
db.volume_get_all_by_project(
|
||||||
self.ctxt, 'p%d' % i, None,
|
self.ctxt, 'p%d' % i, None,
|
||||||
None, 'host', None))
|
None, ['host'], None))
|
||||||
|
|
||||||
def test_volume_get_by_name(self):
|
def test_volume_get_by_name(self):
|
||||||
db.volume_create(self.ctxt, {'display_name': 'vol1'})
|
db.volume_create(self.ctxt, {'display_name': 'vol1'})
|
||||||
@ -441,17 +441,17 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
db.volume_create(self.ctxt, {'display_name': 'vol3'})
|
db.volume_create(self.ctxt, {'display_name': 'vol3'})
|
||||||
|
|
||||||
# no name filter
|
# no name filter
|
||||||
volumes = db.volume_get_all(self.ctxt, None, None, 'created_at',
|
volumes = db.volume_get_all(self.ctxt, None, None, ['created_at'],
|
||||||
'asc')
|
['asc'])
|
||||||
self.assertEqual(len(volumes), 3)
|
self.assertEqual(len(volumes), 3)
|
||||||
# filter on name
|
# filter on name
|
||||||
volumes = db.volume_get_all(self.ctxt, None, None, 'created_at',
|
volumes = db.volume_get_all(self.ctxt, None, None, ['created_at'],
|
||||||
'asc', {'display_name': 'vol2'})
|
['asc'], {'display_name': 'vol2'})
|
||||||
self.assertEqual(len(volumes), 1)
|
self.assertEqual(len(volumes), 1)
|
||||||
self.assertEqual(volumes[0]['display_name'], 'vol2')
|
self.assertEqual(volumes[0]['display_name'], 'vol2')
|
||||||
# filter no match
|
# filter no match
|
||||||
volumes = db.volume_get_all(self.ctxt, None, None, 'created_at',
|
volumes = db.volume_get_all(self.ctxt, None, None, ['created_at'],
|
||||||
'asc', {'display_name': 'vol4'})
|
['asc'], {'display_name': 'vol4'})
|
||||||
self.assertEqual(len(volumes), 0)
|
self.assertEqual(len(volumes), 0)
|
||||||
|
|
||||||
def test_volume_list_by_status(self):
|
def test_volume_list_by_status(self):
|
||||||
@ -463,47 +463,52 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
'status': 'in-use'})
|
'status': 'in-use'})
|
||||||
|
|
||||||
# no status filter
|
# no status filter
|
||||||
volumes = db.volume_get_all(self.ctxt, None, None, 'created_at',
|
volumes = db.volume_get_all(self.ctxt, None, None, ['created_at'],
|
||||||
'asc')
|
['asc'])
|
||||||
self.assertEqual(len(volumes), 3)
|
self.assertEqual(len(volumes), 3)
|
||||||
# single match
|
# single match
|
||||||
volumes = db.volume_get_all(self.ctxt, None, None, 'created_at',
|
volumes = db.volume_get_all(self.ctxt, None, None, ['created_at'],
|
||||||
'asc', {'status': 'in-use'})
|
['asc'], {'status': 'in-use'})
|
||||||
self.assertEqual(len(volumes), 1)
|
self.assertEqual(len(volumes), 1)
|
||||||
self.assertEqual(volumes[0]['status'], 'in-use')
|
self.assertEqual(volumes[0]['status'], 'in-use')
|
||||||
# multiple match
|
# multiple match
|
||||||
volumes = db.volume_get_all(self.ctxt, None, None, 'created_at',
|
volumes = db.volume_get_all(self.ctxt, None, None, ['created_at'],
|
||||||
'asc', {'status': 'available'})
|
['asc'], {'status': 'available'})
|
||||||
self.assertEqual(len(volumes), 2)
|
self.assertEqual(len(volumes), 2)
|
||||||
for volume in volumes:
|
for volume in volumes:
|
||||||
self.assertEqual(volume['status'], 'available')
|
self.assertEqual(volume['status'], 'available')
|
||||||
# multiple filters
|
# multiple filters
|
||||||
volumes = db.volume_get_all(self.ctxt, None, None, 'created_at',
|
volumes = db.volume_get_all(self.ctxt, None, None, ['created_at'],
|
||||||
'asc', {'status': 'available',
|
['asc'], {'status': 'available',
|
||||||
'display_name': 'vol1'})
|
'display_name': 'vol1'})
|
||||||
self.assertEqual(len(volumes), 1)
|
self.assertEqual(len(volumes), 1)
|
||||||
self.assertEqual(volumes[0]['display_name'], 'vol1')
|
self.assertEqual(volumes[0]['display_name'], 'vol1')
|
||||||
self.assertEqual(volumes[0]['status'], 'available')
|
self.assertEqual(volumes[0]['status'], 'available')
|
||||||
# no match
|
# no match
|
||||||
volumes = db.volume_get_all(self.ctxt, None, None, 'created_at',
|
volumes = db.volume_get_all(self.ctxt, None, None, ['created_at'],
|
||||||
'asc', {'status': 'in-use',
|
['asc'], {'status': 'in-use',
|
||||||
'display_name': 'vol1'})
|
'display_name': 'vol1'})
|
||||||
self.assertEqual(len(volumes), 0)
|
self.assertEqual(len(volumes), 0)
|
||||||
|
|
||||||
def _assertEqualsVolumeOrderResult(self, correct_order, limit=None,
|
def _assertEqualsVolumeOrderResult(self, correct_order, limit=None,
|
||||||
sort_key='created_at', sort_dir='asc',
|
sort_keys=None, sort_dirs=None,
|
||||||
filters=None, project_id=None,
|
filters=None, project_id=None,
|
||||||
|
marker=None,
|
||||||
match_keys=['id', 'display_name',
|
match_keys=['id', 'display_name',
|
||||||
'volume_metadata',
|
'volume_metadata',
|
||||||
'created_at']):
|
'created_at']):
|
||||||
""""Verifies that volumes are returned in the correct order."""
|
""""Verifies that volumes are returned in the correct order."""
|
||||||
if project_id:
|
if project_id:
|
||||||
result = db.volume_get_all_by_project(self.ctxt, project_id, None,
|
result = db.volume_get_all_by_project(self.ctxt, project_id,
|
||||||
limit, sort_key,
|
marker, limit,
|
||||||
sort_dir, filters=filters)
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
filters=filters)
|
||||||
else:
|
else:
|
||||||
result = db.volume_get_all(self.ctxt, None, limit, sort_key,
|
result = db.volume_get_all(self.ctxt, marker, limit,
|
||||||
sort_dir, filters=filters)
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
filters=filters)
|
||||||
self.assertEqual(len(correct_order), len(result))
|
self.assertEqual(len(correct_order), len(result))
|
||||||
for vol1, vol2 in zip(result, correct_order):
|
for vol1, vol2 in zip(result, correct_order):
|
||||||
for key in match_keys:
|
for key in match_keys:
|
||||||
@ -517,6 +522,7 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
self.assertDictMatch(val1_dict, val2_dict)
|
self.assertDictMatch(val1_dict, val2_dict)
|
||||||
else:
|
else:
|
||||||
self.assertEqual(val1, val2)
|
self.assertEqual(val1, val2)
|
||||||
|
return result
|
||||||
|
|
||||||
def test_volume_get_by_filter(self):
|
def test_volume_get_by_filter(self):
|
||||||
"""Verifies that all filtering is done at the DB layer."""
|
"""Verifies that all filtering is done at the DB layer."""
|
||||||
@ -543,7 +549,7 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
|
|
||||||
# By project, filter on size and name
|
# By project, filter on size and name
|
||||||
filters = {'size': '1'}
|
filters = {'size': '1'}
|
||||||
correct_order = [vols[0], vols[1]]
|
correct_order = [vols[1], vols[0]]
|
||||||
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
||||||
project_id='g1')
|
project_id='g1')
|
||||||
filters = {'size': '1', 'display_name': 'name_1'}
|
filters = {'size': '1', 'display_name': 'name_1'}
|
||||||
@ -553,18 +559,18 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
|
|
||||||
# Remove project scope
|
# Remove project scope
|
||||||
filters = {'size': '1'}
|
filters = {'size': '1'}
|
||||||
correct_order = [vols[0], vols[1], vols[6], vols[7]]
|
correct_order = [vols[7], vols[6], vols[1], vols[0]]
|
||||||
self._assertEqualsVolumeOrderResult(correct_order, filters=filters)
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters)
|
||||||
filters = {'size': '1', 'display_name': 'name_1'}
|
filters = {'size': '1', 'display_name': 'name_1'}
|
||||||
correct_order = [vols[1], vols[7]]
|
correct_order = [vols[7], vols[1]]
|
||||||
self._assertEqualsVolumeOrderResult(correct_order, filters=filters)
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters)
|
||||||
|
|
||||||
# Remove size constraint
|
# Remove size constraint
|
||||||
filters = {'display_name': 'name_1'}
|
filters = {'display_name': 'name_1'}
|
||||||
correct_order = [vols[1], vols[3], vols[5]]
|
correct_order = [vols[5], vols[3], vols[1]]
|
||||||
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
||||||
project_id='g1')
|
project_id='g1')
|
||||||
correct_order = [vols[1], vols[3], vols[5], vols[7]]
|
correct_order = [vols[7], vols[5], vols[3], vols[1]]
|
||||||
self._assertEqualsVolumeOrderResult(correct_order, filters=filters)
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters)
|
||||||
|
|
||||||
# Verify bogus values return nothing
|
# Verify bogus values return nothing
|
||||||
@ -598,7 +604,7 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
db.volume_admin_metadata_update(self.ctxt, vol5.id,
|
db.volume_admin_metadata_update(self.ctxt, vol5.id,
|
||||||
{"readonly": "True"}, False)
|
{"readonly": "True"}, False)
|
||||||
|
|
||||||
vols = [vol1, vol2, vol3, vol4, vol5]
|
vols = [vol5, vol4, vol3, vol2, vol1]
|
||||||
|
|
||||||
# Ensure we have 5 total instances
|
# Ensure we have 5 total instances
|
||||||
self._assertEqualsVolumeOrderResult(vols)
|
self._assertEqualsVolumeOrderResult(vols)
|
||||||
@ -609,20 +615,20 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
|
|
||||||
# Just the test2 volumes
|
# Just the test2 volumes
|
||||||
filters = {'display_name': 'test2'}
|
filters = {'display_name': 'test2'}
|
||||||
self._assertEqualsVolumeOrderResult([vol2, vol3], filters=filters)
|
self._assertEqualsVolumeOrderResult([vol3, vol2], filters=filters)
|
||||||
self._assertEqualsVolumeOrderResult([vol2], limit=1,
|
self._assertEqualsVolumeOrderResult([vol3], limit=1,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
self._assertEqualsVolumeOrderResult([vol2, vol3], limit=2,
|
self._assertEqualsVolumeOrderResult([vol3, vol2], limit=2,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
self._assertEqualsVolumeOrderResult([vol2, vol3], limit=100,
|
self._assertEqualsVolumeOrderResult([vol3, vol2], limit=100,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
|
|
||||||
# metadata filters
|
# metadata filters
|
||||||
filters = {'metadata': {'key1': 'val1'}}
|
filters = {'metadata': {'key1': 'val1'}}
|
||||||
self._assertEqualsVolumeOrderResult([vol3, vol4], filters=filters)
|
self._assertEqualsVolumeOrderResult([vol4, vol3], filters=filters)
|
||||||
self._assertEqualsVolumeOrderResult([vol3], limit=1,
|
self._assertEqualsVolumeOrderResult([vol4], limit=1,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
self._assertEqualsVolumeOrderResult([vol3, vol4], limit=10,
|
self._assertEqualsVolumeOrderResult([vol4, vol3], limit=10,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
|
|
||||||
filters = {'metadata': {'readonly': 'True'}}
|
filters = {'metadata': {'readonly': 'True'}}
|
||||||
@ -675,22 +681,160 @@ class DBAPIVolumeTestCase(BaseTest):
|
|||||||
'migration_status': 'btarget:'})
|
'migration_status': 'btarget:'})
|
||||||
vol4 = db.volume_create(self.ctxt, {'display_name': 'test4',
|
vol4 = db.volume_create(self.ctxt, {'display_name': 'test4',
|
||||||
'migration_status': 'target:'})
|
'migration_status': 'target:'})
|
||||||
vols = [vol1, vol2, vol3, vol4]
|
|
||||||
|
|
||||||
# Ensure we have 4 total instances
|
# Ensure we have 4 total instances, default sort of created_at (desc)
|
||||||
self._assertEqualsVolumeOrderResult(vols)
|
self._assertEqualsVolumeOrderResult([vol4, vol3, vol2, vol1])
|
||||||
|
|
||||||
# Apply the unique filter
|
# Apply the unique filter
|
||||||
filters = {'no_migration_targets': True}
|
filters = {'no_migration_targets': True}
|
||||||
self._assertEqualsVolumeOrderResult([vol1, vol2, vol3],
|
self._assertEqualsVolumeOrderResult([vol3, vol2, vol1],
|
||||||
filters=filters)
|
filters=filters)
|
||||||
self._assertEqualsVolumeOrderResult([vol1, vol2], limit=2,
|
self._assertEqualsVolumeOrderResult([vol3, vol2], limit=2,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
|
|
||||||
filters = {'no_migration_targets': True,
|
filters = {'no_migration_targets': True,
|
||||||
'display_name': 'test4'}
|
'display_name': 'test4'}
|
||||||
self._assertEqualsVolumeOrderResult([], filters=filters)
|
self._assertEqualsVolumeOrderResult([], filters=filters)
|
||||||
|
|
||||||
|
def test_volume_get_all_by_filters_sort_keys(self):
|
||||||
|
# Volumes that will reply to the query
|
||||||
|
test_h1_avail = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'status': 'available',
|
||||||
|
'host': 'h1'})
|
||||||
|
test_h1_error = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'status': 'error',
|
||||||
|
'host': 'h1'})
|
||||||
|
test_h1_error2 = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'status': 'error',
|
||||||
|
'host': 'h1'})
|
||||||
|
test_h2_avail = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'status': 'available',
|
||||||
|
'host': 'h2'})
|
||||||
|
test_h2_error = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'status': 'error',
|
||||||
|
'host': 'h2'})
|
||||||
|
test_h2_error2 = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'status': 'error',
|
||||||
|
'host': 'h2'})
|
||||||
|
# Other volumes in the DB, will not match name filter
|
||||||
|
other_error = db.volume_create(self.ctxt, {'display_name': 'other',
|
||||||
|
'status': 'error',
|
||||||
|
'host': 'a'})
|
||||||
|
other_active = db.volume_create(self.ctxt, {'display_name': 'other',
|
||||||
|
'status': 'available',
|
||||||
|
'host': 'a'})
|
||||||
|
filters = {'display_name': 'test'}
|
||||||
|
|
||||||
|
# Verify different sort key/direction combinations
|
||||||
|
sort_keys = ['host', 'status', 'created_at']
|
||||||
|
sort_dirs = ['asc', 'asc', 'asc']
|
||||||
|
correct_order = [test_h1_avail, test_h1_error, test_h1_error2,
|
||||||
|
test_h2_avail, test_h2_error, test_h2_error2]
|
||||||
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs)
|
||||||
|
|
||||||
|
sort_dirs = ['asc', 'desc', 'asc']
|
||||||
|
correct_order = [test_h1_error, test_h1_error2, test_h1_avail,
|
||||||
|
test_h2_error, test_h2_error2, test_h2_avail]
|
||||||
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs)
|
||||||
|
|
||||||
|
sort_dirs = ['desc', 'desc', 'asc']
|
||||||
|
correct_order = [test_h2_error, test_h2_error2, test_h2_avail,
|
||||||
|
test_h1_error, test_h1_error2, test_h1_avail]
|
||||||
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs)
|
||||||
|
|
||||||
|
# created_at is added by default if not supplied, descending order
|
||||||
|
sort_keys = ['host', 'status']
|
||||||
|
sort_dirs = ['desc', 'desc']
|
||||||
|
correct_order = [test_h2_error2, test_h2_error, test_h2_avail,
|
||||||
|
test_h1_error2, test_h1_error, test_h1_avail]
|
||||||
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs)
|
||||||
|
|
||||||
|
sort_dirs = ['asc', 'asc']
|
||||||
|
correct_order = [test_h1_avail, test_h1_error, test_h1_error2,
|
||||||
|
test_h2_avail, test_h2_error, test_h2_error2]
|
||||||
|
self._assertEqualsVolumeOrderResult(correct_order, filters=filters,
|
||||||
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs)
|
||||||
|
|
||||||
|
# Remove name filter
|
||||||
|
correct_order = [other_active, other_error,
|
||||||
|
test_h1_avail, test_h1_error, test_h1_error2,
|
||||||
|
test_h2_avail, test_h2_error, test_h2_error2]
|
||||||
|
self._assertEqualsVolumeOrderResult(correct_order, sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs)
|
||||||
|
|
||||||
|
# No sort data, default sort of created_at, id (desc)
|
||||||
|
correct_order = [other_active, other_error,
|
||||||
|
test_h2_error2, test_h2_error, test_h2_avail,
|
||||||
|
test_h1_error2, test_h1_error, test_h1_avail]
|
||||||
|
self._assertEqualsVolumeOrderResult(correct_order)
|
||||||
|
|
||||||
|
def test_volume_get_all_by_filters_sort_keys_paginate(self):
|
||||||
|
'''Verifies sort order with pagination.'''
|
||||||
|
# Volumes that will reply to the query
|
||||||
|
test1_avail = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'size': 1,
|
||||||
|
'status': 'available'})
|
||||||
|
test1_error = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'size': 1,
|
||||||
|
'status': 'error'})
|
||||||
|
test1_error2 = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'size': 1,
|
||||||
|
'status': 'error'})
|
||||||
|
test2_avail = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'size': 2,
|
||||||
|
'status': 'available'})
|
||||||
|
test2_error = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'size': 2,
|
||||||
|
'status': 'error'})
|
||||||
|
test2_error2 = db.volume_create(self.ctxt, {'display_name': 'test',
|
||||||
|
'size': 2,
|
||||||
|
'status': 'error'})
|
||||||
|
|
||||||
|
# Other volumes in the DB, will not match name filter
|
||||||
|
db.volume_create(self.ctxt, {'display_name': 'other'})
|
||||||
|
db.volume_create(self.ctxt, {'display_name': 'other'})
|
||||||
|
filters = {'display_name': 'test'}
|
||||||
|
# Common sort information for every query
|
||||||
|
sort_keys = ['size', 'status', 'created_at']
|
||||||
|
sort_dirs = ['asc', 'desc', 'asc']
|
||||||
|
# Overall correct volume order based on the sort keys
|
||||||
|
correct_order = [test1_error, test1_error2, test1_avail,
|
||||||
|
test2_error, test2_error2, test2_avail]
|
||||||
|
|
||||||
|
# Limits of 1, 2, and 3, verify that the volumes returned are in the
|
||||||
|
# correct sorted order, update the marker to get the next correct page
|
||||||
|
for limit in range(1, 4):
|
||||||
|
marker = None
|
||||||
|
# Include the maximum number of volumes (ie, 6) to ensure that
|
||||||
|
# the last query (with marker pointing to the last volume)
|
||||||
|
# returns 0 servers
|
||||||
|
for i in range(0, 7, limit):
|
||||||
|
if i == len(correct_order):
|
||||||
|
correct = []
|
||||||
|
else:
|
||||||
|
correct = correct_order[i:i + limit]
|
||||||
|
vols = self._assertEqualsVolumeOrderResult(
|
||||||
|
correct, filters=filters,
|
||||||
|
sort_keys=sort_keys, sort_dirs=sort_dirs,
|
||||||
|
limit=limit, marker=marker)
|
||||||
|
if correct:
|
||||||
|
marker = vols[-1]['id']
|
||||||
|
self.assertEqual(correct[-1]['id'], marker)
|
||||||
|
|
||||||
|
def test_volume_get_all_invalid_sort_key(self):
|
||||||
|
for keys in (['foo'], ['display_name', 'foo']):
|
||||||
|
self.assertRaises(exception.InvalidInput, db.volume_get_all,
|
||||||
|
self.ctxt, None, None, sort_keys=keys)
|
||||||
|
|
||||||
def test_volume_get_iscsi_target_num(self):
|
def test_volume_get_iscsi_target_num(self):
|
||||||
db.iscsi_target_create_safe(self.ctxt, {'volume_id': 42,
|
db.iscsi_target_create_safe(self.ctxt, {'volume_id': 42,
|
||||||
'target_num': 43})
|
'target_num': 43})
|
||||||
|
@ -375,8 +375,8 @@ class API(base.Base):
|
|||||||
|
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def get_all(self, context, marker=None, limit=None, sort_key='created_at',
|
def get_all(self, context, marker=None, limit=None, sort_keys=None,
|
||||||
sort_dir='desc', filters=None, viewable_admin_meta=False):
|
sort_dirs=None, filters=None, viewable_admin_meta=False):
|
||||||
check_policy(context, 'get_all')
|
check_policy(context, 'get_all')
|
||||||
|
|
||||||
if filters is None:
|
if filters is None:
|
||||||
@ -407,15 +407,18 @@ class API(base.Base):
|
|||||||
if context.is_admin and allTenants:
|
if context.is_admin and allTenants:
|
||||||
# Need to remove all_tenants to pass the filtering below.
|
# Need to remove all_tenants to pass the filtering below.
|
||||||
del filters['all_tenants']
|
del filters['all_tenants']
|
||||||
volumes = self.db.volume_get_all(context, marker, limit, sort_key,
|
volumes = self.db.volume_get_all(context, marker, limit,
|
||||||
sort_dir, filters=filters)
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
|
filters=filters)
|
||||||
else:
|
else:
|
||||||
if viewable_admin_meta:
|
if viewable_admin_meta:
|
||||||
context = context.elevated()
|
context = context.elevated()
|
||||||
volumes = self.db.volume_get_all_by_project(context,
|
volumes = self.db.volume_get_all_by_project(context,
|
||||||
context.project_id,
|
context.project_id,
|
||||||
marker, limit,
|
marker, limit,
|
||||||
sort_key, sort_dir,
|
sort_keys=sort_keys,
|
||||||
|
sort_dirs=sort_dirs,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
|
|
||||||
return volumes
|
return volumes
|
||||||
|
@ -258,8 +258,7 @@ class VolumeManager(manager.SchedulerDependentManager):
|
|||||||
|
|
||||||
:param ctxt: our working context
|
:param ctxt: our working context
|
||||||
"""
|
"""
|
||||||
vol_entries = self.db.volume_get_all(ctxt, None, 1, 'created_at',
|
vol_entries = self.db.volume_get_all(ctxt, None, 1, filters=None)
|
||||||
None, filters=None)
|
|
||||||
|
|
||||||
if len(vol_entries) == 0:
|
if len(vol_entries) == 0:
|
||||||
LOG.info(_LI("Determined volume DB was empty at startup."))
|
LOG.info(_LI("Determined volume DB was empty at startup."))
|
||||||
|
Loading…
Reference in New Issue
Block a user