nova/nova/tests/unit/virt/vmwareapi/test_configdrive.py
Eric Fried 76d30c8a81 Send Allocations to spawn
This change adds a new 'allocations' kwarg to the
nova.virt.driver.ComputeDriver.spawn method and its overrides.  The
value is the 'allocations' member of the dict returned from GET
/allocations/{instance_uuid}, representing the resources allocated to
the instance from the scheduler via placement.

This provides the virt driver with a way to know exactly which inventory
has been allocated to an instance by placement, from which resource
providers.  Previously, virt drivers would process the flavor to glean
this information.  This works fine as long as there's one monolithic
resource provider - the compute host - providing all the inventory in
a known fashion.  However, as we expand to using nested and shared
resource providers, it becomes necessary for the virt driver to know
that e.g. CPU inventory has been allocated from a specific NUMA node; or
e.g. an SR-IOV VF has been allocated from a specific PF.  Placement
allows such allocations to be represented generically; this change
is how virt is made aware of the same.

Change-Id: I00eab47edf1150788777300680e853a872c1db40
2017-10-18 06:43:57 -05:00

172 lines
7.2 KiB
Python

# Copyright 2013 IBM Corp.
# Copyright 2011 OpenStack Foundation
#
# 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 fixtures
import mock
from nova import context
from nova.image import glance
from nova import objects
from nova import test
from nova.tests.unit import fake_instance
import nova.tests.unit.image.fake
from nova.tests.unit import utils
from nova.tests.unit.virt.vmwareapi import fake as vmwareapi_fake
from nova.tests.unit.virt.vmwareapi import stubs
from nova.tests import uuidsentinel
from nova.virt import fake
from nova.virt.vmwareapi import driver
from nova.virt.vmwareapi import vm_util
from nova.virt.vmwareapi import vmops
class ConfigDriveTestCase(test.NoDBTestCase):
REQUIRES_LOCKING = True
@mock.patch.object(objects.Service, 'get_by_compute_host')
@mock.patch.object(driver.VMwareVCDriver, '_register_openstack_extension')
def setUp(self, mock_register, mock_service):
super(ConfigDriveTestCase, self).setUp()
vm_util.vm_refs_cache_reset()
self.context = context.RequestContext('fake', 'fake', is_admin=False)
self.flags(cluster_name='test_cluster',
host_ip='testhostname',
host_username='test_username',
host_password='test_pass',
use_linked_clone=False, group='vmware')
self.flags(enabled=False, group='vnc')
vmwareapi_fake.reset()
stubs.set_stubs(self)
nova.tests.unit.image.fake.stub_out_image_service(self)
self.conn = driver.VMwareVCDriver(fake.FakeVirtAPI)
self.network_info = utils.get_test_network_info()
self.node_name = self.conn._nodename
image_ref = nova.tests.unit.image.fake.get_valid_image_id()
instance_values = {
'vm_state': 'building',
'project_id': 'fake',
'user_id': 'fake',
'name': '1',
'kernel_id': '1',
'ramdisk_id': '1',
'mac_addresses': [{'address': 'de:ad:be:ef:be:ef'}],
'memory_mb': 8192,
'flavor': objects.Flavor(vcpus=4, extra_specs={}),
'instance_type_id': 0,
'vcpus': 4,
'root_gb': 80,
'image_ref': image_ref,
'host': 'fake_host',
'task_state': 'scheduling',
'reservation_id': 'r-3t8muvr0',
'id': 1,
'uuid': uuidsentinel.foo,
'node': self.node_name,
'metadata': [],
'expected_attrs': ['system_metadata'],
}
self.test_instance = fake_instance.fake_instance_obj(self.context,
**instance_values)
self.test_instance.flavor = objects.Flavor(vcpus=4, memory_mb=8192,
root_gb=80,
ephemeral_gb=0, swap=0,
extra_specs={})
(image_service, image_id) = glance.get_remote_image_service(context,
image_ref)
metadata = image_service.show(context, image_id)
self.image = objects.ImageMeta.from_dict({
'id': image_ref,
'disk_format': 'vmdk',
'size': int(metadata['size']),
})
class FakeInstanceMetadata(object):
def __init__(self, instance, content=None, extra_md=None,
network_info=None, request_context=None):
pass
def metadata_for_config_drive(self):
return []
self.useFixture(fixtures.MonkeyPatch(
'nova.api.metadata.base.InstanceMetadata',
FakeInstanceMetadata))
def fake_make_drive(_self, _path):
pass
# We can't actually make a config drive v2 because ensure_tree has
# been faked out
self.stub_out('nova.virt.configdrive.ConfigDriveBuilder.make_drive',
fake_make_drive)
def fake_upload_iso_to_datastore(iso_path, instance, **kwargs):
pass
self.stub_out('nova.virt.vmwareapi.images.upload_iso_to_datastore',
fake_upload_iso_to_datastore)
def tearDown(self):
super(ConfigDriveTestCase, self).tearDown()
vmwareapi_fake.cleanup()
nova.tests.unit.image.fake.FakeImageService_reset()
@mock.patch.object(vmops.VMwareVMOps, '_get_instance_metadata',
return_value='fake_metadata')
def _spawn_vm(self, fake_get_instance_meta,
injected_files=None, admin_password=None,
block_device_info=None):
injected_files = injected_files or []
self.conn.spawn(self.context, self.test_instance, self.image,
injected_files=injected_files,
admin_password=admin_password,
allocations={},
network_info=self.network_info,
block_device_info=block_device_info)
@mock.patch.object(vmops.VMwareVMOps, '_create_config_drive',
return_value=('[ds1] fake.iso'))
@mock.patch.object(vmops.VMwareVMOps, '_attach_cdrom_to_vm')
def test_create_vm_with_config_drive_verify_method_invocation(self,
mock_attach_cdrom, mock_create_config_drive):
self.test_instance.config_drive = 'True'
self._spawn_vm()
mock_create_config_drive.assert_called_once_with(mock.ANY,
self.test_instance,
mock.ANY,
mock.ANY,
mock.ANY,
mock.ANY,
mock.ANY,
mock.ANY,
mock.ANY)
mock_attach_cdrom.assert_called_once_with(mock.ANY, mock.ANY,
mock.ANY, mock.ANY)
@mock.patch.object(vmops.VMwareVMOps, '_create_config_drive',
return_value=('[ds1] fake.iso'))
@mock.patch.object(vmops.VMwareVMOps, '_attach_cdrom_to_vm')
def test_create_vm_without_config_drive(self, mock_attach_cdrom,
mock_create_config_drive):
self.test_instance.config_drive = None
self._spawn_vm()
mock_create_config_drive.assert_not_called()
mock_attach_cdrom.assert_not_called()
def test_create_vm_with_config_drive(self):
self.test_instance.config_drive = 'True'
self._spawn_vm()