Merge "GET servers API sorting REST API updates"

This commit is contained in:
Jenkins 2014-12-02 06:18:09 +00:00 committed by Gerrit Code Review
commit d2298c6433
32 changed files with 454 additions and 157 deletions

View File

@ -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"
}
]
}

View File

@ -287,4 +287,7 @@
<extension alias="os-volumes" updated="2011-03-25T00:00:00Z" namespace="http://docs.openstack.org/compute/ext/volumes/api/v1.1" name="Volumes">
<description>Volumes support.</description>
</extension>
<extension alias="os-server-sort-keys" updated="2014-05-22T00:00:00Z" namespace="http://docs.openstack.org/compute/ext/server_sort_keys/api/v2" name="ServerSortKeys">
<description>Add sorting support in get Server v2 API.</description>
</extension>
</extensions>

View File

@ -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"
}
}

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="http://docs.openstack.org/compute/api/v1.1" imageRef="http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b" flavorRef="http://openstack.example.com/openstack/flavors/1" name="new-server-test">
</server>

View File

@ -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"
}
]
}
}

View File

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="e08e6d34-fcc1-480e-b11e-24a675b479f8" adminPass="jDje6SdBHGfQ">
<metadata/>
<atom:link href="http://openstack.example.com/v2/openstack/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8" rel="self"/>
<atom:link href="http://openstack.example.com/openstack/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8" rel="bookmark"/>
</server>

View File

@ -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"
}
]
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<servers xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1">
<server name="new-server-test" id="e08e6d34-fcc1-480e-b11e-24a675b479f8">
<atom:link href="http://openstack.example.com/v2/openstack/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8" rel="self"/>
<atom:link href="http://openstack.example.com/openstack/servers/e08e6d34-fcc1-480e-b11e-24a675b479f8" rel="bookmark"/>
</server>
</servers>

View File

@ -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"
}
}

View File

@ -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"
}
]
}
}

View File

@ -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"
}
]
}

View File

@ -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"

View File

@ -350,10 +350,12 @@ class ServersController(wsgi.Controller):
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)

View File

@ -596,12 +596,18 @@ class Controller(wsgi.Controller):
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)

View File

@ -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"
}
]
}

View File

@ -266,4 +266,7 @@
<extension alias="os-server-group-quotas" updated="%(isotime)s" namespace="http://docs.openstack.org/compute/ext/server-group-quotas/api/v2" name="ServerGroupQuotas">
<description>%(text)s</description>
</extension>
<extension alias="os-server-sort-keys" updated="%(isotime)s" namespace="http://docs.openstack.org/compute/ext/server_sort_keys/api/v2" name="ServerSortKeys">
<description>%(text)s</description>
</extension>
</extensions>

View File

@ -0,0 +1,7 @@
{
"server" : {
"name" : "new-server-test",
"imageRef" : "%(host)s/openstack/images/%(image_id)s",
"flavorRef" : "%(host)s/openstack/flavors/1"
}
}

View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<server xmlns="http://docs.openstack.org/compute/api/v1.1" imageRef="%(host)s/openstack/images/%(image_id)s" flavorRef="%(host)s/openstack/flavors/1" name="new-server-test">
</server>

View File

@ -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"
}
]
}
}

View File

@ -0,0 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1" id="%(id)s" adminPass="%(password)s">
<metadata/>
<atom:link href="%(host)s/v2/openstack/servers/%(uuid)s" rel="self"/>
<atom:link href="%(host)s/openstack/servers/%(uuid)s" rel="bookmark"/>
</server>

View File

@ -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"
}
]
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<servers xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://docs.openstack.org/compute/api/v1.1">
<server name="new-server-test" id="%(id)s">
<atom:link href="%(host)s/v2/openstack/servers/%(id)s" rel="self"/>
<atom:link href="%(host)s/openstack/servers/%(id)s" rel="bookmark"/>
</server>
</servers>

View File

@ -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'

View File

@ -0,0 +1,7 @@
{
"server" : {
"name" : "new-server-test",
"imageRef" : "%(host)s/openstack/images/%(image_id)s",
"flavorRef" : "%(host)s/openstack/flavors/1"
}
}

View File

@ -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"
}
]
}
}

View File

@ -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"
}
]
}

View File

@ -64,6 +64,17 @@ class ServersSampleJsonTest(ServersSampleBase):
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

View File

@ -69,8 +69,13 @@ class ConfigDriveTestV21(test.TestCase):
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']

View File

@ -312,8 +312,13 @@ class KeypairsTestV21(test.TestCase):
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']

View File

@ -180,7 +180,9 @@ class ControllerTest(test.TestCase):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
}
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 []

View File

@ -176,6 +176,9 @@ class ControllerTest(test.TestCase):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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 @@ class ServersControllerTest(ControllerTest):
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.*')

View File

@ -395,6 +395,12 @@ def fake_instance_get_all_by_filters(num_servers=5, **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,