
"Get-me-a-network" feature is supported in Nova API 2.37 or later. To support this in horizon, a dummy "auto_allocated_network" is shown in the launch instance form. I believe this approach fits the current way of the launch instance form. The dummy network is a special network ID and if specified the nova API wrapper converts 'nics' parameter properly. In addition, a dummy "auto_allocated_network" is now shown in the network table. This is because Neutron creates an actual auto allocated network once a server is created specifying nics=="auto". I believe this fake behavior brings consistency in the network table to some extent, while this is just a compromise. Note that this patch does not cover the network topology integration. "auto_allocated_network" is not shown until the actual auto allocated network is created. The network topology integration requires more work. For example, the link for the fake auto allocated network should be disabled in the flat view. The pop-up for the fake auto allocated network should be disabled in the graph view. Change-Id: I062fc1b7ed75dc771ddc7f13c8324ed4ffab6808 Closes-Bug: #1690433
833 lines
34 KiB
Python
833 lines
34 KiB
Python
# Copyright 2012 United States Government as represented by the
|
|
# Administrator of the National Aeronautics and Space Administration.
|
|
# All Rights Reserved.
|
|
#
|
|
# Copyright 2012 Nebula, Inc.
|
|
# Copyright (c) 2012 X.commerce, a business unit of eBay 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.
|
|
|
|
from __future__ import absolute_import
|
|
|
|
from django.conf import settings
|
|
from django.test.utils import override_settings
|
|
|
|
import mock
|
|
from novaclient import api_versions
|
|
from novaclient import exceptions as nova_exceptions
|
|
from novaclient.v2 import flavor_access as nova_flavor_access
|
|
from novaclient.v2 import quotas
|
|
from novaclient.v2 import servers
|
|
|
|
from horizon import exceptions as horizon_exceptions
|
|
from openstack_dashboard import api
|
|
from openstack_dashboard.test import helpers as test
|
|
|
|
|
|
class ServerWrapperTests(test.TestCase):
|
|
|
|
def test_get_base_attribute(self):
|
|
server = api.nova.Server(self.servers.first(), self.request)
|
|
self.assertEqual(self.servers.first().id, server.id)
|
|
|
|
@mock.patch.object(api.glance, 'image_get')
|
|
def test_image_name(self, mock_image_get):
|
|
image = self.images.first()
|
|
mock_image_get.return_value = image
|
|
|
|
server = api.nova.Server(self.servers.first(), self.request)
|
|
self.assertEqual(image.name, server.image_name)
|
|
mock_image_get.assert_called_once_with(test.IsHttpRequest(), image.id)
|
|
|
|
@mock.patch.object(api.glance, 'image_get')
|
|
def test_image_name_no_glance_service(self, mock_image_get):
|
|
server = self.servers.first()
|
|
exc_catalog = horizon_exceptions.ServiceCatalogException('image')
|
|
mock_image_get.side_effect = exc_catalog
|
|
|
|
server = api.nova.Server(server, self.request)
|
|
self.assertIsNone(server.image_name)
|
|
mock_image_get.assert_called_once_with(test.IsHttpRequest(),
|
|
server.image['id'])
|
|
|
|
|
|
class ComputeApiTests(test.APIMockTestCase):
|
|
|
|
def _mock_current_version(self, mock_novaclient, version,
|
|
min_version=None):
|
|
ver = mock.Mock()
|
|
ver.min_version = min_version or '2.1'
|
|
ver.version = version
|
|
mock_novaclient.versions.get_current.return_value = ver
|
|
# To handle upgrade_api
|
|
mock_novaclient.api_version = api_versions.APIVersion(version)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_reboot(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
HARDNESS = servers.REBOOT_HARD
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.servers.reboot.return_value = None
|
|
|
|
ret_val = api.nova.server_reboot(self.request, server.id)
|
|
|
|
self.assertIsNone(ret_val)
|
|
novaclient.servers.reboot.assert_called_once_with(
|
|
server.id, HARDNESS)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_soft_reboot(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
HARDNESS = servers.REBOOT_SOFT
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.servers.reboot.return_value = None
|
|
|
|
ret_val = api.nova.server_reboot(self.request, server.id, HARDNESS)
|
|
|
|
self.assertIsNone(ret_val)
|
|
novaclient.servers.reboot.assert_called_once_with(
|
|
server.id, HARDNESS)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_vnc_console(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
console = self.servers.vnc_console_data
|
|
console_type = console["console"]["type"]
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.servers.get_vnc_console.return_value = console
|
|
|
|
ret_val = api.nova.server_vnc_console(self.request,
|
|
server.id,
|
|
console_type)
|
|
|
|
self.assertIsInstance(ret_val, api.nova.VNCConsole)
|
|
novaclient.servers.get_vnc_console.assert_called_once_with(
|
|
server.id, console_type)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_spice_console(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
console = self.servers.spice_console_data
|
|
console_type = console["console"]["type"]
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.servers.get_spice_console.return_value = console
|
|
|
|
ret_val = api.nova.server_spice_console(self.request,
|
|
server.id,
|
|
console_type)
|
|
self.assertIsInstance(ret_val, api.nova.SPICEConsole)
|
|
novaclient.servers.get_spice_console.assert_called_once_with(
|
|
server.id, console_type)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_rdp_console(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
console = self.servers.rdp_console_data
|
|
console_type = console["console"]["type"]
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.servers.get_rdp_console.return_value = console
|
|
|
|
ret_val = api.nova.server_rdp_console(self.request,
|
|
server.id,
|
|
console_type)
|
|
self.assertIsInstance(ret_val, api.nova.RDPConsole)
|
|
novaclient.servers.get_rdp_console.assert_called_once_with(
|
|
server.id, console_type)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_mks_console(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
console = self.servers.mks_console_data
|
|
console_type = console["remote_console"]["type"]
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.53')
|
|
novaclient.servers.get_mks_console.return_value = console
|
|
|
|
ret_val = api.nova.server_mks_console(self.request,
|
|
server.id,
|
|
console_type)
|
|
self.assertIsInstance(ret_val, api.nova.MKSConsole)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.servers.get_mks_console.assert_called_once_with(
|
|
server.id, console_type)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_list(self, mock_novaclient):
|
|
servers = self.servers.list()
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.40')
|
|
novaclient.servers.list.return_value = servers
|
|
|
|
ret_val, has_more = api.nova.server_list(
|
|
self.request,
|
|
search_opts={'all_tenants': True})
|
|
for server in ret_val:
|
|
self.assertIsInstance(server, api.nova.Server)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.servers.list.assert_called_once_with(
|
|
True, {'all_tenants': True})
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_list_pagination(self, mock_novaclient):
|
|
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 20)
|
|
servers = self.servers.list()
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.45')
|
|
novaclient.servers.list.return_value = servers
|
|
|
|
ret_val, has_more = api.nova.server_list(self.request,
|
|
{'marker': None,
|
|
'paginate': True,
|
|
'all_tenants': True})
|
|
for server in ret_val:
|
|
self.assertIsInstance(server, api.nova.Server)
|
|
self.assertFalse(has_more)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.servers.list.assert_called_once_with(
|
|
True,
|
|
{'all_tenants': True,
|
|
'marker': None,
|
|
'limit': page_size + 1})
|
|
|
|
@override_settings(API_RESULT_PAGE_SIZE=1)
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_list_pagination_more(self, mock_novaclient):
|
|
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 1)
|
|
servers = self.servers.list()
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.45')
|
|
novaclient.servers.list.return_value = servers[:page_size + 1]
|
|
|
|
ret_val, has_more = api.nova.server_list(self.request,
|
|
{'marker': None,
|
|
'paginate': True,
|
|
'all_tenants': True})
|
|
|
|
for server in ret_val:
|
|
self.assertIsInstance(server, api.nova.Server)
|
|
self.assertEqual(page_size, len(ret_val))
|
|
self.assertTrue(has_more)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.servers.list.assert_called_once_with(
|
|
True,
|
|
{'all_tenants': True,
|
|
'marker': None,
|
|
'limit': page_size + 1})
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_usage_get(self, mock_novaclient):
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.1')
|
|
novaclient.usages.get.return_value = self.usages.first()
|
|
|
|
ret_val = api.nova.usage_get(self.request, self.tenant.id,
|
|
'start', 'end')
|
|
|
|
self.assertIsInstance(ret_val, api.nova.NovaUsage)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.usage.get.assert_called_once_with(
|
|
self.tenant.id, 'start', 'end')
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_usage_get_paginated(self, mock_novaclient):
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.40')
|
|
novaclient.usage.get.side_effect = [
|
|
self.usages.first(),
|
|
{},
|
|
]
|
|
|
|
ret_val = api.nova.usage_get(self.request, self.tenant.id,
|
|
'start', 'end')
|
|
|
|
self.assertIsInstance(ret_val, api.nova.NovaUsage)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.usage.get.assert_has_calls([
|
|
mock.call(self.tenant.id, 'start', 'end'),
|
|
mock.call(self.tenant.id, 'start', 'end',
|
|
marker=u'063cf7f3-ded1-4297-bc4c-31eae876cc93'),
|
|
])
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_usage_list(self, mock_novaclient):
|
|
usages = self.usages.list()
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.1')
|
|
novaclient.usage.list.return_value = usages
|
|
|
|
ret_val = api.nova.usage_list(self.request, 'start', 'end')
|
|
|
|
for usage in ret_val:
|
|
self.assertIsInstance(usage, api.nova.NovaUsage)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.usage.list.assert_called_once_with('start', 'end', True)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_usage_list_paginated(self, mock_novaclient):
|
|
usages = self.usages.list()
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.40')
|
|
novaclient.usage.list.side_effect = [
|
|
usages,
|
|
{},
|
|
]
|
|
|
|
ret_val = api.nova.usage_list(self.request, 'start', 'end')
|
|
|
|
for usage in ret_val:
|
|
self.assertIsInstance(usage, api.nova.NovaUsage)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.usage.list.assert_has_calls([
|
|
mock.call('start', 'end', True),
|
|
mock.call('start', 'end', True,
|
|
marker=u'063cf7f3-ded1-4297-bc4c-31eae876cc93'),
|
|
])
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_get(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.45')
|
|
novaclient.servers.get.return_value = server
|
|
|
|
ret_val = api.nova.server_get(self.request, server.id)
|
|
self.assertIsInstance(ret_val, api.nova.Server)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.servers.get.assert_called_once_with(server.id)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_metadata_update(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
metadata = {'foo': 'bar'}
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.servers.set_meta.return_value = None
|
|
|
|
ret_val = api.nova.server_metadata_update(self.request,
|
|
server.id,
|
|
metadata)
|
|
self.assertIsNone(ret_val)
|
|
novaclient.servers.set_meta.assert_called_once_with(server.id,
|
|
metadata)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_metadata_delete(self, mock_novaclient):
|
|
server = self.servers.first()
|
|
keys = ['a', 'b']
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.servers.delete_meta.return_value = None
|
|
|
|
ret_val = api.nova.server_metadata_delete(self.request,
|
|
server.id,
|
|
keys)
|
|
self.assertIsNone(ret_val)
|
|
novaclient.servers.delete_meta.assert_called_once_with(server.id, keys)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def _test_absolute_limits(self, values, expected_results, mock_novaclient):
|
|
limits = mock.Mock()
|
|
limits.absolute = []
|
|
for key, val in values.items():
|
|
limit = mock.Mock()
|
|
limit.name = key
|
|
limit.value = val
|
|
limits.absolute.append(limit)
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.limits.get.return_value = limits
|
|
|
|
ret_val = api.nova.tenant_absolute_limits(self.request, reserved=True)
|
|
|
|
for key in expected_results.keys():
|
|
self.assertEqual(expected_results[key], ret_val[key])
|
|
novaclient.limits.get.assert_called_once_with(reserved=True,
|
|
tenant_id=None)
|
|
|
|
def test_absolute_limits_handle_unlimited(self):
|
|
values = {"maxTotalCores": -1, "maxTotalInstances": 10}
|
|
expected_results = {"maxTotalCores": float("inf"),
|
|
"maxTotalInstances": 10}
|
|
self._test_absolute_limits(values, expected_results)
|
|
|
|
def test_absolute_limits_negative_used_workaround(self):
|
|
values = {"maxTotalCores": -1,
|
|
"maxTotalInstances": 10,
|
|
"totalInstancesUsed": -1,
|
|
"totalCoresUsed": -1,
|
|
"totalRAMUsed": -2048,
|
|
"totalSecurityGroupsUsed": 1,
|
|
"totalFloatingIpsUsed": 0,
|
|
}
|
|
expected_results = {"maxTotalCores": float("inf"),
|
|
"maxTotalInstances": 10,
|
|
"totalInstancesUsed": 0,
|
|
"totalCoresUsed": 0,
|
|
"totalRAMUsed": 0,
|
|
"totalSecurityGroupsUsed": 1,
|
|
"totalFloatingIpsUsed": 0,
|
|
}
|
|
self._test_absolute_limits(values, expected_results)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_cold_migrate_host_succeed(self, mock_novaclient):
|
|
hypervisor = self.hypervisors.first()
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.hypervisors.search.return_value = [hypervisor]
|
|
novaclient.servers.migrate.return_value = None
|
|
|
|
ret_val = api.nova.migrate_host(self.request, "host", False, True,
|
|
True)
|
|
|
|
self.assertTrue(ret_val)
|
|
novaclient.hypervisors.search.assert_called_once_with('host', True)
|
|
novaclient.servers.migrate.assert_called_once_with('test_uuid')
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_cold_migrate_host_fails(self, mock_novaclient):
|
|
hypervisor = self.hypervisors.first()
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.hypervisors.search.return_value = [hypervisor]
|
|
novaclient.servers.migrate.side_effect = \
|
|
nova_exceptions.ClientException(404)
|
|
|
|
self.assertRaises(nova_exceptions.ClientException,
|
|
api.nova.migrate_host,
|
|
self.request, "host", False, True, True)
|
|
novaclient.hypervisors.search.assert_called_once_with('host', True)
|
|
novaclient.servers.migrate.assert_called_once_with('test_uuid')
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_live_migrate_host_with_active_vm(self, mock_novaclient):
|
|
hypervisor = self.hypervisors.first()
|
|
server = self.servers.first()
|
|
novaclient = mock_novaclient.return_value
|
|
server_uuid = hypervisor.servers[0]["uuid"]
|
|
|
|
self._mock_current_version(novaclient, '2.45')
|
|
novaclient.hypervisors.search.return_value = [hypervisor]
|
|
novaclient.servers.get.return_value = server
|
|
novaclient.servers.live_migrate.return_value = None
|
|
|
|
ret_val = api.nova.migrate_host(self.request, "host", True, True,
|
|
True)
|
|
|
|
self.assertTrue(ret_val)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.hypervisors.search.assert_called_once_with('host', True)
|
|
novaclient.servers.get.assert_called_once_with(server_uuid)
|
|
novaclient.servers.live_migrate.assert_called_once_with(
|
|
server_uuid, None, True, True)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_live_migrate_host_with_paused_vm(self, mock_novaclient):
|
|
hypervisor = self.hypervisors.first()
|
|
server = self.servers.list()[3]
|
|
novaclient = mock_novaclient.return_value
|
|
server_uuid = hypervisor.servers[0]["uuid"]
|
|
|
|
self._mock_current_version(novaclient, '2.45')
|
|
novaclient.hypervisors.search.return_value = [hypervisor]
|
|
novaclient.servers.get.return_value = server
|
|
novaclient.servers.live_migrate.return_value = None
|
|
|
|
ret_val = api.nova.migrate_host(self.request, "host", True, True, True)
|
|
|
|
self.assertTrue(ret_val)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.hypervisors.search.assert_called_once_with('host', True)
|
|
novaclient.servers.get.assert_called_once_with(server_uuid)
|
|
novaclient.servers.live_migrate.assert_called_once_with(
|
|
server_uuid, None, True, True)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_live_migrate_host_without_running_vm(self, mock_novaclient):
|
|
hypervisor = self.hypervisors.first()
|
|
server = self.servers.list()[1]
|
|
novaclient = mock_novaclient.return_value
|
|
server_uuid = hypervisor.servers[0]["uuid"]
|
|
|
|
self._mock_current_version(novaclient, '2.45')
|
|
novaclient.hypervisors.search.return_value = [hypervisor]
|
|
novaclient.servers.get.return_value = server
|
|
novaclient.servers.migrate.return_value = None
|
|
|
|
ret_val = api.nova.migrate_host(self.request, "host", True, True, True)
|
|
|
|
self.assertTrue(ret_val)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.hypervisors.search.assert_called_once_with('host', True)
|
|
novaclient.servers.get.assert_called_once_with(server_uuid)
|
|
novaclient.servers.migrate.assert_called_once_with(server_uuid)
|
|
|
|
"""Flavor Tests"""
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_flavor_list_no_extras(self, mock_novaclient):
|
|
flavors = self.flavors.list()
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavors.list.return_value = flavors
|
|
|
|
api_flavors = api.nova.flavor_list(self.request)
|
|
|
|
self.assertEqual(len(flavors), len(api_flavors))
|
|
novaclient.flavors.list.assert_called_once_with(is_public=True)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_flavor_get_no_extras(self, mock_novaclient):
|
|
flavor = self.flavors.list()[1]
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavors.get.return_value = flavor
|
|
|
|
api_flavor = api.nova.flavor_get(self.request, flavor.id)
|
|
|
|
self.assertEqual(api_flavor.id, flavor.id)
|
|
novaclient.flavors.get.assert_called_once_with(flavor.id)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def _test_flavor_list_paged(self, mock_novaclient,
|
|
reversed_order=False, paginate=True):
|
|
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 20)
|
|
flavors = self.flavors.list()
|
|
order = 'asc' if reversed_order else 'desc'
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavors.list.return_value = flavors
|
|
|
|
api_flavors, has_more, has_prev = api.nova.flavor_list_paged(
|
|
self.request, True, False, None, paginate=paginate,
|
|
reversed_order=reversed_order)
|
|
|
|
for flavor in api_flavors:
|
|
self.assertIsInstance(flavor, type(flavors[0]))
|
|
self.assertFalse(has_more)
|
|
self.assertFalse(has_prev)
|
|
if paginate:
|
|
novaclient.flavors.list.assert_called_once_with(
|
|
is_public=True, marker=None, limit=page_size + 1,
|
|
sort_key='name', sort_dir=order)
|
|
else:
|
|
novaclient.flavors.list.assert_called_once_with(
|
|
is_public=True)
|
|
|
|
@override_settings(API_RESULT_PAGE_SIZE=1)
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_flavor_list_pagination_more_and_prev(self, mock_novaclient):
|
|
page_size = getattr(settings, 'API_RESULT_PAGE_SIZE', 1)
|
|
flavors = self.flavors.list()
|
|
marker = flavors[0].id
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavors.list.return_value = flavors[1:page_size + 2]
|
|
|
|
api_flavors, has_more, has_prev = api.nova\
|
|
.flavor_list_paged(
|
|
self.request,
|
|
True,
|
|
False,
|
|
marker,
|
|
paginate=True)
|
|
|
|
for flavor in api_flavors:
|
|
self.assertIsInstance(flavor, type(flavors[0]))
|
|
self.assertEqual(page_size, len(api_flavors))
|
|
self.assertTrue(has_more)
|
|
self.assertTrue(has_prev)
|
|
novaclient.flavors.list.assert_called_once_with(
|
|
is_public=True, marker=marker, limit=page_size + 1,
|
|
sort_key='name', sort_dir='desc')
|
|
|
|
def test_flavor_list_paged_default_order(self):
|
|
self._test_flavor_list_paged()
|
|
|
|
def test_flavor_list_paged_reversed_order(self):
|
|
self._test_flavor_list_paged(reversed_order=True)
|
|
|
|
def test_flavor_list_paged_paginate_false(self):
|
|
self._test_flavor_list_paged(paginate=False)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_flavor_create(self, mock_novaclient):
|
|
flavor = self.flavors.first()
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavors.create.return_value = flavor
|
|
|
|
api_flavor = api.nova.flavor_create(self.request,
|
|
flavor.name,
|
|
flavor.ram,
|
|
flavor.vcpus,
|
|
flavor.disk)
|
|
|
|
self.assertIsInstance(api_flavor, type(flavor))
|
|
self.assertEqual(flavor.name, api_flavor.name)
|
|
self.assertEqual(flavor.ram, api_flavor.ram)
|
|
self.assertEqual(flavor.vcpus, api_flavor.vcpus)
|
|
self.assertEqual(flavor.disk, api_flavor.disk)
|
|
self.assertEqual(0, api_flavor.ephemeral)
|
|
self.assertEqual(0, api_flavor.swap)
|
|
self.assertTrue(api_flavor.is_public)
|
|
self.assertEqual(1, api_flavor.rxtx_factor)
|
|
|
|
novaclient.flavors.create.assert_called_once_with(
|
|
flavor.name, flavor.ram, flavor.vcpus, flavor.disk,
|
|
flavorid='auto', ephemeral=0, swap=0, is_public=True,
|
|
rxtx_factor=1)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_flavor_delete(self, mock_novaclient):
|
|
flavor = self.flavors.first()
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavors.delete.return_value = None
|
|
|
|
api_val = api.nova.flavor_delete(self.request, flavor.id)
|
|
|
|
self.assertIsNone(api_val)
|
|
novaclient.flavors.delete.assert_called_once_with(flavor.id)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_flavor_access_list(self, mock_novaclient):
|
|
flavor_access = self.flavor_access.list()
|
|
flavor = [f for f in self.flavors.list() if f.id ==
|
|
flavor_access[0].flavor_id][0]
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavor_access.list.return_value = flavor_access
|
|
|
|
api_flavor_access = api.nova.flavor_access_list(self.request, flavor)
|
|
|
|
self.assertEqual(len(flavor_access), len(api_flavor_access))
|
|
for access in api_flavor_access:
|
|
self.assertIsInstance(access, nova_flavor_access.FlavorAccess)
|
|
self.assertEqual(access.flavor_id, flavor.id)
|
|
novaclient.flavor_access.list.assert_called_once_with(flavor=flavor)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_add_tenant_to_flavor(self, mock_novaclient):
|
|
flavor_access = [self.flavor_access.first()]
|
|
flavor = [f for f in self.flavors.list() if f.id ==
|
|
flavor_access[0].flavor_id][0]
|
|
tenant = [t for t in self.tenants.list() if t.id ==
|
|
flavor_access[0].tenant_id][0]
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavor_access.add_tenant_access.return_value = flavor_access
|
|
|
|
api_flavor_access = api.nova.add_tenant_to_flavor(self.request,
|
|
flavor,
|
|
tenant)
|
|
self.assertIsInstance(api_flavor_access, list)
|
|
self.assertEqual(len(flavor_access), len(api_flavor_access))
|
|
|
|
for access in api_flavor_access:
|
|
self.assertEqual(access.flavor_id, flavor.id)
|
|
self.assertEqual(access.tenant_id, tenant.id)
|
|
|
|
novaclient.flavor_access.add_tenant_access.assert_called_once_with(
|
|
flavor=flavor, tenant=tenant)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_remove_tenant_from_flavor(self, mock_novaclient):
|
|
flavor_access = [self.flavor_access.first()]
|
|
flavor = [f for f in self.flavors.list() if f.id ==
|
|
flavor_access[0].flavor_id][0]
|
|
tenant = [t for t in self.tenants.list() if t.id ==
|
|
flavor_access[0].tenant_id][0]
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.flavor_access.remove_tenant_access.return_value = []
|
|
|
|
api_val = api.nova.remove_tenant_from_flavor(self.request,
|
|
flavor,
|
|
tenant)
|
|
|
|
self.assertEqual(len(api_val), len([]))
|
|
self.assertIsInstance(api_val, list)
|
|
novaclient.flavor_access.remove_tenant_access.assert_called_once_with(
|
|
flavor=flavor, tenant=tenant)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_group_list(self, mock_novaclient):
|
|
server_groups = self.server_groups.list()
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.server_groups.list.return_value = server_groups
|
|
|
|
ret_val = api.nova.server_group_list(self.request)
|
|
|
|
self.assertIsInstance(ret_val, list)
|
|
self.assertEqual(len(ret_val), len(server_groups))
|
|
novaclient.server_groups.list.assert_called_once_with()
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_group_create(self, mock_novaclient):
|
|
servergroup = self.server_groups.first()
|
|
kwargs = {'name': servergroup.name, 'policies': servergroup.policies}
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.45')
|
|
novaclient.server_groups.create.return_value = servergroup
|
|
|
|
ret_val = api.nova.server_group_create(self.request, **kwargs)
|
|
|
|
self.assertEqual(servergroup.name, ret_val.name)
|
|
self.assertEqual(servergroup.policies, ret_val.policies)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.server_groups.create.assert_called_once_with(**kwargs)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_group_delete(self, mock_novaclient):
|
|
servergroup_id = self.server_groups.first().id
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.server_groups.delete.return_value = None
|
|
|
|
api_val = api.nova.server_group_delete(self.request, servergroup_id)
|
|
|
|
self.assertIsNone(api_val)
|
|
novaclient.server_groups.delete.assert_called_once_with(servergroup_id)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_server_group_get(self, mock_novaclient):
|
|
servergroup = self.server_groups.first()
|
|
novaclient = mock_novaclient.return_value
|
|
self._mock_current_version(novaclient, '2.45')
|
|
novaclient.server_groups.get.return_value = servergroup
|
|
|
|
ret_val = api.nova.server_group_get(self.request, servergroup.id)
|
|
|
|
self.assertEqual(ret_val.id, servergroup.id)
|
|
novaclient.versions.get_current.assert_called_once_with()
|
|
novaclient.server_groups.get.assert_called_once_with(servergroup.id)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_tenant_quota_get(self, mock_novaclient):
|
|
tenant_id = '10'
|
|
quota_data = {
|
|
'cores': 20,
|
|
'injected_file_content_bytes': 10240,
|
|
'injected_file_path_bytes': 255,
|
|
'injected_files': 5,
|
|
'instances': 10,
|
|
'key_pairs': 100,
|
|
'metadata_items': 128,
|
|
'ram': 51200,
|
|
'server_group_members': 10,
|
|
'server_groups': 10,
|
|
'fixed_ips': -1,
|
|
'floating_ips': 10,
|
|
'security_groups': 10,
|
|
'security_group_rules': 20,
|
|
}
|
|
nova_qs = quotas.QuotaSet(quotas.QuotaSetManager(None), quota_data)
|
|
|
|
novaclient = mock_novaclient.return_value
|
|
novaclient.quotas.get.return_value = nova_qs
|
|
|
|
ret_val = api.nova.tenant_quota_get(self.request, tenant_id)
|
|
ret_keys = [q.name for q in ret_val]
|
|
ignore_keys = {'fixed_ips', 'floating_ips',
|
|
'security_groups', 'security_group_rules'}
|
|
expected_keys = set(quota_data.keys()) - ignore_keys
|
|
# Check ignore_keys are not included
|
|
self.assertEqual(expected_keys, set(ret_keys))
|
|
for key in expected_keys:
|
|
self.assertEqual(quota_data[key], ret_val.get(key).limit)
|
|
novaclient.quotas.get.assert_called_once_with(tenant_id)
|
|
|
|
@mock.patch.object(api.nova, 'novaclient')
|
|
def test_availability_zone_list(self, mock_novaclient):
|
|
novaclient = mock_novaclient.return_value
|
|
detailed = False
|
|
zones = [mock.Mock(zoneName='john'), mock.Mock(zoneName='sam'),
|
|
mock.Mock(zoneName='bob')]
|
|
novaclient.availability_zones.list.return_value = zones
|
|
|
|
ret_val = api.nova.availability_zone_list(self.request, detailed)
|
|
self.assertEqual([zone.zoneName for zone in ret_val],
|
|
['bob', 'john', 'sam'])
|
|
novaclient.availability_zones.list.assert_called_once_with(
|
|
detailed=detailed)
|
|
|
|
@test.create_mocks({api.nova: ['get_microversion',
|
|
'novaclient']})
|
|
def _test_server_create(self, extra_kwargs=None, expected_kwargs=None):
|
|
extra_kwargs = extra_kwargs or {}
|
|
expected_kwargs = expected_kwargs or {}
|
|
expected_kwargs.setdefault('nics', None)
|
|
|
|
self.mock_get_microversion.return_value = mock.sentinel.microversion
|
|
novaclient = mock.Mock()
|
|
self.mock_novaclient.return_value = novaclient
|
|
|
|
ret = api.nova.server_create(
|
|
mock.sentinel.request,
|
|
'vm1', 'image1', 'flavor1', 'key1', 'userdata1', ['sg1'],
|
|
**extra_kwargs)
|
|
|
|
self.assertIsInstance(ret, api.nova.Server)
|
|
self.mock_get_microversion.assert_called_once_with(
|
|
mock.sentinel.request, ('instance_description',
|
|
'auto_allocated_network'))
|
|
self.mock_novaclient.assert_called_once_with(
|
|
mock.sentinel.request, version=mock.sentinel.microversion)
|
|
novaclient.servers.create.assert_called_once_with(
|
|
'vm1', 'image1', 'flavor1', userdata='userdata1',
|
|
security_groups=['sg1'], key_name='key1',
|
|
block_device_mapping=None, block_device_mapping_v2=None,
|
|
availability_zone=None, min_count=1, admin_pass=None,
|
|
disk_config=None, config_drive=None, meta=None,
|
|
scheduler_hints=None, **expected_kwargs)
|
|
|
|
def test_server_create(self):
|
|
self._test_server_create()
|
|
|
|
def test_server_create_with_description(self):
|
|
kwargs = {'description': 'desc1'}
|
|
self._test_server_create(extra_kwargs=kwargs, expected_kwargs=kwargs)
|
|
|
|
def test_server_create_with_normal_nics(self):
|
|
kwargs = {
|
|
'nics': [
|
|
{'net-id': 'net1'},
|
|
{'port-id': 'port1'},
|
|
]
|
|
}
|
|
self._test_server_create(extra_kwargs=kwargs, expected_kwargs=kwargs)
|
|
|
|
def test_server_create_with_auto_nic(self):
|
|
kwargs = {
|
|
'nics': [
|
|
{'net-id': api.neutron.AUTO_ALLOCATE_ID},
|
|
]
|
|
}
|
|
self._test_server_create(extra_kwargs=kwargs,
|
|
expected_kwargs={'nics': 'auto'})
|
|
|
|
def test_server_create_with_auto_nic_with_others(self):
|
|
# This actually never happens. Just for checking the logic.
|
|
kwargs = {
|
|
'nics': [
|
|
{'net-id': 'net1'},
|
|
{'net-id': api.neutron.AUTO_ALLOCATE_ID},
|
|
{'port-id': 'port1'},
|
|
]
|
|
}
|
|
self._test_server_create(extra_kwargs=kwargs,
|
|
expected_kwargs={'nics': 'auto'})
|