672c43c43e
Part of the removal of OPENSTACK_NOVA_EXTENSIONS_BLACKLIST (3/3) Clean up nova extensions related code in the API layer. Change-Id: I9730095365342cac1023f4112bae4b3a28cdeaf7
1110 lines
47 KiB
Python
1110 lines
47 KiB
Python
# Copyright 2014, Rackspace, US, Inc.
|
|
#
|
|
# 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.
|
|
|
|
import json
|
|
from json import loads as to_json
|
|
from unittest import mock
|
|
import uuid
|
|
|
|
from django.conf import settings
|
|
|
|
from openstack_dashboard import api
|
|
from openstack_dashboard.api.base import Quota
|
|
from openstack_dashboard.api.rest import nova
|
|
from openstack_dashboard.test import helpers as test
|
|
from openstack_dashboard.usage import quotas
|
|
|
|
|
|
# NOTE(flwang): mock.Mock and mock.MagicMock do not support sort, so the test
|
|
# case involved sorted will fail. This fake class is for the flavor test cases
|
|
# related to sort.
|
|
class FakeFlavor(object):
|
|
def __init__(self, id, ram=1):
|
|
self.id = id
|
|
self.ram = ram
|
|
self.extras = {}
|
|
|
|
def to_dict(self):
|
|
return {"id": self.id}
|
|
|
|
|
|
class NovaRestTestCase(test.TestCase):
|
|
|
|
#
|
|
# Snapshots
|
|
#
|
|
@test.create_mocks({api.nova: ['snapshot_create']})
|
|
def test_snapshots_create(self):
|
|
body = '{"instance_id": "1234", "name": "foo"}'
|
|
request = self.mock_rest_request(body=body)
|
|
self.mock_snapshot_create.return_value = {'id': 'abcd', 'name': 'foo'}
|
|
response = nova.Snapshots().post(request)
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(response.json, {'id': 'abcd', 'name': 'foo'})
|
|
self.mock_snapshot_create.assert_called_once_with(request,
|
|
instance_id='1234',
|
|
name='foo')
|
|
|
|
#
|
|
# Server Actions
|
|
#
|
|
@test.create_mocks({api.nova: ['instance_action_list']})
|
|
def test_serveractions_list(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_instance_action_list.return_value = [
|
|
mock.Mock(**{'to_dict.return_value': {'id': '1'}}),
|
|
mock.Mock(**{'to_dict.return_value': {'id': '2'}}),
|
|
]
|
|
response = nova.ServerActions().get(request, 'MegaMan')
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(response.json, {'items': [{'id': '1'}, {'id': '2'}]})
|
|
self.mock_instance_action_list.assert_called_once_with(request,
|
|
'MegaMan')
|
|
|
|
@test.create_mocks({api.nova: ['server_start']})
|
|
def test_server_start(self):
|
|
self.mock_server_start.return_value = None
|
|
request = self.mock_rest_request(body='{"operation": "start"}')
|
|
response = nova.Server().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 204)
|
|
self.mock_server_start.assert_called_once_with(request, 'MegaMan')
|
|
|
|
@test.create_mocks({api.nova: ['server_stop']})
|
|
def test_server_stop(self):
|
|
self.mock_server_stop.return_value = None
|
|
request = self.mock_rest_request(body='{"operation": "stop"}')
|
|
response = nova.Server().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 204)
|
|
self.mock_server_stop.assert_called_once_with(request, 'MegaMan')
|
|
|
|
@test.create_mocks({api.nova: ['server_pause']})
|
|
def test_server_pause(self):
|
|
self.mock_server_pause.return_value = None
|
|
request = self.mock_rest_request(body='{"operation": "pause"}')
|
|
response = nova.Server().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 204)
|
|
self.mock_server_pause.assert_called_once_with(request, 'MegaMan')
|
|
|
|
@test.create_mocks({api.nova: ['server_unpause']})
|
|
def test_server_unpause(self):
|
|
self.mock_server_unpause.return_value = None
|
|
request = self.mock_rest_request(body='{"operation": "unpause"}')
|
|
response = nova.Server().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 204)
|
|
self.mock_server_unpause.assert_called_once_with(request, 'MegaMan')
|
|
|
|
@test.create_mocks({api.nova: ['server_suspend']})
|
|
def test_server_suspend(self):
|
|
self.mock_server_suspend.return_value = None
|
|
request = self.mock_rest_request(body='{"operation": "suspend"}')
|
|
response = nova.Server().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 204)
|
|
self.mock_server_suspend.assert_called_once_with(request, 'MegaMan')
|
|
|
|
@test.create_mocks({api.nova: ['server_resume']})
|
|
def test_server_resume(self):
|
|
self.mock_server_resume.return_value = None
|
|
request = self.mock_rest_request(body='{"operation": "resume"}')
|
|
response = nova.Server().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 204)
|
|
self.mock_server_resume.assert_called_once_with(request, 'MegaMan')
|
|
|
|
@test.create_mocks({api.nova: ['server_reboot']})
|
|
def test_server_hard_reboot(self):
|
|
self.mock_server_reboot.return_value = None
|
|
request = self.mock_rest_request(body='{"operation": "hard_reboot"}')
|
|
response = nova.Server().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 204)
|
|
self.mock_server_reboot.assert_called_once_with(request, 'MegaMan',
|
|
False)
|
|
|
|
@test.create_mocks({api.nova: ['server_reboot']})
|
|
def test_server_soft_reboot(self):
|
|
self.mock_server_reboot.return_value = None
|
|
request = self.mock_rest_request(body='{"operation": "soft_reboot"}')
|
|
response = nova.Server().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 204)
|
|
self.mock_server_reboot.assert_called_once_with(request, 'MegaMan',
|
|
True)
|
|
|
|
#
|
|
# Security Groups
|
|
#
|
|
@test.create_mocks({api.neutron: ['server_security_groups']})
|
|
def test_securitygroups_list(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_server_security_groups.return_value = [
|
|
mock.Mock(**{'to_dict.return_value': {'id': '1'}}),
|
|
mock.Mock(**{'to_dict.return_value': {'id': '2'}}),
|
|
]
|
|
response = nova.SecurityGroups().get(request, 'MegaMan')
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(response.json, {'items': [{'id': '1'}, {'id': '2'}]})
|
|
self.mock_server_security_groups.assert_called_once_with(request,
|
|
'MegaMan')
|
|
|
|
#
|
|
# Console Output
|
|
#
|
|
@test.create_mocks({api.nova: ['server_console_output']})
|
|
def test_console_output(self):
|
|
request = self.mock_rest_request(body='{"length": 50}')
|
|
self.mock_server_console_output.return_value = "this\nis\ncool"
|
|
response = nova.ConsoleOutput().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(response.json, {'lines': ["this", "is", "cool"]})
|
|
self.mock_server_console_output.assert_called_once_with(request,
|
|
'MegaMan',
|
|
tail_length=50)
|
|
|
|
#
|
|
# Remote Console Info
|
|
#
|
|
@test.create_mocks({api.nova: ['server_serial_console']})
|
|
def test_console_info(self):
|
|
request = self.mock_rest_request(body='{"console_type": "SERIAL"}')
|
|
retval = mock.Mock(**{"url": "http://here.com"})
|
|
self.mock_server_serial_console.return_value = retval
|
|
response = nova.RemoteConsoleInfo().post(request, 'MegaMan')
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(response.json,
|
|
{"type": "SERIAL", "url": "http://here.com"})
|
|
self.mock_server_serial_console.assert_called_once_with(request,
|
|
'MegaMan')
|
|
|
|
#
|
|
# Volumes
|
|
#
|
|
@test.create_mocks({api.nova: ['instance_volumes_list']})
|
|
def test_volumes_list(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_instance_volumes_list.return_value = [
|
|
mock.Mock(**{'to_dict.return_value': {'id': '1'}}),
|
|
mock.Mock(**{'to_dict.return_value': {'id': '2'}}),
|
|
]
|
|
response = nova.Volumes().get(request, 'MegaMan')
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(response.json, {'items': [{'id': '1'}, {'id': '2'}]})
|
|
self.mock_instance_volumes_list.assert_called_once_with(request,
|
|
'MegaMan')
|
|
|
|
#
|
|
# Keypairs
|
|
#
|
|
@test.create_mocks({api.nova: ['keypair_list']})
|
|
def test_keypair_list(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_keypair_list.return_value = [
|
|
mock.Mock(**{'to_dict.return_value': {'id': 'one'}}),
|
|
mock.Mock(**{'to_dict.return_value': {'id': 'two'}}),
|
|
]
|
|
response = nova.Keypairs().get(request)
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual({"items": [{"id": "one"}, {"id": "two"}]},
|
|
response.json)
|
|
self.mock_keypair_list.assert_called_once_with(request)
|
|
|
|
@test.create_mocks({api.nova: ['keypair_create']})
|
|
def test_keypair_create(self):
|
|
request = self.mock_rest_request(body='''{"name": "Ni!",
|
|
"key_type": "ssh"}''')
|
|
new = self.mock_keypair_create.return_value
|
|
new.to_dict.return_value = {'name': 'Ni!',
|
|
'key_type': 'ssh',
|
|
'public_key': 'sekrit'}
|
|
new.name = 'Ni!'
|
|
with mock.patch.object(settings, 'DEBUG', True):
|
|
response = nova.Keypairs().post(request)
|
|
self.assertStatusCode(response, 201)
|
|
self.assertEqual({"name": "Ni!",
|
|
"key_type": "ssh",
|
|
"public_key": "sekrit"},
|
|
response.json)
|
|
self.assertEqual('/api/nova/keypairs/Ni%21', response['location'])
|
|
self.mock_keypair_create.assert_called_once_with(request, 'Ni!', 'ssh')
|
|
|
|
@test.create_mocks({api.nova: ['keypair_import']})
|
|
def test_keypair_import(self):
|
|
request = self.mock_rest_request(body='''
|
|
{"name": "Ni!", "public_key": "hi", "key_type": "ssh"}
|
|
''')
|
|
new = self.mock_keypair_import.return_value
|
|
new.to_dict.return_value = {'name': 'Ni!',
|
|
'public_key': 'hi',
|
|
'key_type': 'ssh'}
|
|
new.name = 'Ni!'
|
|
with mock.patch.object(settings, 'DEBUG', True):
|
|
response = nova.Keypairs().post(request)
|
|
self.assertStatusCode(response, 201)
|
|
self.assertEqual({"name": "Ni!",
|
|
"public_key": "hi",
|
|
"key_type": "ssh"},
|
|
response.json)
|
|
self.assertEqual('/api/nova/keypairs/Ni%21', response['location'])
|
|
self.mock_keypair_import.assert_called_once_with(request,
|
|
'Ni!',
|
|
'hi',
|
|
'ssh')
|
|
|
|
@test.create_mocks({api.nova: ['keypair_get']})
|
|
def test_keypair_get(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_keypair_get.return_value.to_dict.return_value = {'name': '1'}
|
|
response = nova.Keypair().get(request, '1')
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual({"name": "1"},
|
|
response.json)
|
|
self.mock_keypair_get.assert_called_once_with(request, "1")
|
|
|
|
@test.create_mocks({api.nova: ['keypair_delete']})
|
|
def test_keypair_delete(self):
|
|
self.mock_keypair_delete.return_value = None
|
|
request = self.mock_rest_request()
|
|
nova.Keypair().delete(request, "1")
|
|
self.mock_keypair_delete.assert_called_once_with(request, "1")
|
|
|
|
#
|
|
# Availability Zones
|
|
#
|
|
def test_availzone_get_brief(self):
|
|
self._test_availzone_get(False)
|
|
|
|
def test_availzone_get_detailed(self):
|
|
self._test_availzone_get(True)
|
|
|
|
@test.create_mocks({api.nova: ['availability_zone_list']})
|
|
def _test_availzone_get(self, detail):
|
|
if detail:
|
|
request = self.mock_rest_request(GET={'detailed': 'true'})
|
|
else:
|
|
request = self.mock_rest_request(GET={})
|
|
self.mock_availability_zone_list.return_value = [
|
|
mock.Mock(**{'to_dict.return_value': {'id': 'one'}}),
|
|
mock.Mock(**{'to_dict.return_value': {'id': 'two'}}),
|
|
]
|
|
response = nova.AvailabilityZones().get(request)
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual({"items": [{"id": "one"}, {"id": "two"}]},
|
|
response.json)
|
|
self.mock_availability_zone_list.assert_called_once_with(request,
|
|
detail)
|
|
|
|
#
|
|
# Limits
|
|
#
|
|
def test_limits_get_not_reserved(self):
|
|
self._test_limits_get(False)
|
|
|
|
def test_limits_get_reserved(self):
|
|
self._test_limits_get(True)
|
|
|
|
@test.create_mocks({api.nova: ['tenant_absolute_limits']})
|
|
def _test_limits_get(self, reserved):
|
|
if reserved:
|
|
request = self.mock_rest_request(GET={'reserved': 'true'})
|
|
else:
|
|
request = self.mock_rest_request(GET={})
|
|
self.mock_tenant_absolute_limits.return_value = {'id': 'one'}
|
|
response = nova.Limits().get(request)
|
|
self.assertStatusCode(response, 200)
|
|
self.mock_tenant_absolute_limits.assert_called_once_with(request,
|
|
reserved)
|
|
self.assertEqual({"id": "one"}, response.json)
|
|
|
|
#
|
|
# Servers
|
|
#
|
|
def test_server_create_missing(self):
|
|
request = self.mock_rest_request(body='''{"name": "hi"}''')
|
|
response = nova.Servers().post(request)
|
|
self.assertStatusCode(response, 400)
|
|
self.assertEqual("missing required parameter 'source_id'",
|
|
response.json)
|
|
|
|
@test.create_mocks({api.nova: ['server_create']})
|
|
def test_server_create_basic(self):
|
|
request = self.mock_rest_request(body='''{"name": "Ni!",
|
|
"source_id": "image123", "flavor_id": "flavor123",
|
|
"key_name": "sekrit", "user_data": "base64 yes",
|
|
"security_groups": [{"name": "root"}]}
|
|
''')
|
|
new = self.mock_server_create.return_value
|
|
new.to_dict.return_value = {'id': 'server123'}
|
|
new.id = 'server123'
|
|
response = nova.Servers().post(request)
|
|
self.assertStatusCode(response, 201)
|
|
self.assertEqual({"id": "server123"}, response.json)
|
|
self.assertEqual('/api/nova/servers/server123', response['location'])
|
|
self.mock_server_create.assert_called_once_with(
|
|
request, 'Ni!', 'image123', 'flavor123', 'sekrit', 'base64 yes',
|
|
[{'name': 'root'}]
|
|
)
|
|
|
|
@test.create_mocks({api.nova: ['server_create']})
|
|
def test_server_create_with_leading_trailing_space(self):
|
|
request = self.mock_rest_request(body='''{"name": " Ni! ",
|
|
"source_id": "image123", "flavor_id": "flavor123",
|
|
"key_name": "sekrit", "user_data": "base64 yes",
|
|
"security_groups": [{"name": "root"}]}
|
|
''')
|
|
new = self.mock_server_create.return_value
|
|
new.to_dict.return_value = {'name': ' Ni! '.strip()}
|
|
new.id = str(uuid.uuid4())
|
|
response = nova.Servers().post(request)
|
|
self.assertStatusCode(response, 201)
|
|
self.assertEqual({"name": "Ni!"}, response.json)
|
|
self.mock_server_create.assert_called_once_with(
|
|
request, ' Ni! ', 'image123', 'flavor123', 'sekrit', 'base64 yes',
|
|
[{'name': 'root'}])
|
|
|
|
@test.create_mocks({api.nova: ['server_list']})
|
|
def test_server_list(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_server_list.return_value = ([
|
|
mock.Mock(**{'to_dict.return_value': {'id': 'one'}}),
|
|
mock.Mock(**{'to_dict.return_value': {'id': 'two'}}),
|
|
], False)
|
|
|
|
response = nova.Servers().get(request)
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual({'items': [{'id': 'one'}, {'id': 'two'}]},
|
|
response.json)
|
|
self.mock_server_list.assert_called_once_with(request)
|
|
|
|
@test.create_mocks({api.nova: ['server_get']})
|
|
def test_server_get_single(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_server_get.return_value.to_dict.return_value = {'name': '1'}
|
|
|
|
response = nova.Server().get(request, "1")
|
|
self.assertStatusCode(response, 200)
|
|
self.mock_server_get.assert_called_once_with(request, "1")
|
|
|
|
#
|
|
# Server Groups
|
|
#
|
|
@test.create_mocks({api.nova: ['server_group_list']})
|
|
def test_server_group_list(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_server_group_list.return_value = [
|
|
mock.Mock(**{'to_dict.return_value': {'id': '1'}}),
|
|
mock.Mock(**{'to_dict.return_value': {'id': '2'}}),
|
|
]
|
|
|
|
response = nova.ServerGroups().get(request)
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual({'items': [{'id': '1'}, {'id': '2'}]},
|
|
response.json)
|
|
self.mock_server_group_list.assert_called_once_with(request)
|
|
|
|
@test.create_mocks({api.nova: ['server_group_create']})
|
|
def test_server_group_create(self):
|
|
req_data = json.dumps({
|
|
'name': 'server_group', 'policies': ['affinity']})
|
|
|
|
self.mock_server_group_create.return_value = mock.Mock(**{
|
|
'id': '123',
|
|
'to_dict.return_value': {'id': '123',
|
|
'name': 'server_group',
|
|
'policies': ['affinity']}
|
|
})
|
|
|
|
server_group_data = {'name': 'server_group',
|
|
'policies': ['affinity']}
|
|
request = self.mock_rest_request(body=req_data)
|
|
response = nova.ServerGroups().post(request)
|
|
|
|
self.assertStatusCode(response, 201)
|
|
self.assertEqual('/api/nova/servergroups/123', response['location'])
|
|
|
|
self.mock_server_group_create.assert_called_once_with(
|
|
request, **server_group_data)
|
|
|
|
@test.create_mocks({api.nova: ['server_group_delete']})
|
|
def test_server_group_delete(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_server_group_delete.return_value = None
|
|
nova.ServerGroup().delete(request, "1")
|
|
self.mock_server_group_delete.assert_called_once_with(request, "1")
|
|
|
|
@test.create_mocks({api.nova: ['server_group_get']})
|
|
def test_server_group_get_single(self):
|
|
request = self.mock_rest_request()
|
|
servergroup = self.server_groups.first()
|
|
self.mock_server_group_get.return_value = servergroup
|
|
|
|
response = nova.ServerGroup().get(request, "1")
|
|
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(servergroup.to_dict(), response.json)
|
|
self.mock_server_group_get.assert_called_once_with(request, "1")
|
|
|
|
#
|
|
# Server Metadata
|
|
#
|
|
@test.create_mocks({api.nova: ['server_get']})
|
|
def test_server_get_metadata(self):
|
|
request = self.mock_rest_request()
|
|
meta = {'foo': 'bar'}
|
|
ret_val_server = self.mock_server_get.return_value
|
|
ret_val_server.to_dict.return_value.get.return_value = meta
|
|
|
|
response = nova.ServerMetadata().get(request, "1")
|
|
self.assertStatusCode(response, 200)
|
|
self.mock_server_get.assert_called_once_with(request, "1")
|
|
|
|
@test.create_mocks({api.nova: ['server_metadata_delete',
|
|
'server_metadata_update']})
|
|
def test_server_edit_metadata(self):
|
|
request = self.mock_rest_request(
|
|
body='{"updated": {"a": "1", "b": "2"}, "removed": ["c", "d"]}'
|
|
)
|
|
self.mock_server_metadata_update.return_value = None
|
|
self.mock_server_metadata_delete.return_value = None
|
|
|
|
response = nova.ServerMetadata().patch(request, '1')
|
|
self.assertStatusCode(response, 204)
|
|
self.assertEqual(b'', response.content)
|
|
self.mock_server_metadata_update.assert_called_once_with(
|
|
request, '1', {'a': '1', 'b': '2'}
|
|
)
|
|
self.mock_server_metadata_delete.assert_called_once_with(
|
|
request, '1', ['c', 'd']
|
|
)
|
|
|
|
#
|
|
# Flavors
|
|
#
|
|
|
|
@test.create_mocks({api.nova: ['flavor_get', 'flavor_access_list']})
|
|
def test_flavor_get_single_with_access_list(self):
|
|
request = self.mock_rest_request(GET={'get_access_list': 'tRuE'})
|
|
self.mock_flavor_get.return_value.to_dict.return_value = {'name': '1'}
|
|
self.mock_flavor_get.return_value.is_public = False
|
|
|
|
self.mock_flavor_access_list.return_value = [
|
|
mock.Mock(**{'tenant_id': '11'}),
|
|
mock.Mock(**{'tenant_id': '22'}),
|
|
]
|
|
|
|
response = nova.Flavor().get(request, "1")
|
|
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(to_json(response.content.decode('utf-8')),
|
|
to_json('{"access-list": ["11", "22"], "name": "1"}'))
|
|
|
|
self.mock_flavor_get.assert_called_once_with(request, "1",
|
|
get_extras=False)
|
|
self.mock_flavor_access_list.assert_called_once_with(request, "1")
|
|
|
|
def test_get_extras_no(self):
|
|
self._test_flavor_get_single(get_extras=False)
|
|
|
|
def test_get_extras_yes(self):
|
|
self._test_flavor_get_single(get_extras=True)
|
|
|
|
def test_get_extras_default(self):
|
|
self._test_flavor_get_single(get_extras=None)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_get']})
|
|
def _test_flavor_get_single(self, get_extras):
|
|
if get_extras:
|
|
request = self.mock_rest_request(GET={'get_extras': 'tRuE'})
|
|
elif get_extras is None:
|
|
request = self.mock_rest_request()
|
|
get_extras = False
|
|
else:
|
|
request = self.mock_rest_request(GET={'get_extras': 'fAlsE'})
|
|
self.mock_flavor_get.return_value.to_dict.return_value = {'name': '1'}
|
|
|
|
response = nova.Flavor().get(request, "1")
|
|
self.assertStatusCode(response, 200)
|
|
if get_extras:
|
|
self.assertEqual(response.json, {"extras": {}, "name": "1"})
|
|
else:
|
|
self.assertEqual({"name": "1"}, response.json)
|
|
self.mock_flavor_get.assert_called_once_with(request, "1",
|
|
get_extras=get_extras)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_get']})
|
|
def test_flavor_get_single_with_swap_set_to_empty(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_flavor_get.return_value\
|
|
.to_dict.return_value = {'name': '1', 'swap': ''}
|
|
|
|
response = nova.Flavor().get(request, "1")
|
|
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(to_json(response.content.decode('utf-8')),
|
|
to_json('{"name": "1", "swap": 0}'))
|
|
self.mock_flavor_get.assert_called_once_with(request, '1',
|
|
get_extras=False)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_delete']})
|
|
def test_flavor_delete(self):
|
|
self.mock_flavor_delete.return_value = None
|
|
request = self.mock_rest_request()
|
|
nova.Flavor().delete(request, "1")
|
|
self.mock_flavor_delete.assert_called_once_with(request, "1")
|
|
|
|
@test.create_mocks({api.nova: ['flavor_create']})
|
|
def test_flavor_create(self):
|
|
flavor_req_data = '{"name": "flavor", ' \
|
|
'"ram": 12, ' \
|
|
'"vcpus": 1, ' \
|
|
'"disk": 2, ' \
|
|
'"OS-FLV-EXT-DATA:ephemeral": 3, ' \
|
|
'"swap": 4, ' \
|
|
'"id": "123"' \
|
|
'}'
|
|
|
|
self.mock_flavor_create.return_value = mock.Mock(**{
|
|
'id': '123',
|
|
'to_dict.return_value': {'id': '123', 'name': 'flavor'}
|
|
})
|
|
|
|
flavor_data = {'name': 'flavor',
|
|
'memory': 12,
|
|
'vcpu': 1,
|
|
'disk': 2,
|
|
'ephemeral': 3,
|
|
'swap': 4,
|
|
'flavorid': '123',
|
|
'is_public': True}
|
|
|
|
request = self.mock_rest_request(body=flavor_req_data)
|
|
response = nova.Flavors().post(request)
|
|
|
|
self.assertStatusCode(response, 201)
|
|
self.assertEqual('/api/nova/flavors/123', response['location'])
|
|
|
|
self.mock_flavor_create.assert_called_once_with(request, **flavor_data)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_create',
|
|
'add_tenant_to_flavor']})
|
|
def test_flavor_create_with_access_list(self):
|
|
flavor_req_data = '{"name": "flavor", ' \
|
|
'"ram": 12, ' \
|
|
'"vcpus": 1, ' \
|
|
'"disk": 2, ' \
|
|
'"OS-FLV-EXT-DATA:ephemeral": 3, ' \
|
|
'"swap": 4, ' \
|
|
'"id": "123", ' \
|
|
'"flavor_access": [{"id":"1", "name":"test"}]' \
|
|
'}'
|
|
|
|
self.mock_flavor_create.return_value = mock.Mock(**{
|
|
'id': '1234',
|
|
'to_dict.return_value': {'id': '1234', 'name': 'flavor'}
|
|
})
|
|
# A list of FlavorAccess object is returned but it is actually unused.
|
|
self.mock_add_tenant_to_flavor.return_value = [
|
|
mock.sentinel.flavor_access1,
|
|
]
|
|
|
|
flavor_data = {'name': 'flavor',
|
|
'memory': 12,
|
|
'vcpu': 1,
|
|
'disk': 2,
|
|
'ephemeral': 3,
|
|
'swap': 4,
|
|
'flavorid': '123',
|
|
'is_public': False}
|
|
|
|
request = self.mock_rest_request(body=flavor_req_data)
|
|
response = nova.Flavors().post(request)
|
|
|
|
self.assertStatusCode(response, 201)
|
|
self.assertEqual('/api/nova/flavors/1234', response['location'])
|
|
|
|
self.mock_flavor_create.assert_called_once_with(request, **flavor_data)
|
|
self.mock_add_tenant_to_flavor.assert_called_once_with(
|
|
request, '1234', '1')
|
|
|
|
@test.create_mocks({api.nova: ['flavor_create',
|
|
'flavor_delete',
|
|
'flavor_get_extras']})
|
|
def test_flavor_update(self):
|
|
flavor_req_data = '{"name": "flavor", ' \
|
|
'"ram": 12, ' \
|
|
'"vcpus": 1, ' \
|
|
'"disk": 2, ' \
|
|
'"OS-FLV-EXT-DATA:ephemeral": 3, ' \
|
|
'"swap": 4' \
|
|
'}'
|
|
|
|
self.mock_flavor_get_extras.return_value = {}
|
|
self.mock_flavor_create.return_value = mock.Mock(**{
|
|
'id': '123',
|
|
'to_dict.return_value': {'id': '123', 'name': 'flavor'}
|
|
})
|
|
self.mock_flavor_delete.return_value = None
|
|
|
|
flavor_data = {'name': 'flavor',
|
|
'memory': 12,
|
|
'vcpu': 1,
|
|
'disk': 2,
|
|
'ephemeral': 3,
|
|
'swap': 4,
|
|
'flavorid': '123',
|
|
'is_public': True}
|
|
|
|
request = self.mock_rest_request(body=flavor_req_data)
|
|
response = nova.Flavor().patch(request, '123')
|
|
|
|
self.assertStatusCode(response, 204)
|
|
|
|
self.mock_flavor_get_extras.assert_called_once_with(
|
|
request, '123', raw=True)
|
|
self.mock_flavor_delete.assert_called_once_with(request, '123')
|
|
self.mock_flavor_create.assert_called_once_with(request, **flavor_data)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_create', 'flavor_delete',
|
|
'flavor_extra_set', 'flavor_get_extras']})
|
|
def test_flavor_update_with_extras(self):
|
|
flavor_req_data = '{"name": "flavor", ' \
|
|
'"ram": 12, ' \
|
|
'"vcpus": 1, ' \
|
|
'"disk": 2, ' \
|
|
'"OS-FLV-EXT-DATA:ephemeral": 3, ' \
|
|
'"swap": 4' \
|
|
'}'
|
|
|
|
extra_dict = mock.Mock()
|
|
|
|
self.mock_flavor_get_extras.return_value = extra_dict
|
|
self.mock_flavor_create.return_value = mock.Mock(**{
|
|
'id': '1234',
|
|
'to_dict.return_value': {'id': '1234', 'name': 'flavor'}
|
|
})
|
|
self.mock_flavor_delete.return_value = None
|
|
self.mock_flavor_extra_set.return_value = None
|
|
|
|
flavor_data = {'name': 'flavor',
|
|
'memory': 12,
|
|
'vcpu': 1,
|
|
'disk': 2,
|
|
'ephemeral': 3,
|
|
'swap': 4,
|
|
'flavorid': '123',
|
|
'is_public': True}
|
|
|
|
request = self.mock_rest_request(body=flavor_req_data)
|
|
response = nova.Flavor().patch(request, '123')
|
|
|
|
self.assertStatusCode(response, 204)
|
|
|
|
self.mock_flavor_delete.assert_called_once_with(request, '123')
|
|
self.mock_flavor_create.assert_called_once_with(request, **flavor_data)
|
|
self.mock_flavor_get_extras.assert_called_once_with(request, '123',
|
|
raw=True)
|
|
self.mock_flavor_extra_set.assert_called_once_with(request, '1234',
|
|
extra_dict)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_create',
|
|
'flavor_delete',
|
|
'flavor_get_extras',
|
|
'add_tenant_to_flavor']})
|
|
def test_flavor_update_with_access_list(self):
|
|
flavor_req_data = '{"name": "flavor", ' \
|
|
'"ram": 12, ' \
|
|
'"vcpus": 1, ' \
|
|
'"disk": 2, ' \
|
|
'"OS-FLV-EXT-DATA:ephemeral": 3, ' \
|
|
'"swap": 4, ' \
|
|
'"flavor_access": [{"id":"1", "name":"test"}]' \
|
|
'}'
|
|
|
|
self.mock_flavor_get_extras.return_value = {}
|
|
self.mock_flavor_create.return_value = mock.Mock(**{
|
|
'id': '1234',
|
|
'to_dict.return_value': {'id': '1234', 'name': 'flavor'}
|
|
})
|
|
self.mock_flavor_delete.return_value = None
|
|
# A list of FlavorAccess object is returned but it is actually unused.
|
|
self.mock_add_tenant_to_flavor.return_value = [
|
|
mock.sentinel.flavor_access1,
|
|
]
|
|
|
|
flavor_data = {'name': 'flavor',
|
|
'memory': 12,
|
|
'vcpu': 1,
|
|
'disk': 2,
|
|
'ephemeral': 3,
|
|
'swap': 4,
|
|
'flavorid': '123',
|
|
'is_public': False}
|
|
|
|
request = self.mock_rest_request(body=flavor_req_data)
|
|
response = nova.Flavor().patch(request, '123')
|
|
|
|
self.assertStatusCode(response, 204)
|
|
|
|
self.mock_flavor_get_extras.assert_called_once_with(
|
|
request, '123', raw=True)
|
|
self.mock_flavor_delete.assert_called_once_with(request, '123')
|
|
self.mock_flavor_create.assert_called_once_with(request, **flavor_data)
|
|
self.mock_add_tenant_to_flavor.assert_called_once_with(
|
|
request, '1234', '1')
|
|
|
|
@test.create_mocks({api.nova: ['flavor_list']})
|
|
def _test_flavor_list_public(self, is_public=None):
|
|
if is_public:
|
|
request = self.mock_rest_request(GET={'is_public': 'tRuE'})
|
|
elif is_public is None:
|
|
request = self.mock_rest_request(GET={})
|
|
else:
|
|
request = self.mock_rest_request(GET={'is_public': 'fAlsE'})
|
|
self.mock_flavor_list.return_value = [
|
|
FakeFlavor("1"), FakeFlavor("2")
|
|
]
|
|
response = nova.Flavors().get(request)
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual({"items": [{"id": "1"}, {"id": "2"}]},
|
|
response.json)
|
|
self.mock_flavor_list.assert_called_once_with(request,
|
|
is_public=is_public,
|
|
get_extras=False)
|
|
|
|
def test_flavor_list_private(self):
|
|
self._test_flavor_list_public(is_public=False)
|
|
|
|
def test_flavor_list_public(self):
|
|
self._test_flavor_list_public(is_public=True)
|
|
|
|
def test_flavor_list_public_none(self):
|
|
self._test_flavor_list_public(is_public=None)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_list']})
|
|
def _test_flavor_list_extras(self, get_extras=None):
|
|
if get_extras:
|
|
request = self.mock_rest_request(GET={'get_extras': 'tRuE'})
|
|
elif get_extras is None:
|
|
request = self.mock_rest_request(GET={})
|
|
get_extras = False
|
|
else:
|
|
request = self.mock_rest_request(GET={'get_extras': 'fAlsE'})
|
|
|
|
self.mock_flavor_list.return_value = [
|
|
FakeFlavor("1"), FakeFlavor("2")
|
|
]
|
|
response = nova.Flavors().get(request)
|
|
self.assertStatusCode(response, 200)
|
|
if get_extras:
|
|
self.assertEqual({"items": [{"extras": {}, "id": "1"},
|
|
{"extras": {}, "id": "2"}]},
|
|
response.json)
|
|
else:
|
|
self.assertEqual({"items": [{"id": "1"}, {"id": "2"}]},
|
|
response.json)
|
|
self.mock_flavor_list.assert_called_once_with(request, is_public=None,
|
|
get_extras=get_extras)
|
|
|
|
def test_flavor_list_extras_no(self):
|
|
self._test_flavor_list_extras(get_extras=False)
|
|
|
|
def test_flavor_list_extras_yes(self):
|
|
self._test_flavor_list_extras(get_extras=True)
|
|
|
|
def test_flavor_list_extras_absent(self):
|
|
self._test_flavor_list_extras(get_extras=None)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_get_extras']})
|
|
def test_flavor_get_extra_specs(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_flavor_get_extras.return_value.to_dict.return_value = \
|
|
{'foo': '1'}
|
|
|
|
response = nova.FlavorExtraSpecs().get(request, "1")
|
|
self.assertStatusCode(response, 200)
|
|
self.mock_flavor_get_extras.assert_called_once_with(request, "1",
|
|
raw=True)
|
|
|
|
@test.create_mocks({api.nova: ['flavor_extra_delete',
|
|
'flavor_extra_set']})
|
|
def test_flavor_edit_extra_specs(self):
|
|
request = self.mock_rest_request(
|
|
body='{"updated": {"a": "1", "b": "2"}, "removed": ["c", "d"]}'
|
|
)
|
|
self.mock_flavor_extra_delete.return_value = None
|
|
self.mock_flavor_extra_set.return_value = {'a': '1', 'b': '2'}
|
|
|
|
response = nova.FlavorExtraSpecs().patch(request, '1')
|
|
self.assertStatusCode(response, 204)
|
|
self.assertEqual(b'', response.content)
|
|
self.mock_flavor_extra_set.assert_called_once_with(
|
|
request, '1', {'a': '1', 'b': '2'}
|
|
)
|
|
self.mock_flavor_extra_delete.assert_called_once_with(
|
|
request, '1', ['c', 'd']
|
|
)
|
|
|
|
@test.create_mocks({api.nova: ['aggregate_get']})
|
|
def test_aggregate_get_extra_specs(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_aggregate_get.return_value.metadata = {'a': '1', 'b': '2'}
|
|
|
|
response = nova.AggregateExtraSpecs().get(request, "1")
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual({"a": "1", "b": "2"}, response.json)
|
|
self.mock_aggregate_get.assert_called_once_with(request, "1")
|
|
|
|
@test.create_mocks({api.nova: ['aggregate_set_metadata']})
|
|
def test_aggregate_edit_extra_specs(self):
|
|
self.mock_aggregate_set_metadata.return_value = self.aggregates.first()
|
|
request = self.mock_rest_request(
|
|
body='{"updated": {"a": "1", "b": "2"}, "removed": ["c", "d"]}'
|
|
)
|
|
|
|
response = nova.AggregateExtraSpecs().patch(request, '1')
|
|
self.assertStatusCode(response, 204)
|
|
self.assertEqual(b'', response.content)
|
|
self.mock_aggregate_set_metadata.assert_called_once_with(
|
|
request, '1', {'a': '1', 'b': '2', 'c': None, 'd': None}
|
|
)
|
|
|
|
#
|
|
# Services
|
|
#
|
|
|
|
@test.create_mocks({api.base: ['is_service_enabled'],
|
|
api.nova: ['service_list']})
|
|
def test_services_get(self):
|
|
request = self.mock_rest_request(GET={})
|
|
self.mock_service_list.return_value = [
|
|
mock.Mock(**{'to_dict.return_value': {'id': '1'}}),
|
|
mock.Mock(**{'to_dict.return_value': {'id': '2'}})
|
|
]
|
|
self.mock_is_service_enabled.return_value = True
|
|
|
|
response = nova.Services().get(request)
|
|
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual('{"items": [{"id": "1"}, {"id": "2"}]}',
|
|
response.content.decode('utf-8'))
|
|
self.mock_service_list.assert_called_once_with(request)
|
|
self.mock_is_service_enabled.assert_called_once_with(request,
|
|
'compute')
|
|
|
|
@mock.patch.object(api.base, 'is_service_enabled')
|
|
def test_services_get_disabled(self, mock_is_service_enabled):
|
|
request = self.mock_rest_request(GET={})
|
|
mock_is_service_enabled.return_value = False
|
|
|
|
response = nova.Services().get(request)
|
|
|
|
self.assertStatusCode(response, 501)
|
|
mock_is_service_enabled.assert_called_once_with(request, 'compute')
|
|
|
|
@test.create_mocks({api.base: ['is_service_enabled'],
|
|
quotas: ['get_disabled_quotas'],
|
|
api.nova: ['default_quota_get']})
|
|
def test_quota_sets_defaults_get(self):
|
|
filters = {'user': {'tenant_id': 'tenant'}}
|
|
request = self.mock_rest_request(**{'GET': dict(filters)})
|
|
|
|
self.mock_is_service_enabled.return_value = True
|
|
self.mock_get_disabled_quotas.return_value = ['floating_ips']
|
|
self.mock_default_quota_get.return_value = [
|
|
Quota('metadata_items', 100),
|
|
Quota('floating_ips', 1),
|
|
Quota('q2', 101)
|
|
]
|
|
|
|
response = nova.DefaultQuotaSets().get(request)
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(response.json,
|
|
{"items": [
|
|
{"limit": 100,
|
|
"display_name": "Metadata Items",
|
|
"name": "metadata_items"},
|
|
{"limit": 101,
|
|
"display_name": "Q2",
|
|
"name": "q2"}
|
|
]})
|
|
|
|
self.mock_is_service_enabled.assert_called_once_with(request,
|
|
'compute')
|
|
self.mock_get_disabled_quotas.assert_called_once_with(request)
|
|
self.mock_default_quota_get.assert_called_once_with(
|
|
request, request.user.tenant_id)
|
|
|
|
@test.create_mocks({api.base: ['is_service_enabled']})
|
|
def test_quota_sets_defaults_get_when_service_is_disabled(self):
|
|
filters = {'user': {'tenant_id': 'tenant'}}
|
|
request = self.mock_rest_request(**{'GET': dict(filters)})
|
|
self.mock_is_service_enabled.return_value = False
|
|
|
|
response = nova.DefaultQuotaSets().get(request)
|
|
|
|
self.assertStatusCode(response, 501)
|
|
self.assertEqual(response.content.decode('utf-8'),
|
|
'"Service Nova is disabled."')
|
|
self.mock_is_service_enabled.assert_called_once_with(request,
|
|
'compute')
|
|
|
|
@test.create_mocks({api.base: ['is_service_enabled'],
|
|
quotas: ['get_disabled_quotas'],
|
|
api.nova: ['default_quota_update']})
|
|
def test_quota_sets_defaults_patch(self):
|
|
request = self.mock_rest_request(body='''
|
|
{"key_pairs": "15", "metadata_items": "5000",
|
|
"cores": "10", "instances": "20", "floating_ips": 10,
|
|
"injected_file_content_bytes": "15",
|
|
"injected_file_path_bytes": "5000",
|
|
"injected_files": "5", "ram": "10", "gigabytes": "5"}
|
|
''')
|
|
|
|
self.mock_is_service_enabled.return_value = True
|
|
self.mock_get_disabled_quotas.return_value = ['floating_ips']
|
|
self.mock_default_quota_update.return_value = None
|
|
|
|
response = nova.DefaultQuotaSets().patch(request)
|
|
|
|
self.assertStatusCode(response, 204)
|
|
self.assertEqual(response.content.decode('utf-8'), '')
|
|
|
|
self.mock_is_service_enabled.assert_called_once_with(request,
|
|
'compute')
|
|
self.mock_get_disabled_quotas.assert_called_once_with(request)
|
|
self.mock_default_quota_update.assert_called_once_with(
|
|
request, key_pairs='15',
|
|
metadata_items='5000', cores='10',
|
|
instances='20', injected_file_content_bytes='15',
|
|
injected_file_path_bytes='5000',
|
|
injected_files='5', ram='10')
|
|
|
|
@test.create_mocks({api.base: ['is_service_enabled']})
|
|
def test_quota_sets_defaults_patch_when_service_is_disabled(self):
|
|
request = self.mock_rest_request(body='''
|
|
{"key_pairs": "15", "metadata_items": "5000",
|
|
"cores": "10", "instances": "20", "floating_ips": 10,
|
|
"injected_file_content_bytes": "15",
|
|
"injected_file_path_bytes": "5000",
|
|
"injected_files": "5", "ram": "10", "gigabytes": "5"}
|
|
''')
|
|
|
|
self.mock_is_service_enabled.return_value = False
|
|
|
|
response = nova.DefaultQuotaSets().patch(request)
|
|
|
|
self.assertStatusCode(response, 501)
|
|
self.assertEqual(response.content.decode('utf-8'),
|
|
'"Service Nova is disabled."')
|
|
|
|
self.mock_is_service_enabled.assert_called_once_with(request,
|
|
'compute')
|
|
|
|
@test.create_mocks({quotas: ['get_disabled_quotas']})
|
|
def test_editable_quotas_get(self):
|
|
disabled_quotas = {'floating_ips', 'fixed_ips',
|
|
'security_groups', 'security_group_rules'}
|
|
editable_quotas = {'cores', 'volumes', 'network', 'fixed_ips'}
|
|
self.mock_get_disabled_quotas.return_value = disabled_quotas
|
|
request = self.mock_rest_request()
|
|
|
|
with mock.patch.object(quotas, 'QUOTA_FIELDS', editable_quotas):
|
|
response = nova.EditableQuotaSets().get(request)
|
|
|
|
self.assertStatusCode(response, 200)
|
|
# NOTE(amotoki): assertItemsCollectionEqual cannot be used below
|
|
# since the item list is generated from a set and the order of items
|
|
# is unpredictable.
|
|
self.assertEqual(set(response.json['items']),
|
|
{'cores', 'volumes', 'network'})
|
|
self.mock_get_disabled_quotas.assert_called_once_with(request)
|
|
|
|
@test.create_mocks({api.base: ['is_service_enabled'],
|
|
quotas: ['get_disabled_quotas'],
|
|
api.nova: ['tenant_quota_update']})
|
|
def test_quota_sets_patch(self):
|
|
quota_data = dict(cores='15', instances='5',
|
|
ram='50000', metadata_items='150',
|
|
injected_files='5',
|
|
injected_file_content_bytes='10240',
|
|
floating_ips='50', fixed_ips='5',
|
|
security_groups='10',
|
|
security_group_rules='100')
|
|
|
|
request = self.mock_rest_request(body='''
|
|
{"cores": "15", "ram": "50000", "instances": "5",
|
|
"metadata_items": "150", "injected_files": "5",
|
|
"injected_file_content_bytes": "10240", "floating_ips": "50",
|
|
"fixed_ips": "5", "security_groups": "10" ,
|
|
"security_group_rules": "100", "volumes": "10"}
|
|
''')
|
|
|
|
self.mock_get_disabled_quotas.return_value = set()
|
|
self.mock_is_service_enabled.return_value = True
|
|
self.mock_tenant_quota_update.return_value = None
|
|
|
|
with mock.patch.object(quotas, 'NOVA_QUOTA_FIELDS',
|
|
{n for n in quota_data}):
|
|
response = nova.QuotaSets().patch(request, 'spam123')
|
|
|
|
self.assertStatusCode(response, 204)
|
|
self.assertEqual(response.content.decode('utf-8'), '')
|
|
self.mock_is_service_enabled.assert_called_once_with(request,
|
|
'compute')
|
|
self.mock_get_disabled_quotas.assert_called_once_with(request)
|
|
self.mock_tenant_quota_update.assert_called_once_with(
|
|
request, 'spam123', **quota_data)
|
|
|
|
@test.create_mocks({api.nova: ['tenant_quota_update'],
|
|
api.base: ['is_service_enabled'],
|
|
quotas: ['get_disabled_quotas']})
|
|
def test_quota_sets_patch_when_service_is_disabled(self):
|
|
quota_data = dict(cores='15', instances='5',
|
|
ram='50000', metadata_items='150',
|
|
injected_files='5',
|
|
injected_file_content_bytes='10240',
|
|
floating_ips='50', fixed_ips='5',
|
|
security_groups='10',
|
|
security_group_rules='100')
|
|
|
|
request = self.mock_rest_request(body='''
|
|
{"cores": "15", "ram": "50000", "instances": "5",
|
|
"metadata_items": "150", "injected_files": "5",
|
|
"injected_file_content_bytes": "10240", "floating_ips": "50",
|
|
"fixed_ips": "5", "security_groups": "10" ,
|
|
"security_group_rules": "100", "volumes": "10"}
|
|
''')
|
|
|
|
self.mock_get_disabled_quotas.return_value = {}
|
|
self.mock_is_service_enabled.return_value = False
|
|
self.mock_tenant_quota_update.return_value = None
|
|
|
|
with mock.patch.object(quotas, 'NOVA_QUOTA_FIELDS',
|
|
{n for n in quota_data}):
|
|
response = nova.QuotaSets().patch(request, 'spam123')
|
|
|
|
self.assertStatusCode(response, 501)
|
|
self.assertEqual(response.content.decode('utf-8'),
|
|
'"Service Nova is disabled."')
|
|
self.mock_get_disabled_quotas.assert_called_once_with(request)
|
|
self.mock_is_service_enabled.assert_called_once_with(request,
|
|
'compute')
|
|
self.mock_tenant_quota_update.assert_not_called()
|
|
|
|
@test.create_mocks({api.nova: ['is_feature_available']})
|
|
def test_version_get(self):
|
|
request = self.mock_rest_request()
|
|
self.mock_is_feature_available.return_value = True
|
|
|
|
response = nova.Features().get(request, 'fake')
|
|
self.assertStatusCode(response, 200)
|
|
self.assertEqual(response.content.decode('utf-8'), 'true')
|
|
self.mock_is_feature_available.assert_called_once_with(request,
|
|
('fake',))
|