Merge "Follow up (#2) for the bw resource provider series"

This commit is contained in:
Zuul 2019-02-12 18:30:28 +00:00 committed by Gerrit Code Review
commit 6516038dea
12 changed files with 121 additions and 192 deletions

View File

@ -558,7 +558,8 @@ def supports_port_resource_request_during_move(req):
NOTE: At the moment there is no such microversion that supports port
resource request during move. This function is added as a preparation for
that microversion.
that microversion (assuming there will be a new microversion, which is
yet to be decided).
:param req: The incoming API request
:returns: True if the requested API microversion is high enough for
@ -570,8 +571,12 @@ def supports_port_resource_request_during_move(req):
def instance_has_port_with_resource_request(
context, instance_uuid, network_api):
search_opts = {'device_id': instance_uuid}
# If we ever store any information about resource requests in the
# instance info cache then we can replace this neutron API call.
search_opts = {'device_id': instance_uuid,
'fields': ['resource_request']}
ports = network_api.list_ports(context, **search_opts).get('ports', [])
ports_with_resource_request = [port for port in ports
if port.get('resource_request', None)]
return bool(ports_with_resource_request)
for port in ports:
if port.get('resource_request'):
return True
return False

View File

@ -117,11 +117,16 @@ class EvacuateController(wsgi.Controller):
msg = _("The target host can't be the same one.")
raise exc.HTTPBadRequest(explanation=msg)
# We could potentially move this check to conductor and avoid the
# extra API call to neutron when we support move operations with ports
# having resource requests.
if (common.instance_has_port_with_resource_request(
context, instance.uuid, self.network_api) and not
common.supports_port_resource_request_during_move(req)):
msg = _("The evacuate server operation with port having QoS "
"policy is not supported.")
msg = _("The evacuate action on a server with ports having "
"resource requests, like a port with a QoS minimum "
"bandwidth policy, is not supported with this "
"microversion")
raise exc.HTTPBadRequest(explanation=msg)
try:

View File

@ -54,11 +54,16 @@ class MigrateServerController(wsgi.Controller):
instance = common.get_instance(self.compute_api, context, id)
# We could potentially move this check to conductor and avoid the
# extra API call to neutron when we support move operations with ports
# having resource requests.
if (common.instance_has_port_with_resource_request(
context, instance.uuid, self.network_api) and not
common.supports_port_resource_request_during_move(req)):
msg = _("The migrate server operation with port having QoS policy "
"is not supported.")
msg = _("The migrate action on a server with ports having "
"resource requests, like a port with a QoS minimum "
"bandwidth policy, is not supported with this "
"microversion")
raise exc.HTTPBadRequest(explanation=msg)
try:
@ -118,11 +123,16 @@ class MigrateServerController(wsgi.Controller):
instance = common.get_instance(self.compute_api, context, id,
expected_attrs=['numa_topology'])
# We could potentially move this check to conductor and avoid the
# extra API call to neutron when we support move operations with ports
# having resource requests.
if (common.instance_has_port_with_resource_request(
context, instance.uuid, self.network_api) and not
common.supports_port_resource_request_during_move(req)):
msg = _("The live migrate server operation with port having QoS "
"policy is not supported.")
msg = _("The os-migrateLive action on a server with ports having "
"resource requests, like a port with a QoS minimum "
"bandwidth policy, is not supported with this "
"microversion")
raise exc.HTTPBadRequest(explanation=msg)
try:

View File

@ -816,11 +816,16 @@ class ServersController(wsgi.Controller):
target={'user_id': instance.user_id,
'project_id': instance.project_id})
# We could potentially move this check to conductor and avoid the
# extra API call to neutron when we support move operations with ports
# having resource requests.
if (common.instance_has_port_with_resource_request(
context, instance_id, self.network_api) and not
common.supports_port_resource_request_during_move(req)):
msg = _("The resize server operation with port having QoS policy "
"is not supported.")
msg = _("The resize action on a server with ports having "
"resource requests, like a port with a QoS minimum "
"bandwidth policy, is not supported with this "
"microversion")
raise exc.HTTPBadRequest(explanation=msg)
try:

View File

@ -82,13 +82,18 @@ class ShelveController(wsgi.Controller):
context.can(shelve_policies.POLICY_ROOT % 'unshelve')
instance = common.get_instance(self.compute_api, context, id)
# We could potentially move this check to conductor and avoid the
# extra API call to neutron when we support move operations with ports
# having resource requests.
if (instance.vm_state == vm_states.SHELVED_OFFLOADED
and common.instance_has_port_with_resource_request(
context, instance.uuid, self.network_api)
and not common.supports_port_resource_request_during_move(
req)):
msg = _("The unshelve server operation on a shelve offloaded "
"server with port having QoS policy is not supported.")
msg = _("The unshelve action on a server with ports having "
"resource requests, like a port with a QoS minimum "
"bandwidth policy, is not supported with this "
"microversion")
raise exc.HTTPBadRequest(explanation=msg)
try:

View File

@ -1408,6 +1408,9 @@ class NeutronFixture(fixtures.Fixture):
return {'networks': copy.deepcopy(networks)}
def list_ports(self, retrieve_all=True, **_params):
# If 'fields' is passed we need to strip that out since it will mess
# up the filtering as 'fields' is not a filter parameter.
_params.pop('fields', None)
ports = [p for p in self._ports.values()
if all(p.get(opt) == _params[opt] for opt in _params)]
return {'ports': copy.deepcopy(ports)}

View File

@ -488,18 +488,16 @@ class ProviderUsageBaseTestCase(test.TestCase, InstanceHelperMixin):
url= ('/resource_providers/%s/inventories' % rp_uuid),
version='1.15', body=inv_body).body
def _update_inventory(self, rp_uuid, inv_body, version='1.20'):
def _update_inventory(self, rp_uuid, inv_body):
"""This will update the inventory for a given resource provider.
:param rp_uuid: UUID of the resource provider to update
:param inv_body: inventory to set on the provider
:param version: the placement microversion used in the request
:returns: APIResponse object with the results
"""
return self.placement_api.put(
url= ('/resource_providers/%s/inventories' % rp_uuid),
body=inv_body,
version=version).body
body=inv_body).body
def _get_resource_provider_by_uuid(self, rp_uuid):
return self.placement_api.get(

View File

@ -5549,6 +5549,15 @@ class PortResourceRequestBasedSchedulingTest(
PortResourceRequestBasedSchedulingTestBase):
"""Tests for handling servers with ports having resource requests """
def _add_resource_request_to_a_bound_port(self, port_id):
# NOTE(gibi): self.neutron._ports contains a copy of each neutron port
# defined on class level in the fixture. So modifying what is in the
# _ports list is safe as it is re-created for each Neutron fixture
# instance therefore for each individual test using that fixture.
bound_port = self.neutron._ports[port_id]
bound_port['resource_request'] = (
self.neutron.port_with_resource_request['resource_request'])
def test_interface_attach_with_port_resource_request(self):
# create a server
server = self._create_server(
@ -5634,12 +5643,9 @@ class PortResourceRequestBasedSchedulingTest(
self._wait_for_state_change(self.admin_api, server, 'ACTIVE')
# We need to simulate that the above server has a port that has
# resource request, we cannot boot with such a port but legacy servers
# can exists with such a port.
bound_port = self.neutron._ports[self.neutron.port_1['id']]
fake_resource_request = self.neutron.port_with_resource_request[
'resource_request']
bound_port['resource_request'] = fake_resource_request
# resource request; we cannot boot with such a port but legacy servers
# can exist with such a port.
self._add_resource_request_to_a_bound_port(self.neutron.port_1['id'])
resize_req = {
'resize': {
@ -5652,8 +5658,8 @@ class PortResourceRequestBasedSchedulingTest(
self.assertEqual(400, ex.response.status_code)
self.assertIn(
'The resize server operation with port having QoS policy is not '
'supported.', six.text_type(ex))
'The resize action on a server with ports having resource '
'requests', six.text_type(ex))
def test_migrate_server_with_port_resource_request_old_microversion(self):
server = self._create_server(
@ -5662,12 +5668,9 @@ class PortResourceRequestBasedSchedulingTest(
self._wait_for_state_change(self.admin_api, server, 'ACTIVE')
# We need to simulate that the above server has a port that has
# resource request, we cannot boot with such a port but legacy servers
# can exists with such a port.
bound_port = self.neutron._ports[self.neutron.port_1['id']]
fake_resource_request = self.neutron.port_with_resource_request[
'resource_request']
bound_port['resource_request'] = fake_resource_request
# resource request; we cannot boot with such a port but legacy servers
# can exist with such a port.
self._add_resource_request_to_a_bound_port(self.neutron.port_1['id'])
ex = self.assertRaises(
client.OpenStackApiException,
@ -5675,8 +5678,8 @@ class PortResourceRequestBasedSchedulingTest(
self.assertEqual(400, ex.response.status_code)
self.assertIn(
'The migrate server operation with port having QoS policy is not '
'supported.', six.text_type(ex))
'The migrate action on a server with ports having resource '
'requests', six.text_type(ex))
def test_live_migrate_server_with_port_resource_request_old_microversion(
self):
@ -5686,12 +5689,9 @@ class PortResourceRequestBasedSchedulingTest(
self._wait_for_state_change(self.admin_api, server, 'ACTIVE')
# We need to simulate that the above server has a port that has
# resource request, we cannot boot with such a port but legacy servers
# can exists with such a port.
bound_port = self.neutron._ports[self.neutron.port_1['id']]
fake_resource_request = self.neutron.port_with_resource_request[
'resource_request']
bound_port['resource_request'] = fake_resource_request
# resource request; we cannot boot with such a port but legacy servers
# can exist with such a port.
self._add_resource_request_to_a_bound_port(self.neutron.port_1['id'])
post = {
'os-migrateLive': {
@ -5705,8 +5705,8 @@ class PortResourceRequestBasedSchedulingTest(
self.assertEqual(400, ex.response.status_code)
self.assertIn(
'The live migrate server operation with port having QoS policy is '
'not supported.', six.text_type(ex))
'The os-migrateLive action on a server with ports having resource '
'requests', six.text_type(ex))
def test_evacuate_server_with_port_resource_request_old_microversion(
self):
@ -5716,12 +5716,9 @@ class PortResourceRequestBasedSchedulingTest(
self._wait_for_state_change(self.admin_api, server, 'ACTIVE')
# We need to simulate that the above server has a port that has
# resource request, we cannot boot with such a port but legacy servers
# can exists with such a port.
bound_port = self.neutron._ports[self.neutron.port_1['id']]
fake_resource_request = self.neutron.port_with_resource_request[
'resource_request']
bound_port['resource_request'] = fake_resource_request
# resource request; we cannot boot with such a port but legacy servers
# can exist with such a port.
self._add_resource_request_to_a_bound_port(self.neutron.port_1['id'])
ex = self.assertRaises(
client.OpenStackApiException,
@ -5729,8 +5726,8 @@ class PortResourceRequestBasedSchedulingTest(
self.assertEqual(400, ex.response.status_code)
self.assertIn(
'The evacuate server operation with port having QoS policy is '
'not supported.', six.text_type(ex))
'The evacuate action on a server with ports having resource '
'requests', six.text_type(ex))
def test_unshelve_offloaded_server_with_port_resource_request_old_version(
self):
@ -5748,12 +5745,9 @@ class PortResourceRequestBasedSchedulingTest(
self.api, server, {'status': 'SHELVED_OFFLOADED'})
# We need to simulate that the above server has a port that has
# resource request, we cannot boot with such a port but legacy servers
# can exists with such a port.
bound_port = self.neutron._ports[self.neutron.port_1['id']]
fake_resource_request = self.neutron.port_with_resource_request[
'resource_request']
bound_port['resource_request'] = fake_resource_request
# resource request; we cannot boot with such a port but legacy servers
# can exist with such a port.
self._add_resource_request_to_a_bound_port(self.neutron.port_1['id'])
ex = self.assertRaises(
client.OpenStackApiException,
@ -5761,8 +5755,8 @@ class PortResourceRequestBasedSchedulingTest(
self.assertEqual(400, ex.response.status_code)
self.assertIn(
'The unshelve server operation on a shelve offloaded server with '
'port having QoS policy is not supported.', six.text_type(ex))
'The unshelve action on a server with ports having resource '
'requests', six.text_type(ex))
def test_unshelve_not_offloaded_server_with_port_resource_request(
self):
@ -5786,19 +5780,22 @@ class PortResourceRequestBasedSchedulingTest(
self.api, server, {'status': 'SHELVED'})
# We need to simulate that the above server has a port that has
# resource request, we cannot boot with such a port but legacy servers
# can exists with such a port.
bound_port = self.neutron._ports[self.neutron.port_1['id']]
fake_resource_request = self.neutron.port_with_resource_request[
'resource_request']
bound_port['resource_request'] = fake_resource_request
# resource request; we cannot boot with such a port but legacy servers
# can exist with such a port.
self._add_resource_request_to_a_bound_port(self.neutron.port_1['id'])
self.api.post_server_action(server['id'], {'unshelve': {}})
self._wait_for_state_change(self.admin_api, server, 'ACTIVE')
class PortResourceRequestBasedSchedulingTestIgnoreMicroversionCheck(
PortResourceRequestBasedSchedulingTestBase):
PortResourceRequestBasedSchedulingTestBase):
"""Tests creating a server with a pre-existing port that has a resource
request for a QoS minimum bandwidth policy. Stubs out the
supports_port_resource_request control method in the API in order to
test the functionality between the API and scheduler before the
microversion is added.
"""
def setUp(self):
super(
@ -5806,7 +5803,7 @@ class PortResourceRequestBasedSchedulingTestIgnoreMicroversionCheck(
self).setUp()
# NOTE(gibi): This mock turns off the api microversion that prevents
# handling of instances operations if the request involves port's with
# handling of instances operations if the request involves ports with
# resource request with old microversion. The new microversion does not
# exists yet as the whole feature is not read for end user consumption.
# This functional tests however would like to prove that some use cases
@ -5842,15 +5839,17 @@ class PortResourceRequestBasedSchedulingTestIgnoreMicroversionCheck(
compute_allocations)
self.assertPortMatchesAllocation(qos_port, network_allocations)
self.api.delete_server(server['id'])
self._wait_until_deleted(server)
fake_notifier.wait_for_versioned_notifications('instance.delete.end')
allocations = self._get_allocations_by_server_uuid(server['id'])
self.assertEqual(0, len(allocations))
self._delete_and_check_allocations(server)
class PortResourceRequestReSchedulingTestIgnoreMicroversionCheck(
PortResourceRequestBasedSchedulingTestBase):
"""Similar to PortResourceRequestBasedSchedulingTestIgnoreMicroversionCheck
except this test uses FakeRescheduleDriver which will test reschedules
during server create work as expected, i.e. that the resource request
allocations are moved from the initially selected compute to the
alternative compute.
"""
compute_driver = 'fake.FakeRescheduleDriver'
@ -5863,7 +5862,7 @@ class PortResourceRequestReSchedulingTestIgnoreMicroversionCheck(
self._create_networking_rp_tree(self.compute2_rp_uuid)
# NOTE(gibi): This mock turns off the api microversion that prevents
# handling of instances operations if the request involves port's with
# handling of instances operations if the request involves ports with
# resource request with old microversion. The new microversion does not
# exists yet as the whole feature is not read for end user consumption.
# This functional tests however would like to prove that some use cases
@ -5914,8 +5913,4 @@ class PortResourceRequestReSchedulingTestIgnoreMicroversionCheck(
self._get_provider_usages(
self.ovs_bridge_rp_per_host[failed_compute_rp]))
self.api.delete_server(server['id'])
self._wait_until_deleted(server)
fake_notifier.wait_for_versioned_notifications('instance.delete.end')
allocations = self._get_allocations_by_server_uuid(server['id'])
self.assertEqual(0, len(allocations))
self._delete_and_check_allocations(server)

View File

@ -243,21 +243,6 @@ class EvacuateTestV21(test.NoDBTestCase):
else:
self.assertIsNone(res)
def test_evacuate_with_port_resource_request_old_microversion(self):
self.mock_list_port.return_value = {'ports': [
{'resource_request': {
"resources": {'CUSTOM_FOO': 1}}}]
}
admin_pass = 'MyNewPass'
ex = self.assertRaises(
webob.exc.HTTPBadRequest, self._get_evacuate_response,
{'host': 'my-host', 'onSharedStorage': 'False',
'adminPass': admin_pass})
self.assertIn('The evacuate server operation with port having QoS '
'policy is not supported.', six.text_type(ex))
class EvacuatePolicyEnforcementv21(test.NoDBTestCase):

View File

@ -106,26 +106,6 @@ class MigrateServerTestsV21(admin_only_action_common.CommonTests):
args_map=args_map, method_translations=method_translations,
exception_args=exception_arg)
def test_migrate_with_port_resource_request_old_microversion(self):
self.mock_list_port.return_value = {'ports': [
{'resource_request': {
"resources": {'CUSTOM_FOO': 1}}}]
}
method_translations = {'_migrate': 'resize',
'_migrate_live': 'live_migrate'}
body_map = {'_migrate_live': self._get_migration_body(host='hostname')}
args_map = {'_migrate_live': ((False, self.disk_over_commit,
'hostname', self.force, self.async_),
{}),
'_migrate': ((), {'host_name': self.host_name})}
ex = self.assertRaises(
webob.exc.HTTPBadRequest, self._test_actions,
['_migrate', '_migrate_live'], body_map=body_map,
method_translations=method_translations, args_map=args_map)
self.assertIn(
'The migrate server operation with port having QoS policy is not '
'supported.', six.text_type(ex))
def test_actions_with_locked_instance(self):
method_translations = {'_migrate': 'resize',
'_migrate_live': 'live_migrate'}
@ -554,20 +534,6 @@ class MigrateServerTestsV256(MigrateServerTestsV234):
method_translations=self.method_translations,
exception_args=exception_arg)
def test_migrate_with_port_resource_request_old_microversion(self):
self.mock_list_port.return_value = {'ports': [
{'resource_request': {
"resources": {'CUSTOM_FOO': 1}}}]
}
ex = self.assertRaises(
webob.exc.HTTPBadRequest, self._test_actions,
['_migrate'], body_map=self.body_map,
method_translations=self.method_translations,
args_map=self.args_map)
self.assertIn(
'The migrate server operation with port having QoS policy is not '
'supported.', six.text_type(ex))
def test_actions_with_locked_instance(self):
self._test_actions_with_locked_instance(
['_migrate'], body_map=self.body_map,

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import fixtures
import mock
from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils import uuidutils
@ -95,6 +96,11 @@ class ServerActionsControllerTestV21(test.TestCase):
self.controller.compute_api, 'compute_task_api')
mock_conductor.start()
self.addCleanup(mock_conductor.stop)
# Assume that none of the tests are using ports with resource requests.
self.mock_list_port = self.useFixture(
fixtures.MockPatch(
'nova.network.neutronv2.api.API.list_ports')).mock
self.mock_list_port.return_value = {'ports': []}
def _get_controller(self):
return self.servers.ServersController()
@ -123,10 +129,7 @@ class ServerActionsControllerTestV21(test.TestCase):
mock.patch.object(compute_api.API, method,
side_effect=exception.InstanceIsLocked(
instance_uuid=instance['uuid'])),
mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request',
return_value=False)
) as (mock_get, mock_method, mock_port_check):
) as (mock_get, mock_method):
controller_function = 'self.controller.' + action
self.assertRaises(webob.exc.HTTPConflict,
@ -620,11 +623,8 @@ class ServerActionsControllerTestV21(test.TestCase):
self.assertEqual(instance_meta['kernel_id'], uuids.kernel_image_id)
self.assertEqual(instance_meta['ramdisk_id'], uuids.ramdisk_image_id)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request', return_value=False)
@mock.patch.object(compute_api.API, 'rebuild')
def test_rebuild_instance_raise_auto_disk_config_exc(
self, mock_rebuild, mock_port_check):
def test_rebuild_instance_raise_auto_disk_config_exc(self, mock_rebuild):
body = {
"rebuild": {
"imageRef": self._image_href,
@ -638,10 +638,7 @@ class ServerActionsControllerTestV21(test.TestCase):
self.controller._action_rebuild,
self.req, FAKE_UUID, body=body)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request',
return_value=False)
def test_resize_server(self, mock_port_check):
def test_resize_server(self):
body = dict(resize=dict(flavorRef="http://localhost/3"))
@ -693,9 +690,7 @@ class ServerActionsControllerTestV21(test.TestCase):
self.controller._action_resize,
self.req, FAKE_UUID, body=body)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request', return_value=False)
def test_resize_with_image_exceptions(self, mock_port_check):
def test_resize_with_image_exceptions(self):
body = dict(resize=dict(flavorRef="http://localhost/3"))
self.resize_called = 0
image_id = 'fake_image_id'
@ -736,33 +731,24 @@ class ServerActionsControllerTestV21(test.TestCase):
' disk resize disabled.')
self.assertEqual(self.resize_called, call_no + 1)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request', return_value=False)
@mock.patch('nova.compute.api.API.resize',
side_effect=exception.CannotResizeDisk(reason=''))
def test_resize_raises_cannot_resize_disk(
self, mock_resize, mock_port_check):
def test_resize_raises_cannot_resize_disk(self, mock_resize):
body = dict(resize=dict(flavorRef="http://localhost/3"))
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller._action_resize,
self.req, FAKE_UUID, body=body)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request', return_value=False)
@mock.patch('nova.compute.api.API.resize',
side_effect=exception.FlavorNotFound(reason='',
flavor_id='fake_id'))
def test_resize_raises_flavor_not_found(
self, mock_resize, mock_port_check):
def test_resize_raises_flavor_not_found(self, mock_resize):
body = dict(resize=dict(flavorRef="http://localhost/3"))
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller._action_resize,
self.req, FAKE_UUID, body=body)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request',
return_value=False)
def test_resize_with_too_many_instances(self, mock_port_check):
def test_resize_with_too_many_instances(self):
body = dict(resize=dict(flavorRef="http://localhost/3"))
def fake_resize(*args, **kwargs):
@ -774,9 +760,7 @@ class ServerActionsControllerTestV21(test.TestCase):
self.controller._action_resize,
self.req, FAKE_UUID, body=body)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request', return_value=False)
def test_resize_raises_conflict_on_invalid_state(self, mock_port_check):
def test_resize_raises_conflict_on_invalid_state(self):
body = dict(resize=dict(flavorRef="http://localhost/3"))
def fake_resize(*args, **kwargs):
@ -790,24 +774,17 @@ class ServerActionsControllerTestV21(test.TestCase):
self.controller._action_resize,
self.req, FAKE_UUID, body=body)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request',
return_value=False)
@mock.patch('nova.compute.api.API.resize',
side_effect=exception.NoValidHost(reason=''))
def test_resize_raises_no_valid_host(self, mock_resize, mock_port_check):
def test_resize_raises_no_valid_host(self, mock_resize):
body = dict(resize=dict(flavorRef="http://localhost/3"))
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller._action_resize,
self.req, FAKE_UUID, body=body)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request',
return_value=False)
@mock.patch.object(compute_api.API, 'resize')
def test_resize_instance_raise_auto_disk_config_exc(
self, mock_resize, mock_port_check):
def test_resize_instance_raise_auto_disk_config_exc(self, mock_resize):
mock_resize.side_effect = exception.AutoDiskConfigDisabledByImage(
image='dummy')
@ -817,12 +794,10 @@ class ServerActionsControllerTestV21(test.TestCase):
self.controller._action_resize,
self.req, FAKE_UUID, body=body)
@mock.patch('nova.api.openstack.common.'
'instance_has_port_with_resource_request', return_value=False)
@mock.patch('nova.compute.api.API.resize',
side_effect=exception.PciRequestAliasNotDefined(
alias='fake_name'))
def test_resize_pci_alias_not_defined(self, mock_resize, mock_check_port):
def test_resize_pci_alias_not_defined(self, mock_resize):
# Tests that PciRequestAliasNotDefined is translated to a 400 error.
body = dict(resize=dict(flavorRef="http://localhost/3"))
self.assertRaises(webob.exc.HTTPBadRequest,

View File

@ -15,11 +15,9 @@
import mock
from oslo_policy import policy as oslo_policy
from oslo_utils.fixture import uuidsentinel
import six
import webob
from nova.api.openstack.compute import shelve as shelve_v21
from nova.compute import vm_states
from nova import exception
from nova import policy
from nova import test
@ -63,27 +61,6 @@ class ShelvePolicyTestV21(test.NoDBTestCase):
self.controller._shelve_offload,
self.req, uuidsentinel.fake, {})
@mock.patch('nova.network.neutronv2.api.API.list_ports')
@mock.patch('nova.api.openstack.common.get_instance')
def test_unshelve_offloaded_with_port_resource_request_old_microversion(
self, get_instance_mock, mock_list_ports):
mock_list_ports.return_value = {'ports': [
{'resource_request': {
"resources": {'CUSTOM_FOO': 1}}}]
}
instance = fake_instance.fake_instance_obj(
self.req.environ['nova.context'])
instance.vm_state = vm_states.SHELVED_OFFLOADED
get_instance_mock.return_value = instance
ex = self.assertRaises(
webob.exc.HTTPBadRequest, self.controller._unshelve, self.req,
uuidsentinel.fake, {})
self.assertIn(
'The unshelve server operation on a shelve offloaded server with '
'port having QoS policy is not supported.', six.text_type(ex))
class ShelvePolicyEnforcementV21(test.NoDBTestCase):