diff --git a/doc/api_samples/all_extensions/extensions-get-resp.json b/doc/api_samples/all_extensions/extensions-get-resp.json index 8b227703dd2..ec9a4547d46 100644 --- a/doc/api_samples/all_extensions/extensions-get-resp.json +++ b/doc/api_samples/all_extensions/extensions-get-resp.json @@ -711,6 +711,14 @@ "name": "Volumes", "namespace": "http://docs.openstack.org/compute/ext/volumes/api/v1.1", "updated": "2011-03-25T00:00:00Z" + }, + { + "alias": "os-server-sort-keys", + "description": "Add sorting support in get Server v2 API.", + "links": [], + "name": "ServerSortKeys", + "namespace": "http://docs.openstack.org/compute/ext/server_sort_keys/api/v2", + "updated": "2014-05-22T00:00:00Z" } ] } diff --git a/doc/api_samples/all_extensions/extensions-get-resp.xml b/doc/api_samples/all_extensions/extensions-get-resp.xml index 727d19f0129..41f5a304f7a 100644 --- a/doc/api_samples/all_extensions/extensions-get-resp.xml +++ b/doc/api_samples/all_extensions/extensions-get-resp.xml @@ -287,4 +287,7 @@ Volumes support. + + Add sorting support in get Server v2 API. + diff --git a/doc/api_samples/os-server-sort-keys/server-post-req.json b/doc/api_samples/os-server-sort-keys/server-post-req.json new file mode 100644 index 00000000000..87fa57c516f --- /dev/null +++ b/doc/api_samples/os-server-sort-keys/server-post-req.json @@ -0,0 +1,7 @@ +{ + "server" : { + "name" : "new-server-test", + "imageRef" : "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "flavorRef" : "http://openstack.example.com/openstack/flavors/1" + } +} diff --git a/doc/api_samples/os-server-sort-keys/server-post-req.xml b/doc/api_samples/os-server-sort-keys/server-post-req.xml new file mode 100644 index 00000000000..d5cc736ee8d --- /dev/null +++ b/doc/api_samples/os-server-sort-keys/server-post-req.xml @@ -0,0 +1,3 @@ + + + diff --git a/doc/api_samples/os-server-sort-keys/server-post-resp.json b/doc/api_samples/os-server-sort-keys/server-post-resp.json new file mode 100644 index 00000000000..11aabffad25 --- /dev/null +++ b/doc/api_samples/os-server-sort-keys/server-post-resp.json @@ -0,0 +1,16 @@ +{ + "server": { + "adminPass": "jDje6SdBHGfQ", + "id": "e08e6d34-fcc1-480e-b11e-24a675b479f8", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8", + "rel": "bookmark" + } + ] + } +} diff --git a/doc/api_samples/os-server-sort-keys/server-post-resp.xml b/doc/api_samples/os-server-sort-keys/server-post-resp.xml new file mode 100644 index 00000000000..742d5158e2d --- /dev/null +++ b/doc/api_samples/os-server-sort-keys/server-post-resp.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/doc/api_samples/os-server-sort-keys/server-sort-keys-list-resp.json b/doc/api_samples/os-server-sort-keys/server-sort-keys-list-resp.json new file mode 100644 index 00000000000..2b8e5055d09 --- /dev/null +++ b/doc/api_samples/os-server-sort-keys/server-sort-keys-list-resp.json @@ -0,0 +1,18 @@ +{ + "servers": [ + { + "id": "e08e6d34-fcc1-480e-b11e-24a675b479f8", + "links": [ + { + "href": "http://openstack.example.com/v2/openstack/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8", + "rel": "self" + }, + { + "href": "http://openstack.example.com/openstack/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8", + "rel": "bookmark" + } + ], + "name": "new-server-test" + } + ] +} diff --git a/doc/api_samples/os-server-sort-keys/server-sort-keys-list-resp.xml b/doc/api_samples/os-server-sort-keys/server-sort-keys-list-resp.xml new file mode 100644 index 00000000000..abd876a7a58 --- /dev/null +++ b/doc/api_samples/os-server-sort-keys/server-sort-keys-list-resp.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/doc/v3/api_samples/servers-sort/server-post-req.json b/doc/v3/api_samples/servers-sort/server-post-req.json new file mode 100644 index 00000000000..87fa57c516f --- /dev/null +++ b/doc/v3/api_samples/servers-sort/server-post-req.json @@ -0,0 +1,7 @@ +{ + "server" : { + "name" : "new-server-test", + "imageRef" : "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b", + "flavorRef" : "http://openstack.example.com/openstack/flavors/1" + } +} diff --git a/doc/v3/api_samples/servers-sort/server-post-resp.json b/doc/v3/api_samples/servers-sort/server-post-resp.json new file mode 100644 index 00000000000..10d1ae16766 --- /dev/null +++ b/doc/v3/api_samples/servers-sort/server-post-resp.json @@ -0,0 +1,16 @@ +{ + "server": { + "adminPass": "jDje6SdBHGfQ", + "id": "e08e6d34-fcc1-480e-b11e-24a675b479f8", + "links": [ + { + "href": "http://openstack.example.com/v3/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8", + "rel": "self" + }, + { + "href": "http://openstack.example.com/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8", + "rel": "bookmark" + } + ] + } +} diff --git a/doc/v3/api_samples/servers-sort/server-sort-keys-list-resp.json b/doc/v3/api_samples/servers-sort/server-sort-keys-list-resp.json new file mode 100644 index 00000000000..e00d199a323 --- /dev/null +++ b/doc/v3/api_samples/servers-sort/server-sort-keys-list-resp.json @@ -0,0 +1,18 @@ +{ + "servers": [ + { + "id": "e08e6d34-fcc1-480e-b11e-24a675b479f8", + "links": [ + { + "href": "http://openstack.example.com/v3/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8", + "rel": "self" + }, + { + "href": "http://openstack.example.com/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8", + "rel": "bookmark" + } + ], + "name": "new-server-test" + } + ] +} diff --git a/nova/api/openstack/compute/contrib/server_sort_keys.py b/nova/api/openstack/compute/contrib/server_sort_keys.py new file mode 100644 index 00000000000..01ce14b7053 --- /dev/null +++ b/nova/api/openstack/compute/contrib/server_sort_keys.py @@ -0,0 +1,25 @@ +# Copyright 2014 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.api.openstack import extensions + + +class Server_sort_keys(extensions.ExtensionDescriptor): + """Add sort keys and directions to the Server GET v2 API.""" + + name = "ServerSortKeys" + alias = "os-server-sort-keys" + namespace = ("http://docs.openstack.org/compute/ext/" + "server_sort_keys/api/v2") + updated = "2014-05-22T00:00:00Z" diff --git a/nova/api/openstack/compute/plugins/v3/servers.py b/nova/api/openstack/compute/plugins/v3/servers.py index 4f1e97b335a..e638bd18bc4 100644 --- a/nova/api/openstack/compute/plugins/v3/servers.py +++ b/nova/api/openstack/compute/plugins/v3/servers.py @@ -350,10 +350,12 @@ def _get_servers(self, req, is_detail): search_opts['user_id'] = context.user_id limit, marker = common.get_limit_and_marker(req) + sort_keys, sort_dirs = common.get_sort_params(req.params) try: instance_list = self.compute_api.get_all(context, search_opts=search_opts, limit=limit, marker=marker, - want_objects=True, expected_attrs=['pci_devices']) + want_objects=True, expected_attrs=['pci_devices'], + sort_keys=sort_keys, sort_dirs=sort_dirs) except exception.MarkerNotFound: msg = _('marker [%s] not found') % marker raise exc.HTTPBadRequest(explanation=msg) diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index 1898a258849..0a062814766 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -596,12 +596,18 @@ def _get_servers(self, req, is_detail): search_opts['user_id'] = context.user_id limit, marker = common.get_limit_and_marker(req) + # Sorting by multiple keys and directions is conditionally enabled + sort_keys, sort_dirs = None, None + if self.ext_mgr.is_loaded('os-server-sort-keys'): + sort_keys, sort_dirs = common.get_sort_params(req.params) try: instance_list = self.compute_api.get_all(context, search_opts=search_opts, limit=limit, marker=marker, - want_objects=True) + want_objects=True, + sort_keys=sort_keys, + sort_dirs=sort_dirs) except exception.MarkerNotFound: msg = _('marker [%s] not found') % marker raise exc.HTTPBadRequest(explanation=msg) diff --git a/nova/tests/functional/api_samples/all_extensions/extensions-get-resp.json.tpl b/nova/tests/functional/api_samples/all_extensions/extensions-get-resp.json.tpl index 668e282e2b1..0815c7ab869 100644 --- a/nova/tests/functional/api_samples/all_extensions/extensions-get-resp.json.tpl +++ b/nova/tests/functional/api_samples/all_extensions/extensions-get-resp.json.tpl @@ -711,6 +711,14 @@ "name": "ServerGroupQuotas", "namespace": "http://docs.openstack.org/compute/ext/server-group-quotas/api/v2", "updated": "%(isotime)s" + }, + { + "alias": "os-server-sort-keys", + "description": "%(text)s", + "links": [], + "name": "ServerSortKeys", + "namespace": "http://docs.openstack.org/compute/ext/server_sort_keys/api/v2", + "updated": "%(isotime)s" } ] } diff --git a/nova/tests/functional/api_samples/all_extensions/extensions-get-resp.xml.tpl b/nova/tests/functional/api_samples/all_extensions/extensions-get-resp.xml.tpl index eaa679f35f8..ddd7faa993c 100644 --- a/nova/tests/functional/api_samples/all_extensions/extensions-get-resp.xml.tpl +++ b/nova/tests/functional/api_samples/all_extensions/extensions-get-resp.xml.tpl @@ -266,4 +266,7 @@ %(text)s + + %(text)s + diff --git a/nova/tests/functional/api_samples/os-server-sort-keys/server-post-req.json.tpl b/nova/tests/functional/api_samples/os-server-sort-keys/server-post-req.json.tpl new file mode 100644 index 00000000000..8fa8b6fe423 --- /dev/null +++ b/nova/tests/functional/api_samples/os-server-sort-keys/server-post-req.json.tpl @@ -0,0 +1,7 @@ +{ + "server" : { + "name" : "new-server-test", + "imageRef" : "%(host)s/openstack/images/%(image_id)s", + "flavorRef" : "%(host)s/openstack/flavors/1" + } +} diff --git a/nova/tests/functional/api_samples/os-server-sort-keys/server-post-req.xml.tpl b/nova/tests/functional/api_samples/os-server-sort-keys/server-post-req.xml.tpl new file mode 100644 index 00000000000..10370edc57a --- /dev/null +++ b/nova/tests/functional/api_samples/os-server-sort-keys/server-post-req.xml.tpl @@ -0,0 +1,3 @@ + + + diff --git a/nova/tests/functional/api_samples/os-server-sort-keys/server-post-resp.json.tpl b/nova/tests/functional/api_samples/os-server-sort-keys/server-post-resp.json.tpl new file mode 100644 index 00000000000..d5f030c8730 --- /dev/null +++ b/nova/tests/functional/api_samples/os-server-sort-keys/server-post-resp.json.tpl @@ -0,0 +1,16 @@ +{ + "server": { + "adminPass": "%(password)s", + "id": "%(id)s", + "links": [ + { + "href": "%(host)s/v2/openstack/servers/%(uuid)s", + "rel": "self" + }, + { + "href": "%(host)s/openstack/servers/%(uuid)s", + "rel": "bookmark" + } + ] + } +} diff --git a/nova/tests/functional/api_samples/os-server-sort-keys/server-post-resp.xml.tpl b/nova/tests/functional/api_samples/os-server-sort-keys/server-post-resp.xml.tpl new file mode 100644 index 00000000000..3bb13e69bd6 --- /dev/null +++ b/nova/tests/functional/api_samples/os-server-sort-keys/server-post-resp.xml.tpl @@ -0,0 +1,6 @@ + + + + + + diff --git a/nova/tests/functional/api_samples/os-server-sort-keys/server-sort-keys-list-resp.json.tpl b/nova/tests/functional/api_samples/os-server-sort-keys/server-sort-keys-list-resp.json.tpl new file mode 100644 index 00000000000..8b97dc28d7d --- /dev/null +++ b/nova/tests/functional/api_samples/os-server-sort-keys/server-sort-keys-list-resp.json.tpl @@ -0,0 +1,18 @@ +{ + "servers": [ + { + "id": "%(id)s", + "links": [ + { + "href": "%(host)s/v2/openstack/servers/%(id)s", + "rel": "self" + }, + { + "href": "%(host)s/openstack/servers/%(id)s", + "rel": "bookmark" + } + ], + "name": "new-server-test" + } + ] +} diff --git a/nova/tests/functional/api_samples/os-server-sort-keys/server-sort-keys-list-resp.xml.tpl b/nova/tests/functional/api_samples/os-server-sort-keys/server-sort-keys-list-resp.xml.tpl new file mode 100644 index 00000000000..03bee03a6ea --- /dev/null +++ b/nova/tests/functional/api_samples/os-server-sort-keys/server-sort-keys-list-resp.xml.tpl @@ -0,0 +1,7 @@ + + + + + + + diff --git a/nova/tests/functional/test_api_samples.py b/nova/tests/functional/test_api_samples.py index 60c2e71eb5e..26dff0ae2c7 100644 --- a/nova/tests/functional/test_api_samples.py +++ b/nova/tests/functional/test_api_samples.py @@ -4433,3 +4433,19 @@ class ServerGroupQuotas_QuotaClassesSampleXmlTests( "server_group_quotas.Server_group_quotas") extends_name = ("nova.api.openstack.compute.contrib.quota_classes." "Quota_classes") + + +class ServerSortKeysJsonTests(ServersSampleBase): + extension_name = ("nova.api.openstack.compute.contrib.server_sort_keys" + ".Server_sort_keys") + + def test_servers_list(self): + self._post_server() + response = self._do_get('servers?sort_key=display_name&sort_dir=asc') + subs = self._get_regexes() + self._verify_response('server-sort-keys-list-resp', subs, response, + 200) + + +class ServerSortKeysXmlTests(ServerSortKeysJsonTests): + ctype = 'xml' diff --git a/nova/tests/functional/v3/api_samples/servers-sort/server-post-req.json.tpl b/nova/tests/functional/v3/api_samples/servers-sort/server-post-req.json.tpl new file mode 100644 index 00000000000..8fa8b6fe423 --- /dev/null +++ b/nova/tests/functional/v3/api_samples/servers-sort/server-post-req.json.tpl @@ -0,0 +1,7 @@ +{ + "server" : { + "name" : "new-server-test", + "imageRef" : "%(host)s/openstack/images/%(image_id)s", + "flavorRef" : "%(host)s/openstack/flavors/1" + } +} diff --git a/nova/tests/functional/v3/api_samples/servers-sort/server-post-resp.json.tpl b/nova/tests/functional/v3/api_samples/servers-sort/server-post-resp.json.tpl new file mode 100644 index 00000000000..adfaaa381e1 --- /dev/null +++ b/nova/tests/functional/v3/api_samples/servers-sort/server-post-resp.json.tpl @@ -0,0 +1,16 @@ +{ + "server": { + "adminPass": "%(password)s", + "id": "%(id)s", + "links": [ + { + "href": "%(host)s/v3/servers/%(uuid)s", + "rel": "self" + }, + { + "href": "%(host)s/servers/%(uuid)s", + "rel": "bookmark" + } + ] + } +} diff --git a/nova/tests/functional/v3/api_samples/servers-sort/server-sort-keys-list-resp.json.tpl b/nova/tests/functional/v3/api_samples/servers-sort/server-sort-keys-list-resp.json.tpl new file mode 100644 index 00000000000..8797266b68f --- /dev/null +++ b/nova/tests/functional/v3/api_samples/servers-sort/server-sort-keys-list-resp.json.tpl @@ -0,0 +1,18 @@ +{ + "servers": [ + { + "id": "%(id)s", + "links": [ + { + "href": "%(host)s/v3/servers/%(id)s", + "rel": "self" + }, + { + "href": "%(host)s/servers/%(id)s", + "rel": "bookmark" + } + ], + "name": "new-server-test" + } + ] +} diff --git a/nova/tests/functional/v3/test_servers.py b/nova/tests/functional/v3/test_servers.py index 0169a862236..88e2001972f 100644 --- a/nova/tests/functional/v3/test_servers.py +++ b/nova/tests/functional/v3/test_servers.py @@ -64,6 +64,17 @@ def test_servers_details(self): self._verify_response('servers-details-resp', subs, response, 200) +class ServerSortKeysJsonTests(ServersSampleBase): + sample_dir = 'servers-sort' + + def test_servers_list(self): + self._post_server() + response = self._do_get('servers?sort_key=display_name&sort_dir=asc') + subs = self._get_regexes() + self._verify_response('server-sort-keys-list-resp', subs, response, + 200) + + class ServersSampleAllExtensionJsonTest(ServersSampleJsonTest): all_extensions = True diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_config_drive.py b/nova/tests/unit/api/openstack/compute/contrib/test_config_drive.py index ef94db0d238..296c2589b0c 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_config_drive.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_config_drive.py @@ -69,8 +69,13 @@ def test_show(self): self.assertIn('config_drive', res_dict['server']) def test_detail_servers(self): + # Sort is disabled in v2 without an extension so stub out + # the non-sorted DB get self.stubs.Set(db, 'instance_get_all_by_filters', fakes.fake_instance_get_all_by_filters()) + # But it is enabled in v3 so stub out the sorted function + self.stubs.Set(db, 'instance_get_all_by_filters_sort', + fakes.fake_instance_get_all_by_filters()) req = fakes.HTTPRequest.blank(self.base_url + 'detail') res = req.get_response(self.app) server_dicts = jsonutils.loads(res.body)['servers'] diff --git a/nova/tests/unit/api/openstack/compute/contrib/test_keypairs.py b/nova/tests/unit/api/openstack/compute/contrib/test_keypairs.py index 6a6c6f0736c..707d4e4895e 100644 --- a/nova/tests/unit/api/openstack/compute/contrib/test_keypairs.py +++ b/nova/tests/unit/api/openstack/compute/contrib/test_keypairs.py @@ -312,8 +312,13 @@ def test_show_server(self): self.assertEqual(res_dict['server']['key_name'], '') def test_detail_servers(self): + # Sort is disabled in v2 without an extension so stub out + # the non-sorted DB get self.stubs.Set(db, 'instance_get_all_by_filters', - fakes.fake_instance_get_all_by_filters()) + fakes.fake_instance_get_all_by_filters()) + # But it is enabled in v3 so stub out the sorted function + self.stubs.Set(db, 'instance_get_all_by_filters_sort', + fakes.fake_instance_get_all_by_filters()) req = fakes.HTTPRequest.blank(self.base_url + '/servers/detail') res = req.get_response(self.app_server) server_dicts = jsonutils.loads(res.body)['servers'] diff --git a/nova/tests/unit/api/openstack/compute/plugins/v3/test_servers.py b/nova/tests/unit/api/openstack/compute/plugins/v3/test_servers.py index 30388300c25..3a78bc8f62b 100644 --- a/nova/tests/unit/api/openstack/compute/plugins/v3/test_servers.py +++ b/nova/tests/unit/api/openstack/compute/plugins/v3/test_servers.py @@ -180,7 +180,9 @@ def setUp(self): fake.stub_out_image_service(self.stubs) return_server = fakes.fake_instance_get() return_servers = fakes.fake_instance_get_all_by_filters() - self.stubs.Set(db, 'instance_get_all_by_filters', + # Server sort keys extension is enabled in v3 so sort data is passed + # to the instance API and the sorted DB API is invoked + self.stubs.Set(db, 'instance_get_all_by_filters_sort', return_servers) self.stubs.Set(db, 'instance_get_by_uuid', return_server) @@ -500,7 +502,7 @@ def fake_instance_get(*args, **kwargs): self.ips_controller.index, req, server_id) def test_get_server_list_empty(self): - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', return_servers_empty) req = fakes.HTTPRequestV3.blank('/servers') @@ -584,7 +586,7 @@ def test_get_servers_with_limit_bad_value(self): self.controller.index, req) def test_get_server_details_empty(self): - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', return_servers_empty) req = fakes.HTTPRequestV3.blank('/servers/detail') @@ -617,7 +619,8 @@ def test_get_server_details_with_limit_bad_value(self): def test_get_server_details_with_limit_and_other_params(self): req = fakes.HTTPRequestV3.blank('/servers/detail' - '?limit=3&blah=2:t') + '?limit=3&blah=2:t' + '&sort_key=id1&sort_dir=asc') res = self.controller.detail(req) servers = res['servers'] @@ -631,6 +634,7 @@ def test_get_server_details_with_limit_and_other_params(self): self.assertEqual('/v3/servers/detail', href_parts.path) params = urlparse.parse_qs(href_parts.query) expected = {'limit': ['3'], 'blah': ['2:t'], + 'sort_key': ['id1'], 'sort_dir': ['asc'], 'marker': [fakes.get_fake_uuid(2)]} self.assertThat(params, matchers.DictMatches(expected)) @@ -665,9 +669,8 @@ def test_get_servers_with_bad_option(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): db_list = [fakes.stub_instance(100, uuid=server_uuid)] return instance_obj._make_instance_list( context, objects.InstanceList(), db_list, FIELDS) @@ -684,9 +687,8 @@ def test_get_servers_allows_image(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('image', search_opts) self.assertEqual(search_opts['image'], '12345') @@ -703,46 +705,42 @@ def fake_get_all(compute_self, context, search_opts=None, self.assertEqual(servers[0]['id'], server_uuid) def test_tenant_id_filter_converts_to_project_id_for_admin(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(filters) self.assertEqual(filters['project_id'], 'newfake') self.assertFalse(filters.get('tenant_id')) return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers' '?all_tenants=1&tenant_id=newfake', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_tenant_id_filter_no_admin_context(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertNotEqual(filters, None) self.assertEqual(filters['project_id'], 'fake') return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers?tenant_id=newfake') - res = self.controller.index(req) - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_tenant_id_filter_implies_all_tenants(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertNotEqual(filters, None) # The project_id assertion checks that the project_id # filter is set to that specified in the request url and @@ -752,91 +750,82 @@ def fake_get_all(context, filters=None, sort_key=None, self.assertFalse(filters.get('tenant_id')) return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers?tenant_id=newfake', use_admin_context=True) - res = self.controller.index(req) - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_normal(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertNotIn('project_id', filters) return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers?all_tenants', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_one(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertNotIn('project_id', filters) return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers?all_tenants=1', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_zero(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertNotIn('all_tenants', filters) return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers?all_tenants=0', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_false(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertNotIn('all_tenants', filters) return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers?all_tenants=false', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_invalid(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertNotIn('all_tenants', filters) return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers?all_tenants=xxx', @@ -845,33 +834,30 @@ def fake_get_all(context, filters=None, sort_key=None, self.controller.index, req) def test_admin_restricted_tenant(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(filters) self.assertEqual(filters['project_id'], 'fake') return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_pass_policy(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, + def fake_get_all(context, filters=None, limit=None, marker=None, columns_to_join=None, use_slave=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(filters) self.assertNotIn('project_id', filters) return [fakes.stub_instance(100)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) rules = { @@ -884,14 +870,12 @@ def fake_get_all(context, filters=None, sort_key=None, policy.set_rules(rules) req = fakes.HTTPRequestV3.blank('/servers?all_tenants=1') - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_fail_policy(self): - def fake_get_all(context, filters=None, sort_key=None, - sort_dir='desc', limit=None, marker=None, - columns_to_join=None): + def fake_get_all(context, filters=None, limit=None, marker=None, + columns_to_join=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(filters) return [fakes.stub_instance(100)] @@ -903,7 +887,7 @@ def fake_get_all(context, filters=None, sort_key=None, } policy.set_rules(rules) - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', fake_get_all) req = fakes.HTTPRequestV3.blank('/servers?all_tenants=1') @@ -914,9 +898,8 @@ def test_get_servers_allows_flavor(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('flavor', search_opts) # flavor is an integer ID @@ -949,9 +932,8 @@ def test_get_servers_allows_status(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('vm_state', search_opts) self.assertEqual(search_opts['vm_state'], [vm_states.ACTIVE]) @@ -972,9 +954,8 @@ def test_get_servers_allows_task_status(self): task_state = task_states.REBOOTING def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('task_state', search_opts) self.assertEqual([task_states.REBOOT_PENDING, @@ -999,9 +980,8 @@ def test_get_servers_resize_status(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIn('vm_state', search_opts) self.assertEqual(search_opts['vm_state'], [vm_states.ACTIVE, vm_states.STOPPED]) @@ -1035,9 +1015,8 @@ def test_get_servers_deleted_status_as_admin(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIn('vm_state', search_opts) self.assertEqual(search_opts['vm_state'], ['deleted']) @@ -1058,9 +1037,8 @@ def test_get_servers_allows_name(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('name', search_opts) self.assertEqual(search_opts['name'], 'whee.*') @@ -1089,9 +1067,8 @@ def test_get_servers_allows_changes_since(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('changes-since', search_opts) changes_since = datetime.datetime(2011, 1, 24, 17, 8, 1, @@ -1124,9 +1101,8 @@ def test_get_servers_admin_filters_as_user(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) # Allowed by user self.assertIn('name', search_opts) @@ -1156,9 +1132,8 @@ def test_get_servers_admin_options_as_admin(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) # Allowed by user self.assertIn('name', search_opts) @@ -1187,9 +1162,8 @@ def test_get_servers_allows_ip(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('ip', search_opts) self.assertEqual(search_opts['ip'], '10\..*') @@ -1212,9 +1186,8 @@ def test_get_servers_admin_allows_ip6(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('ip6', search_opts) self.assertEqual(search_opts['ip6'], 'ffff.*') @@ -1274,7 +1247,7 @@ def return_servers_with_host(context, *args, **kwargs): uuid=fakes.get_fake_uuid(i)) for i in xrange(5)] - self.stubs.Set(db, 'instance_get_all_by_filters', + self.stubs.Set(db, 'instance_get_all_by_filters_sort', return_servers_with_host) req = fakes.HTTPRequestV3.blank('/servers/detail') @@ -1294,9 +1267,8 @@ def test_get_servers_joins_pci_devices(self): self.expected_attrs = None def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', limit=None, marker=None, want_objects=False, - expected_attrs=None): + expected_attrs=None, sort_keys=None, sort_dirs=None): self.expected_attrs = expected_attrs return [] diff --git a/nova/tests/unit/api/openstack/compute/test_servers.py b/nova/tests/unit/api/openstack/compute/test_servers.py index b413587dc25..15c9bdc05b0 100644 --- a/nova/tests/unit/api/openstack/compute/test_servers.py +++ b/nova/tests/unit/api/openstack/compute/test_servers.py @@ -176,6 +176,9 @@ def setUp(self): fake.stub_out_image_service(self.stubs) return_server = fakes.fake_instance_get() return_servers = fakes.fake_instance_get_all_by_filters() + # Server sort keys extension is not enabled in v2 test so no sort + # data is passed to the instance API and the non-sorted DB API is + # invoked self.stubs.Set(db, 'instance_get_all_by_filters', return_servers) self.stubs.Set(db, 'instance_get_by_uuid', @@ -572,7 +575,8 @@ def test_get_server_details_with_limit_bad_value(self): def test_get_server_details_with_limit_and_other_params(self): req = fakes.HTTPRequest.blank('/fake/servers/detail' - '?limit=3&blah=2:t') + '?limit=3&blah=2:t' + '&sort_key=id1&sort_dir=asc') res = self.controller.detail(req) servers = res['servers'] @@ -581,11 +585,16 @@ def test_get_server_details_with_limit_and_other_params(self): servers_links = res['servers_links'] self.assertEqual(servers_links[0]['rel'], 'next') - + # Retrieve the parameters from the next link, they 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. href_parts = urlparse.urlparse(servers_links[0]['href']) self.assertEqual('/v2/fake/servers/detail', href_parts.path) params = urlparse.parse_qs(href_parts.query) expected = {'limit': ['3'], 'blah': ['2:t'], + 'sort_key': ['id1'], 'sort_dir': ['asc'], 'marker': [fakes.get_fake_uuid(2)]} self.assertThat(params, matchers.DictMatches(expected)) @@ -616,12 +625,38 @@ def test_get_servers_with_bad_marker(self): self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, req) + @mock.patch('nova.compute.api.API.get_all') + def test_get_servers_with_sorting_enabled(self, mock_compute_get_all): + '''Sorting params honored if os-server-sort-keys is loaded.''' + self.ext_mgr.extensions = {'os-server-sort-keys': 'fake'} + req = fakes.HTTPRequest.blank('/fake/servers' + '?sort_key=id1&sort_dir=asc') + self.controller.index(req) + self.assertEqual(mock_compute_get_all.call_count, 1) + # Ensure that sort_dirs and sort_dirs is correct + kwargs = mock_compute_get_all.call_args[1] + self.assertEqual(['id1'], kwargs['sort_keys']) + self.assertEqual(['asc'], kwargs['sort_dirs']) + + @mock.patch('nova.compute.api.API.get_all') + def test_get_servers_with_sorting_disabled(self, mock_compute_get_all): + '''Sorting params ignored if os-server-sort-keys is not loaded.''' + self.ext_mgr.extensions = {} + req = fakes.HTTPRequest.blank('/fake/servers' + '?sort_key=id1&sort_dir=asc') + self.controller.index(req) + self.assertEqual(mock_compute_get_all.call_count, 1) + # Ensure that sort_dirs and sort_dirs is None + kwargs = mock_compute_get_all.call_args[1] + self.assertIsNone(kwargs['sort_keys']) + self.assertIsNone(kwargs['sort_dirs']) + def test_get_servers_with_bad_option(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): db_list = [fakes.stub_instance(100, uuid=server_uuid)] return instance_obj._make_instance_list( context, objects.InstanceList(), db_list, FIELDS) @@ -638,8 +673,8 @@ def test_get_servers_allows_image(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('image', search_opts) self.assertEqual(search_opts['image'], '12345') @@ -670,9 +705,8 @@ def fake_get_all(context, filters=None, sort_key=None, req = fakes.HTTPRequest.blank('/fake/servers' '?all_tenants=1&tenant_id=newfake', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_normal(self): def fake_get_all(context, filters=None, sort_key=None, @@ -686,9 +720,8 @@ def fake_get_all(context, filters=None, sort_key=None, req = fakes.HTTPRequest.blank('/fake/servers?all_tenants', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_one(self): def fake_get_all(context, filters=None, sort_key=None, @@ -702,9 +735,8 @@ def fake_get_all(context, filters=None, sort_key=None, req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=1', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_zero(self): def fake_get_all(context, filters=None, sort_key=None, @@ -718,9 +750,8 @@ def fake_get_all(context, filters=None, sort_key=None, req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=0', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_false(self): def fake_get_all(context, filters=None, sort_key=None, @@ -734,9 +765,8 @@ def fake_get_all(context, filters=None, sort_key=None, req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=false', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_param_invalid(self): def fake_get_all(context, filters=None, sort_key=None, @@ -766,9 +796,8 @@ def fake_get_all(context, filters=None, sort_key=None, req = fakes.HTTPRequest.blank('/fake/servers', use_admin_context=True) - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_pass_policy(self): def fake_get_all(context, filters=None, sort_key=None, @@ -791,9 +820,8 @@ def fake_get_all(context, filters=None, sort_key=None, policy.set_rules(rules) req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=1') - res = self.controller.index(req) - - self.assertIn('servers', res) + servers = self.controller.index(req)['servers'] + self.assertEqual(len(servers), 1) def test_all_tenants_fail_policy(self): def fake_get_all(context, filters=None, sort_key=None, @@ -821,8 +849,8 @@ def test_get_servers_allows_flavor(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('flavor', search_opts) # flavor is an integer ID @@ -855,8 +883,8 @@ def test_get_servers_allows_status(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('vm_state', search_opts) self.assertEqual(search_opts['vm_state'], [vm_states.ACTIVE]) @@ -893,7 +921,8 @@ def test_get_servers_allows_multi_status(self, get_all_mock): project_id='fake') get_all_mock.assert_called_once_with(mock.ANY, search_opts=expected_search_opts, limit=mock.ANY, - marker=mock.ANY, want_objects=mock.ANY) + marker=mock.ANY, want_objects=mock.ANY, + sort_keys=mock.ANY, sort_dirs=mock.ANY) @mock.patch.object(compute_api.API, 'get_all') def test_get_servers_system_metadata_filter(self, get_all_mock): @@ -918,7 +947,8 @@ def test_get_servers_system_metadata_filter(self, get_all_mock): system_metadata=expected_system_metadata, project_id='fake') get_all_mock.assert_called_once_with(mock.ANY, search_opts=expected_search_opts, limit=mock.ANY, - marker=mock.ANY, want_objects=mock.ANY) + marker=mock.ANY, want_objects=mock.ANY, + sort_keys=mock.ANY, sort_dirs=mock.ANY) @mock.patch.object(compute_api.API, 'get_all') def test_get_servers_flavor_not_found(self, get_all_mock): @@ -949,15 +979,16 @@ def test_get_servers_allows_invalid_status(self, get_all_mock): project_id='fake') get_all_mock.assert_called_once_with(mock.ANY, search_opts=expected_search_opts, limit=mock.ANY, - marker=mock.ANY, want_objects=mock.ANY) + marker=mock.ANY, want_objects=mock.ANY, + sort_keys=mock.ANY, sort_dirs=mock.ANY) def test_get_servers_allows_task_status(self): server_uuid = str(uuid.uuid4()) task_state = task_states.REBOOTING def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('task_state', search_opts) self.assertEqual([task_states.REBOOT_PENDING, @@ -982,8 +1013,8 @@ def test_get_servers_resize_status(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIn('vm_state', search_opts) self.assertEqual(search_opts['vm_state'], [vm_states.ACTIVE, vm_states.STOPPED]) @@ -1017,8 +1048,8 @@ def test_get_servers_deleted_status_as_admin(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIn('vm_state', search_opts) self.assertEqual(search_opts['vm_state'], ['deleted']) @@ -1039,8 +1070,8 @@ def test_get_servers_allows_name(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('name', search_opts) self.assertEqual(search_opts['name'], 'whee.*') @@ -1060,8 +1091,8 @@ def test_get_servers_allows_changes_since(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('changes-since', search_opts) changes_since = datetime.datetime(2011, 1, 24, 17, 8, 1, @@ -1094,8 +1125,8 @@ def test_get_servers_admin_filters_as_user(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) # Allowed by user self.assertIn('name', search_opts) @@ -1125,8 +1156,8 @@ def test_get_servers_admin_options_as_admin(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) # Allowed by user self.assertIn('name', search_opts) @@ -1154,8 +1185,8 @@ def test_get_servers_allows_ip(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('ip', search_opts) self.assertEqual(search_opts['ip'], '10\..*') @@ -1178,8 +1209,8 @@ def test_get_servers_admin_allows_ip6(self): server_uuid = str(uuid.uuid4()) def fake_get_all(compute_self, context, search_opts=None, - sort_key=None, sort_dir='desc', - limit=None, marker=None, want_objects=False): + limit=None, marker=None, want_objects=False, + sort_keys=None, sort_dirs=None): self.assertIsNotNone(search_opts) self.assertIn('ip6', search_opts) self.assertEqual(search_opts['ip6'], 'ffff.*') diff --git a/nova/tests/unit/api/openstack/fakes.py b/nova/tests/unit/api/openstack/fakes.py index 34c072a634d..d06f3fc8389 100644 --- a/nova/tests/unit/api/openstack/fakes.py +++ b/nova/tests/unit/api/openstack/fakes.py @@ -399,6 +399,12 @@ def _return_servers(context, *args, **kwargs): if 'use_slave' in kwargs: kwargs.pop('use_slave') + if 'sort_keys' in kwargs: + kwargs.pop('sort_keys') + + if 'sort_dirs' in kwargs: + kwargs.pop('sort_dirs') + for i in xrange(num_servers): uuid = get_fake_uuid(i) server = stub_instance(id=i + 1, uuid=uuid,