diff options
Diffstat (limited to 'nova/tests/virt/vmwareapi')
-rw-r--r-- | nova/tests/virt/vmwareapi/__init__.py | 0 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/fake.py | 1606 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/stubs.py | 131 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_configdrive.py | 168 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_driver_api.py | 2650 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_ds_util.py | 548 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_ds_util_datastore_selection.py | 163 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_imagecache.py | 277 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_images.py | 216 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_io_util.py | 33 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_read_write_util.py | 39 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_vif.py | 346 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_vim_util.py | 117 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_vm_util.py | 1069 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_vmops.py | 1293 | ||||
-rw-r--r-- | nova/tests/virt/vmwareapi/test_volumeops.py | 95 |
16 files changed, 0 insertions, 8751 deletions
diff --git a/nova/tests/virt/vmwareapi/__init__.py b/nova/tests/virt/vmwareapi/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/nova/tests/virt/vmwareapi/__init__.py +++ /dev/null diff --git a/nova/tests/virt/vmwareapi/fake.py b/nova/tests/virt/vmwareapi/fake.py deleted file mode 100644 index 5bd2b7fb4f..0000000000 --- a/nova/tests/virt/vmwareapi/fake.py +++ /dev/null @@ -1,1606 +0,0 @@ -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# Copyright (c) 2012 VMware, Inc. -# Copyright (c) 2011 Citrix Systems, Inc. -# 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. - -""" -A fake VMware VI API implementation. -""" - -import collections -import pprint - -from oslo.serialization import jsonutils -from oslo.utils import units -from oslo.vmware import exceptions as vexc - -from nova import exception -from nova.i18n import _ -from nova.openstack.common import log as logging -from nova.openstack.common import uuidutils -from nova.virt.vmwareapi import constants -from nova.virt.vmwareapi import ds_util - -_CLASSES = ['Datacenter', 'Datastore', 'ResourcePool', 'VirtualMachine', - 'Network', 'HostSystem', 'HostNetworkSystem', 'Task', 'session', - 'files', 'ClusterComputeResource', 'HostStorageSystem'] - -_FAKE_FILE_SIZE = 1024 - -_db_content = {} -_array_types = {} -_vim_map = {} - -LOG = logging.getLogger(__name__) - - -def log_db_contents(msg=None): - """Log DB Contents.""" - LOG.debug("%(text)s: _db_content => %(content)s", - {'text': msg or "", 'content': pprint.pformat(_db_content)}) - - -def reset(): - """Resets the db contents.""" - cleanup() - create_network() - create_host_network_system() - create_host_storage_system() - ds_ref1 = create_datastore('ds1', 1024, 500) - create_host(ds_ref=ds_ref1) - ds_ref2 = create_datastore('ds2', 1024, 500) - create_host(ds_ref=ds_ref2) - create_datacenter('dc1', ds_ref1) - create_datacenter('dc2', ds_ref2) - create_res_pool() - create_cluster('test_cluster', ds_ref1) - create_cluster('test_cluster2', ds_ref2) - - -def cleanup(): - """Clear the db contents.""" - for c in _CLASSES: - # We fake the datastore by keeping the file references as a list of - # names in the db - if c == 'files': - _db_content[c] = [] - else: - _db_content[c] = {} - - -def _create_object(table, table_obj): - """Create an object in the db.""" - _db_content[table][table_obj.obj] = table_obj - - -def _get_object(obj_ref): - """Get object for the give reference.""" - return _db_content[obj_ref.type][obj_ref] - - -def _get_objects(obj_type): - """Get objects of the type.""" - lst_objs = FakeRetrieveResult() - for key in _db_content[obj_type]: - lst_objs.add_object(_db_content[obj_type][key]) - return lst_objs - - -def _convert_to_array_of_mor(mors): - """Wraps the given array into a DataObject.""" - array_of_mors = DataObject() - array_of_mors.ManagedObjectReference = mors - return array_of_mors - - -def _convert_to_array_of_opt_val(optvals): - """Wraps the given array into a DataObject.""" - array_of_optv = DataObject() - array_of_optv.OptionValue = optvals - return array_of_optv - - -def _create_array_of_type(t): - """Returns an array to contain objects of type t.""" - if t in _array_types: - return _array_types[t]() - - array_type_name = 'ArrayOf%s' % t - array_type = type(array_type_name, (DataObject,), {}) - - def __init__(self): - super(array_type, self).__init__(array_type_name) - setattr(self, t, []) - - setattr(array_type, '__init__', __init__) - - _array_types[t] = array_type - return array_type() - - -class FakeRetrieveResult(object): - """Object to retrieve a ObjectContent list.""" - - def __init__(self, token=None): - self.objects = [] - if token is not None: - self.token = token - - def add_object(self, object): - self.objects.append(object) - - -class MissingProperty(object): - """Missing object in ObjectContent's missing set.""" - def __init__(self, path='fake-path', message='fake_message', - method_fault=None): - self.path = path - self.fault = DataObject() - self.fault.localizedMessage = message - self.fault.fault = method_fault - - -def _get_object_refs(obj_type): - """Get object References of the type.""" - lst_objs = [] - for key in _db_content[obj_type]: - lst_objs.append(key) - return lst_objs - - -def _update_object(table, table_obj): - """Update objects of the type.""" - _db_content[table][table_obj.obj] = table_obj - - -class Prop(object): - """Property Object base class.""" - - def __init__(self, name=None, val=None): - self.name = name - self.val = val - - -class ManagedObjectReference(object): - """A managed object reference is a remote identifier.""" - - def __init__(self, name="ManagedObject", value=None): - super(ManagedObjectReference, self) - # Managed Object Reference value attributes - # typically have values like vm-123 or - # host-232 and not UUID. - self.value = value - # Managed Object Reference type - # attributes hold the name of the type - # of the vCenter object the value - # attribute is the identifier for - self.type = name - self._type = name - - -class ObjectContent(object): - """ObjectContent array holds dynamic properties.""" - - # This class is a *fake* of a class sent back to us by - # SOAP. It has its own names. These names are decided - # for us by the API we are *faking* here. - def __init__(self, obj_ref, prop_list=None, missing_list=None): - self.obj = obj_ref - - if not isinstance(prop_list, collections.Iterable): - prop_list = [] - - if not isinstance(missing_list, collections.Iterable): - missing_list = [] - - # propSet is the name your Python code will need to - # use since this is the name that the API will use - if prop_list: - self.propSet = prop_list - - # missingSet is the name your python code will - # need to use since this is the name that the - # API we are talking to will use. - if missing_list: - self.missingSet = missing_list - - -class ManagedObject(object): - """Managed Object base class.""" - _counter = 0 - - def __init__(self, mo_id_prefix="obj"): - """Sets the obj property which acts as a reference to the object.""" - object.__setattr__(self, 'mo_id', self._generate_moid(mo_id_prefix)) - object.__setattr__(self, 'propSet', []) - object.__setattr__(self, 'obj', - ManagedObjectReference(self.__class__.__name__, - self.mo_id)) - - def set(self, attr, val): - """Sets an attribute value. Not using the __setattr__ directly for we - want to set attributes of the type 'a.b.c' and using this function - class we set the same. - """ - self.__setattr__(attr, val) - - def get(self, attr): - """Gets an attribute. Used as an intermediary to get nested - property like 'a.b.c' value. - """ - return self.__getattr__(attr) - - def delete(self, attr): - """Deletes an attribute.""" - self.propSet = filter(lambda elem: elem.name != attr, self.propSet) - - def __setattr__(self, attr, val): - # TODO(hartsocks): this is adds unnecessary complexity to the class - for prop in self.propSet: - if prop.name == attr: - prop.val = val - return - elem = Prop() - elem.name = attr - elem.val = val - self.propSet.append(elem) - - def __getattr__(self, attr): - # TODO(hartsocks): remove this - # in a real ManagedObject you have to iterate the propSet - # in a real ManagedObject, the propSet is a *set* not a list - for elem in self.propSet: - if elem.name == attr: - return elem.val - msg = _("Property %(attr)s not set for the managed object %(name)s") - raise exception.NovaException(msg % {'attr': attr, - 'name': self.__class__.__name__}) - - def _generate_moid(self, prefix): - """Generates a new Managed Object ID.""" - self.__class__._counter += 1 - return prefix + "-" + str(self.__class__._counter) - - def __repr__(self): - return jsonutils.dumps(dict([(elem.name, elem.val) - for elem in self.propSet])) - - -class DataObject(object): - """Data object base class.""" - - def __init__(self, obj_name=None): - self.obj_name = obj_name - - def __repr__(self): - return str(self.__dict__) - - -class HostInternetScsiHba(DataObject): - """iSCSI Host Bus Adapter.""" - - def __init__(self): - super(HostInternetScsiHba, self).__init__() - self.device = 'vmhba33' - self.key = 'key-vmhba33' - - -class FileAlreadyExists(DataObject): - """File already exists class.""" - - def __init__(self): - super(FileAlreadyExists, self).__init__() - self.__name__ = vexc.FILE_ALREADY_EXISTS - - -class FileNotFound(DataObject): - """File not found class.""" - - def __init__(self): - super(FileNotFound, self).__init__() - self.__name__ = vexc.FILE_NOT_FOUND - - -class FileFault(DataObject): - """File fault.""" - - def __init__(self): - super(FileFault, self).__init__() - self.__name__ = vexc.FILE_FAULT - - -class CannotDeleteFile(DataObject): - """Cannot delete file.""" - - def __init__(self): - super(CannotDeleteFile, self).__init__() - self.__name__ = vexc.CANNOT_DELETE_FILE - - -class FileLocked(DataObject): - """File locked.""" - - def __init__(self): - super(FileLocked, self).__init__() - self.__name__ = vexc.FILE_LOCKED - - -class VirtualDisk(DataObject): - """Virtual Disk class.""" - - def __init__(self, controllerKey=0, unitNumber=0): - super(VirtualDisk, self).__init__() - self.key = 0 - self.controllerKey = controllerKey - self.unitNumber = unitNumber - - -class VirtualDiskFlatVer2BackingInfo(DataObject): - """VirtualDiskFlatVer2BackingInfo class.""" - - def __init__(self): - super(VirtualDiskFlatVer2BackingInfo, self).__init__() - self.thinProvisioned = False - self.eagerlyScrub = False - - -class VirtualDiskRawDiskMappingVer1BackingInfo(DataObject): - """VirtualDiskRawDiskMappingVer1BackingInfo class.""" - - def __init__(self): - super(VirtualDiskRawDiskMappingVer1BackingInfo, self).__init__() - self.lunUuid = "" - - -class VirtualIDEController(DataObject): - - def __init__(self, key=0): - self.key = key - - -class VirtualLsiLogicController(DataObject): - """VirtualLsiLogicController class.""" - def __init__(self, key=0, scsiCtlrUnitNumber=0): - self.key = key - self.scsiCtlrUnitNumber = scsiCtlrUnitNumber - - -class VirtualLsiLogicSASController(DataObject): - """VirtualLsiLogicSASController class.""" - pass - - -class VirtualPCNet32(DataObject): - """VirtualPCNet32 class.""" - - def __init__(self): - super(VirtualPCNet32, self).__init__() - self.key = 4000 - - -class OptionValue(DataObject): - """OptionValue class.""" - - def __init__(self, key=None, value=None): - super(OptionValue, self).__init__() - self.key = key - self.value = value - - -class VirtualMachine(ManagedObject): - """Virtual Machine class.""" - - def __init__(self, **kwargs): - super(VirtualMachine, self).__init__("vm") - self.set("name", kwargs.get("name", 'test-vm')) - self.set("runtime.connectionState", - kwargs.get("conn_state", "connected")) - self.set("summary.config.guestId", - kwargs.get("guest", constants.DEFAULT_OS_TYPE)) - ds_do = kwargs.get("ds", None) - self.set("datastore", _convert_to_array_of_mor(ds_do)) - self.set("summary.guest.toolsStatus", kwargs.get("toolsstatus", - "toolsOk")) - self.set("summary.guest.toolsRunningStatus", kwargs.get( - "toolsrunningstate", "guestToolsRunning")) - self.set("runtime.powerState", kwargs.get("powerstate", "poweredOn")) - self.set("config.files.vmPathName", kwargs.get("vmPathName")) - self.set("summary.config.numCpu", kwargs.get("numCpu", 1)) - self.set("summary.config.memorySizeMB", kwargs.get("mem", 1)) - self.set("summary.config.instanceUuid", kwargs.get("instanceUuid")) - - devices = _create_array_of_type('VirtualDevice') - devices.VirtualDevice = kwargs.get("virtual_device", []) - self.set("config.hardware.device", devices) - - exconfig_do = kwargs.get("extra_config", None) - self.set("config.extraConfig", - _convert_to_array_of_opt_val(exconfig_do)) - if exconfig_do: - for optval in exconfig_do: - self.set('config.extraConfig["%s"]' % optval.key, optval) - self.set('runtime.host', kwargs.get("runtime_host", None)) - self.device = kwargs.get("virtual_device", []) - # Sample of diagnostics data is below. - config = [ - ('template', False), - ('vmPathName', 'fake_path'), - ('memorySizeMB', 512), - ('cpuReservation', 0), - ('memoryReservation', 0), - ('numCpu', 1), - ('numEthernetCards', 1), - ('numVirtualDisks', 1)] - self.set("summary.config", config) - - quickStats = [ - ('overallCpuUsage', 0), - ('overallCpuDemand', 0), - ('guestMemoryUsage', 0), - ('hostMemoryUsage', 141), - ('balloonedMemory', 0), - ('consumedOverheadMemory', 20)] - self.set("summary.quickStats", quickStats) - - key1 = {'key': 'cpuid.AES'} - key2 = {'key': 'cpuid.AVX'} - runtime = [ - ('connectionState', 'connected'), - ('powerState', 'poweredOn'), - ('toolsInstallerMounted', False), - ('suspendInterval', 0), - ('memoryOverhead', 21417984), - ('maxCpuUsage', 2000), - ('featureRequirement', [key1, key2])] - self.set("summary.runtime", runtime) - - def _update_extra_config(self, extra): - extra_config = self.get("config.extraConfig") - values = extra_config.OptionValue - for value in values: - if value.key == extra.key: - value.value = extra.value - return - kv = DataObject() - kv.key = extra.key - kv.value = extra.value - extra_config.OptionValue.append(kv) - self.set("config.extraConfig", extra_config) - extra_config = self.get("config.extraConfig") - - def reconfig(self, factory, val): - """Called to reconfigure the VM. Actually customizes the property - setting of the Virtual Machine object. - """ - - if hasattr(val, 'name') and val.name: - self.set("name", val.name) - - if hasattr(val, 'extraConfig'): - extraConfigs = _merge_extraconfig( - self.get("config.extraConfig").OptionValue, - val.extraConfig) - self.get("config.extraConfig").OptionValue = extraConfigs - - if hasattr(val, 'instanceUuid') and val.instanceUuid is not None: - if val.instanceUuid == "": - val.instanceUuid = uuidutils.generate_uuid() - self.set("summary.config.instanceUuid", val.instanceUuid) - - try: - if not hasattr(val, 'deviceChange'): - return - - if hasattr(val, 'extraConfig'): - # there are 2 cases - new entry or update an existing one - for extra in val.extraConfig: - self._update_extra_config(extra) - - if len(val.deviceChange) < 2: - return - - # Case of Reconfig of VM to attach disk - controller_key = val.deviceChange[0].device.controllerKey - filename = val.deviceChange[0].device.backing.fileName - - disk = VirtualDisk() - disk.controllerKey = controller_key - - disk_backing = VirtualDiskFlatVer2BackingInfo() - disk_backing.fileName = filename - disk_backing.key = -101 - disk.backing = disk_backing - - controller = VirtualLsiLogicController() - controller.key = controller_key - - devices = _create_array_of_type('VirtualDevice') - devices.VirtualDevice = [disk, controller, self.device[0]] - self.set("config.hardware.device", devices) - except AttributeError: - pass - - -class Network(ManagedObject): - """Network class.""" - - def __init__(self): - super(Network, self).__init__("network") - self.set("summary.name", "vmnet0") - - -class ResourcePool(ManagedObject): - """Resource Pool class.""" - - def __init__(self, name="test_ResPool", value="resgroup-test"): - super(ResourcePool, self).__init__("rp") - self.set("name", name) - summary = DataObject() - runtime = DataObject() - config = DataObject() - memory = DataObject() - cpu = DataObject() - - memoryAllocation = DataObject() - cpuAllocation = DataObject() - vm_list = DataObject() - - memory.maxUsage = 1000 * units.Mi - memory.overallUsage = 500 * units.Mi - cpu.maxUsage = 10000 - cpu.overallUsage = 1000 - runtime.cpu = cpu - runtime.memory = memory - summary.runtime = runtime - cpuAllocation.limit = 10000 - memoryAllocation.limit = 1024 - memoryAllocation.reservation = 1024 - config.memoryAllocation = memoryAllocation - config.cpuAllocation = cpuAllocation - vm_list.ManagedObjectReference = [] - self.set("summary", summary) - self.set("summary.runtime.memory", memory) - self.set("config", config) - self.set("vm", vm_list) - parent = ManagedObjectReference(value=value, - name=name) - owner = ManagedObjectReference(value=value, - name=name) - self.set("parent", parent) - self.set("owner", owner) - - -class DatastoreHostMount(DataObject): - def __init__(self, value='host-100'): - super(DatastoreHostMount, self).__init__() - host_ref = (_db_content["HostSystem"] - [_db_content["HostSystem"].keys()[0]].obj) - host_system = DataObject() - host_system.ManagedObjectReference = [host_ref] - host_system.value = value - self.key = host_system - - -class ClusterComputeResource(ManagedObject): - """Cluster class.""" - - def __init__(self, name="test_cluster"): - super(ClusterComputeResource, self).__init__("domain") - self.set("name", name) - self.set("host", None) - self.set("datastore", None) - self.set("resourcePool", None) - - summary = DataObject() - summary.numHosts = 0 - summary.numCpuCores = 0 - summary.numCpuThreads = 0 - summary.numEffectiveHosts = 0 - summary.totalMemory = 0 - summary.effectiveMemory = 0 - summary.effectiveCpu = 10000 - self.set("summary", summary) - - def _add_root_resource_pool(self, r_pool): - if r_pool: - self.set("resourcePool", r_pool) - - def _add_host(self, host_sys): - if host_sys: - hosts = self.get("host") - if hosts is None: - hosts = DataObject() - hosts.ManagedObjectReference = [] - self.set("host", hosts) - hosts.ManagedObjectReference.append(host_sys) - # Update summary every time a new host is added - self._update_summary() - - def _add_datastore(self, datastore): - if datastore: - datastores = self.get("datastore") - if datastores is None: - datastores = DataObject() - datastores.ManagedObjectReference = [] - self.set("datastore", datastores) - datastores.ManagedObjectReference.append(datastore) - - # Method to update summary of a cluster upon host addition - def _update_summary(self): - summary = self.get("summary") - summary.numHosts = 0 - summary.numCpuCores = 0 - summary.numCpuThreads = 0 - summary.numEffectiveHosts = 0 - summary.totalMemory = 0 - summary.effectiveMemory = 0 - - hosts = self.get("host") - # Compute the aggregate stats - summary.numHosts = len(hosts.ManagedObjectReference) - for host_ref in hosts.ManagedObjectReference: - host_sys = _get_object(host_ref) - connected = host_sys.get("connected") - host_summary = host_sys.get("summary") - summary.numCpuCores += host_summary.hardware.numCpuCores - summary.numCpuThreads += host_summary.hardware.numCpuThreads - summary.totalMemory += host_summary.hardware.memorySize - free_memory = (host_summary.hardware.memorySize / units.Mi - - host_summary.quickStats.overallMemoryUsage) - summary.effectiveMemory += free_memory if connected else 0 - summary.numEffectiveHosts += 1 if connected else 0 - self.set("summary", summary) - - -class Datastore(ManagedObject): - """Datastore class.""" - - def __init__(self, name="fake-ds", capacity=1024, free=500, - accessible=True, maintenance_mode="normal"): - super(Datastore, self).__init__("ds") - self.set("summary.type", "VMFS") - self.set("summary.name", name) - self.set("summary.capacity", capacity * units.Gi) - self.set("summary.freeSpace", free * units.Gi) - self.set("summary.accessible", accessible) - self.set("summary.maintenanceMode", maintenance_mode) - self.set("browser", "") - - -class HostNetworkSystem(ManagedObject): - """HostNetworkSystem class.""" - - def __init__(self, name="networkSystem"): - super(HostNetworkSystem, self).__init__("ns") - self.set("name", name) - - pnic_do = DataObject() - pnic_do.device = "vmnic0" - - net_info_pnic = DataObject() - net_info_pnic.PhysicalNic = [pnic_do] - - self.set("networkInfo.pnic", net_info_pnic) - - -class HostStorageSystem(ManagedObject): - """HostStorageSystem class.""" - - def __init__(self): - super(HostStorageSystem, self).__init__("storageSystem") - - -class HostSystem(ManagedObject): - """Host System class.""" - - def __init__(self, name="ha-host", connected=True, ds_ref=None, - maintenance_mode=False): - super(HostSystem, self).__init__("host") - self.set("name", name) - if _db_content.get("HostNetworkSystem", None) is None: - create_host_network_system() - if not _get_object_refs('HostStorageSystem'): - create_host_storage_system() - host_net_key = _db_content["HostNetworkSystem"].keys()[0] - host_net_sys = _db_content["HostNetworkSystem"][host_net_key].obj - self.set("configManager.networkSystem", host_net_sys) - host_storage_sys_key = _get_object_refs('HostStorageSystem')[0] - self.set("configManager.storageSystem", host_storage_sys_key) - - if not ds_ref: - ds_ref = create_datastore('local-host-%s' % name, 500, 500) - datastores = DataObject() - datastores.ManagedObjectReference = [ds_ref] - self.set("datastore", datastores) - - summary = DataObject() - hardware = DataObject() - hardware.numCpuCores = 8 - hardware.numCpuPkgs = 2 - hardware.numCpuThreads = 16 - hardware.vendor = "Intel" - hardware.cpuModel = "Intel(R) Xeon(R)" - hardware.uuid = "host-uuid" - hardware.memorySize = units.Gi - summary.hardware = hardware - - runtime = DataObject() - if connected: - runtime.connectionState = "connected" - else: - runtime.connectionState = "disconnected" - - runtime.inMaintenanceMode = maintenance_mode - - summary.runtime = runtime - - quickstats = DataObject() - quickstats.overallMemoryUsage = 500 - summary.quickStats = quickstats - - product = DataObject() - product.name = "VMware ESXi" - product.version = "5.0.0" - config = DataObject() - config.product = product - summary.config = config - - pnic_do = DataObject() - pnic_do.device = "vmnic0" - net_info_pnic = DataObject() - net_info_pnic.PhysicalNic = [pnic_do] - - self.set("summary", summary) - self.set("capability.maxHostSupportedVcpus", 600) - self.set("summary.hardware", hardware) - self.set("summary.runtime", runtime) - self.set("config.network.pnic", net_info_pnic) - self.set("connected", connected) - - if _db_content.get("Network", None) is None: - create_network() - net_ref = _db_content["Network"][_db_content["Network"].keys()[0]].obj - network_do = DataObject() - network_do.ManagedObjectReference = [net_ref] - self.set("network", network_do) - - vswitch_do = DataObject() - vswitch_do.pnic = ["vmnic0"] - vswitch_do.name = "vSwitch0" - vswitch_do.portgroup = ["PortGroup-vmnet0"] - - net_swicth = DataObject() - net_swicth.HostVirtualSwitch = [vswitch_do] - self.set("config.network.vswitch", net_swicth) - - host_pg_do = DataObject() - host_pg_do.key = "PortGroup-vmnet0" - - pg_spec = DataObject() - pg_spec.vlanId = 0 - pg_spec.name = "vmnet0" - - host_pg_do.spec = pg_spec - - host_pg = DataObject() - host_pg.HostPortGroup = [host_pg_do] - self.set("config.network.portgroup", host_pg) - - config = DataObject() - storageDevice = DataObject() - - iscsi_hba = HostInternetScsiHba() - iscsi_hba.iScsiName = "iscsi-name" - host_bus_adapter_array = DataObject() - host_bus_adapter_array.HostHostBusAdapter = [iscsi_hba] - storageDevice.hostBusAdapter = host_bus_adapter_array - config.storageDevice = storageDevice - self.set("config.storageDevice.hostBusAdapter", host_bus_adapter_array) - - # Set the same on the storage system managed object - host_storage_sys = _get_object(host_storage_sys_key) - host_storage_sys.set('storageDeviceInfo.hostBusAdapter', - host_bus_adapter_array) - - def _add_iscsi_target(self, data): - default_lun = DataObject() - default_lun.scsiLun = 'key-vim.host.ScsiDisk-010' - default_lun.key = 'key-vim.host.ScsiDisk-010' - default_lun.deviceName = 'fake-device' - default_lun.uuid = 'fake-uuid' - scsi_lun_array = DataObject() - scsi_lun_array.ScsiLun = [default_lun] - self.set("config.storageDevice.scsiLun", scsi_lun_array) - - transport = DataObject() - transport.address = [data['target_portal']] - transport.iScsiName = data['target_iqn'] - default_target = DataObject() - default_target.lun = [default_lun] - default_target.transport = transport - - iscsi_adapter = DataObject() - iscsi_adapter.adapter = 'key-vmhba33' - iscsi_adapter.transport = transport - iscsi_adapter.target = [default_target] - iscsi_topology = DataObject() - iscsi_topology.adapter = [iscsi_adapter] - self.set("config.storageDevice.scsiTopology", iscsi_topology) - - def _add_port_group(self, spec): - """Adds a port group to the host system object in the db.""" - pg_name = spec.name - vswitch_name = spec.vswitchName - vlanid = spec.vlanId - - vswitch_do = DataObject() - vswitch_do.pnic = ["vmnic0"] - vswitch_do.name = vswitch_name - vswitch_do.portgroup = ["PortGroup-%s" % pg_name] - - vswitches = self.get("config.network.vswitch").HostVirtualSwitch - vswitches.append(vswitch_do) - - host_pg_do = DataObject() - host_pg_do.key = "PortGroup-%s" % pg_name - - pg_spec = DataObject() - pg_spec.vlanId = vlanid - pg_spec.name = pg_name - - host_pg_do.spec = pg_spec - host_pgrps = self.get("config.network.portgroup").HostPortGroup - host_pgrps.append(host_pg_do) - - -class Datacenter(ManagedObject): - """Datacenter class.""" - - def __init__(self, name="ha-datacenter", ds_ref=None): - super(Datacenter, self).__init__("dc") - self.set("name", name) - self.set("vmFolder", "vm_folder_ref") - if _db_content.get("Network", None) is None: - create_network() - net_ref = _db_content["Network"][_db_content["Network"].keys()[0]].obj - network_do = DataObject() - network_do.ManagedObjectReference = [net_ref] - self.set("network", network_do) - if ds_ref: - datastore = DataObject() - datastore.ManagedObjectReference = [ds_ref] - else: - datastore = None - self.set("datastore", datastore) - - -class Task(ManagedObject): - """Task class.""" - - def __init__(self, task_name, state="running", result=None, - error_fault=None): - super(Task, self).__init__("Task") - info = DataObject() - info.name = task_name - info.state = state - if state == 'error': - error = DataObject() - error.localizedMessage = "Error message" - if not error_fault: - error.fault = DataObject() - else: - error.fault = error_fault - info.error = error - info.result = result - self.set("info", info) - - -def create_host_network_system(): - host_net_system = HostNetworkSystem() - _create_object("HostNetworkSystem", host_net_system) - - -def create_host_storage_system(): - host_storage_system = HostStorageSystem() - _create_object("HostStorageSystem", host_storage_system) - - -def create_host(ds_ref=None): - host_system = HostSystem(ds_ref=ds_ref) - _create_object('HostSystem', host_system) - - -def create_datacenter(name, ds_ref=None): - data_center = Datacenter(name, ds_ref) - _create_object('Datacenter', data_center) - - -def create_datastore(name, capacity, free): - data_store = Datastore(name, capacity, free) - _create_object('Datastore', data_store) - return data_store.obj - - -def create_res_pool(): - res_pool = ResourcePool() - _create_object('ResourcePool', res_pool) - return res_pool.obj - - -def create_network(): - network = Network() - _create_object('Network', network) - - -def create_cluster(name, ds_ref): - cluster = ClusterComputeResource(name=name) - cluster._add_host(_get_object_refs("HostSystem")[0]) - cluster._add_host(_get_object_refs("HostSystem")[1]) - cluster._add_datastore(ds_ref) - cluster._add_root_resource_pool(create_res_pool()) - _create_object('ClusterComputeResource', cluster) - - -def create_vm(uuid=None, name=None, - cpus=1, memory=128, devices=None, - vmPathName=None, extraConfig=None, - res_pool_ref=None, host_ref=None): - if uuid is None: - uuid = uuidutils.generate_uuid() - - if name is None: - name = uuid - - if devices is None: - devices = [] - - if vmPathName is None: - vm_path = ds_util.DatastorePath(_db_content['Datastore'].values()[0]) - else: - vm_path = ds_util.DatastorePath.parse(vmPathName) - - if res_pool_ref is None: - res_pool_ref = _db_content['ResourcePool'].keys()[0] - - if host_ref is None: - host_ref = _db_content["HostSystem"].keys()[0] - - # Fill in the default path to the vmx file if we were only given a - # datastore. Note that if you create a VM with vmPathName '[foo]', when you - # retrieve vmPathName it will be '[foo] uuid/uuid.vmx'. Hence we use - # vm_path below for the stored value of vmPathName. - if vm_path.rel_path == '': - vm_path = vm_path.join(name, name + '.vmx') - - for key, value in _db_content["Datastore"].iteritems(): - if value.get('summary.name') == vm_path.datastore: - ds = key - break - else: - ds = create_datastore(vm_path.datastore, 1024, 500) - - vm_dict = {"name": name, - "ds": [ds], - "runtime_host": host_ref, - "powerstate": "poweredOff", - "vmPathName": str(vm_path), - "numCpu": cpus, - "mem": memory, - "extra_config": extraConfig, - "virtual_device": devices, - "instanceUuid": uuid} - vm = VirtualMachine(**vm_dict) - _create_object("VirtualMachine", vm) - - res_pool = _get_object(res_pool_ref) - res_pool.vm.ManagedObjectReference.append(vm.obj) - - return vm.obj - - -def create_task(task_name, state="running", result=None, error_fault=None): - task = Task(task_name, state, result, error_fault) - _create_object("Task", task) - return task - - -def _add_file(file_path): - """Adds a file reference to the db.""" - _db_content["files"].append(file_path) - - -def _remove_file(file_path): - """Removes a file reference from the db.""" - # Check if the remove is for a single file object or for a folder - if file_path.find(".vmdk") != -1: - if file_path not in _db_content.get("files"): - raise vexc.FileNotFoundException(file_path) - _db_content.get("files").remove(file_path) - else: - # Removes the files in the folder and the folder too from the db - to_delete = set() - for file in _db_content.get("files"): - if file.find(file_path) != -1: - to_delete.add(file) - for file in to_delete: - _db_content.get("files").remove(file) - - -def fake_plug_vifs(*args, **kwargs): - """Fakes plugging vifs.""" - pass - - -def fake_get_network(*args, **kwargs): - """Fake get network.""" - return {'type': 'fake'} - - -def get_file(file_path): - """Check if file exists in the db.""" - return file_path in _db_content.get("files") - - -def fake_upload_image(context, image, instance, **kwargs): - """Fakes the upload of an image.""" - pass - - -def fake_fetch_image(context, instance, host, dc_name, ds_name, file_path, - cookies=None): - """Fakes the fetch of an image.""" - ds_file_path = "[" + ds_name + "] " + file_path - _add_file(ds_file_path) - - -def _get_vm_mdo(vm_ref): - """Gets the Virtual Machine with the ref from the db.""" - if _db_content.get("VirtualMachine", None) is None: - raise exception.NotFound(_("There is no VM registered")) - if vm_ref not in _db_content.get("VirtualMachine"): - raise exception.NotFound(_("Virtual Machine with ref %s is not " - "there") % vm_ref) - return _db_content.get("VirtualMachine")[vm_ref] - - -def _merge_extraconfig(existing, changes): - """Imposes the changes in extraConfig over the existing extraConfig.""" - existing = existing or [] - if (changes): - for c in changes: - if len([x for x in existing if x.key == c.key]) > 0: - extraConf = [x for x in existing if x.key == c.key][0] - extraConf.value = c.value - else: - existing.append(c) - return existing - - -class FakeFactory(object): - """Fake factory class for the suds client.""" - - def create(self, obj_name): - """Creates a namespace object.""" - return DataObject(obj_name) - - -class FakeService(DataObject): - """Fake service class.""" - - def Logout(self, session_manager): - pass - - def FindExtension(self, extension_manager, key): - return [] - - -class FakeClient(DataObject): - """Fake client class.""" - - def __init__(self): - """Creates a namespace object.""" - self.service = FakeService() - - -class FakeSession(object): - """Fake Session Class.""" - - def __init__(self): - self.vim = FakeVim() - - def _call_method(self, module, method, *args, **kwargs): - raise NotImplementedError() - - def _wait_for_task(self, task_ref): - raise NotImplementedError() - - -class FakeObjectRetrievalSession(FakeSession): - """A session for faking object retrieval tasks. - - _call_method() returns a given set of objects - sequentially, regardless of the method called. - """ - - def __init__(self, *ret): - super(FakeObjectRetrievalSession, self).__init__() - self.ret = ret - self.ind = 0 - - def _call_method(self, module, method, *args, **kwargs): - # return fake objects in a circular manner - self.ind = (self.ind + 1) % len(self.ret) - return self.ret[self.ind - 1] - - -def get_fake_vim_object(vmware_api_session): - key = vmware_api_session.__repr__() - if key not in _vim_map: - _vim_map[key] = FakeVim() - return _vim_map[key] - - -class FakeVim(object): - """Fake VIM Class.""" - - def __init__(self, protocol="https", host="localhost", trace=None): - """Initializes the suds client object, sets the service content - contents and the cookies for the session. - """ - self._session = None - self.client = FakeClient() - self.client.factory = FakeFactory() - - transport = DataObject() - transport.cookiejar = "Fake-CookieJar" - options = DataObject() - options.transport = transport - - self.client.options = options - - service_content = self.client.factory.create('ns0:ServiceContent') - service_content.propertyCollector = "PropCollector" - service_content.virtualDiskManager = "VirtualDiskManager" - service_content.fileManager = "FileManager" - service_content.rootFolder = "RootFolder" - service_content.sessionManager = "SessionManager" - service_content.extensionManager = "ExtensionManager" - service_content.searchIndex = "SearchIndex" - - about_info = DataObject() - about_info.name = "VMware vCenter Server" - about_info.version = "5.1.0" - service_content.about = about_info - - self._service_content = service_content - - @property - def service_content(self): - return self._service_content - - def __repr__(self): - return "Fake VIM Object" - - def __str__(self): - return "Fake VIM Object" - - def _login(self): - """Logs in and sets the session object in the db.""" - self._session = uuidutils.generate_uuid() - session = DataObject() - session.key = self._session - session.userName = 'sessionUserName' - _db_content['session'][self._session] = session - return session - - def _terminate_session(self, *args, **kwargs): - """Terminates a session.""" - s = kwargs.get("sessionId")[0] - if s not in _db_content['session']: - return - del _db_content['session'][s] - - def _check_session(self): - """Checks if the session is active.""" - if (self._session is None or self._session not in - _db_content['session']): - LOG.debug("Session is faulty") - raise vexc.VimFaultException( - [vexc.NOT_AUTHENTICATED], - _("Session Invalid")) - - def _session_is_active(self, *args, **kwargs): - try: - self._check_session() - return True - except Exception: - return False - - def _create_vm(self, method, *args, **kwargs): - """Creates and registers a VM object with the Host System.""" - config_spec = kwargs.get("config") - - if config_spec.guestId not in constants.VALID_OS_TYPES: - ex = vexc.VMwareDriverException('A specified parameter was ' - 'not correct.') - return create_task(method, "error", error_fault=ex).obj - - pool = kwargs.get('pool') - - devices = [] - for device_change in config_spec.deviceChange: - if device_change.operation == 'add': - devices.append(device_change.device) - - vm_ref = create_vm(config_spec.instanceUuid, config_spec.name, - config_spec.numCPUs, config_spec.memoryMB, - devices, config_spec.files.vmPathName, - config_spec.extraConfig, pool) - - task_mdo = create_task(method, "success", result=vm_ref) - return task_mdo.obj - - def _reconfig_vm(self, method, *args, **kwargs): - """Reconfigures a VM and sets the properties supplied.""" - vm_ref = args[0] - vm_mdo = _get_vm_mdo(vm_ref) - vm_mdo.reconfig(self.client.factory, kwargs.get("spec")) - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _create_copy_disk(self, method, vmdk_file_path): - """Creates/copies a vmdk file object in the datastore.""" - # We need to add/create both .vmdk and .-flat.vmdk files - flat_vmdk_file_path = vmdk_file_path.replace(".vmdk", "-flat.vmdk") - _add_file(vmdk_file_path) - _add_file(flat_vmdk_file_path) - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _extend_disk(self, method, size): - """Extend disk size when create a instance.""" - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _snapshot_vm(self, method): - """Snapshots a VM. Here we do nothing for faking sake.""" - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _find_all_by_uuid(self, *args, **kwargs): - uuid = kwargs.get('uuid') - vm_refs = [] - for vm_ref in _db_content.get("VirtualMachine"): - vm = _get_object(vm_ref) - vm_uuid = vm.get("summary.config.instanceUuid") - if vm_uuid == uuid: - vm_refs.append(vm_ref) - return vm_refs - - def _delete_snapshot(self, method, *args, **kwargs): - """Deletes a VM snapshot. Here we do nothing for faking sake.""" - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _delete_file(self, method, *args, **kwargs): - """Deletes a file from the datastore.""" - _remove_file(kwargs.get("name")) - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _just_return(self): - """Fakes a return.""" - return - - def _just_return_task(self, method): - """Fakes a task return.""" - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _clone_vm(self, method, *args, **kwargs): - """Fakes a VM clone.""" - """Creates and registers a VM object with the Host System.""" - source_vmref = args[0] - source_vm_mdo = _get_vm_mdo(source_vmref) - clone_spec = kwargs.get("spec") - vm_dict = { - "name": kwargs.get("name"), - "ds": source_vm_mdo.get("datastore"), - "runtime_host": source_vm_mdo.get("runtime.host"), - "powerstate": source_vm_mdo.get("runtime.powerState"), - "vmPathName": source_vm_mdo.get("config.files.vmPathName"), - "numCpu": source_vm_mdo.get("summary.config.numCpu"), - "mem": source_vm_mdo.get("summary.config.memorySizeMB"), - "extra_config": source_vm_mdo.get("config.extraConfig").OptionValue, - "virtual_device": - source_vm_mdo.get("config.hardware.device").VirtualDevice, - "instanceUuid": source_vm_mdo.get("summary.config.instanceUuid")} - - if clone_spec.config is not None: - # Impose the config changes specified in the config property - if (hasattr(clone_spec.config, 'instanceUuid') and - clone_spec.config.instanceUuid is not None): - vm_dict["instanceUuid"] = clone_spec.config.instanceUuid - - if hasattr(clone_spec.config, 'extraConfig'): - extraConfigs = _merge_extraconfig(vm_dict["extra_config"], - clone_spec.config.extraConfig) - vm_dict["extra_config"] = extraConfigs - - virtual_machine = VirtualMachine(**vm_dict) - _create_object("VirtualMachine", virtual_machine) - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _unregister_vm(self, method, *args, **kwargs): - """Unregisters a VM from the Host System.""" - vm_ref = args[0] - _get_vm_mdo(vm_ref) - del _db_content["VirtualMachine"][vm_ref] - - def _search_ds(self, method, *args, **kwargs): - """Searches the datastore for a file.""" - # TODO(garyk): add support for spec parameter - ds_path = kwargs.get("datastorePath") - matched_files = set() - # Check if we are searching for a file or a directory - directory = False - dname = '%s/' % ds_path - for file in _db_content.get("files"): - if file == dname: - directory = True - break - # A directory search implies that we must return all - # subdirectories - if directory: - for file in _db_content.get("files"): - if file.find(ds_path) != -1: - if not file.endswith(ds_path): - path = file.lstrip(dname).split('/') - if path: - matched_files.add(path[0]) - if not matched_files: - matched_files.add('/') - else: - for file in _db_content.get("files"): - if file.find(ds_path) != -1: - matched_files.add(ds_path) - if matched_files: - result = DataObject() - result.path = ds_path - result.file = [] - for file in matched_files: - matched = DataObject() - matched.path = file - result.file.append(matched) - task_mdo = create_task(method, "success", result=result) - else: - task_mdo = create_task(method, "error", error_fault=FileNotFound()) - return task_mdo.obj - - def _move_file(self, method, *args, **kwargs): - source = kwargs.get('sourceName') - destination = kwargs.get('destinationName') - new_files = [] - if source != destination: - for file in _db_content.get("files"): - if source in file: - new_file = file.replace(source, destination) - new_files.append(new_file) - # if source is not a file then the children will also - # be deleted - _remove_file(source) - for file in new_files: - _add_file(file) - task_mdo = create_task(method, "success") - return task_mdo.obj - - def fake_transfer_file(self, ds_name, file_path): - """Fakes fetch image call. - Just adds a reference to the db for the file. - """ - ds_file_path = "[" + ds_name + "] " + file_path - _add_file(ds_file_path) - - def _make_dir(self, method, *args, **kwargs): - """Creates a directory in the datastore.""" - ds_path = kwargs.get("name") - if get_file(ds_path): - raise vexc.FileAlreadyExistsException() - _db_content["files"].append('%s/' % ds_path) - - def _set_power_state(self, method, vm_ref, pwr_state="poweredOn"): - """Sets power state for the VM.""" - if _db_content.get("VirtualMachine", None) is None: - raise exception.NotFound(_("No Virtual Machine has been " - "registered yet")) - if vm_ref not in _db_content.get("VirtualMachine"): - raise exception.NotFound(_("Virtual Machine with ref %s is not " - "there") % vm_ref) - vm_mdo = _db_content.get("VirtualMachine").get(vm_ref) - vm_mdo.set("runtime.powerState", pwr_state) - task_mdo = create_task(method, "success") - return task_mdo.obj - - def _retrieve_properties_continue(self, method, *args, **kwargs): - """Continues the retrieve.""" - return FakeRetrieveResult() - - def _retrieve_properties_cancel(self, method, *args, **kwargs): - """Cancels the retrieve.""" - return None - - def _retrieve_properties(self, method, *args, **kwargs): - """Retrieves properties based on the type.""" - spec_set = kwargs.get("specSet")[0] - spec_type = spec_set.propSet[0].type - properties = spec_set.propSet[0].pathSet - if not isinstance(properties, list): - properties = properties.split() - objs = spec_set.objectSet - lst_ret_objs = FakeRetrieveResult() - for obj in objs: - try: - obj_ref = obj.obj - if obj_ref == "RootFolder": - # This means that we are retrieving props for all managed - # data objects of the specified 'type' in the entire - # inventory. This gets invoked by vim_util.get_objects. - mdo_refs = _db_content[spec_type] - elif obj_ref.type != spec_type: - # This means that we are retrieving props for the managed - # data objects in the parent object's 'path' property. - # This gets invoked by vim_util.get_inner_objects - # eg. obj_ref = <ManagedObjectReference of a cluster> - # type = 'DataStore' - # path = 'datastore' - # the above will retrieve all datastores in the given - # cluster. - parent_mdo = _db_content[obj_ref.type][obj_ref] - path = obj.selectSet[0].path - mdo_refs = parent_mdo.get(path).ManagedObjectReference - else: - # This means that we are retrieving props of the given - # managed data object. This gets invoked by - # vim_util.get_properties_for_a_collection_of_objects. - mdo_refs = [obj_ref] - - for mdo_ref in mdo_refs: - mdo = _db_content[spec_type][mdo_ref] - prop_list = [] - for prop_name in properties: - prop = Prop(prop_name, mdo.get(prop_name)) - prop_list.append(prop) - obj_content = ObjectContent(mdo.obj, prop_list) - lst_ret_objs.add_object(obj_content) - except Exception as exc: - LOG.exception(exc) - continue - return lst_ret_objs - - def _add_port_group(self, method, *args, **kwargs): - """Adds a port group to the host system.""" - _host_sk = _db_content["HostSystem"].keys()[0] - host_mdo = _db_content["HostSystem"][_host_sk] - host_mdo._add_port_group(kwargs.get("portgrp")) - - def _add_iscsi_send_tgt(self, method, *args, **kwargs): - """Adds a iscsi send target to the hba.""" - send_targets = kwargs.get('targets') - host_storage_sys = _get_objects('HostStorageSystem').objects[0] - iscsi_hba_array = host_storage_sys.get('storageDeviceInfo' - '.hostBusAdapter') - iscsi_hba = iscsi_hba_array.HostHostBusAdapter[0] - if hasattr(iscsi_hba, 'configuredSendTarget'): - iscsi_hba.configuredSendTarget.extend(send_targets) - else: - iscsi_hba.configuredSendTarget = send_targets - - def __getattr__(self, attr_name): - if attr_name != "Login": - self._check_session() - if attr_name == "Login": - return lambda *args, **kwargs: self._login() - elif attr_name == "SessionIsActive": - return lambda *args, **kwargs: self._session_is_active( - *args, **kwargs) - elif attr_name == "TerminateSession": - return lambda *args, **kwargs: self._terminate_session( - *args, **kwargs) - elif attr_name == "CreateVM_Task": - return lambda *args, **kwargs: self._create_vm(attr_name, - *args, **kwargs) - elif attr_name == "ReconfigVM_Task": - return lambda *args, **kwargs: self._reconfig_vm(attr_name, - *args, **kwargs) - elif attr_name == "CreateVirtualDisk_Task": - return lambda *args, **kwargs: self._create_copy_disk(attr_name, - kwargs.get("name")) - elif attr_name == "DeleteDatastoreFile_Task": - return lambda *args, **kwargs: self._delete_file(attr_name, - *args, **kwargs) - elif attr_name == "PowerOnVM_Task": - return lambda *args, **kwargs: self._set_power_state(attr_name, - args[0], "poweredOn") - elif attr_name == "PowerOffVM_Task": - return lambda *args, **kwargs: self._set_power_state(attr_name, - args[0], "poweredOff") - elif attr_name == "RebootGuest": - return lambda *args, **kwargs: self._just_return() - elif attr_name == "ResetVM_Task": - return lambda *args, **kwargs: self._set_power_state(attr_name, - args[0], "poweredOn") - elif attr_name == "SuspendVM_Task": - return lambda *args, **kwargs: self._set_power_state(attr_name, - args[0], "suspended") - elif attr_name == "CreateSnapshot_Task": - return lambda *args, **kwargs: self._snapshot_vm(attr_name) - elif attr_name == "RemoveSnapshot_Task": - return lambda *args, **kwargs: self._delete_snapshot(attr_name, - *args, **kwargs) - elif attr_name == "CopyVirtualDisk_Task": - return lambda *args, **kwargs: self._create_copy_disk(attr_name, - kwargs.get("destName")) - elif attr_name == "ExtendVirtualDisk_Task": - return lambda *args, **kwargs: self._extend_disk(attr_name, - kwargs.get("size")) - elif attr_name == "Destroy_Task": - return lambda *args, **kwargs: self._unregister_vm(attr_name, - *args, **kwargs) - elif attr_name == "UnregisterVM": - return lambda *args, **kwargs: self._unregister_vm(attr_name, - *args, **kwargs) - elif attr_name == "CloneVM_Task": - return lambda *args, **kwargs: self._clone_vm(attr_name, - *args, **kwargs) - elif attr_name == "FindAllByUuid": - return lambda *args, **kwargs: self._find_all_by_uuid(attr_name, - *args, **kwargs) - elif attr_name == "SearchDatastore_Task": - return lambda *args, **kwargs: self._search_ds(attr_name, - *args, **kwargs) - elif attr_name == "MoveDatastoreFile_Task": - return lambda *args, **kwargs: self._move_file(attr_name, - *args, **kwargs) - elif attr_name == "MakeDirectory": - return lambda *args, **kwargs: self._make_dir(attr_name, - *args, **kwargs) - elif attr_name == "RetrievePropertiesEx": - return lambda *args, **kwargs: self._retrieve_properties( - attr_name, *args, **kwargs) - elif attr_name == "ContinueRetrievePropertiesEx": - return lambda *args, **kwargs: self._retrieve_properties_continue( - attr_name, *args, **kwargs) - elif attr_name == "CancelRetrievePropertiesEx": - return lambda *args, **kwargs: self._retrieve_properties_cancel( - attr_name, *args, **kwargs) - elif attr_name == "AddPortGroup": - return lambda *args, **kwargs: self._add_port_group(attr_name, - *args, **kwargs) - elif attr_name == "RebootHost_Task": - return lambda *args, **kwargs: self._just_return_task(attr_name) - elif attr_name == "ShutdownHost_Task": - return lambda *args, **kwargs: self._just_return_task(attr_name) - elif attr_name == "PowerUpHostFromStandBy_Task": - return lambda *args, **kwargs: self._just_return_task(attr_name) - elif attr_name == "EnterMaintenanceMode_Task": - return lambda *args, **kwargs: self._just_return_task(attr_name) - elif attr_name == "ExitMaintenanceMode_Task": - return lambda *args, **kwargs: self._just_return_task(attr_name) - elif attr_name == "AddInternetScsiSendTargets": - return lambda *args, **kwargs: self._add_iscsi_send_tgt(attr_name, - *args, **kwargs) - elif attr_name == "RescanHba": - return lambda *args, **kwargs: self._just_return_task(attr_name) diff --git a/nova/tests/virt/vmwareapi/stubs.py b/nova/tests/virt/vmwareapi/stubs.py deleted file mode 100644 index fb207176cc..0000000000 --- a/nova/tests/virt/vmwareapi/stubs.py +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright (c) 2011 Citrix Systems, Inc. -# 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. - -""" -Stubouts for the test suite -""" - -import contextlib - -import mock -from oslo.vmware import exceptions as vexc - -from nova import db -from nova.tests import test_flavors -from nova.tests.virt.vmwareapi import fake -from nova.virt.vmwareapi import driver -from nova.virt.vmwareapi import images -from nova.virt.vmwareapi import network_util - - -def fake_get_vim_object(arg): - """Stubs out the VMwareAPISession's get_vim_object method.""" - return fake.FakeVim() - - -@property -def fake_vim_prop(arg): - """Stubs out the VMwareAPISession's vim property access method.""" - return fake.get_fake_vim_object(arg) - - -def fake_is_vim_object(arg, module): - """Stubs out the VMwareAPISession's is_vim_object method.""" - return isinstance(module, fake.FakeVim) - - -def fake_temp_method_exception(): - raise vexc.VimFaultException( - [vexc.NOT_AUTHENTICATED], - "Session Empty/Not Authenticated") - - -def fake_temp_session_exception(): - raise vexc.VimConnectionException("it's a fake!", - "Session Exception") - - -def fake_session_file_exception(): - fault_list = [vexc.FILE_ALREADY_EXISTS] - raise vexc.VimFaultException(fault_list, - Exception('fake')) - - -def fake_session_permission_exception(): - fault_list = [vexc.NO_PERMISSION] - fault_string = 'Permission to perform this operation was denied.' - details = {'privilegeId': 'Resource.AssignVMToPool', 'object': 'domain-c7'} - raise vexc.VimFaultException(fault_list, fault_string, details=details) - - -def _fake_flavor_get(context, id): - for instance_type in test_flavors.DEFAULT_FLAVORS: - if instance_type['id'] == id: - return instance_type - return {'memory_mb': 128, 'root_gb': 0, 'deleted_at': None, - 'name': 'm1.micro', 'deleted': 0, 'created_at': None, - 'ephemeral_gb': 0, 'updated_at': None, - 'disabled': False, 'vcpus': 1, 'extra_specs': {}, - 'swap': 0, 'rxtx_factor': 1.0, 'is_public': True, - 'flavorid': '1', 'vcpu_weight': None, 'id': 2} - - -def set_stubs(stubs): - """Set the stubs.""" - stubs.Set(network_util, 'get_network_with_the_name', - fake.fake_get_network) - stubs.Set(images, 'upload_image', fake.fake_upload_image) - stubs.Set(images, 'fetch_image', fake.fake_fetch_image) - stubs.Set(driver.VMwareAPISession, "vim", fake_vim_prop) - stubs.Set(driver.VMwareAPISession, "_is_vim_object", - fake_is_vim_object) - stubs.Set(db, 'flavor_get', _fake_flavor_get) - - -def fake_suds_context(calls=None): - """Generate a suds client which automatically mocks all SOAP method calls. - - Calls are stored in <calls>, indexed by the name of the call. If you need - to mock the behaviour of specific API calls you can pre-populate <calls> - with appropriate Mock objects. - """ - - calls = calls or {} - - class fake_factory: - def create(self, name): - return mock.NonCallableMagicMock(name=name) - - class fake_service: - def __getattr__(self, attr_name): - if attr_name in calls: - return calls[attr_name] - - mock_call = mock.MagicMock(name=attr_name) - calls[attr_name] = mock_call - return mock_call - - class fake_client: - def __init__(self, wdsl_url, **kwargs): - self.service = fake_service() - self.factory = fake_factory() - - return contextlib.nested( - mock.patch('suds.client.Client', fake_client), - - # As we're not connecting to a real host there's no need to wait - # between retries - mock.patch.object(driver, 'TIME_BETWEEN_API_CALL_RETRIES', 0) - ) diff --git a/nova/tests/virt/vmwareapi/test_configdrive.py b/nova/tests/virt/vmwareapi/test_configdrive.py deleted file mode 100644 index 3cb06dee18..0000000000 --- a/nova/tests/virt/vmwareapi/test_configdrive.py +++ /dev/null @@ -1,168 +0,0 @@ -# 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 -import mox - -from nova import context -from nova.image import glance -from nova import test -from nova.tests import fake_instance -import nova.tests.image.fake -from nova.tests import utils -from nova.tests.virt.vmwareapi import fake as vmwareapi_fake -from nova.tests.virt.vmwareapi import stubs -from nova.virt import fake -from nova.virt.vmwareapi import driver -from nova.virt.vmwareapi import images -from nova.virt.vmwareapi import vm_util -from nova.virt.vmwareapi import vmops - - -class ConfigDriveTestCase(test.NoDBTestCase): - - REQUIRES_LOCKING = True - - @mock.patch.object(driver.VMwareVCDriver, '_register_openstack_extension') - def setUp(self, mock_register): - super(ConfigDriveTestCase, self).setUp() - vm_util.vm_refs_cache_reset() - self.context = context.RequestContext('fake', 'fake', is_admin=False) - cluster_name = 'test_cluster' - self.flags(cluster_name=[cluster_name], - host_ip='test_url', - host_username='test_username', - host_password='test_pass', - use_linked_clone=False, group='vmware') - self.flags(vnc_enabled=False) - vmwareapi_fake.reset() - stubs.set_stubs(self.stubs) - nova.tests.image.fake.stub_out_image_service(self.stubs) - self.conn = driver.VMwareVCDriver(fake.FakeVirtAPI) - self.network_info = utils.get_test_network_info() - self.node_name = '%s(%s)' % (self.conn.dict_mors.keys()[0], - cluster_name) - image_ref = nova.tests.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': 'm1.large', - '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': 'fake-uuid', - 'node': self.node_name, - 'metadata': [], - 'expected_attrs': ['system_metadata'], - } - self.test_instance = fake_instance.fake_instance_obj(self.context, - **instance_values) - - (image_service, image_id) = glance.get_remote_image_service(context, - image_ref) - metadata = image_service.show(context, image_id) - self.image = { - 'id': image_ref, - 'disk_format': 'vmdk', - 'size': int(metadata['size']), - } - - class FakeInstanceMetadata(object): - def __init__(self, instance, content=None, extra_md=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.stubs.Set(nova.virt.configdrive.ConfigDriveBuilder, - 'make_drive', fake_make_drive) - - def fake_upload_iso_to_datastore(iso_path, instance, **kwargs): - pass - self.stubs.Set(images, - 'upload_iso_to_datastore', - fake_upload_iso_to_datastore) - - def tearDown(self): - super(ConfigDriveTestCase, self).tearDown() - vmwareapi_fake.cleanup() - nova.tests.image.fake.FakeImageService_reset() - - def _spawn_vm(self, 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, - network_info=self.network_info, - block_device_info=block_device_info) - - def test_create_vm_with_config_drive_verify_method_invocation(self): - self.test_instance.config_drive = 'True' - self.mox.StubOutWithMock(vmops.VMwareVMOps, '_create_config_drive') - self.mox.StubOutWithMock(vmops.VMwareVMOps, '_attach_cdrom_to_vm') - self.conn._vmops._create_config_drive(self.test_instance, - mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg() - ).AndReturn('[ds1] fake.iso') - self.conn._vmops._attach_cdrom_to_vm(mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg()) - self.mox.ReplayAll() - # if spawn does not call the _create_config_drive or - # _attach_cdrom_to_vm call with the correct set of parameters - # then mox's VerifyAll will throw a Expected methods never called - # Exception - self._spawn_vm() - - def test_create_vm_without_config_drive(self): - self.test_instance.config_drive = None - self.mox.StubOutWithMock(vmops.VMwareVMOps, '_create_config_drive') - self.mox.StubOutWithMock(vmops.VMwareVMOps, '_attach_cdrom_to_vm') - self.mox.ReplayAll() - # if spawn ends up calling _create_config_drive or - # _attach_cdrom_to_vm then mox will log a Unexpected method call - # exception - self._spawn_vm() - - def test_create_vm_with_config_drive(self): - self.test_instance.config_drive = 'True' - self._spawn_vm() diff --git a/nova/tests/virt/vmwareapi/test_driver_api.py b/nova/tests/virt/vmwareapi/test_driver_api.py deleted file mode 100644 index 384f579ffa..0000000000 --- a/nova/tests/virt/vmwareapi/test_driver_api.py +++ /dev/null @@ -1,2650 +0,0 @@ -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# Copyright (c) 2012 VMware, Inc. -# Copyright (c) 2011 Citrix Systems, Inc. -# 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. - -""" -Test suite for VMwareAPI. -""" - -import collections -import contextlib -import copy -import datetime - -from eventlet import greenthread -import mock -import mox -from oslo.config import cfg -from oslo.serialization import jsonutils -from oslo.utils import timeutils -from oslo.utils import units -from oslo.vmware import exceptions as vexc -from oslo.vmware import pbm -from oslo.vmware import vim -from oslo.vmware import vim_util as oslo_vim_util -import suds - -from nova import block_device -from nova.compute import api as compute_api -from nova.compute import power_state -from nova.compute import task_states -from nova.compute import vm_states -from nova import context -from nova import exception -from nova.image import glance -from nova.network import model as network_model -from nova.openstack.common import uuidutils -from nova import test -from nova.tests import fake_instance -import nova.tests.image.fake -from nova.tests import matchers -from nova.tests import test_flavors -from nova.tests import utils -from nova.tests.virt.vmwareapi import fake as vmwareapi_fake -from nova.tests.virt.vmwareapi import stubs -from nova import utils as nova_utils -from nova.virt import driver as v_driver -from nova.virt.vmwareapi import constants -from nova.virt.vmwareapi import driver -from nova.virt.vmwareapi import ds_util -from nova.virt.vmwareapi import error_util -from nova.virt.vmwareapi import imagecache -from nova.virt.vmwareapi import images -from nova.virt.vmwareapi import vif -from nova.virt.vmwareapi import vim_util -from nova.virt.vmwareapi import vm_util -from nova.virt.vmwareapi import vmops -from nova.virt.vmwareapi import volumeops - -CONF = cfg.CONF -CONF.import_opt('host', 'nova.netconf') -CONF.import_opt('remove_unused_original_minimum_age_seconds', - 'nova.virt.imagecache') - - -class fake_vm_ref(object): - def __init__(self): - self.value = 4 - self._type = 'VirtualMachine' - - -class fake_service_content(object): - def __init__(self): - self.ServiceContent = vmwareapi_fake.DataObject() - self.ServiceContent.fake = 'fake' - - -class VMwareSudsTest(test.NoDBTestCase): - - def setUp(self): - super(VMwareSudsTest, self).setUp() - - def new_client_init(self, url, **kwargs): - return - - mock.patch.object(suds.client.Client, - '__init__', new=new_client_init).start() - self.vim = self._vim_create() - self.addCleanup(mock.patch.stopall) - - def _mock_getattr(self, attr_name): - self.assertEqual("RetrieveServiceContent", attr_name) - return lambda obj, **kwargs: fake_service_content() - - def _vim_create(self): - with mock.patch.object(vim.Vim, '__getattr__', self._mock_getattr): - return vim.Vim() - - def test_exception_with_deepcopy(self): - self.assertIsNotNone(self.vim) - self.assertRaises(vexc.VimException, - copy.deepcopy, self.vim) - - -def _fake_create_session(inst): - session = vmwareapi_fake.DataObject() - session.key = 'fake_key' - session.userName = 'fake_username' - session._pbm_wsdl_loc = None - session._pbm = None - inst._session = session - - -class VMwareDriverStartupTestCase(test.NoDBTestCase): - def _start_driver_with_flags(self, expected_exception_type, startup_flags): - self.flags(**startup_flags) - with mock.patch( - 'nova.virt.vmwareapi.driver.VMwareAPISession.__init__'): - e = self.assertRaises( - Exception, driver.VMwareVCDriver, None) # noqa - self.assertIs(type(e), expected_exception_type) - - def test_start_driver_no_user(self): - self._start_driver_with_flags( - Exception, - dict(host_ip='ip', host_password='password', - group='vmware')) - - def test_start_driver_no_host(self): - self._start_driver_with_flags( - Exception, - dict(host_username='username', host_password='password', - group='vmware')) - - def test_start_driver_no_password(self): - self._start_driver_with_flags( - Exception, - dict(host_ip='ip', host_username='username', - group='vmware')) - - def test_start_driver_with_user_host_password(self): - # Getting the InvalidInput exception signifies that no exception - # is raised regarding missing user/password/host - self._start_driver_with_flags( - nova.exception.InvalidInput, - dict(host_ip='ip', host_password='password', - host_username="user", datastore_regex="bad(regex", - group='vmware')) - - -class VMwareSessionTestCase(test.NoDBTestCase): - - @mock.patch.object(driver.VMwareAPISession, '_is_vim_object', - return_value=False) - def test_call_method(self, mock_is_vim): - with contextlib.nested( - mock.patch.object(driver.VMwareAPISession, '_create_session', - _fake_create_session), - mock.patch.object(driver.VMwareAPISession, 'invoke_api'), - ) as (fake_create, fake_invoke): - session = driver.VMwareAPISession() - session._vim = mock.Mock() - module = mock.Mock() - session._call_method(module, 'fira') - fake_invoke.assert_called_once_with(module, 'fira', session._vim) - - @mock.patch.object(driver.VMwareAPISession, '_is_vim_object', - return_value=True) - def test_call_method_vim(self, mock_is_vim): - with contextlib.nested( - mock.patch.object(driver.VMwareAPISession, '_create_session', - _fake_create_session), - mock.patch.object(driver.VMwareAPISession, 'invoke_api'), - ) as (fake_create, fake_invoke): - session = driver.VMwareAPISession() - module = mock.Mock() - session._call_method(module, 'fira') - fake_invoke.assert_called_once_with(module, 'fira') - - -class VMwareAPIVMTestCase(test.NoDBTestCase): - """Unit tests for Vmware API connection calls.""" - - REQUIRES_LOCKING = True - - @mock.patch.object(driver.VMwareVCDriver, '_register_openstack_extension') - def setUp(self, mock_register, create_connection=True): - super(VMwareAPIVMTestCase, self).setUp() - vm_util.vm_refs_cache_reset() - self.context = context.RequestContext('fake', 'fake', is_admin=False) - cluster_name = 'test_cluster' - cluster_name2 = 'test_cluster2' - self.flags(cluster_name=[cluster_name, cluster_name2], - host_ip='test_url', - host_username='test_username', - host_password='test_pass', - api_retry_count=1, - use_linked_clone=False, group='vmware') - self.flags(vnc_enabled=False, - image_cache_subdirectory_name='vmware_base', - my_ip='') - self.user_id = 'fake' - self.project_id = 'fake' - self.context = context.RequestContext(self.user_id, self.project_id) - stubs.set_stubs(self.stubs) - vmwareapi_fake.reset() - nova.tests.image.fake.stub_out_image_service(self.stubs) - if create_connection: - self.conn = driver.VMwareVCDriver(None, False) - self._set_exception_vars() - self.node_name = self.conn._resources.keys()[0] - self.node_name2 = self.conn._resources.keys()[1] - if cluster_name2 in self.node_name2: - self.ds = 'ds1' - else: - self.ds = 'ds2' - - self.vim = vmwareapi_fake.FakeVim() - - # NOTE(vish): none of the network plugging code is actually - # being tested - self.network_info = utils.get_test_network_info() - image_ref = nova.tests.image.fake.get_valid_image_id() - (image_service, image_id) = glance.get_remote_image_service( - self.context, image_ref) - metadata = image_service.show(self.context, image_id) - self.image = { - 'id': image_ref, - 'disk_format': 'vmdk', - 'size': int(metadata['size']), - } - self.fake_image_uuid = self.image['id'] - nova.tests.image.fake.stub_out_image_service(self.stubs) - self.vnc_host = 'ha-host' - self.instance_without_compute = {'node': None, - 'vm_state': 'building', - 'project_id': 'fake', - 'user_id': 'fake', - 'name': '1', - 'display_description': '1', - 'kernel_id': '1', - 'ramdisk_id': '1', - 'mac_addresses': [ - {'address': 'de:ad:be:ef:be:ef'} - ], - 'memory_mb': 8192, - 'instance_type': 'm1.large', - 'vcpus': 4, - 'root_gb': 80, - 'image_ref': self.image['id'], - 'host': 'fake_host', - 'task_state': - 'scheduling', - 'reservation_id': 'r-3t8muvr0', - 'id': 1, - 'uuid': 'fake-uuid', - 'metadata': []} - - def tearDown(self): - super(VMwareAPIVMTestCase, self).tearDown() - vmwareapi_fake.cleanup() - nova.tests.image.fake.FakeImageService_reset() - - def test_get_host_ip_addr(self): - self.assertEqual('test_url', self.conn.get_host_ip_addr()) - - def test_init_host_with_no_session(self): - self.conn._session = mock.Mock() - self.conn._session.vim = None - self.conn.init_host('fake_host') - self.conn._session._create_session.assert_called_once_with() - - def test_init_host(self): - try: - self.conn.init_host("fake_host") - except Exception as ex: - self.fail("init_host raised: %s" % ex) - - def _set_exception_vars(self): - self.wait_task = self.conn._session._wait_for_task - self.call_method = self.conn._session._call_method - self.task_ref = None - self.exception = False - - def test_cleanup_host(self): - self.conn.init_host("fake_host") - try: - self.conn.cleanup_host("fake_host") - except Exception as ex: - self.fail("cleanup_host raised: %s" % ex) - - @mock.patch('nova.virt.vmwareapi.driver.VMwareVCDriver.__init__') - def test_cleanup_host_direct(self, mock_init): - mock_init.return_value = None - vcdriver = driver.VMwareVCDriver(None, False) - vcdriver._session = mock.Mock() - vcdriver.cleanup_host("foo") - vcdriver._session.vim.client.service.Logout.assert_called_once_with( - vcdriver._session.vim.service_content.sessionManager - ) - - @mock.patch('nova.virt.vmwareapi.driver.VMwareVCDriver.__init__') - def test_cleanup_host_direct_with_bad_logout(self, mock_init): - mock_init.return_value = None - vcdriver = driver.VMwareVCDriver(None, False) - vcdriver._session = mock.Mock() - fault = suds.WebFault(mock.Mock(), mock.Mock()) - vcdriver._session.vim.client.service.Logout.side_effect = fault - vcdriver.cleanup_host("foo") - - def test_driver_capabilities(self): - self.assertTrue(self.conn.capabilities['has_imagecache']) - self.assertFalse(self.conn.capabilities['supports_recreate']) - - def test_configuration_linked_clone(self): - self.flags(use_linked_clone=None, group='vmware') - self.assertRaises(vexc.UseLinkedCloneConfigurationFault, - self.conn._validate_configuration) - - @mock.patch.object(pbm, 'get_profile_id_by_name') - def test_configuration_pbm(self, get_profile_mock): - get_profile_mock.return_value = 'fake-profile' - self.flags(pbm_enabled=True, - pbm_default_policy='fake-policy', - pbm_wsdl_location='fake-location', group='vmware') - self.conn._validate_configuration() - - @mock.patch.object(pbm, 'get_profile_id_by_name') - def test_configuration_pbm_bad_default(self, get_profile_mock): - get_profile_mock.return_value = None - self.flags(pbm_enabled=True, - pbm_wsdl_location='fake-location', - pbm_default_policy='fake-policy', group='vmware') - self.assertRaises(error_util.PbmDefaultPolicyDoesNotExist, - self.conn._validate_configuration) - - def test_login_retries(self): - self.attempts = 0 - self.login_session = vmwareapi_fake.FakeVim()._login() - - def _fake_login(_self): - self.attempts += 1 - if self.attempts == 1: - raise vexc.VimConnectionException('Here is my fake exception') - return self.login_session - - def _fake_check_session(_self): - return True - - self.stubs.Set(vmwareapi_fake.FakeVim, '_login', _fake_login) - self.stubs.Set(vmwareapi_fake.FakeVim, '_check_session', - _fake_check_session) - - with mock.patch.object(greenthread, 'sleep'): - self.conn = driver.VMwareAPISession() - self.assertEqual(self.attempts, 2) - - def _get_instance_type_by_name(self, type): - for instance_type in test_flavors.DEFAULT_FLAVORS: - if instance_type['name'] == type: - return instance_type - if type == 'm1.micro': - return {'memory_mb': 128, 'root_gb': 0, 'deleted_at': None, - 'name': 'm1.micro', 'deleted': 0, 'created_at': None, - 'ephemeral_gb': 0, 'updated_at': None, - 'disabled': False, 'vcpus': 1, 'extra_specs': {}, - 'swap': 0, 'rxtx_factor': 1.0, 'is_public': True, - 'flavorid': '1', 'vcpu_weight': None, 'id': 2} - - def _create_instance(self, node=None, set_image_ref=True, - uuid=None, instance_type='m1.large'): - if not node: - node = self.node_name - if not uuid: - uuid = uuidutils.generate_uuid() - self.type_data = self._get_instance_type_by_name(instance_type) - values = {'name': 'fake_name', - 'id': 1, - 'uuid': uuid, - 'project_id': self.project_id, - 'user_id': self.user_id, - 'kernel_id': "fake_kernel_uuid", - 'ramdisk_id': "fake_ramdisk_uuid", - 'mac_address': "de:ad:be:ef:be:ef", - 'flavor': instance_type, - 'node': node, - 'memory_mb': self.type_data['memory_mb'], - 'root_gb': self.type_data['root_gb'], - 'ephemeral_gb': self.type_data['ephemeral_gb'], - 'vcpus': self.type_data['vcpus'], - 'swap': self.type_data['swap'], - 'expected_attrs': ['system_metadata'], - } - if set_image_ref: - values['image_ref'] = self.fake_image_uuid - self.instance_node = node - self.uuid = uuid - self.instance = fake_instance.fake_instance_obj( - self.context, **values) - - def _create_vm(self, node=None, num_instances=1, uuid=None, - instance_type='m1.large', powered_on=True): - """Create and spawn the VM.""" - if not node: - node = self.node_name - self._create_instance(node=node, uuid=uuid, - instance_type=instance_type) - self.assertIsNone(vm_util.vm_ref_cache_get(self.uuid)) - self.conn.spawn(self.context, self.instance, self.image, - injected_files=[], admin_password=None, - network_info=self.network_info, - block_device_info=None) - self._check_vm_record(num_instances=num_instances, - powered_on=powered_on) - self.assertIsNotNone(vm_util.vm_ref_cache_get(self.uuid)) - - def _get_vm_record(self): - # Get record for VM - vms = vmwareapi_fake._get_objects("VirtualMachine") - for vm in vms.objects: - if vm.get('name') == self.uuid: - return vm - self.fail('Unable to find VM backing!') - - def _check_vm_record(self, num_instances=1, powered_on=True): - """Check if the spawned VM's properties correspond to the instance in - the db. - """ - instances = self.conn.list_instances() - self.assertEqual(len(instances), num_instances) - - # Get Nova record for VM - vm_info = self.conn.get_info({'uuid': self.uuid, - 'name': 1, - 'node': self.instance_node}) - - vm = self._get_vm_record() - - # Check that m1.large above turned into the right thing. - mem_kib = long(self.type_data['memory_mb']) << 10 - vcpus = self.type_data['vcpus'] - self.assertEqual(vm_info['max_mem'], mem_kib) - self.assertEqual(vm_info['mem'], mem_kib) - self.assertEqual(vm.get("summary.config.instanceUuid"), self.uuid) - self.assertEqual(vm.get("summary.config.numCpu"), vcpus) - self.assertEqual(vm.get("summary.config.memorySizeMB"), - self.type_data['memory_mb']) - - self.assertEqual( - vm.get("config.hardware.device").VirtualDevice[2].obj_name, - "ns0:VirtualE1000") - if powered_on: - # Check that the VM is running according to Nova - self.assertEqual(power_state.RUNNING, vm_info['state']) - - # Check that the VM is running according to vSphere API. - self.assertEqual('poweredOn', vm.get("runtime.powerState")) - else: - # Check that the VM is not running according to Nova - self.assertEqual(power_state.SHUTDOWN, vm_info['state']) - - # Check that the VM is not running according to vSphere API. - self.assertEqual('poweredOff', vm.get("runtime.powerState")) - - found_vm_uuid = False - found_iface_id = False - extras = vm.get("config.extraConfig") - for c in extras.OptionValue: - if (c.key == "nvp.vm-uuid" and c.value == self.instance['uuid']): - found_vm_uuid = True - if (c.key == "nvp.iface-id.0" and c.value == "vif-xxx-yyy-zzz"): - found_iface_id = True - - self.assertTrue(found_vm_uuid) - self.assertTrue(found_iface_id) - - def _check_vm_info(self, info, pwr_state=power_state.RUNNING): - """Check if the get_info returned values correspond to the instance - object in the db. - """ - mem_kib = long(self.type_data['memory_mb']) << 10 - self.assertEqual(info["state"], pwr_state) - self.assertEqual(info["max_mem"], mem_kib) - self.assertEqual(info["mem"], mem_kib) - self.assertEqual(info["num_cpu"], self.type_data['vcpus']) - - def test_instance_exists(self): - self._create_vm() - self.assertTrue(self.conn.instance_exists(self.instance)) - invalid_instance = dict(uuid='foo', name='bar', node=self.node_name) - self.assertFalse(self.conn.instance_exists(invalid_instance)) - - def test_list_instances(self): - instances = self.conn.list_instances() - self.assertEqual(len(instances), 0) - - def test_list_instances_1(self): - self._create_vm() - instances = self.conn.list_instances() - self.assertEqual(len(instances), 1) - - def test_list_instance_uuids(self): - self._create_vm() - uuids = self.conn.list_instance_uuids() - self.assertEqual(len(uuids), 1) - - def test_list_instance_uuids_invalid_uuid(self): - self._create_vm(uuid='fake_id') - uuids = self.conn.list_instance_uuids() - self.assertEqual(len(uuids), 0) - - def _cached_files_exist(self, exists=True): - cache = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.vmdk' % self.fake_image_uuid) - if exists: - self.assertTrue(vmwareapi_fake.get_file(str(cache))) - else: - self.assertFalse(vmwareapi_fake.get_file(str(cache))) - - @mock.patch.object(nova.virt.vmwareapi.images.VMwareImage, - 'from_image') - def test_instance_dir_disk_created(self, mock_from_image): - """Test image file is cached when even when use_linked_clone - is False - """ - img_props = images.VMwareImage( - image_id=self.fake_image_uuid, - linked_clone=False) - - mock_from_image.return_value = img_props - self._create_vm() - path = ds_util.DatastorePath(self.ds, self.uuid, '%s.vmdk' % self.uuid) - self.assertTrue(vmwareapi_fake.get_file(str(path))) - self._cached_files_exist() - - @mock.patch.object(nova.virt.vmwareapi.images.VMwareImage, - 'from_image') - def test_cache_dir_disk_created(self, mock_from_image): - """Test image disk is cached when use_linked_clone is True.""" - self.flags(use_linked_clone=True, group='vmware') - - img_props = images.VMwareImage( - image_id=self.fake_image_uuid, - file_size=1 * units.Ki, - disk_type=constants.DISK_TYPE_SPARSE) - - mock_from_image.return_value = img_props - - self._create_vm() - path = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.vmdk' % self.fake_image_uuid) - root = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.80.vmdk' % self.fake_image_uuid) - self.assertTrue(vmwareapi_fake.get_file(str(path))) - self.assertTrue(vmwareapi_fake.get_file(str(root))) - - def _iso_disk_type_created(self, instance_type='m1.large'): - self.image['disk_format'] = 'iso' - self._create_vm(instance_type=instance_type) - path = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.iso' % self.fake_image_uuid) - self.assertTrue(vmwareapi_fake.get_file(str(path))) - - def test_iso_disk_type_created(self): - self._iso_disk_type_created() - path = ds_util.DatastorePath(self.ds, self.uuid, '%s.vmdk' % self.uuid) - self.assertTrue(vmwareapi_fake.get_file(str(path))) - - def test_iso_disk_type_created_with_root_gb_0(self): - self._iso_disk_type_created(instance_type='m1.micro') - path = ds_util.DatastorePath(self.ds, self.uuid, '%s.vmdk' % self.uuid) - self.assertFalse(vmwareapi_fake.get_file(str(path))) - - def test_iso_disk_cdrom_attach(self): - iso_path = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.iso' % self.fake_image_uuid) - - def fake_attach_cdrom(vm_ref, instance, data_store_ref, - iso_uploaded_path): - self.assertEqual(iso_uploaded_path, str(iso_path)) - - self.stubs.Set(self.conn._vmops, "_attach_cdrom_to_vm", - fake_attach_cdrom) - self.image['disk_format'] = 'iso' - self._create_vm() - - @mock.patch.object(nova.virt.vmwareapi.images.VMwareImage, - 'from_image') - def test_iso_disk_cdrom_attach_with_config_drive(self, - mock_from_image): - img_props = images.VMwareImage( - image_id=self.fake_image_uuid, - file_size=80 * units.Gi, - file_type='iso', - linked_clone=False) - - mock_from_image.return_value = img_props - - self.flags(force_config_drive=True) - iso_path = [ - ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.iso' % self.fake_image_uuid), - ds_util.DatastorePath(self.ds, 'fake-config-drive')] - self.iso_index = 0 - - def fake_create_config_drive(instance, injected_files, password, - data_store_name, folder, uuid, cookies): - return 'fake-config-drive' - - def fake_attach_cdrom(vm_ref, instance, data_store_ref, - iso_uploaded_path): - self.assertEqual(iso_uploaded_path, str(iso_path[self.iso_index])) - self.iso_index += 1 - - self.stubs.Set(self.conn._vmops, "_attach_cdrom_to_vm", - fake_attach_cdrom) - self.stubs.Set(self.conn._vmops, '_create_config_drive', - fake_create_config_drive) - - self.image['disk_format'] = 'iso' - self._create_vm() - self.assertEqual(self.iso_index, 2) - - def test_cdrom_attach_with_config_drive(self): - self.flags(force_config_drive=True) - - iso_path = ds_util.DatastorePath(self.ds, 'fake-config-drive') - self.cd_attach_called = False - - def fake_create_config_drive(instance, injected_files, password, - data_store_name, folder, uuid, cookies): - return 'fake-config-drive' - - def fake_attach_cdrom(vm_ref, instance, data_store_ref, - iso_uploaded_path): - self.assertEqual(iso_uploaded_path, str(iso_path)) - self.cd_attach_called = True - - self.stubs.Set(self.conn._vmops, "_attach_cdrom_to_vm", - fake_attach_cdrom) - self.stubs.Set(self.conn._vmops, '_create_config_drive', - fake_create_config_drive) - - self._create_vm() - self.assertTrue(self.cd_attach_called) - - def test_spawn(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - - def test_spawn_vm_ref_cached(self): - uuid = uuidutils.generate_uuid() - self.assertIsNone(vm_util.vm_ref_cache_get(uuid)) - self._create_vm(uuid=uuid) - self.assertIsNotNone(vm_util.vm_ref_cache_get(uuid)) - - def _spawn_power_state(self, power_on): - self._spawn = self.conn._vmops.spawn - self._power_on = power_on - - def _fake_spawn(context, instance, image_meta, injected_files, - admin_password, network_info, block_device_info=None, - instance_name=None, power_on=True): - return self._spawn(context, instance, image_meta, - injected_files, admin_password, network_info, - block_device_info=block_device_info, - instance_name=instance_name, - power_on=self._power_on) - - with ( - mock.patch.object(self.conn._vmops, 'spawn', _fake_spawn) - ): - self._create_vm(powered_on=power_on) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - if power_on: - self._check_vm_info(info, power_state.RUNNING) - else: - self._check_vm_info(info, power_state.SHUTDOWN) - - def test_spawn_no_power_on(self): - self._spawn_power_state(False) - - def test_spawn_power_on(self): - self._spawn_power_state(True) - - def test_spawn_root_size_0(self): - self._create_vm(instance_type='m1.micro') - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - cache = ('[%s] vmware_base/%s/%s.vmdk' % - (self.ds, self.fake_image_uuid, self.fake_image_uuid)) - gb_cache = ('[%s] vmware_base/%s/%s.0.vmdk' % - (self.ds, self.fake_image_uuid, self.fake_image_uuid)) - self.assertTrue(vmwareapi_fake.get_file(cache)) - self.assertFalse(vmwareapi_fake.get_file(gb_cache)) - - def _spawn_with_delete_exception(self, fault=None): - - def fake_call_method(module, method, *args, **kwargs): - task_ref = self.call_method(module, method, *args, **kwargs) - if method == "DeleteDatastoreFile_Task": - self.exception = True - task_mdo = vmwareapi_fake.create_task(method, "error", - error_fault=fault) - return task_mdo.obj - return task_ref - - with ( - mock.patch.object(self.conn._session, '_call_method', - fake_call_method) - ): - if fault: - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - else: - self.assertRaises(vexc.VMwareDriverException, self._create_vm) - self.assertTrue(self.exception) - - def test_spawn_with_delete_exception_not_found(self): - self._spawn_with_delete_exception(vmwareapi_fake.FileNotFound()) - - def test_spawn_with_delete_exception_file_fault(self): - self._spawn_with_delete_exception(vmwareapi_fake.FileFault()) - - def test_spawn_with_delete_exception_cannot_delete_file(self): - self._spawn_with_delete_exception(vmwareapi_fake.CannotDeleteFile()) - - def test_spawn_with_delete_exception_file_locked(self): - self._spawn_with_delete_exception(vmwareapi_fake.FileLocked()) - - def test_spawn_with_delete_exception_general(self): - self._spawn_with_delete_exception() - - def test_spawn_disk_extend(self): - self.mox.StubOutWithMock(self.conn._vmops, '_extend_virtual_disk') - requested_size = 80 * units.Mi - self.conn._vmops._extend_virtual_disk(mox.IgnoreArg(), - requested_size, mox.IgnoreArg(), mox.IgnoreArg()) - self.mox.ReplayAll() - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - - def test_spawn_disk_extend_exists(self): - root = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.80.vmdk' % self.fake_image_uuid) - - def _fake_extend(instance, requested_size, name, dc_ref): - vmwareapi_fake._add_file(str(root)) - - self.stubs.Set(self.conn._vmops, '_extend_virtual_disk', - _fake_extend) - - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.assertTrue(vmwareapi_fake.get_file(str(root))) - - @mock.patch.object(nova.virt.vmwareapi.images.VMwareImage, - 'from_image') - def test_spawn_disk_extend_sparse(self, mock_from_image): - img_props = images.VMwareImage( - image_id=self.fake_image_uuid, - file_size=units.Ki, - disk_type=constants.DISK_TYPE_SPARSE, - linked_clone=True) - - mock_from_image.return_value = img_props - - with contextlib.nested( - mock.patch.object(self.conn._vmops, '_extend_virtual_disk'), - mock.patch.object(self.conn._vmops, 'get_datacenter_ref_and_name'), - ) as (mock_extend, mock_get_dc): - dc_val = mock.Mock() - dc_val.ref = "fake_dc_ref" - dc_val.name = "dc1" - mock_get_dc.return_value = dc_val - self._create_vm() - iid = img_props.image_id - cached_image = ds_util.DatastorePath(self.ds, 'vmware_base', - iid, '%s.80.vmdk' % iid) - mock_extend.assert_called_once_with( - self.instance, self.instance.root_gb * units.Mi, - str(cached_image), "fake_dc_ref") - - def test_spawn_disk_extend_failed_copy(self): - # Spawn instance - # copy for extend fails without creating a file - # - # Expect the copy error to be raised - self.flags(use_linked_clone=True, group='vmware') - - CopyError = vexc.FileFaultException - - def fake_wait_for_task(task_ref): - if task_ref == 'fake-copy-task': - raise CopyError('Copy failed!') - return self.wait_task(task_ref) - - def fake_call_method(module, method, *args, **kwargs): - if method == "CopyVirtualDisk_Task": - return 'fake-copy-task' - - return self.call_method(module, method, *args, **kwargs) - - with contextlib.nested( - mock.patch.object(self.conn._session, '_call_method', - new=fake_call_method), - mock.patch.object(self.conn._session, '_wait_for_task', - new=fake_wait_for_task)): - self.assertRaises(CopyError, self._create_vm) - - def test_spawn_disk_extend_failed_partial_copy(self): - # Spawn instance - # Copy for extend fails, leaving a file behind - # - # Expect the file to be cleaned up - # Expect the copy error to be raised - self.flags(use_linked_clone=True, group='vmware') - self.task_ref = None - uuid = self.fake_image_uuid - cached_image = '[%s] vmware_base/%s/%s.80.vmdk' % (self.ds, - uuid, uuid) - - CopyError = vexc.FileFaultException - - def fake_wait_for_task(task_ref): - if task_ref == self.task_ref: - self.task_ref = None - self.assertTrue(vmwareapi_fake.get_file(cached_image)) - # N.B. We don't test for -flat here because real - # CopyVirtualDisk_Task doesn't actually create it - raise CopyError('Copy failed!') - return self.wait_task(task_ref) - - def fake_call_method(module, method, *args, **kwargs): - task_ref = self.call_method(module, method, *args, **kwargs) - if method == "CopyVirtualDisk_Task": - self.task_ref = task_ref - return task_ref - - with contextlib.nested( - mock.patch.object(self.conn._session, '_call_method', - new=fake_call_method), - mock.patch.object(self.conn._session, '_wait_for_task', - new=fake_wait_for_task)): - self.assertRaises(CopyError, self._create_vm) - self.assertFalse(vmwareapi_fake.get_file(cached_image)) - - def test_spawn_disk_extend_failed_partial_copy_failed_cleanup(self): - # Spawn instance - # Copy for extend fails, leaves file behind - # File cleanup fails - # - # Expect file to be left behind - # Expect file cleanup error to be raised - self.flags(use_linked_clone=True, group='vmware') - self.task_ref = None - uuid = self.fake_image_uuid - cached_image = '[%s] vmware_base/%s/%s.80.vmdk' % (self.ds, - uuid, uuid) - - CopyError = vexc.FileFaultException - DeleteError = vexc.CannotDeleteFileException - - def fake_wait_for_task(task_ref): - if task_ref == self.task_ref: - self.task_ref = None - self.assertTrue(vmwareapi_fake.get_file(cached_image)) - # N.B. We don't test for -flat here because real - # CopyVirtualDisk_Task doesn't actually create it - raise CopyError('Copy failed!') - elif task_ref == 'fake-delete-task': - raise DeleteError('Delete failed!') - return self.wait_task(task_ref) - - def fake_call_method(module, method, *args, **kwargs): - if method == "DeleteDatastoreFile_Task": - return 'fake-delete-task' - - task_ref = self.call_method(module, method, *args, **kwargs) - if method == "CopyVirtualDisk_Task": - self.task_ref = task_ref - return task_ref - - with contextlib.nested( - mock.patch.object(self.conn._session, '_wait_for_task', - new=fake_wait_for_task), - mock.patch.object(self.conn._session, '_call_method', - new=fake_call_method)): - self.assertRaises(DeleteError, self._create_vm) - self.assertTrue(vmwareapi_fake.get_file(cached_image)) - - @mock.patch.object(nova.virt.vmwareapi.images.VMwareImage, - 'from_image') - def test_spawn_disk_invalid_disk_size(self, mock_from_image): - img_props = images.VMwareImage( - image_id=self.fake_image_uuid, - file_size=82 * units.Gi, - disk_type=constants.DISK_TYPE_SPARSE, - linked_clone=True) - - mock_from_image.return_value = img_props - - self.assertRaises(exception.InstanceUnacceptable, - self._create_vm) - - @mock.patch.object(nova.virt.vmwareapi.images.VMwareImage, - 'from_image') - def test_spawn_disk_extend_insufficient_disk_space(self, mock_from_image): - img_props = images.VMwareImage( - image_id=self.fake_image_uuid, - file_size=1024, - disk_type=constants.DISK_TYPE_SPARSE, - linked_clone=True) - - mock_from_image.return_value = img_props - - cached_image = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.80.vmdk' % - self.fake_image_uuid) - tmp_file = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - '%s.80-flat.vmdk' % - self.fake_image_uuid) - - NoDiskSpace = vexc.get_fault_class('NoDiskSpace') - - def fake_wait_for_task(task_ref): - if task_ref == self.task_ref: - self.task_ref = None - raise NoDiskSpace() - return self.wait_task(task_ref) - - def fake_call_method(module, method, *args, **kwargs): - task_ref = self.call_method(module, method, *args, **kwargs) - if method == 'ExtendVirtualDisk_Task': - self.task_ref = task_ref - return task_ref - - with contextlib.nested( - mock.patch.object(self.conn._session, '_wait_for_task', - fake_wait_for_task), - mock.patch.object(self.conn._session, '_call_method', - fake_call_method) - ) as (mock_wait_for_task, mock_call_method): - self.assertRaises(NoDiskSpace, self._create_vm) - self.assertFalse(vmwareapi_fake.get_file(str(cached_image))) - self.assertFalse(vmwareapi_fake.get_file(str(tmp_file))) - - def test_spawn_with_move_file_exists_exception(self): - # The test will validate that the spawn completes - # successfully. The "MoveDatastoreFile_Task" will - # raise an file exists exception. The flag - # self.exception will be checked to see that - # the exception has indeed been raised. - - def fake_wait_for_task(task_ref): - if task_ref == self.task_ref: - self.task_ref = None - self.exception = True - raise vexc.FileAlreadyExistsException() - return self.wait_task(task_ref) - - def fake_call_method(module, method, *args, **kwargs): - task_ref = self.call_method(module, method, *args, **kwargs) - if method == "MoveDatastoreFile_Task": - self.task_ref = task_ref - return task_ref - - with contextlib.nested( - mock.patch.object(self.conn._session, '_wait_for_task', - fake_wait_for_task), - mock.patch.object(self.conn._session, '_call_method', - fake_call_method) - ) as (_wait_for_task, _call_method): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.assertTrue(self.exception) - - def test_spawn_with_move_general_exception(self): - # The test will validate that the spawn completes - # successfully. The "MoveDatastoreFile_Task" will - # raise a general exception. The flag self.exception - # will be checked to see that the exception has - # indeed been raised. - - def fake_wait_for_task(task_ref): - if task_ref == self.task_ref: - self.task_ref = None - self.exception = True - raise vexc.VMwareDriverException('Exception!') - return self.wait_task(task_ref) - - def fake_call_method(module, method, *args, **kwargs): - task_ref = self.call_method(module, method, *args, **kwargs) - if method == "MoveDatastoreFile_Task": - self.task_ref = task_ref - return task_ref - - with contextlib.nested( - mock.patch.object(self.conn._session, '_wait_for_task', - fake_wait_for_task), - mock.patch.object(self.conn._session, '_call_method', - fake_call_method) - ) as (_wait_for_task, _call_method): - self.assertRaises(vexc.VMwareDriverException, - self._create_vm) - self.assertTrue(self.exception) - - def test_spawn_with_move_poll_exception(self): - self.call_method = self.conn._session._call_method - - def fake_call_method(module, method, *args, **kwargs): - task_ref = self.call_method(module, method, *args, **kwargs) - if method == "MoveDatastoreFile_Task": - task_mdo = vmwareapi_fake.create_task(method, "error") - return task_mdo.obj - return task_ref - - with ( - mock.patch.object(self.conn._session, '_call_method', - fake_call_method) - ): - self.assertRaises(vexc.VMwareDriverException, - self._create_vm) - - def test_spawn_with_move_file_exists_poll_exception(self): - # The test will validate that the spawn completes - # successfully. The "MoveDatastoreFile_Task" will - # raise a file exists exception. The flag self.exception - # will be checked to see that the exception has - # indeed been raised. - - def fake_call_method(module, method, *args, **kwargs): - task_ref = self.call_method(module, method, *args, **kwargs) - if method == "MoveDatastoreFile_Task": - self.exception = True - task_mdo = vmwareapi_fake.create_task(method, "error", - error_fault=vmwareapi_fake.FileAlreadyExists()) - return task_mdo.obj - return task_ref - - with ( - mock.patch.object(self.conn._session, '_call_method', - fake_call_method) - ): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.assertTrue(self.exception) - - def _spawn_attach_volume_vmdk(self, set_image_ref=True, vc_support=False): - self._create_instance(set_image_ref=set_image_ref) - self.mox.StubOutWithMock(block_device, 'volume_in_mapping') - self.mox.StubOutWithMock(v_driver, 'block_device_info_get_mapping') - connection_info = self._test_vmdk_connection_info('vmdk') - root_disk = [{'connection_info': connection_info}] - v_driver.block_device_info_get_mapping( - mox.IgnoreArg()).AndReturn(root_disk) - if vc_support: - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_get_res_pool_of_vm') - volumeops.VMwareVolumeOps._get_res_pool_of_vm( - mox.IgnoreArg()).AndReturn('fake_res_pool') - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_relocate_vmdk_volume') - volumeops.VMwareVolumeOps._relocate_vmdk_volume(mox.IgnoreArg(), - 'fake_res_pool', mox.IgnoreArg()) - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - 'attach_volume') - volumeops.VMwareVolumeOps.attach_volume(connection_info, - self.instance, mox.IgnoreArg()) - self.mox.ReplayAll() - block_device_info = {'mount_device': 'vda'} - self.conn.spawn(self.context, self.instance, self.image, - injected_files=[], admin_password=None, - network_info=self.network_info, - block_device_info=block_device_info) - - def test_spawn_attach_volume_iscsi(self): - self._create_instance() - self.mox.StubOutWithMock(block_device, 'volume_in_mapping') - self.mox.StubOutWithMock(v_driver, 'block_device_info_get_mapping') - connection_info = self._test_vmdk_connection_info('iscsi') - root_disk = [{'connection_info': connection_info}] - v_driver.block_device_info_get_mapping( - mox.IgnoreArg()).AndReturn(root_disk) - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - 'attach_volume') - volumeops.VMwareVolumeOps.attach_volume(connection_info, - self.instance, mox.IgnoreArg()) - self.mox.ReplayAll() - block_device_info = {'mount_device': 'vda'} - self.conn.spawn(self.context, self.instance, self.image, - injected_files=[], admin_password=None, - network_info=self.network_info, - block_device_info=block_device_info) - - def mock_upload_image(self, context, image, instance, **kwargs): - self.assertEqual(image, 'Test-Snapshot') - self.assertEqual(instance, self.instance) - self.assertEqual(kwargs['disk_type'], 'preallocated') - - def test_get_vm_ref_using_extra_config(self): - self._create_vm() - vm_ref = vm_util._get_vm_ref_from_extraconfig(self.conn._session, - self.instance['uuid']) - self.assertIsNotNone(vm_ref, 'VM Reference cannot be none') - # Disrupt the fake Virtual Machine object so that extraConfig - # cannot be matched. - fake_vm = self._get_vm_record() - fake_vm.get('config.extraConfig["nvp.vm-uuid"]').value = "" - # We should not get a Virtual Machine through extraConfig. - vm_ref = vm_util._get_vm_ref_from_extraconfig(self.conn._session, - self.instance['uuid']) - self.assertIsNone(vm_ref, 'VM Reference should be none') - # Check if we can find the Virtual Machine using the name. - vm_ref = vm_util.get_vm_ref(self.conn._session, self.instance) - self.assertIsNotNone(vm_ref, 'VM Reference cannot be none') - - def test_search_vm_ref_by_identifier(self): - self._create_vm() - vm_ref = vm_util.search_vm_ref_by_identifier(self.conn._session, - self.instance['uuid']) - self.assertIsNotNone(vm_ref, 'VM Reference cannot be none') - fake_vm = self._get_vm_record() - fake_vm.set("summary.config.instanceUuid", "foo") - fake_vm.set("name", "foo") - fake_vm.get('config.extraConfig["nvp.vm-uuid"]').value = "foo" - self.assertIsNone(vm_util.search_vm_ref_by_identifier( - self.conn._session, self.instance['uuid']), - "VM Reference should be none") - self.assertIsNotNone( - vm_util.search_vm_ref_by_identifier(self.conn._session, "foo"), - "VM Reference should not be none") - - def test_get_object_for_optionvalue(self): - self._create_vm() - vms = self.conn._session._call_method(vim_util, "get_objects", - "VirtualMachine", ['config.extraConfig["nvp.vm-uuid"]']) - vm_ref = vm_util._get_object_for_optionvalue(vms, - self.instance["uuid"]) - self.assertIsNotNone(vm_ref, 'VM Reference cannot be none') - - def _test_snapshot(self): - expected_calls = [ - {'args': (), - 'kwargs': - {'task_state': task_states.IMAGE_PENDING_UPLOAD}}, - {'args': (), - 'kwargs': - {'task_state': task_states.IMAGE_UPLOADING, - 'expected_state': task_states.IMAGE_PENDING_UPLOAD}}] - func_call_matcher = matchers.FunctionCallMatcher(expected_calls) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - with mock.patch.object(images, 'upload_image', - self.mock_upload_image): - self.conn.snapshot(self.context, self.instance, "Test-Snapshot", - func_call_matcher.call) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.assertIsNone(func_call_matcher.match()) - - def test_snapshot(self): - self._create_vm() - self._test_snapshot() - - def test_snapshot_no_root_disk(self): - self._iso_disk_type_created(instance_type='m1.micro') - self.assertRaises(error_util.NoRootDiskDefined, self.conn.snapshot, - self.context, self.instance, "Test-Snapshot", - lambda *args, **kwargs: None) - - def test_snapshot_non_existent(self): - self._create_instance() - self.assertRaises(exception.InstanceNotFound, self.conn.snapshot, - self.context, self.instance, "Test-Snapshot", - lambda *args, **kwargs: None) - - def test_snapshot_delete_vm_snapshot(self): - self._create_vm() - fake_vm = self._get_vm_record() - snapshot_ref = vmwareapi_fake.ManagedObjectReference( - value="Snapshot-123", - name="VirtualMachineSnapshot") - - self.mox.StubOutWithMock(vmops.VMwareVMOps, - '_create_vm_snapshot') - self.conn._vmops._create_vm_snapshot( - self.instance, fake_vm.obj).AndReturn(snapshot_ref) - - self.mox.StubOutWithMock(vmops.VMwareVMOps, - '_delete_vm_snapshot') - self.conn._vmops._delete_vm_snapshot( - self.instance, fake_vm.obj, snapshot_ref).AndReturn(None) - self.mox.ReplayAll() - - self._test_snapshot() - - def _snapshot_delete_vm_snapshot_exception(self, exception, call_count=1): - self._create_vm() - fake_vm = vmwareapi_fake._get_objects("VirtualMachine").objects[0].obj - snapshot_ref = vmwareapi_fake.ManagedObjectReference( - value="Snapshot-123", - name="VirtualMachineSnapshot") - - with contextlib.nested( - mock.patch.object(self.conn._session, '_wait_for_task', - side_effect=exception), - mock.patch.object(vmops, '_time_sleep_wrapper') - ) as (_fake_wait, _fake_sleep): - if exception != error_util.TaskInProgress: - self.assertRaises(exception, - self.conn._vmops._delete_vm_snapshot, - self.instance, fake_vm, snapshot_ref) - self.assertEqual(0, _fake_sleep.call_count) - else: - self.conn._vmops._delete_vm_snapshot(self.instance, fake_vm, - snapshot_ref) - self.assertEqual(call_count - 1, _fake_sleep.call_count) - self.assertEqual(call_count, _fake_wait.call_count) - - def test_snapshot_delete_vm_snapshot_exception(self): - self._snapshot_delete_vm_snapshot_exception(exception.NovaException) - - def test_snapshot_delete_vm_snapshot_exception_retry(self): - self.flags(api_retry_count=5, group='vmware') - self._snapshot_delete_vm_snapshot_exception(error_util.TaskInProgress, - 5) - - def test_reboot(self): - self._create_vm() - info = self.conn.get_info({'name': 1, 'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - reboot_type = "SOFT" - self.conn.reboot(self.context, self.instance, self.network_info, - reboot_type) - info = self.conn.get_info({'name': 1, 'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - - def test_reboot_with_uuid(self): - """Test fall back to use name when can't find by uuid.""" - self._create_vm() - info = self.conn.get_info({'name': 'fake-name', 'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - reboot_type = "SOFT" - self.conn.reboot(self.context, self.instance, self.network_info, - reboot_type) - info = self.conn.get_info({'name': 'fake-name', 'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - - def test_reboot_non_existent(self): - self._create_instance() - self.assertRaises(exception.InstanceNotFound, self.conn.reboot, - self.context, self.instance, self.network_info, - 'SOFT') - - def test_poll_rebooting_instances(self): - self.mox.StubOutWithMock(compute_api.API, 'reboot') - compute_api.API.reboot(mox.IgnoreArg(), mox.IgnoreArg(), - mox.IgnoreArg()) - self.mox.ReplayAll() - self._create_vm() - instances = [self.instance] - self.conn.poll_rebooting_instances(60, instances) - - def test_reboot_not_poweredon(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.suspend(self.instance) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.SUSPENDED) - self.assertRaises(exception.InstanceRebootFailure, self.conn.reboot, - self.context, self.instance, self.network_info, - 'SOFT') - - def test_suspend(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.suspend(self.instance) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.SUSPENDED) - - def test_suspend_non_existent(self): - self._create_instance() - self.assertRaises(exception.InstanceNotFound, self.conn.suspend, - self.instance) - - def test_resume(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.suspend(self.instance) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.SUSPENDED) - self.conn.resume(self.context, self.instance, self.network_info) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - - def test_resume_non_existent(self): - self._create_instance() - self.assertRaises(exception.InstanceNotFound, self.conn.resume, - self.context, self.instance, self.network_info) - - def test_resume_not_suspended(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.assertRaises(exception.InstanceResumeFailure, self.conn.resume, - self.context, self.instance, self.network_info) - - def test_power_on(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.power_off(self.instance) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.SHUTDOWN) - self.conn.power_on(self.context, self.instance, self.network_info) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - - def test_power_on_non_existent(self): - self._create_instance() - self.assertRaises(exception.InstanceNotFound, self.conn.power_on, - self.context, self.instance, self.network_info) - - def test_power_off(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.power_off(self.instance) - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.SHUTDOWN) - - def test_power_off_non_existent(self): - self._create_instance() - self.assertRaises(exception.InstanceNotFound, self.conn.power_off, - self.instance) - - def test_resume_state_on_host_boot(self): - self._create_vm() - self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') - self.mox.StubOutWithMock(self.conn, "reboot") - vm_util.get_vm_state_from_name(mox.IgnoreArg(), - self.instance['uuid']).AndReturn("poweredOff") - self.conn.reboot(self.context, self.instance, 'network_info', - 'hard', None) - self.mox.ReplayAll() - self.conn.resume_state_on_host_boot(self.context, self.instance, - 'network_info') - - def test_resume_state_on_host_boot_no_reboot_1(self): - """Don't call reboot on instance which is poweredon.""" - self._create_vm() - self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') - self.mox.StubOutWithMock(self.conn, 'reboot') - vm_util.get_vm_state_from_name(mox.IgnoreArg(), - self.instance['uuid']).AndReturn("poweredOn") - self.mox.ReplayAll() - self.conn.resume_state_on_host_boot(self.context, self.instance, - 'network_info') - - def test_resume_state_on_host_boot_no_reboot_2(self): - """Don't call reboot on instance which is suspended.""" - self._create_vm() - self.mox.StubOutWithMock(vm_util, 'get_vm_state_from_name') - self.mox.StubOutWithMock(self.conn, 'reboot') - vm_util.get_vm_state_from_name(mox.IgnoreArg(), - self.instance['uuid']).AndReturn("suspended") - self.mox.ReplayAll() - self.conn.resume_state_on_host_boot(self.context, self.instance, - 'network_info') - - def destroy_rescued(self, fake_method): - self._rescue() - with contextlib.nested( - mock.patch.object(self.conn._volumeops, "detach_disk_from_vm", - fake_method), - mock.patch.object(vm_util, "power_on_instance"), - ) as (fake_detach, fake_power_on): - self.instance['vm_state'] = vm_states.RESCUED - self.conn.destroy(self.context, self.instance, self.network_info) - inst_path = ds_util.DatastorePath(self.ds, self.uuid, - '%s.vmdk' % self.uuid) - self.assertFalse(vmwareapi_fake.get_file(str(inst_path))) - rescue_file_path = ds_util.DatastorePath( - self.ds, '%s-rescue' % self.uuid, '%s-rescue.vmdk' % self.uuid) - self.assertFalse(vmwareapi_fake.get_file(str(rescue_file_path))) - # Unrescue does not power on with destroy - self.assertFalse(fake_power_on.called) - - def test_destroy_rescued(self): - def fake_detach_disk_from_vm(*args, **kwargs): - pass - self.destroy_rescued(fake_detach_disk_from_vm) - - def test_destroy_rescued_with_exception(self): - def fake_detach_disk_from_vm(*args, **kwargs): - raise exception.NovaException('Here is my fake exception') - self.destroy_rescued(fake_detach_disk_from_vm) - - def test_destroy(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - instances = self.conn.list_instances() - self.assertEqual(len(instances), 1) - self.conn.destroy(self.context, self.instance, self.network_info) - instances = self.conn.list_instances() - self.assertEqual(len(instances), 0) - self.assertIsNone(vm_util.vm_ref_cache_get(self.uuid)) - - def test_destroy_no_datastore(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - instances = self.conn.list_instances() - self.assertEqual(len(instances), 1) - # Delete the vmPathName - vm = self._get_vm_record() - vm.delete('config.files.vmPathName') - self.conn.destroy(self.context, self.instance, self.network_info) - instances = self.conn.list_instances() - self.assertEqual(len(instances), 0) - - def test_destroy_non_existent(self): - self.destroy_disks = True - with mock.patch.object(self.conn._vmops, - "destroy") as mock_destroy: - self._create_instance() - self.conn.destroy(self.context, self.instance, - self.network_info, - None, self.destroy_disks) - mock_destroy.assert_called_once_with(self.instance, - self.destroy_disks) - - def test_destroy_instance_without_compute(self): - self.destroy_disks = True - with mock.patch.object(self.conn._vmops, - "destroy") as mock_destroy: - self.conn.destroy(self.context, self.instance_without_compute, - self.network_info, - None, self.destroy_disks) - self.assertFalse(mock_destroy.called) - - def _destroy_instance_without_vm_ref(self, resize_exists=False, - task_state=None): - - def fake_vm_ref_from_name(session, vm_name): - if resize_exists: - return 'fake-ref' - - self._create_instance() - with contextlib.nested( - mock.patch.object(vm_util, 'get_vm_ref_from_name', - fake_vm_ref_from_name), - mock.patch.object(self.conn._session, - '_call_method'), - mock.patch.object(self.conn._vmops, - '_destroy_instance') - ) as (mock_get, mock_call, mock_destroy): - self.instance.task_state = task_state - self.conn.destroy(self.context, self.instance, - self.network_info, - None, True) - if resize_exists: - if task_state == task_states.RESIZE_REVERTING: - expected = 1 - else: - expected = 2 - else: - expected = 1 - self.assertEqual(expected, mock_destroy.call_count) - self.assertFalse(mock_call.called) - - def test_destroy_instance_without_vm_ref(self): - self._destroy_instance_without_vm_ref() - - def test_destroy_instance_without_vm_ref_with_resize(self): - self._destroy_instance_without_vm_ref(resize_exists=True) - - def test_destroy_instance_without_vm_ref_with_resize_revert(self): - self._destroy_instance_without_vm_ref(resize_exists=True, - task_state=task_states.RESIZE_REVERTING) - - def _rescue(self, config_drive=False): - # validate that the power on is only called once - self._power_on = vm_util.power_on_instance - self._power_on_called = 0 - - def fake_attach_disk_to_vm(vm_ref, instance, - adapter_type, disk_type, vmdk_path=None, - disk_size=None, linked_clone=False, - controller_key=None, unit_number=None, - device_name=None): - info = self.conn.get_info(instance) - self._check_vm_info(info, power_state.SHUTDOWN) - - if config_drive: - def fake_create_config_drive(instance, injected_files, password, - data_store_name, folder, - instance_uuid, cookies): - self.assertTrue(uuidutils.is_uuid_like(instance['uuid'])) - return str(ds_util.DatastorePath(data_store_name, - instance_uuid, 'fake.iso')) - - self.stubs.Set(self.conn._vmops, '_create_config_drive', - fake_create_config_drive) - - self._create_vm() - - def fake_power_on_instance(session, instance, vm_ref=None): - self._power_on_called += 1 - return self._power_on(session, instance, vm_ref=vm_ref) - - info = self.conn.get_info({'name': 1, 'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.stubs.Set(vm_util, "power_on_instance", - fake_power_on_instance) - self.stubs.Set(self.conn._volumeops, "attach_disk_to_vm", - fake_attach_disk_to_vm) - - self.conn.rescue(self.context, self.instance, self.network_info, - self.image, 'fake-password') - - info = self.conn.get_info({'name': '1-rescue', - 'uuid': '%s-rescue' % self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - info = self.conn.get_info({'name': 1, 'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.SHUTDOWN) - self.assertIsNotNone(vm_util.vm_ref_cache_get('%s-rescue' % self.uuid)) - self.assertEqual(1, self._power_on_called) - - def test_rescue(self): - self._rescue() - inst_file_path = ds_util.DatastorePath(self.ds, self.uuid, - '%s.vmdk' % self.uuid) - self.assertTrue(vmwareapi_fake.get_file(str(inst_file_path))) - rescue_file_path = ds_util.DatastorePath(self.ds, - '%s-rescue' % self.uuid, - '%s-rescue.vmdk' % self.uuid) - self.assertTrue(vmwareapi_fake.get_file(str(rescue_file_path))) - - def test_rescue_with_config_drive(self): - self.flags(force_config_drive=True) - self._rescue(config_drive=True) - - def test_unrescue(self): - # NOTE(dims): driver unrescue ends up eventually in vmops.unrescue - # with power_on=True, the test_destroy_rescued tests the - # vmops.unrescue with power_on=False - self._rescue() - vm_ref = vm_util.get_vm_ref(self.conn._session, - self.instance) - vm_rescue_ref = vm_util.get_vm_ref_from_name(self.conn._session, - '%s-rescue' % self.uuid) - - self.poweroff_instance = vm_util.power_off_instance - - def fake_power_off_instance(session, instance, vm_ref): - # This is called so that we actually poweroff the simulated vm. - # The reason for this is that there is a validation in destroy - # that the instance is not powered on. - self.poweroff_instance(session, instance, vm_ref) - - def fake_detach_disk_from_vm(vm_ref, instance, - device_name, destroy_disk=False): - self.test_device_name = device_name - info = self.conn.get_info(instance) - self._check_vm_info(info, power_state.SHUTDOWN) - - with contextlib.nested( - mock.patch.object(vm_util, "power_off_instance", - side_effect=fake_power_off_instance), - mock.patch.object(self.conn._volumeops, "detach_disk_from_vm", - side_effect=fake_detach_disk_from_vm), - mock.patch.object(vm_util, "power_on_instance"), - ) as (poweroff, detach, fake_power_on): - self.conn.unrescue(self.instance, None) - poweroff.assert_called_once_with(self.conn._session, mock.ANY, - vm_rescue_ref) - detach.assert_called_once_with(vm_rescue_ref, mock.ANY, - self.test_device_name) - fake_power_on.assert_called_once_with(self.conn._session, - self.instance, - vm_ref=vm_ref) - self.test_vm_ref = None - self.test_device_name = None - - def test_get_diagnostics(self): - self._create_vm() - expected = {'memoryReservation': 0, 'suspendInterval': 0, - 'maxCpuUsage': 2000, 'toolsInstallerMounted': False, - 'consumedOverheadMemory': 20, 'numEthernetCards': 1, - 'numCpu': 1, 'featureRequirement': [{'key': 'cpuid.AES'}], - 'memoryOverhead': 21417984, - 'guestMemoryUsage': 0, 'connectionState': 'connected', - 'memorySizeMB': 512, 'balloonedMemory': 0, - 'vmPathName': 'fake_path', 'template': False, - 'overallCpuUsage': 0, 'powerState': 'poweredOn', - 'cpuReservation': 0, 'overallCpuDemand': 0, - 'numVirtualDisks': 1, 'hostMemoryUsage': 141} - expected = dict([('vmware:' + k, v) for k, v in expected.items()]) - self.assertThat( - self.conn.get_diagnostics({'name': 1, 'uuid': self.uuid, - 'node': self.instance_node}), - matchers.DictMatches(expected)) - - def test_get_instance_diagnostics(self): - self._create_vm() - expected = {'uptime': 0, - 'memory_details': {'used': 0, 'maximum': 512}, - 'nic_details': [], - 'driver': 'vmwareapi', - 'state': 'running', - 'version': '1.0', - 'cpu_details': [], - 'disk_details': [], - 'hypervisor_os': 'esxi', - 'config_drive': False} - actual = self.conn.get_instance_diagnostics( - {'name': 1, 'uuid': self.uuid, 'node': self.instance_node}) - self.assertThat(actual.serialize(), matchers.DictMatches(expected)) - - def test_get_console_output(self): - self.assertRaises(NotImplementedError, self.conn.get_console_output, - None, None) - - def _test_finish_migration(self, power_on, resize_instance=False): - self._create_vm() - self.conn.finish_migration(context=self.context, - migration=None, - instance=self.instance, - disk_info=None, - network_info=None, - block_device_info=None, - resize_instance=resize_instance, - image_meta=None, - power_on=power_on) - - def _test_finish_revert_migration(self, power_on): - self._create_vm() - # Ensure ESX driver throws an error - self.assertRaises(NotImplementedError, - self.conn.finish_revert_migration, - self.context, - instance=self.instance, - network_info=None) - - def test_get_vnc_console_non_existent(self): - self._create_instance() - self.assertRaises(exception.InstanceNotFound, - self.conn.get_vnc_console, - self.context, - self.instance) - - def _test_get_vnc_console(self): - self._create_vm() - fake_vm = self._get_vm_record() - OptionValue = collections.namedtuple('OptionValue', ['key', 'value']) - opt_val = OptionValue(key='', value=5906) - fake_vm.set(vm_util.VNC_CONFIG_KEY, opt_val) - vnc_console = self.conn.get_vnc_console(self.context, self.instance) - self.assertEqual(self.vnc_host, vnc_console.host) - self.assertEqual(5906, vnc_console.port) - - def test_get_vnc_console(self): - self._test_get_vnc_console() - - def test_get_vnc_console_noport(self): - self._create_vm() - self.assertRaises(exception.ConsoleTypeUnavailable, - self.conn.get_vnc_console, - self.context, - self.instance) - - def test_get_volume_connector(self): - self._create_vm() - connector_dict = self.conn.get_volume_connector(self.instance) - fake_vm = self._get_vm_record() - fake_vm_id = fake_vm.obj.value - self.assertEqual(connector_dict['ip'], 'test_url') - self.assertEqual(connector_dict['initiator'], 'iscsi-name') - self.assertEqual(connector_dict['host'], 'test_url') - self.assertEqual(connector_dict['instance'], fake_vm_id) - - def _test_vmdk_connection_info(self, type): - return {'driver_volume_type': type, - 'serial': 'volume-fake-id', - 'data': {'volume': 'vm-10', - 'volume_id': 'volume-fake-id'}} - - def test_volume_attach_vmdk(self): - self._create_vm() - connection_info = self._test_vmdk_connection_info('vmdk') - mount_point = '/dev/vdc' - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_attach_volume_vmdk') - volumeops.VMwareVolumeOps._attach_volume_vmdk(connection_info, - self.instance, mount_point) - self.mox.ReplayAll() - self.conn.attach_volume(None, connection_info, self.instance, - mount_point) - - def test_volume_detach_vmdk(self): - self._create_vm() - connection_info = self._test_vmdk_connection_info('vmdk') - mount_point = '/dev/vdc' - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_detach_volume_vmdk') - volumeops.VMwareVolumeOps._detach_volume_vmdk(connection_info, - self.instance, mount_point) - self.mox.ReplayAll() - self.conn.detach_volume(connection_info, self.instance, mount_point, - encryption=None) - - def test_attach_vmdk_disk_to_vm(self): - self._create_vm() - connection_info = self._test_vmdk_connection_info('vmdk') - mount_point = '/dev/vdc' - - # create fake backing info - volume_device = vmwareapi_fake.DataObject() - volume_device.backing = vmwareapi_fake.DataObject() - volume_device.backing.fileName = 'fake_path' - - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_get_vmdk_base_volume_device') - volumeops.VMwareVolumeOps._get_vmdk_base_volume_device( - mox.IgnoreArg()).AndReturn(volume_device) - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - 'attach_disk_to_vm') - volumeops.VMwareVolumeOps.attach_disk_to_vm(mox.IgnoreArg(), - self.instance, mox.IgnoreArg(), mox.IgnoreArg(), - vmdk_path='fake_path') - self.mox.ReplayAll() - self.conn.attach_volume(None, connection_info, self.instance, - mount_point) - - def test_detach_vmdk_disk_from_vm(self): - self._create_vm() - connection_info = self._test_vmdk_connection_info('vmdk') - mount_point = '/dev/vdc' - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_get_volume_uuid') - volumeops.VMwareVolumeOps._get_volume_uuid(mox.IgnoreArg(), - 'volume-fake-id').AndReturn('fake_disk_uuid') - self.mox.StubOutWithMock(vm_util, 'get_vmdk_backed_disk_device') - vm_util.get_vmdk_backed_disk_device(mox.IgnoreArg(), - 'fake_disk_uuid').AndReturn('fake_device') - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_consolidate_vmdk_volume') - volumeops.VMwareVolumeOps._consolidate_vmdk_volume(self.instance, - mox.IgnoreArg(), 'fake_device', mox.IgnoreArg()) - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - 'detach_disk_from_vm') - volumeops.VMwareVolumeOps.detach_disk_from_vm(mox.IgnoreArg(), - self.instance, mox.IgnoreArg()) - self.mox.ReplayAll() - self.conn.detach_volume(connection_info, self.instance, mount_point, - encryption=None) - - def test_volume_attach_iscsi(self): - self._create_vm() - connection_info = self._test_vmdk_connection_info('iscsi') - mount_point = '/dev/vdc' - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_attach_volume_iscsi') - volumeops.VMwareVolumeOps._attach_volume_iscsi(connection_info, - self.instance, mount_point) - self.mox.ReplayAll() - self.conn.attach_volume(None, connection_info, self.instance, - mount_point) - - def test_volume_detach_iscsi(self): - self._create_vm() - connection_info = self._test_vmdk_connection_info('iscsi') - mount_point = '/dev/vdc' - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_detach_volume_iscsi') - volumeops.VMwareVolumeOps._detach_volume_iscsi(connection_info, - self.instance, mount_point) - self.mox.ReplayAll() - self.conn.detach_volume(connection_info, self.instance, mount_point, - encryption=None) - - def test_attach_iscsi_disk_to_vm(self): - self._create_vm() - connection_info = self._test_vmdk_connection_info('iscsi') - connection_info['data']['target_portal'] = 'fake_target_host:port' - connection_info['data']['target_iqn'] = 'fake_target_iqn' - mount_point = '/dev/vdc' - discover = ('fake_name', 'fake_uuid') - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_iscsi_get_target') - # simulate target not found - volumeops.VMwareVolumeOps._iscsi_get_target( - connection_info['data']).AndReturn((None, None)) - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_iscsi_add_send_target_host') - # rescan gets called with target portal - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_iscsi_rescan_hba') - volumeops.VMwareVolumeOps._iscsi_rescan_hba( - connection_info['data']['target_portal']) - # simulate target found - volumeops.VMwareVolumeOps._iscsi_get_target( - connection_info['data']).AndReturn(discover) - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - 'attach_disk_to_vm') - volumeops.VMwareVolumeOps.attach_disk_to_vm(mox.IgnoreArg(), - self.instance, mox.IgnoreArg(), 'rdmp', - device_name=mox.IgnoreArg()) - self.mox.ReplayAll() - self.conn.attach_volume(None, connection_info, self.instance, - mount_point) - - def test_iscsi_rescan_hba(self): - fake_target_portal = 'fake_target_host:port' - host_storage_sys = vmwareapi_fake._get_objects( - "HostStorageSystem").objects[0] - iscsi_hba_array = host_storage_sys.get('storageDeviceInfo' - '.hostBusAdapter') - iscsi_hba = iscsi_hba_array.HostHostBusAdapter[0] - # Check the host system does not have the send target - self.assertRaises(AttributeError, getattr, iscsi_hba, - 'configuredSendTarget') - # Rescan HBA with the target portal - vops = volumeops.VMwareVolumeOps(self.conn._session) - vops._iscsi_rescan_hba(fake_target_portal) - # Check if HBA has the target portal configured - self.assertEqual('fake_target_host', - iscsi_hba.configuredSendTarget[0].address) - # Rescan HBA with same portal - vops._iscsi_rescan_hba(fake_target_portal) - self.assertEqual(1, len(iscsi_hba.configuredSendTarget)) - - def test_iscsi_get_target(self): - data = {'target_portal': 'fake_target_host:port', - 'target_iqn': 'fake_target_iqn'} - host = vmwareapi_fake._get_objects('HostSystem').objects[0] - host._add_iscsi_target(data) - vops = volumeops.VMwareVolumeOps(self.conn._session) - result = vops._iscsi_get_target(data) - self.assertEqual(('fake-device', 'fake-uuid'), result) - - def test_detach_iscsi_disk_from_vm(self): - self._create_vm() - connection_info = self._test_vmdk_connection_info('iscsi') - connection_info['data']['target_portal'] = 'fake_target_portal' - connection_info['data']['target_iqn'] = 'fake_target_iqn' - mount_point = '/dev/vdc' - find = ('fake_name', 'fake_uuid') - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - '_iscsi_get_target') - volumeops.VMwareVolumeOps._iscsi_get_target( - connection_info['data']).AndReturn(find) - self.mox.StubOutWithMock(vm_util, 'get_rdm_disk') - device = 'fake_device' - vm_util.get_rdm_disk(mox.IgnoreArg(), 'fake_uuid').AndReturn(device) - self.mox.StubOutWithMock(volumeops.VMwareVolumeOps, - 'detach_disk_from_vm') - volumeops.VMwareVolumeOps.detach_disk_from_vm(mox.IgnoreArg(), - self.instance, device, destroy_disk=True) - self.mox.ReplayAll() - self.conn.detach_volume(connection_info, self.instance, mount_point, - encryption=None) - - def test_connection_info_get(self): - self._create_vm() - connector = self.conn.get_volume_connector(self.instance) - self.assertEqual(connector['ip'], 'test_url') - self.assertEqual(connector['host'], 'test_url') - self.assertEqual(connector['initiator'], 'iscsi-name') - self.assertIn('instance', connector) - - def test_connection_info_get_after_destroy(self): - self._create_vm() - self.conn.destroy(self.context, self.instance, self.network_info) - connector = self.conn.get_volume_connector(self.instance) - self.assertEqual(connector['ip'], 'test_url') - self.assertEqual(connector['host'], 'test_url') - self.assertEqual(connector['initiator'], 'iscsi-name') - self.assertNotIn('instance', connector) - - def test_refresh_instance_security_rules(self): - self.assertRaises(NotImplementedError, - self.conn.refresh_instance_security_rules, - instance=None) - - def test_image_aging_image_used(self): - self._create_vm() - all_instances = [self.instance] - self.conn.manage_image_cache(self.context, all_instances) - self._cached_files_exist() - - def _get_timestamp_filename(self): - return '%s%s' % (imagecache.TIMESTAMP_PREFIX, - timeutils.strtime(at=self.old_time, - fmt=imagecache.TIMESTAMP_FORMAT)) - - def _override_time(self): - self.old_time = datetime.datetime(2012, 11, 22, 12, 00, 00) - - def _fake_get_timestamp_filename(fake): - return self._get_timestamp_filename() - - self.stubs.Set(imagecache.ImageCacheManager, '_get_timestamp_filename', - _fake_get_timestamp_filename) - - def _timestamp_file_exists(self, exists=True): - timestamp = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, - self._get_timestamp_filename() + '/') - if exists: - self.assertTrue(vmwareapi_fake.get_file(str(timestamp))) - else: - self.assertFalse(vmwareapi_fake.get_file(str(timestamp))) - - def _image_aging_image_marked_for_deletion(self): - self._create_vm(uuid=uuidutils.generate_uuid()) - self._cached_files_exist() - all_instances = [] - self.conn.manage_image_cache(self.context, all_instances) - self._cached_files_exist() - self._timestamp_file_exists() - - def test_image_aging_image_marked_for_deletion(self): - self._override_time() - self._image_aging_image_marked_for_deletion() - - def _timestamp_file_removed(self): - self._override_time() - self._image_aging_image_marked_for_deletion() - self._create_vm(num_instances=2, - uuid=uuidutils.generate_uuid()) - self._timestamp_file_exists(exists=False) - - def test_timestamp_file_removed_spawn(self): - self._timestamp_file_removed() - - def test_timestamp_file_removed_aging(self): - self._timestamp_file_removed() - ts = self._get_timestamp_filename() - ts_path = ds_util.DatastorePath(self.ds, 'vmware_base', - self.fake_image_uuid, ts + '/') - vmwareapi_fake._add_file(str(ts_path)) - self._timestamp_file_exists() - all_instances = [self.instance] - self.conn.manage_image_cache(self.context, all_instances) - self._timestamp_file_exists(exists=False) - - def test_image_aging_disabled(self): - self._override_time() - self.flags(remove_unused_base_images=False) - self._create_vm() - self._cached_files_exist() - all_instances = [] - self.conn.manage_image_cache(self.context, all_instances) - self._cached_files_exist(exists=True) - self._timestamp_file_exists(exists=False) - - def _image_aging_aged(self, aging_time=100): - self._override_time() - cur_time = datetime.datetime(2012, 11, 22, 12, 00, 10) - self.flags(remove_unused_original_minimum_age_seconds=aging_time) - self._image_aging_image_marked_for_deletion() - all_instances = [] - timeutils.set_time_override(cur_time) - self.conn.manage_image_cache(self.context, all_instances) - - def test_image_aging_aged(self): - self._image_aging_aged(aging_time=8) - self._cached_files_exist(exists=False) - - def test_image_aging_not_aged(self): - self._image_aging_aged() - self._cached_files_exist() - - -class VMwareAPIVCDriverTestCase(VMwareAPIVMTestCase): - - @mock.patch.object(driver.VMwareVCDriver, '_register_openstack_extension') - def setUp(self, mock_register): - super(VMwareAPIVCDriverTestCase, self).setUp(create_connection=False) - cluster_name = 'test_cluster' - cluster_name2 = 'test_cluster2' - self.flags(cluster_name=[cluster_name, cluster_name2], - api_retry_count=1, - task_poll_interval=10, datastore_regex='.*', group='vmware') - self.flags(vnc_enabled=False, - image_cache_subdirectory_name='vmware_base') - vmwareapi_fake.reset() - self.conn = driver.VMwareVCDriver(None, False) - self._set_exception_vars() - self.node_name = self.conn._resources.keys()[0] - self.node_name2 = self.conn._resources.keys()[1] - if cluster_name2 in self.node_name2: - self.ds = 'ds1' - else: - self.ds = 'ds2' - self.vnc_host = 'ha-host' - - def tearDown(self): - super(VMwareAPIVCDriverTestCase, self).tearDown() - vmwareapi_fake.cleanup() - - def test_public_api_signatures(self): - self.assertPublicAPISignatures(v_driver.ComputeDriver(None), self.conn) - - def test_register_extension(self): - with mock.patch.object(self.conn._session, '_call_method', - return_value=None) as mock_call_method: - self.conn._register_openstack_extension() - mock_call_method.assert_has_calls( - [mock.call(oslo_vim_util, 'find_extension', - constants.EXTENSION_KEY), - mock.call(oslo_vim_util, 'register_extension', - constants.EXTENSION_KEY, - constants.EXTENSION_TYPE_INSTANCE)]) - - def test_register_extension_already_exists(self): - with mock.patch.object(self.conn._session, '_call_method', - return_value='fake-extension') as mock_find_ext: - self.conn._register_openstack_extension() - mock_find_ext.assert_called_once_with(oslo_vim_util, - 'find_extension', - constants.EXTENSION_KEY) - - def test_list_instances(self): - instances = self.conn.list_instances() - self.assertEqual(0, len(instances)) - - def test_list_instances_from_nodes(self): - # Create instance on node1 - self._create_vm(self.node_name) - # Create instances on the other node - self._create_vm(self.node_name2, num_instances=2) - self._create_vm(self.node_name2, num_instances=3) - node1_vmops = self.conn._get_vmops_for_compute_node(self.node_name) - node2_vmops = self.conn._get_vmops_for_compute_node(self.node_name2) - self.assertEqual(1, len(node1_vmops.list_instances())) - self.assertEqual(2, len(node2_vmops.list_instances())) - self.assertEqual(3, len(self.conn.list_instances())) - - def _setup_mocks_for_session(self, mock_init): - mock_init.return_value = None - - vcdriver = driver.VMwareVCDriver(None, False) - vcdriver._session = mock.Mock() - vcdriver._session.vim = None - - def side_effect(): - vcdriver._session.vim = mock.Mock() - vcdriver._session._create_session.side_effect = side_effect - return vcdriver - - def test_host_power_action(self): - self.assertRaises(NotImplementedError, - self.conn.host_power_action, 'host', 'action') - - def test_host_maintenance_mode(self): - self.assertRaises(NotImplementedError, - self.conn.host_maintenance_mode, 'host', 'mode') - - def test_set_host_enabled(self): - self.assertRaises(NotImplementedError, - self.conn.set_host_enabled, 'host', 'state') - - def test_datastore_regex_configured(self): - for node in self.conn._resources.keys(): - self.assertEqual(self.conn._datastore_regex, - self.conn._resources[node]['vmops']._datastore_regex) - - def test_get_available_resource(self): - stats = self.conn.get_available_resource(self.node_name) - cpu_info = {"model": ["Intel(R) Xeon(R)", "Intel(R) Xeon(R)"], - "vendor": ["Intel", "Intel"], - "topology": {"cores": 16, - "threads": 32}} - self.assertEqual(stats['vcpus'], 32) - self.assertEqual(stats['local_gb'], 1024) - self.assertEqual(stats['local_gb_used'], 1024 - 500) - self.assertEqual(stats['memory_mb'], 1000) - self.assertEqual(stats['memory_mb_used'], 500) - self.assertEqual(stats['hypervisor_type'], 'VMware vCenter Server') - self.assertEqual(stats['hypervisor_version'], 5001000) - self.assertEqual(stats['hypervisor_hostname'], self.node_name) - self.assertEqual(stats['cpu_info'], jsonutils.dumps(cpu_info)) - self.assertEqual(stats['supported_instances'], - '[["i686", "vmware", "hvm"], ["x86_64", "vmware", "hvm"]]') - - def test_invalid_datastore_regex(self): - - # Tests if we raise an exception for Invalid Regular Expression in - # vmware_datastore_regex - self.flags(cluster_name=['test_cluster'], datastore_regex='fake-ds(01', - group='vmware') - self.assertRaises(exception.InvalidInput, driver.VMwareVCDriver, None) - - def test_get_available_nodes(self): - nodelist = self.conn.get_available_nodes() - self.assertEqual(len(nodelist), 2) - self.assertIn(self.node_name, nodelist) - self.assertIn(self.node_name2, nodelist) - - def test_spawn_multiple_node(self): - - def fake_is_neutron(): - return False - - self.stubs.Set(nova_utils, 'is_neutron', fake_is_neutron) - uuid1 = uuidutils.generate_uuid() - uuid2 = uuidutils.generate_uuid() - self._create_vm(node=self.node_name, num_instances=1, - uuid=uuid1) - info = self.conn.get_info({'uuid': uuid1, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - self.conn.destroy(self.context, self.instance, self.network_info) - self._create_vm(node=self.node_name2, num_instances=1, - uuid=uuid2) - info = self.conn.get_info({'uuid': uuid2, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - - def test_snapshot(self): - self._create_vm() - self._test_snapshot() - - def test_snapshot_using_file_manager(self): - self._create_vm() - uuid_str = uuidutils.generate_uuid() - self.mox.StubOutWithMock(uuidutils, - 'generate_uuid') - uuidutils.generate_uuid().AndReturn(uuid_str) - - self.mox.StubOutWithMock(ds_util, 'file_delete') - disk_ds_path = ds_util.DatastorePath( - self.ds, "vmware_temp", "%s.vmdk" % uuid_str) - disk_ds_flat_path = ds_util.DatastorePath( - self.ds, "vmware_temp", "%s-flat.vmdk" % uuid_str) - # Check calls for delete vmdk and -flat.vmdk pair - ds_util.file_delete( - mox.IgnoreArg(), disk_ds_flat_path, - mox.IgnoreArg()).AndReturn(None) - ds_util.file_delete( - mox.IgnoreArg(), disk_ds_path, mox.IgnoreArg()).AndReturn(None) - - self.mox.ReplayAll() - self._test_snapshot() - - def test_spawn_invalid_node(self): - self._create_instance(node='InvalidNodeName') - self.assertRaises(exception.NotFound, self.conn.spawn, - self.context, self.instance, self.image, - injected_files=[], admin_password=None, - network_info=self.network_info, - block_device_info=None) - - @mock.patch.object(nova.virt.vmwareapi.images.VMwareImage, - 'from_image') - def test_spawn_with_sparse_image(self, mock_from_image): - img_info = images.VMwareImage( - image_id=self.fake_image_uuid, - file_size=1024, - disk_type=constants.DISK_TYPE_SPARSE, - linked_clone=False) - - mock_from_image.return_value = img_info - - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - - def test_plug_vifs(self): - # Check to make sure the method raises NotImplementedError. - self._create_instance() - self.assertRaises(NotImplementedError, - self.conn.plug_vifs, - instance=self.instance, network_info=None) - - def test_unplug_vifs(self): - # Check to make sure the method raises NotImplementedError. - self._create_instance() - self.assertRaises(NotImplementedError, - self.conn.unplug_vifs, - instance=self.instance, network_info=None) - - def _create_vif(self): - gw_4 = network_model.IP(address='101.168.1.1', type='gateway') - dns_4 = network_model.IP(address='8.8.8.8', type=None) - subnet_4 = network_model.Subnet(cidr='101.168.1.0/24', - dns=[dns_4], - gateway=gw_4, - routes=None, - dhcp_server='191.168.1.1') - - gw_6 = network_model.IP(address='101:1db9::1', type='gateway') - subnet_6 = network_model.Subnet(cidr='101:1db9::/64', - dns=None, - gateway=gw_6, - ips=None, - routes=None) - - network_neutron = network_model.Network(id='network-id-xxx-yyy-zzz', - bridge=None, - label=None, - subnets=[subnet_4, - subnet_6], - bridge_interface='eth0', - vlan=99) - - vif_bridge_neutron = network_model.VIF(id='new-vif-xxx-yyy-zzz', - address='ca:fe:de:ad:be:ef', - network=network_neutron, - type=None, - devname='tap-xxx-yyy-zzz', - ovs_interfaceid='aaa-bbb-ccc') - return vif_bridge_neutron - - def _validate_interfaces(self, id, index, num_iface_ids): - vm = self._get_vm_record() - found_iface_id = False - extras = vm.get("config.extraConfig") - key = "nvp.iface-id.%s" % index - num_found = 0 - for c in extras.OptionValue: - if c.key.startswith("nvp.iface-id."): - num_found += 1 - if c.key == key and c.value == id: - found_iface_id = True - self.assertTrue(found_iface_id) - self.assertEqual(num_found, num_iface_ids) - - def _attach_interface(self, vif): - self.conn.attach_interface(self.instance, self.image, vif) - self._validate_interfaces(vif['id'], 1, 2) - - def test_attach_interface(self): - self._create_vm() - vif = self._create_vif() - self._attach_interface(vif) - - def test_attach_interface_with_exception(self): - self._create_vm() - vif = self._create_vif() - - with mock.patch.object(self.conn._session, '_wait_for_task', - side_effect=Exception): - self.assertRaises(exception.InterfaceAttachFailed, - self.conn.attach_interface, - self.instance, self.image, vif) - - @mock.patch.object(vif, 'get_network_device', - return_value='fake_device') - def _detach_interface(self, vif, mock_get_device): - self._create_vm() - self._attach_interface(vif) - self.conn.detach_interface(self.instance, vif) - self._validate_interfaces('free', 1, 2) - - def test_detach_interface(self): - vif = self._create_vif() - self._detach_interface(vif) - - def test_detach_interface_and_attach(self): - vif = self._create_vif() - self._detach_interface(vif) - self.conn.attach_interface(self.instance, self.image, vif) - self._validate_interfaces(vif['id'], 1, 2) - - def test_detach_interface_no_device(self): - self._create_vm() - vif = self._create_vif() - self._attach_interface(vif) - self.assertRaises(exception.NotFound, self.conn.detach_interface, - self.instance, vif) - - def test_detach_interface_no_vif_match(self): - self._create_vm() - vif = self._create_vif() - self._attach_interface(vif) - vif['id'] = 'bad-id' - self.assertRaises(exception.NotFound, self.conn.detach_interface, - self.instance, vif) - - @mock.patch.object(vif, 'get_network_device', - return_value='fake_device') - def test_detach_interface_with_exception(self, mock_get_device): - self._create_vm() - vif = self._create_vif() - self._attach_interface(vif) - - with mock.patch.object(self.conn._session, '_wait_for_task', - side_effect=Exception): - self.assertRaises(exception.InterfaceDetachFailed, - self.conn.detach_interface, - self.instance, vif) - - def test_migrate_disk_and_power_off(self): - def fake_update_instance_progress(context, instance, step, - total_steps): - pass - - def fake_get_host_ref_from_name(dest): - return None - - self._create_vm(instance_type='m1.large') - vm_ref_orig = vm_util.get_vm_ref(self.conn._session, self.instance) - flavor = self._get_instance_type_by_name('m1.large') - self.stubs.Set(self.conn._vmops, "_update_instance_progress", - fake_update_instance_progress) - self.stubs.Set(self.conn._vmops, "_get_host_ref_from_name", - fake_get_host_ref_from_name) - self.conn.migrate_disk_and_power_off(self.context, self.instance, - 'fake_dest', flavor, - None) - vm_ref = vm_util.get_vm_ref(self.conn._session, self.instance) - self.assertNotEqual(vm_ref_orig.value, vm_ref.value, - "These should be different") - - def test_disassociate_vmref_from_instance(self): - self._create_vm() - vm_ref = vm_util.get_vm_ref(self.conn._session, self.instance) - vm_util.disassociate_vmref_from_instance(self.conn._session, - self.instance, vm_ref, "-backup") - self.assertRaises(exception.InstanceNotFound, - vm_util.get_vm_ref, self.conn._session, self.instance) - - def test_clone_vmref_for_instance(self): - self._create_vm() - vm_ref = vm_util.get_vm_ref(self.conn._session, self.instance) - vm_util.disassociate_vmref_from_instance(self.conn._session, - self.instance, vm_ref, "-backup") - host_ref = vmwareapi_fake._get_object_refs("HostSystem")[0] - ds_ref = vmwareapi_fake._get_object_refs("Datastore")[0] - dc_obj = vmwareapi_fake._get_objects("Datacenter").objects[0] - vm_util.clone_vmref_for_instance(self.conn._session, self.instance, - vm_ref, host_ref, ds_ref, - dc_obj.get("vmFolder")) - self.assertIsNotNone( - vm_util.get_vm_ref(self.conn._session, self.instance), - "No VM found") - cloned_vm_ref = vm_util.get_vm_ref(self.conn._session, self.instance) - self.assertNotEqual(vm_ref.value, cloned_vm_ref.value, - "Reference for the cloned VM should be different") - vm_obj = vmwareapi_fake._get_vm_mdo(vm_ref) - cloned_vm_obj = vmwareapi_fake._get_vm_mdo(cloned_vm_ref) - self.assertEqual(vm_obj.name, self.instance['uuid'] + "-backup", - "Original VM name should be with suffix -backup") - self.assertEqual(cloned_vm_obj.name, self.instance['uuid'], - "VM name does not match instance['uuid']") - self.assertRaises(vexc.MissingParameter, - vm_util.clone_vmref_for_instance, self.conn._session, - self.instance, None, host_ref, ds_ref, - dc_obj.get("vmFolder")) - - def test_associate_vmref_for_instance(self): - self._create_vm() - vm_ref = vm_util.get_vm_ref(self.conn._session, self.instance) - # First disassociate the VM from the instance so that we have a VM - # to later associate using the associate_vmref_for_instance method - vm_util.disassociate_vmref_from_instance(self.conn._session, - self.instance, vm_ref, "-backup") - # Ensure that the VM is indeed disassociated and that we cannot find - # the VM using the get_vm_ref method - self.assertRaises(exception.InstanceNotFound, - vm_util.get_vm_ref, self.conn._session, self.instance) - # Associate the VM back to the instance - vm_util.associate_vmref_for_instance(self.conn._session, self.instance, - suffix="-backup") - # Verify if we can get the VM reference - self.assertIsNotNone( - vm_util.get_vm_ref(self.conn._session, self.instance), - "No VM found") - - def test_confirm_migration(self): - self._create_vm() - self.conn.confirm_migration(self.context, self.instance, None) - - def test_resize_to_smaller_disk(self): - self._create_vm(instance_type='m1.large') - flavor = self._get_instance_type_by_name('m1.small') - self.assertRaises(exception.InstanceFaultRollback, - self.conn.migrate_disk_and_power_off, self.context, - self.instance, 'fake_dest', flavor, None) - - def test_spawn_attach_volume_vmdk(self): - self._spawn_attach_volume_vmdk(vc_support=True) - - def test_spawn_attach_volume_vmdk_no_image_ref(self): - self._spawn_attach_volume_vmdk(set_image_ref=False, vc_support=True) - - def test_pause(self): - # Tests that the VMwareVCDriver does not implement the pause method. - self._create_instance() - self.assertRaises(NotImplementedError, self.conn.pause, self.instance) - - def test_unpause(self): - # Tests that the VMwareVCDriver does not implement the unpause method. - self._create_instance() - self.assertRaises(NotImplementedError, self.conn.unpause, - self.instance) - - def test_datastore_dc_map(self): - vmops = self.conn._resources[self.node_name]['vmops'] - self.assertEqual({}, vmops._datastore_dc_mapping) - self._create_vm() - # currently there are 2 data stores - self.assertEqual(2, len(vmops._datastore_dc_mapping)) - - def test_rollback_live_migration_at_destination(self): - with mock.patch.object(self.conn, "destroy") as mock_destroy: - self.conn.rollback_live_migration_at_destination(self.context, - "instance", [], None) - mock_destroy.assert_called_once_with(self.context, - "instance", [], None) - - def test_get_instance_disk_info_is_implemented(self): - # Ensure that the method has been implemented in the driver - try: - disk_info = self.conn.get_instance_disk_info('fake_instance_name') - self.assertIsNone(disk_info) - except NotImplementedError: - self.fail("test_get_instance_disk_info() should not raise " - "NotImplementedError") - - def test_destroy(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - instances = self.conn.list_instances() - self.assertEqual(1, len(instances)) - self.conn.destroy(self.context, self.instance, self.network_info) - instances = self.conn.list_instances() - self.assertEqual(0, len(instances)) - self.assertIsNone(vm_util.vm_ref_cache_get(self.uuid)) - - def test_destroy_no_datastore(self): - self._create_vm() - info = self.conn.get_info({'uuid': self.uuid, - 'node': self.instance_node}) - self._check_vm_info(info, power_state.RUNNING) - instances = self.conn.list_instances() - self.assertEqual(1, len(instances)) - # Overwrite the vmPathName - vm = self._get_vm_record() - vm.set("config.files.vmPathName", None) - self.conn.destroy(self.context, self.instance, self.network_info) - instances = self.conn.list_instances() - self.assertEqual(0, len(instances)) - - def test_destroy_non_existent(self): - self.destroy_disks = True - with mock.patch.object(self.conn._vmops, - "destroy") as mock_destroy: - self._create_instance() - self.conn.destroy(self.context, self.instance, - self.network_info, - None, self.destroy_disks) - mock_destroy.assert_called_once_with(self.instance, - self.destroy_disks) - - def test_destroy_instance_without_compute(self): - self.destroy_disks = True - with mock.patch.object(self.conn._vmops, - "destroy") as mock_destroy: - self.conn.destroy(self.context, self.instance_without_compute, - self.network_info, - None, self.destroy_disks) - self.assertFalse(mock_destroy.called) - - def test_get_host_uptime(self): - self.assertRaises(NotImplementedError, - self.conn.get_host_uptime, 'host') - - def _test_finish_migration(self, power_on, resize_instance=False): - """Tests the finish_migration method on VC Driver.""" - # setup the test instance in the database - self._create_vm() - if resize_instance: - self.instance.system_metadata = {'old_instance_type_root_gb': '0'} - vm_ref = vm_util.get_vm_ref(self.conn._session, self.instance) - datastore = ds_util.Datastore(ref='fake-ref', name='fake') - dc_info = vmops.DcInfo(ref='fake_ref', name='fake', - vmFolder='fake_folder') - with contextlib.nested( - mock.patch.object(self.conn._session, "_call_method", - return_value='fake-task'), - mock.patch.object(self.conn._vmops, - "_update_instance_progress"), - mock.patch.object(self.conn._session, "_wait_for_task"), - mock.patch.object(vm_util, "get_vm_resize_spec", - return_value='fake-spec'), - mock.patch.object(ds_util, "get_datastore", - return_value=datastore), - mock.patch.object(self.conn._vmops, - 'get_datacenter_ref_and_name', - return_value=dc_info), - mock.patch.object(self.conn._vmops, '_extend_virtual_disk'), - mock.patch.object(vm_util, "power_on_instance") - ) as (fake_call_method, fake_update_instance_progress, - fake_wait_for_task, fake_vm_resize_spec, - fake_get_datastore, fake_get_datacenter_ref_and_name, - fake_extend_virtual_disk, fake_power_on): - self.conn.finish_migration(context=self.context, - migration=None, - instance=self.instance, - disk_info=None, - network_info=None, - block_device_info=None, - resize_instance=resize_instance, - image_meta=None, - power_on=power_on) - if resize_instance: - fake_vm_resize_spec.assert_called_once_with( - self.conn._session.vim.client.factory, - self.instance) - fake_call_method.assert_any_call( - self.conn._session.vim, - "ReconfigVM_Task", - vm_ref, - spec='fake-spec') - fake_wait_for_task.assert_called_once_with('fake-task') - fake_extend_virtual_disk.assert_called_once_with( - self.instance, self.instance['root_gb'] * units.Mi, - None, dc_info.ref) - else: - self.assertFalse(fake_vm_resize_spec.called) - self.assertFalse(fake_call_method.called) - self.assertFalse(fake_wait_for_task.called) - self.assertFalse(fake_extend_virtual_disk.called) - - if power_on: - fake_power_on.assert_called_once_with(self.conn._session, - self.instance, - vm_ref=vm_ref) - else: - self.assertFalse(fake_power_on.called) - fake_update_instance_progress.called_once_with( - self.context, self.instance, 4, vmops.RESIZE_TOTAL_STEPS) - - def test_finish_migration_power_on(self): - self._test_finish_migration(power_on=True) - - def test_finish_migration_power_off(self): - self._test_finish_migration(power_on=False) - - def test_finish_migration_power_on_resize(self): - self._test_finish_migration(power_on=True, - resize_instance=True) - - @mock.patch.object(vm_util, 'associate_vmref_for_instance') - @mock.patch.object(vm_util, 'power_on_instance') - def _test_finish_revert_migration(self, fake_power_on, - fake_associate_vmref, power_on): - """Tests the finish_revert_migration method on VC Driver.""" - - # setup the test instance in the database - self._create_instance() - self.conn.finish_revert_migration(self.context, - instance=self.instance, - network_info=None, - block_device_info=None, - power_on=power_on) - fake_associate_vmref.assert_called_once_with(self.conn._session, - self.instance, - suffix='-orig') - if power_on: - fake_power_on.assert_called_once_with(self.conn._session, - self.instance) - else: - self.assertFalse(fake_power_on.called) - - def test_finish_revert_migration_power_on(self): - self._test_finish_revert_migration(power_on=True) - - def test_finish_revert_migration_power_off(self): - self._test_finish_revert_migration(power_on=False) - - def test_pbm_wsdl_location(self): - self.flags(pbm_enabled=True, - pbm_wsdl_location='fira', - group='vmware') - self.conn._update_pbm_location() - self.assertEqual('fira', self.conn._session._pbm_wsdl_loc) - self.assertIsNone(self.conn._session._pbm) diff --git a/nova/tests/virt/vmwareapi/test_ds_util.py b/nova/tests/virt/vmwareapi/test_ds_util.py deleted file mode 100644 index 0ad8ef213d..0000000000 --- a/nova/tests/virt/vmwareapi/test_ds_util.py +++ /dev/null @@ -1,548 +0,0 @@ -# Copyright (c) 2014 VMware, 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 contextlib -import re - -import mock -from oslo.utils import units -from oslo.vmware import exceptions as vexc -from testtools import matchers - -from nova import exception -from nova.i18n import _ -from nova import test -from nova.tests.virt.vmwareapi import fake -from nova.virt.vmwareapi import ds_util - - -class DsUtilTestCase(test.NoDBTestCase): - def setUp(self): - super(DsUtilTestCase, self).setUp() - self.session = fake.FakeSession() - self.flags(api_retry_count=1, group='vmware') - fake.reset() - - def tearDown(self): - super(DsUtilTestCase, self).tearDown() - fake.reset() - - def test_file_delete(self): - def fake_call_method(module, method, *args, **kwargs): - self.assertEqual('DeleteDatastoreFile_Task', method) - name = kwargs.get('name') - self.assertEqual('[ds] fake/path', name) - datacenter = kwargs.get('datacenter') - self.assertEqual('fake-dc-ref', datacenter) - return 'fake_delete_task' - - with contextlib.nested( - mock.patch.object(self.session, '_wait_for_task'), - mock.patch.object(self.session, '_call_method', - fake_call_method) - ) as (_wait_for_task, _call_method): - ds_path = ds_util.DatastorePath('ds', 'fake/path') - ds_util.file_delete(self.session, - ds_path, 'fake-dc-ref') - _wait_for_task.assert_has_calls([ - mock.call('fake_delete_task')]) - - def test_file_move(self): - def fake_call_method(module, method, *args, **kwargs): - self.assertEqual('MoveDatastoreFile_Task', method) - sourceName = kwargs.get('sourceName') - self.assertEqual('[ds] tmp/src', sourceName) - destinationName = kwargs.get('destinationName') - self.assertEqual('[ds] base/dst', destinationName) - sourceDatacenter = kwargs.get('sourceDatacenter') - self.assertEqual('fake-dc-ref', sourceDatacenter) - destinationDatacenter = kwargs.get('destinationDatacenter') - self.assertEqual('fake-dc-ref', destinationDatacenter) - return 'fake_move_task' - - with contextlib.nested( - mock.patch.object(self.session, '_wait_for_task'), - mock.patch.object(self.session, '_call_method', - fake_call_method) - ) as (_wait_for_task, _call_method): - src_ds_path = ds_util.DatastorePath('ds', 'tmp/src') - dst_ds_path = ds_util.DatastorePath('ds', 'base/dst') - ds_util.file_move(self.session, - 'fake-dc-ref', src_ds_path, dst_ds_path) - _wait_for_task.assert_has_calls([ - mock.call('fake_move_task')]) - - def test_mkdir(self): - def fake_call_method(module, method, *args, **kwargs): - self.assertEqual('MakeDirectory', method) - name = kwargs.get('name') - self.assertEqual('[ds] fake/path', name) - datacenter = kwargs.get('datacenter') - self.assertEqual('fake-dc-ref', datacenter) - createParentDirectories = kwargs.get('createParentDirectories') - self.assertTrue(createParentDirectories) - - with mock.patch.object(self.session, '_call_method', - fake_call_method): - ds_path = ds_util.DatastorePath('ds', 'fake/path') - ds_util.mkdir(self.session, ds_path, 'fake-dc-ref') - - def test_file_exists(self): - def fake_call_method(module, method, *args, **kwargs): - if method == 'SearchDatastore_Task': - ds_browser = args[0] - self.assertEqual('fake-browser', ds_browser) - datastorePath = kwargs.get('datastorePath') - self.assertEqual('[ds] fake/path', datastorePath) - return 'fake_exists_task' - - # Should never get here - self.fail() - - def fake_wait_for_task(task_ref): - if task_ref == 'fake_exists_task': - result_file = fake.DataObject() - result_file.path = 'fake-file' - - result = fake.DataObject() - result.file = [result_file] - result.path = '[ds] fake/path' - - task_info = fake.DataObject() - task_info.result = result - - return task_info - - # Should never get here - self.fail() - - with contextlib.nested( - mock.patch.object(self.session, '_call_method', - fake_call_method), - mock.patch.object(self.session, '_wait_for_task', - fake_wait_for_task)): - ds_path = ds_util.DatastorePath('ds', 'fake/path') - file_exists = ds_util.file_exists(self.session, - 'fake-browser', ds_path, 'fake-file') - self.assertTrue(file_exists) - - def test_file_exists_fails(self): - def fake_call_method(module, method, *args, **kwargs): - if method == 'SearchDatastore_Task': - return 'fake_exists_task' - - # Should never get here - self.fail() - - def fake_wait_for_task(task_ref): - if task_ref == 'fake_exists_task': - raise vexc.FileNotFoundException() - - # Should never get here - self.fail() - - with contextlib.nested( - mock.patch.object(self.session, '_call_method', - fake_call_method), - mock.patch.object(self.session, '_wait_for_task', - fake_wait_for_task)): - ds_path = ds_util.DatastorePath('ds', 'fake/path') - file_exists = ds_util.file_exists(self.session, - 'fake-browser', ds_path, 'fake-file') - self.assertFalse(file_exists) - - def _mock_get_datastore_calls(self, *datastores): - """Mock vim_util calls made by get_datastore.""" - - datastores_i = [None] - - # For the moment, at least, this list of datastores is simply passed to - # get_properties_for_a_collection_of_objects, which we mock below. We - # don't need to over-complicate the fake function by worrying about its - # contents. - fake_ds_list = ['fake-ds'] - - def fake_call_method(module, method, *args, **kwargs): - # Mock the call which returns a list of datastores for the cluster - if (module == ds_util.vim_util and - method == 'get_dynamic_property' and - args == ('fake-cluster', 'ClusterComputeResource', - 'datastore')): - fake_ds_mor = fake.DataObject() - fake_ds_mor.ManagedObjectReference = fake_ds_list - return fake_ds_mor - - # Return the datastore result sets we were passed in, in the order - # given - if (module == ds_util.vim_util and - method == 'get_properties_for_a_collection_of_objects' and - args[0] == 'Datastore' and - args[1] == fake_ds_list): - # Start a new iterator over given datastores - datastores_i[0] = iter(datastores) - return datastores_i[0].next() - - # Continue returning results from the current iterator. - if (module == ds_util.vim_util and - method == 'continue_to_get_objects'): - try: - return datastores_i[0].next() - except StopIteration: - return None - - # Sentinel that get_datastore's use of vim has changed - self.fail('Unexpected vim call in get_datastore: %s' % method) - - return mock.patch.object(self.session, '_call_method', - side_effect=fake_call_method) - - def test_get_datastore(self): - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(fake.Datastore()) - fake_objects.add_object(fake.Datastore("fake-ds-2", 2048, 1000, - False, "normal")) - fake_objects.add_object(fake.Datastore("fake-ds-3", 4096, 2000, - True, "inMaintenance")) - - with self._mock_get_datastore_calls(fake_objects): - result = ds_util.get_datastore(self.session, 'fake-cluster') - self.assertEqual("fake-ds", result.name) - self.assertEqual(units.Ti, result.capacity) - self.assertEqual(500 * units.Gi, result.freespace) - - def test_get_datastore_with_regex(self): - # Test with a regex that matches with a datastore - datastore_valid_regex = re.compile("^openstack.*\d$") - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(fake.Datastore("openstack-ds0")) - fake_objects.add_object(fake.Datastore("fake-ds0")) - fake_objects.add_object(fake.Datastore("fake-ds1")) - - with self._mock_get_datastore_calls(fake_objects): - result = ds_util.get_datastore(self.session, 'fake-cluster', - datastore_valid_regex) - self.assertEqual("openstack-ds0", result.name) - - def test_get_datastore_with_token(self): - regex = re.compile("^ds.*\d$") - fake0 = fake.FakeRetrieveResult() - fake0.add_object(fake.Datastore("ds0", 10 * units.Gi, 5 * units.Gi)) - fake0.add_object(fake.Datastore("foo", 10 * units.Gi, 9 * units.Gi)) - setattr(fake0, 'token', 'token-0') - fake1 = fake.FakeRetrieveResult() - fake1.add_object(fake.Datastore("ds2", 10 * units.Gi, 8 * units.Gi)) - fake1.add_object(fake.Datastore("ds3", 10 * units.Gi, 1 * units.Gi)) - - with self._mock_get_datastore_calls(fake0, fake1): - result = ds_util.get_datastore(self.session, 'fake-cluster', regex) - self.assertEqual("ds2", result.name) - - def test_get_datastore_with_list(self): - # Test with a regex containing whitelist of datastores - datastore_valid_regex = re.compile("(openstack-ds0|openstack-ds2)") - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(fake.Datastore("openstack-ds0")) - fake_objects.add_object(fake.Datastore("openstack-ds1")) - fake_objects.add_object(fake.Datastore("openstack-ds2")) - - with self._mock_get_datastore_calls(fake_objects): - result = ds_util.get_datastore(self.session, 'fake-cluster', - datastore_valid_regex) - self.assertNotEqual("openstack-ds1", result.name) - - def test_get_datastore_with_regex_error(self): - # Test with a regex that has no match - # Checks if code raises DatastoreNotFound with a specific message - datastore_invalid_regex = re.compile("unknown-ds") - exp_message = (_("Datastore regex %s did not match any datastores") - % datastore_invalid_regex.pattern) - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(fake.Datastore("fake-ds0")) - fake_objects.add_object(fake.Datastore("fake-ds1")) - # assertRaisesRegExp would have been a good choice instead of - # try/catch block, but it's available only from Py 2.7. - try: - with self._mock_get_datastore_calls(fake_objects): - ds_util.get_datastore(self.session, 'fake-cluster', - datastore_invalid_regex) - except exception.DatastoreNotFound as e: - self.assertEqual(exp_message, e.args[0]) - else: - self.fail("DatastoreNotFound Exception was not raised with " - "message: %s" % exp_message) - - def test_get_datastore_without_datastore(self): - self.assertRaises(exception.DatastoreNotFound, - ds_util.get_datastore, - fake.FakeObjectRetrievalSession(None), cluster="fake-cluster") - - def test_get_datastore_inaccessible_ds(self): - data_store = fake.Datastore() - data_store.set("summary.accessible", False) - - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(data_store) - - with self._mock_get_datastore_calls(fake_objects): - self.assertRaises(exception.DatastoreNotFound, - ds_util.get_datastore, - self.session, 'fake-cluster') - - def test_get_datastore_ds_in_maintenance(self): - data_store = fake.Datastore() - data_store.set("summary.maintenanceMode", "inMaintenance") - - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(data_store) - - with self._mock_get_datastore_calls(fake_objects): - self.assertRaises(exception.DatastoreNotFound, - ds_util.get_datastore, - self.session, 'fake-cluster') - - def test_get_datastore_no_host_in_cluster(self): - def fake_call_method(module, method, *args, **kwargs): - return '' - - with mock.patch.object(self.session, '_call_method', - fake_call_method): - self.assertRaises(exception.DatastoreNotFound, - ds_util.get_datastore, - self.session, 'fake-cluster') - - def _test_is_datastore_valid(self, accessible=True, - maintenance_mode="normal", - type="VMFS", - datastore_regex=None): - propdict = {} - propdict["summary.accessible"] = accessible - propdict["summary.maintenanceMode"] = maintenance_mode - propdict["summary.type"] = type - propdict["summary.name"] = "ds-1" - - return ds_util._is_datastore_valid(propdict, datastore_regex) - - def test_is_datastore_valid(self): - for ds_type in ds_util.ALLOWED_DATASTORE_TYPES: - self.assertTrue(self._test_is_datastore_valid(True, - "normal", - ds_type)) - - def test_is_datastore_valid_inaccessible_ds(self): - self.assertFalse(self._test_is_datastore_valid(False, - "normal", - "VMFS")) - - def test_is_datastore_valid_ds_in_maintenance(self): - self.assertFalse(self._test_is_datastore_valid(True, - "inMaintenance", - "VMFS")) - - def test_is_datastore_valid_ds_type_invalid(self): - self.assertFalse(self._test_is_datastore_valid(True, - "normal", - "vfat")) - - def test_is_datastore_valid_not_matching_regex(self): - datastore_regex = re.compile("ds-2") - self.assertFalse(self._test_is_datastore_valid(True, - "normal", - "VMFS", - datastore_regex)) - - def test_is_datastore_valid_matching_regex(self): - datastore_regex = re.compile("ds-1") - self.assertTrue(self._test_is_datastore_valid(True, - "normal", - "VMFS", - datastore_regex)) - - -class DatastoreTestCase(test.NoDBTestCase): - def test_ds(self): - ds = ds_util.Datastore( - "fake_ref", "ds_name", 2 * units.Gi, 1 * units.Gi) - self.assertEqual('ds_name', ds.name) - self.assertEqual('fake_ref', ds.ref) - self.assertEqual(2 * units.Gi, ds.capacity) - self.assertEqual(1 * units.Gi, ds.freespace) - - def test_ds_invalid_space(self): - self.assertRaises(ValueError, ds_util.Datastore, - "fake_ref", "ds_name", 1 * units.Gi, 2 * units.Gi) - self.assertRaises(ValueError, ds_util.Datastore, - "fake_ref", "ds_name", None, 2 * units.Gi) - - def test_ds_no_capacity_no_freespace(self): - ds = ds_util.Datastore("fake_ref", "ds_name") - self.assertIsNone(ds.capacity) - self.assertIsNone(ds.freespace) - - def test_ds_invalid(self): - self.assertRaises(ValueError, ds_util.Datastore, None, "ds_name") - self.assertRaises(ValueError, ds_util.Datastore, "fake_ref", None) - - def test_build_path(self): - ds = ds_util.Datastore("fake_ref", "ds_name") - ds_path = ds.build_path("some_dir", "foo.vmdk") - self.assertEqual('[ds_name] some_dir/foo.vmdk', str(ds_path)) - - -class DatastorePathTestCase(test.NoDBTestCase): - - def test_ds_path(self): - p = ds_util.DatastorePath('dsname', 'a/b/c', 'file.iso') - self.assertEqual('[dsname] a/b/c/file.iso', str(p)) - self.assertEqual('a/b/c/file.iso', p.rel_path) - self.assertEqual('a/b/c', p.parent.rel_path) - self.assertEqual('[dsname] a/b/c', str(p.parent)) - self.assertEqual('dsname', p.datastore) - self.assertEqual('file.iso', p.basename) - self.assertEqual('a/b/c', p.dirname) - - def test_ds_path_no_ds_name(self): - bad_args = [ - ('', ['a/b/c', 'file.iso']), - (None, ['a/b/c', 'file.iso'])] - for t in bad_args: - self.assertRaises( - ValueError, ds_util.DatastorePath, - t[0], *t[1]) - - def test_ds_path_invalid_path_components(self): - bad_args = [ - ('dsname', [None]), - ('dsname', ['', None]), - ('dsname', ['a', None]), - ('dsname', ['a', None, 'b']), - ('dsname', [None, '']), - ('dsname', [None, 'b'])] - - for t in bad_args: - self.assertRaises( - ValueError, ds_util.DatastorePath, - t[0], *t[1]) - - def test_ds_path_no_subdir(self): - args = [ - ('dsname', ['', 'x.vmdk']), - ('dsname', ['x.vmdk'])] - - canonical_p = ds_util.DatastorePath('dsname', 'x.vmdk') - self.assertEqual('[dsname] x.vmdk', str(canonical_p)) - self.assertEqual('', canonical_p.dirname) - self.assertEqual('x.vmdk', canonical_p.basename) - self.assertEqual('x.vmdk', canonical_p.rel_path) - for t in args: - p = ds_util.DatastorePath(t[0], *t[1]) - self.assertEqual(str(canonical_p), str(p)) - - def test_ds_path_ds_only(self): - args = [ - ('dsname', []), - ('dsname', ['']), - ('dsname', ['', ''])] - - canonical_p = ds_util.DatastorePath('dsname') - self.assertEqual('[dsname]', str(canonical_p)) - self.assertEqual('', canonical_p.rel_path) - self.assertEqual('', canonical_p.basename) - self.assertEqual('', canonical_p.dirname) - for t in args: - p = ds_util.DatastorePath(t[0], *t[1]) - self.assertEqual(str(canonical_p), str(p)) - self.assertEqual(canonical_p.rel_path, p.rel_path) - - def test_ds_path_equivalence(self): - args = [ - ('dsname', ['a/b/c/', 'x.vmdk']), - ('dsname', ['a/', 'b/c/', 'x.vmdk']), - ('dsname', ['a', 'b', 'c', 'x.vmdk']), - ('dsname', ['a/b/c', 'x.vmdk'])] - - canonical_p = ds_util.DatastorePath('dsname', 'a/b/c', 'x.vmdk') - for t in args: - p = ds_util.DatastorePath(t[0], *t[1]) - self.assertEqual(str(canonical_p), str(p)) - self.assertEqual(canonical_p.datastore, p.datastore) - self.assertEqual(canonical_p.rel_path, p.rel_path) - self.assertEqual(str(canonical_p.parent), str(p.parent)) - - def test_ds_path_non_equivalence(self): - args = [ - # leading slash - ('dsname', ['/a', 'b', 'c', 'x.vmdk']), - ('dsname', ['/a/b/c/', 'x.vmdk']), - ('dsname', ['a/b/c', '/x.vmdk']), - # leading space - ('dsname', ['a/b/c/', ' x.vmdk']), - ('dsname', ['a/', ' b/c/', 'x.vmdk']), - ('dsname', [' a', 'b', 'c', 'x.vmdk']), - # trailing space - ('dsname', ['/a/b/c/', 'x.vmdk ']), - ('dsname', ['a/b/c/ ', 'x.vmdk'])] - - canonical_p = ds_util.DatastorePath('dsname', 'a/b/c', 'x.vmdk') - for t in args: - p = ds_util.DatastorePath(t[0], *t[1]) - self.assertNotEqual(str(canonical_p), str(p)) - - def test_ds_path_hashable(self): - ds1 = ds_util.DatastorePath('dsname', 'path') - ds2 = ds_util.DatastorePath('dsname', 'path') - - # If the above objects have the same hash, they will only be added to - # the set once - self.assertThat(set([ds1, ds2]), matchers.HasLength(1)) - - def test_equal(self): - a = ds_util.DatastorePath('ds_name', 'a') - b = ds_util.DatastorePath('ds_name', 'a') - self.assertEqual(a, b) - - def test_join(self): - p = ds_util.DatastorePath('ds_name', 'a') - ds_path = p.join('b') - self.assertEqual('[ds_name] a/b', str(ds_path)) - - p = ds_util.DatastorePath('ds_name', 'a') - ds_path = p.join() - self.assertEqual('[ds_name] a', str(ds_path)) - - bad_args = [ - [None], - ['', None], - ['a', None], - ['a', None, 'b']] - for arg in bad_args: - self.assertRaises(ValueError, p.join, *arg) - - def test_ds_path_parse(self): - p = ds_util.DatastorePath.parse('[dsname]') - self.assertEqual('dsname', p.datastore) - self.assertEqual('', p.rel_path) - - p = ds_util.DatastorePath.parse('[dsname] folder') - self.assertEqual('dsname', p.datastore) - self.assertEqual('folder', p.rel_path) - - p = ds_util.DatastorePath.parse('[dsname] folder/file') - self.assertEqual('dsname', p.datastore) - self.assertEqual('folder/file', p.rel_path) - - for p in [None, '']: - self.assertRaises(ValueError, ds_util.DatastorePath.parse, p) - - for p in ['bad path', '/a/b/c', 'a/b/c']: - self.assertRaises(IndexError, ds_util.DatastorePath.parse, p) diff --git a/nova/tests/virt/vmwareapi/test_ds_util_datastore_selection.py b/nova/tests/virt/vmwareapi/test_ds_util_datastore_selection.py deleted file mode 100644 index 1351530143..0000000000 --- a/nova/tests/virt/vmwareapi/test_ds_util_datastore_selection.py +++ /dev/null @@ -1,163 +0,0 @@ -# -# 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 collections -import re - -from oslo.utils import units - -from nova import test -from nova.virt.vmwareapi import ds_util - -ResultSet = collections.namedtuple('ResultSet', ['objects']) -ObjectContent = collections.namedtuple('ObjectContent', ['obj', 'propSet']) -DynamicProperty = collections.namedtuple('Property', ['name', 'val']) -MoRef = collections.namedtuple('ManagedObjectReference', ['value']) - - -class VMwareDSUtilDatastoreSelectionTestCase(test.NoDBTestCase): - - def setUp(self): - super(VMwareDSUtilDatastoreSelectionTestCase, self).setUp() - self.data = [ - ['VMFS', 'os-some-name', True, 'normal', 987654321, 12346789], - ['NFS', 'another-name', True, 'normal', 9876543210, 123467890], - ['BAD', 'some-name-bad', True, 'normal', 98765432100, 1234678900], - ['VMFS', 'some-name-good', False, 'normal', 987654321, 12346789], - ['VMFS', 'new-name', True, 'inMaintenance', 987654321, 12346789] - ] - - def build_result_set(self, mock_data, name_list=None): - # datastores will have a moref_id of ds-000 and - # so on based on their index in the mock_data list - if name_list is None: - name_list = self.propset_name_list - - objects = [] - for id, row in enumerate(mock_data): - obj = ObjectContent( - obj=MoRef(value="ds-%03d" % id), - propSet=[]) - for index, value in enumerate(row): - obj.propSet.append( - DynamicProperty(name=name_list[index], val=row[index])) - objects.append(obj) - return ResultSet(objects=objects) - - @property - def propset_name_list(self): - return ['summary.type', 'summary.name', 'summary.accessible', - 'summary.maintenanceMode', 'summary.capacity', - 'summary.freeSpace'] - - def test_filter_datastores_simple(self): - datastores = self.build_result_set(self.data) - best_match = ds_util.Datastore(ref='fake_ref', name='ds', - capacity=0, freespace=0) - rec = ds_util._select_datastore(datastores, best_match) - - self.assertIsNotNone(rec.ref, "could not find datastore!") - self.assertEqual('ds-001', rec.ref.value, - "didn't find the right datastore!") - self.assertEqual(123467890, rec.freespace, - "did not obtain correct freespace!") - - def test_filter_datastores_empty(self): - data = [] - datastores = self.build_result_set(data) - - best_match = ds_util.Datastore(ref='fake_ref', name='ds', - capacity=0, freespace=0) - rec = ds_util._select_datastore(datastores, best_match) - - self.assertEqual(rec, best_match) - - def test_filter_datastores_no_match(self): - datastores = self.build_result_set(self.data) - datastore_regex = re.compile('no_match.*') - - best_match = ds_util.Datastore(ref='fake_ref', name='ds', - capacity=0, freespace=0) - rec = ds_util._select_datastore(datastores, - best_match, - datastore_regex) - - self.assertEqual(rec, best_match, "did not match datastore properly") - - def test_filter_datastores_specific_match(self): - - data = [ - ['VMFS', 'os-some-name', True, 'normal', 987654321, 1234678], - ['NFS', 'another-name', True, 'normal', 9876543210, 123467890], - ['BAD', 'some-name-bad', True, 'normal', 98765432100, 1234678900], - ['VMFS', 'some-name-good', True, 'normal', 987654321, 12346789], - ['VMFS', 'some-other-good', False, 'normal', 987654321000, - 12346789000], - ['VMFS', 'new-name', True, 'inMaintenance', 987654321000, - 12346789000] - ] - # only the DS some-name-good is accessible and matches the regex - datastores = self.build_result_set(data) - datastore_regex = re.compile('.*-good$') - - best_match = ds_util.Datastore(ref='fake_ref', name='ds', - capacity=0, freespace=0) - rec = ds_util._select_datastore(datastores, - best_match, - datastore_regex) - - self.assertIsNotNone(rec, "could not find datastore!") - self.assertEqual('ds-003', rec.ref.value, - "didn't find the right datastore!") - self.assertNotEqual('ds-004', rec.ref.value, - "accepted an unreachable datastore!") - self.assertEqual('some-name-good', rec.name) - self.assertEqual(12346789, rec.freespace, - "did not obtain correct freespace!") - self.assertEqual(987654321, rec.capacity, - "did not obtain correct capacity!") - - def test_filter_datastores_missing_props(self): - data = [ - ['VMFS', 'os-some-name', 987654321, 1234678], - ['NFS', 'another-name', 9876543210, 123467890], - ] - # no matches are expected when 'summary.accessible' is missing - prop_names = ['summary.type', 'summary.name', - 'summary.capacity', 'summary.freeSpace'] - datastores = self.build_result_set(data, prop_names) - best_match = ds_util.Datastore(ref='fake_ref', name='ds', - capacity=0, freespace=0) - - rec = ds_util._select_datastore(datastores, best_match) - self.assertEqual(rec, best_match, "no matches were expected") - - def test_filter_datastores_best_match(self): - data = [ - ['VMFS', 'spam-good', True, 20 * units.Gi, 10 * units.Gi], - ['NFS', 'eggs-good', True, 40 * units.Gi, 15 * units.Gi], - ['BAD', 'some-name-bad', True, 30 * units.Gi, 20 * units.Gi], - ['VMFS', 'some-name-good', True, 50 * units.Gi, 5 * units.Gi], - ['VMFS', 'some-other-good', True, 10 * units.Gi, 10 * units.Gi], - ] - - datastores = self.build_result_set(data) - datastore_regex = re.compile('.*-good$') - - # the current best match is better than all candidates - best_match = ds_util.Datastore(ref='ds-100', name='best-ds-good', - capacity=20 * units.Gi, freespace=19 * units.Gi) - rec = ds_util._select_datastore(datastores, - best_match, - datastore_regex) - self.assertEqual(rec, best_match, "did not match datastore properly") diff --git a/nova/tests/virt/vmwareapi/test_imagecache.py b/nova/tests/virt/vmwareapi/test_imagecache.py deleted file mode 100644 index 9f4fa91376..0000000000 --- a/nova/tests/virt/vmwareapi/test_imagecache.py +++ /dev/null @@ -1,277 +0,0 @@ -# Copyright (c) 2014 VMware, 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 contextlib -import datetime - -import mock -from oslo.config import cfg -from oslo.utils import timeutils - -from nova import test -from nova.tests import fake_instance -from nova.tests.virt.vmwareapi import fake -from nova.virt.vmwareapi import ds_util -from nova.virt.vmwareapi import imagecache -from nova.virt.vmwareapi import vim_util -from nova.virt.vmwareapi import vmops - -CONF = cfg.CONF - - -class ImageCacheManagerTestCase(test.NoDBTestCase): - - REQUIRES_LOCKING = True - - def setUp(self): - super(ImageCacheManagerTestCase, self).setUp() - self._session = mock.Mock(name='session') - self._imagecache = imagecache.ImageCacheManager(self._session, - 'fake-base-folder') - self._time = datetime.datetime(2012, 11, 22, 12, 00, 00) - self._file_name = 'ts-2012-11-22-12-00-00' - fake.reset() - - def tearDown(self): - super(ImageCacheManagerTestCase, self).tearDown() - fake.reset() - - def test_timestamp_cleanup(self): - def fake_get_timestamp(ds_browser, ds_path): - self.assertEqual('fake-ds-browser', ds_browser) - self.assertEqual('[fake-ds] fake-path', str(ds_path)) - if not self.exists: - return - ts = '%s%s' % (imagecache.TIMESTAMP_PREFIX, - timeutils.strtime(at=self._time, - fmt=imagecache.TIMESTAMP_FORMAT)) - return ts - - with contextlib.nested( - mock.patch.object(self._imagecache, '_get_timestamp', - fake_get_timestamp), - mock.patch.object(ds_util, 'file_delete') - ) as (_get_timestamp, _file_delete): - self.exists = False - self._imagecache.timestamp_cleanup( - 'fake-dc-ref', 'fake-ds-browser', - ds_util.DatastorePath('fake-ds', 'fake-path')) - self.assertEqual(0, _file_delete.call_count) - self.exists = True - self._imagecache.timestamp_cleanup( - 'fake-dc-ref', 'fake-ds-browser', - ds_util.DatastorePath('fake-ds', 'fake-path')) - expected_ds_path = ds_util.DatastorePath( - 'fake-ds', 'fake-path', self._file_name) - _file_delete.assert_called_once_with(self._session, - expected_ds_path, 'fake-dc-ref') - - def test_get_timestamp(self): - def fake_get_sub_folders(session, ds_browser, ds_path): - self.assertEqual('fake-ds-browser', ds_browser) - self.assertEqual('[fake-ds] fake-path', str(ds_path)) - if self.exists: - files = set() - files.add(self._file_name) - return files - - with contextlib.nested( - mock.patch.object(ds_util, 'get_sub_folders', - fake_get_sub_folders) - ): - self.exists = True - ts = self._imagecache._get_timestamp( - 'fake-ds-browser', - ds_util.DatastorePath('fake-ds', 'fake-path')) - self.assertEqual(self._file_name, ts) - self.exists = False - ts = self._imagecache._get_timestamp( - 'fake-ds-browser', - ds_util.DatastorePath('fake-ds', 'fake-path')) - self.assertIsNone(ts) - - def test_get_timestamp_filename(self): - timeutils.set_time_override(override_time=self._time) - fn = self._imagecache._get_timestamp_filename() - self.assertEqual(self._file_name, fn) - - def test_get_datetime_from_filename(self): - t = self._imagecache._get_datetime_from_filename(self._file_name) - self.assertEqual(self._time, t) - - def test_get_ds_browser(self): - cache = self._imagecache._ds_browser - ds_browser = mock.Mock() - moref = fake.ManagedObjectReference('datastore-100') - self.assertIsNone(cache.get(moref.value)) - mock_get_method = mock.Mock(return_value=ds_browser) - with mock.patch.object(vim_util, 'get_dynamic_property', - mock_get_method): - ret = self._imagecache._get_ds_browser(moref) - mock_get_method.assert_called_once_with(mock.ANY, moref, - 'Datastore', 'browser') - self.assertIs(ds_browser, ret) - self.assertIs(ds_browser, cache.get(moref.value)) - - def test_list_base_images(self): - def fake_get_dynamic_property(vim, mobj, type, property_name): - return 'fake-ds-browser' - - def fake_get_sub_folders(session, ds_browser, ds_path): - files = set() - files.add('image-ref-uuid') - return files - - with contextlib.nested( - mock.patch.object(vim_util, 'get_dynamic_property', - fake_get_dynamic_property), - mock.patch.object(ds_util, 'get_sub_folders', - fake_get_sub_folders) - ) as (_get_dynamic, _get_sub_folders): - fake_ds_ref = fake.ManagedObjectReference('fake-ds-ref') - datastore = ds_util.Datastore(name='ds', ref=fake_ds_ref) - ds_path = datastore.build_path('base_folder') - images = self._imagecache._list_datastore_images( - ds_path, datastore) - originals = set() - originals.add('image-ref-uuid') - self.assertEqual({'originals': originals, - 'unexplained_images': []}, - images) - - @mock.patch.object(imagecache.ImageCacheManager, 'timestamp_folder_get') - @mock.patch.object(imagecache.ImageCacheManager, 'timestamp_cleanup') - @mock.patch.object(imagecache.ImageCacheManager, '_get_ds_browser') - def test_enlist_image(self, - mock_get_ds_browser, - mock_timestamp_cleanup, - mock_timestamp_folder_get): - image_id = "fake_image_id" - dc_ref = "fake_dc_ref" - fake_ds_ref = mock.Mock() - ds = ds_util.Datastore( - ref=fake_ds_ref, name='fake_ds', - capacity=1, - freespace=1) - - ds_browser = mock.Mock() - mock_get_ds_browser.return_value = ds_browser - timestamp_folder_path = mock.Mock() - mock_timestamp_folder_get.return_value = timestamp_folder_path - - self._imagecache.enlist_image(image_id, ds, dc_ref) - - cache_root_folder = ds.build_path("fake-base-folder") - mock_get_ds_browser.assert_called_once_with( - ds.ref) - mock_timestamp_folder_get.assert_called_once_with( - cache_root_folder, "fake_image_id") - mock_timestamp_cleanup.assert_called_once_with( - dc_ref, ds_browser, timestamp_folder_path) - - def test_age_cached_images(self): - def fake_get_ds_browser(ds_ref): - return 'fake-ds-browser' - - def fake_get_timestamp(ds_browser, ds_path): - self._get_timestamp_called += 1 - path = str(ds_path) - if path == '[fake-ds] fake-path/fake-image-1': - # No time stamp exists - return - if path == '[fake-ds] fake-path/fake-image-2': - # Timestamp that will be valid => no deletion - return 'ts-2012-11-22-10-00-00' - if path == '[fake-ds] fake-path/fake-image-3': - # Timestamp that will be invalid => deletion - return 'ts-2012-11-20-12-00-00' - self.fail() - - def fake_mkdir(session, ts_path, dc_ref): - self.assertEqual( - '[fake-ds] fake-path/fake-image-1/ts-2012-11-22-12-00-00', - str(ts_path)) - - def fake_file_delete(session, ds_path, dc_ref): - self.assertEqual('[fake-ds] fake-path/fake-image-3', str(ds_path)) - - def fake_timestamp_cleanup(dc_ref, ds_browser, ds_path): - self.assertEqual('[fake-ds] fake-path/fake-image-4', str(ds_path)) - - with contextlib.nested( - mock.patch.object(self._imagecache, '_get_ds_browser', - fake_get_ds_browser), - mock.patch.object(self._imagecache, '_get_timestamp', - fake_get_timestamp), - mock.patch.object(ds_util, 'mkdir', - fake_mkdir), - mock.patch.object(ds_util, 'file_delete', - fake_file_delete), - mock.patch.object(self._imagecache, 'timestamp_cleanup', - fake_timestamp_cleanup), - ) as (_get_ds_browser, _get_timestamp, _mkdir, _file_delete, - _timestamp_cleanup): - timeutils.set_time_override(override_time=self._time) - datastore = ds_util.Datastore(name='ds', ref='fake-ds-ref') - dc_info = vmops.DcInfo(ref='dc_ref', name='name', - vmFolder='vmFolder') - self._get_timestamp_called = 0 - self._imagecache.originals = set(['fake-image-1', 'fake-image-2', - 'fake-image-3', 'fake-image-4']) - self._imagecache.used_images = set(['fake-image-4']) - self._imagecache._age_cached_images( - 'fake-context', datastore, dc_info, - ds_util.DatastorePath('fake-ds', 'fake-path')) - self.assertEqual(3, self._get_timestamp_called) - - def test_update(self): - def fake_list_datastore_images(ds_path, datastore): - return {'unexplained_images': [], - 'originals': self.images} - - def fake_age_cached_images(context, datastore, - dc_info, ds_path): - self.assertEqual('[ds] fake-base-folder', str(ds_path)) - self.assertEqual(self.images, - self._imagecache.used_images) - self.assertEqual(self.images, - self._imagecache.originals) - - with contextlib.nested( - mock.patch.object(self._imagecache, '_list_datastore_images', - fake_list_datastore_images), - mock.patch.object(self._imagecache, - '_age_cached_images', - fake_age_cached_images) - ) as (_list_base, _age_and_verify): - instances = [{'image_ref': '1', - 'host': CONF.host, - 'name': 'inst-1', - 'uuid': '123', - 'vm_state': '', - 'task_state': ''}, - {'image_ref': '2', - 'host': CONF.host, - 'name': 'inst-2', - 'uuid': '456', - 'vm_state': '', - 'task_state': ''}] - all_instances = [fake_instance.fake_instance_obj(None, **instance) - for instance in instances] - self.images = set(['1', '2']) - datastore = ds_util.Datastore(name='ds', ref='fake-ds-ref') - dc_info = vmops.DcInfo(ref='dc_ref', name='name', - vmFolder='vmFolder') - datastores_info = [(datastore, dc_info)] - self._imagecache.update('context', all_instances, datastores_info) diff --git a/nova/tests/virt/vmwareapi/test_images.py b/nova/tests/virt/vmwareapi/test_images.py deleted file mode 100644 index 613705cf78..0000000000 --- a/nova/tests/virt/vmwareapi/test_images.py +++ /dev/null @@ -1,216 +0,0 @@ -# Copyright (c) 2014 VMware, 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. - -""" -Test suite for images. -""" - -import contextlib - -import mock -from oslo.utils import units - -from nova import exception -from nova import test -import nova.tests.image.fake -from nova.virt.vmwareapi import constants -from nova.virt.vmwareapi import images -from nova.virt.vmwareapi import read_write_util - - -class VMwareImagesTestCase(test.NoDBTestCase): - """Unit tests for Vmware API connection calls.""" - - def test_fetch_image(self): - """Test fetching images.""" - - dc_name = 'fake-dc' - file_path = 'fake_file' - ds_name = 'ds1' - host = mock.MagicMock() - context = mock.MagicMock() - - image_data = { - 'id': nova.tests.image.fake.get_valid_image_id(), - 'disk_format': 'vmdk', - 'size': 512, - } - read_file_handle = mock.MagicMock() - write_file_handle = mock.MagicMock() - read_iter = mock.MagicMock() - instance = {} - instance['image_ref'] = image_data['id'] - instance['uuid'] = 'fake-uuid' - - def fake_read_handle(read_iter): - return read_file_handle - - def fake_write_handle(host, dc_name, ds_name, cookies, - file_path, file_size): - return write_file_handle - - with contextlib.nested( - mock.patch.object(read_write_util, 'GlanceFileRead', - side_effect=fake_read_handle), - mock.patch.object(read_write_util, 'VMwareHTTPWriteFile', - side_effect=fake_write_handle), - mock.patch.object(images, 'start_transfer'), - mock.patch.object(images.IMAGE_API, 'get', - return_value=image_data), - mock.patch.object(images.IMAGE_API, 'download', - return_value=read_iter), - ) as (glance_read, http_write, start_transfer, image_show, - image_download): - images.fetch_image(context, instance, - host, dc_name, - ds_name, file_path) - - glance_read.assert_called_once_with(read_iter) - http_write.assert_called_once_with(host, dc_name, ds_name, None, - file_path, image_data['size']) - start_transfer.assert_called_once_with( - context, read_file_handle, - image_data['size'], - write_file_handle=write_file_handle) - image_download.assert_called_once_with(context, instance['image_ref']) - image_show.assert_called_once_with(context, instance['image_ref']) - - def _setup_mock_get_remote_image_service(self, - mock_get_remote_image_service, - metadata): - mock_image_service = mock.MagicMock() - mock_image_service.show.return_value = metadata - mock_get_remote_image_service.return_value = [mock_image_service, 'i'] - - def test_from_image_with_image_ref(self): - raw_disk_size_in_gb = 83 - raw_disk_size_in_bytes = raw_disk_size_in_gb * units.Gi - image_id = nova.tests.image.fake.get_valid_image_id() - mdata = {'size': raw_disk_size_in_bytes, - 'disk_format': 'vmdk', - 'properties': { - "vmware_ostype": constants.DEFAULT_OS_TYPE, - "vmware_adaptertype": constants.DEFAULT_ADAPTER_TYPE, - "vmware_disktype": constants.DEFAULT_DISK_TYPE, - "hw_vif_model": constants.DEFAULT_VIF_MODEL, - images.LINKED_CLONE_PROPERTY: True}} - - img_props = images.VMwareImage.from_image(image_id, mdata) - - image_size_in_kb = raw_disk_size_in_bytes / units.Ki - - # assert that defaults are set and no value returned is left empty - self.assertEqual(constants.DEFAULT_OS_TYPE, img_props.os_type) - self.assertEqual(constants.DEFAULT_ADAPTER_TYPE, - img_props.adapter_type) - self.assertEqual(constants.DEFAULT_DISK_TYPE, img_props.disk_type) - self.assertEqual(constants.DEFAULT_VIF_MODEL, img_props.vif_model) - self.assertTrue(img_props.linked_clone) - self.assertEqual(image_size_in_kb, img_props.file_size_in_kb) - - def _image_build(self, image_lc_setting, global_lc_setting, - disk_format=constants.DEFAULT_DISK_FORMAT, - os_type=constants.DEFAULT_OS_TYPE, - adapter_type=constants.DEFAULT_ADAPTER_TYPE, - disk_type=constants.DEFAULT_DISK_TYPE, - vif_model=constants.DEFAULT_VIF_MODEL): - self.flags(use_linked_clone=global_lc_setting, group='vmware') - raw_disk_size_in_gb = 93 - raw_disk_size_in_btyes = raw_disk_size_in_gb * units.Gi - - image_id = nova.tests.image.fake.get_valid_image_id() - mdata = {'size': raw_disk_size_in_btyes, - 'disk_format': disk_format, - 'properties': { - "vmware_ostype": os_type, - "vmware_adaptertype": adapter_type, - "vmware_disktype": disk_type, - "hw_vif_model": vif_model}} - - if image_lc_setting is not None: - mdata['properties'][ - images.LINKED_CLONE_PROPERTY] = image_lc_setting - - return images.VMwareImage.from_image(image_id, mdata) - - def test_use_linked_clone_override_nf(self): - image_props = self._image_build(None, False) - self.assertFalse(image_props.linked_clone, - "No overrides present but still overridden!") - - def test_use_linked_clone_override_nt(self): - image_props = self._image_build(None, True) - self.assertTrue(image_props.linked_clone, - "No overrides present but still overridden!") - - def test_use_linked_clone_override_ny(self): - image_props = self._image_build(None, "yes") - self.assertTrue(image_props.linked_clone, - "No overrides present but still overridden!") - - def test_use_linked_clone_override_ft(self): - image_props = self._image_build(False, True) - self.assertFalse(image_props.linked_clone, - "image level metadata failed to override global") - - def test_use_linked_clone_override_string_nt(self): - image_props = self._image_build("no", True) - self.assertFalse(image_props.linked_clone, - "image level metadata failed to override global") - - def test_use_linked_clone_override_string_yf(self): - image_props = self._image_build("yes", False) - self.assertTrue(image_props.linked_clone, - "image level metadata failed to override global") - - def test_use_disk_format_none(self): - image = self._image_build(None, True, disk_format=None) - self.assertIsNone(image.file_type) - self.assertFalse(image.is_iso) - - def test_use_disk_format_iso(self): - image = self._image_build(None, True, disk_format='iso') - self.assertEqual('iso', image.file_type) - self.assertTrue(image.is_iso) - - def test_use_bad_disk_format(self): - self.assertRaises(exception.InvalidDiskFormat, - self._image_build, - None, - True, - disk_format='bad_disk_format') - - def test_image_no_defaults(self): - image = self._image_build(False, False, - disk_format='iso', - os_type='fake-os-type', - adapter_type='fake-adapter-type', - disk_type='fake-disk-type', - vif_model='fake-vif-model') - self.assertEqual('iso', image.file_type) - self.assertEqual('fake-os-type', image.os_type) - self.assertEqual('fake-adapter-type', image.adapter_type) - self.assertEqual('fake-disk-type', image.disk_type) - self.assertEqual('fake-vif-model', image.vif_model) - self.assertFalse(image.linked_clone) - - def test_image_defaults(self): - image = images.VMwareImage(image_id='fake-image-id') - - # N.B. We intentially don't use the defined constants here. Amongst - # other potential failures, we're interested in changes to their - # values, which would not otherwise be picked up. - self.assertEqual('otherGuest', image.os_type) - self.assertEqual('lsiLogic', image.adapter_type) - self.assertEqual('preallocated', image.disk_type) - self.assertEqual('e1000', image.vif_model) diff --git a/nova/tests/virt/vmwareapi/test_io_util.py b/nova/tests/virt/vmwareapi/test_io_util.py deleted file mode 100644 index a03c1e95b5..0000000000 --- a/nova/tests/virt/vmwareapi/test_io_util.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (c) 2014 VMware, 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 mock - -from nova import exception -from nova import test -from nova.virt.vmwareapi import io_util - - -@mock.patch.object(io_util, 'IMAGE_API') -class GlanceWriteThreadTestCase(test.NoDBTestCase): - - def test_start_image_update_service_exception(self, mocked): - mocked.update.side_effect = exception.ImageNotAuthorized( - image_id='image') - write_thread = io_util.GlanceWriteThread( - None, None, image_id=None) - write_thread.start() - self.assertRaises(exception.ImageNotAuthorized, write_thread.wait) - write_thread.stop() - write_thread.close() diff --git a/nova/tests/virt/vmwareapi/test_read_write_util.py b/nova/tests/virt/vmwareapi/test_read_write_util.py deleted file mode 100644 index 468d8b213a..0000000000 --- a/nova/tests/virt/vmwareapi/test_read_write_util.py +++ /dev/null @@ -1,39 +0,0 @@ -# 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 httplib - -from oslo.config import cfg - -from nova import test -from nova.virt.vmwareapi import read_write_util - -CONF = cfg.CONF - - -class ReadWriteUtilTestCase(test.NoDBTestCase): - def test_ipv6_host(self): - ipv6_host = 'fd8c:215d:178e:c51e:200:c9ff:fed1:584c' - self.mox.StubOutWithMock(httplib.HTTPConnection, 'endheaders') - httplib.HTTPConnection.endheaders() - self.mox.ReplayAll() - file = read_write_util.VMwareHTTPWriteFile(ipv6_host, - 'fake_dc', - 'fake_ds', - dict(), - '/tmp/fake.txt', - 0) - self.assertEqual(ipv6_host, file.conn.host) - self.assertEqual(443, file.conn.port) diff --git a/nova/tests/virt/vmwareapi/test_vif.py b/nova/tests/virt/vmwareapi/test_vif.py deleted file mode 100644 index 3e446e5e7d..0000000000 --- a/nova/tests/virt/vmwareapi/test_vif.py +++ /dev/null @@ -1,346 +0,0 @@ -# Copyright 2013 Canonical Corp. -# All Rights Reserved. -# -# 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 contextlib - -import mock -from oslo.config import cfg -from oslo.vmware import exceptions as vexc - -from nova import exception -from nova.network import model as network_model -from nova import test -from nova.tests import matchers -from nova.tests import utils -from nova.tests.virt.vmwareapi import fake -from nova.virt.vmwareapi import network_util -from nova.virt.vmwareapi import vif -from nova.virt.vmwareapi import vim_util -from nova.virt.vmwareapi import vm_util - -CONF = cfg.CONF - - -class VMwareVifTestCase(test.NoDBTestCase): - def setUp(self): - super(VMwareVifTestCase, self).setUp() - self.flags(vlan_interface='vmnet0', group='vmware') - network = network_model.Network(id=0, - bridge='fa0', - label='fake', - vlan=3, - bridge_interface='eth0', - injected=True) - - self.vif = network_model.NetworkInfo([ - network_model.VIF(id=None, - address='DE:AD:BE:EF:00:00', - network=network, - type=None, - devname=None, - ovs_interfaceid=None, - rxtx_cap=3) - ])[0] - self.session = fake.FakeSession() - self.cluster = None - - def tearDown(self): - super(VMwareVifTestCase, self).tearDown() - - def test_ensure_vlan_bridge(self): - self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') - self.mox.StubOutWithMock(network_util, - 'get_vswitch_for_vlan_interface') - self.mox.StubOutWithMock(network_util, - 'check_if_vlan_interface_exists') - self.mox.StubOutWithMock(network_util, 'create_port_group') - network_util.get_network_with_the_name(self.session, 'fa0', - self.cluster).AndReturn(None) - network_util.get_vswitch_for_vlan_interface(self.session, 'vmnet0', - self.cluster).AndReturn('vmnet0') - network_util.check_if_vlan_interface_exists(self.session, 'vmnet0', - self.cluster).AndReturn(True) - network_util.create_port_group(self.session, 'fa0', 'vmnet0', 3, - self.cluster) - network_util.get_network_with_the_name(self.session, 'fa0', None) - - self.mox.ReplayAll() - vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=True) - - # FlatDHCP network mode without vlan - network doesn't exist with the host - def test_ensure_vlan_bridge_without_vlan(self): - self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') - self.mox.StubOutWithMock(network_util, - 'get_vswitch_for_vlan_interface') - self.mox.StubOutWithMock(network_util, - 'check_if_vlan_interface_exists') - self.mox.StubOutWithMock(network_util, 'create_port_group') - - network_util.get_network_with_the_name(self.session, 'fa0', - self.cluster).AndReturn(None) - network_util.get_vswitch_for_vlan_interface(self.session, 'vmnet0', - self.cluster).AndReturn('vmnet0') - network_util.check_if_vlan_interface_exists(self.session, 'vmnet0', - self.cluster).AndReturn(True) - network_util.create_port_group(self.session, 'fa0', 'vmnet0', 0, - self.cluster) - network_util.get_network_with_the_name(self.session, 'fa0', None) - self.mox.ReplayAll() - vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=False) - - # FlatDHCP network mode without vlan - network exists with the host - # Get vswitch and check vlan interface should not be called - def test_ensure_vlan_bridge_with_network(self): - self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') - self.mox.StubOutWithMock(network_util, - 'get_vswitch_for_vlan_interface') - self.mox.StubOutWithMock(network_util, - 'check_if_vlan_interface_exists') - self.mox.StubOutWithMock(network_util, 'create_port_group') - vm_network = {'name': 'VM Network', 'type': 'Network'} - network_util.get_network_with_the_name(self.session, 'fa0', - self.cluster).AndReturn(vm_network) - self.mox.ReplayAll() - vif.ensure_vlan_bridge(self.session, self.vif, create_vlan=False) - - # Flat network mode with DVS - def test_ensure_vlan_bridge_with_existing_dvs(self): - network_ref = {'dvpg': 'dvportgroup-2062', - 'type': 'DistributedVirtualPortgroup'} - self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') - self.mox.StubOutWithMock(network_util, - 'get_vswitch_for_vlan_interface') - self.mox.StubOutWithMock(network_util, - 'check_if_vlan_interface_exists') - self.mox.StubOutWithMock(network_util, 'create_port_group') - - network_util.get_network_with_the_name(self.session, 'fa0', - self.cluster).AndReturn(network_ref) - self.mox.ReplayAll() - ref = vif.ensure_vlan_bridge(self.session, - self.vif, - create_vlan=False) - self.assertThat(ref, matchers.DictMatches(network_ref)) - - def test_get_network_ref_neutron(self): - self.mox.StubOutWithMock(vif, 'get_neutron_network') - vif.get_neutron_network(self.session, 'fa0', self.cluster, self.vif) - self.mox.ReplayAll() - vif.get_network_ref(self.session, self.cluster, self.vif, True) - - def test_get_network_ref_flat_dhcp(self): - self.mox.StubOutWithMock(vif, 'ensure_vlan_bridge') - vif.ensure_vlan_bridge(self.session, self.vif, cluster=self.cluster, - create_vlan=False) - self.mox.ReplayAll() - vif.get_network_ref(self.session, self.cluster, self.vif, False) - - def test_get_network_ref_bridge(self): - self.mox.StubOutWithMock(vif, 'ensure_vlan_bridge') - vif.ensure_vlan_bridge(self.session, self.vif, cluster=self.cluster, - create_vlan=True) - self.mox.ReplayAll() - network = network_model.Network(id=0, - bridge='fa0', - label='fake', - vlan=3, - bridge_interface='eth0', - injected=True, - should_create_vlan=True) - self.vif = network_model.NetworkInfo([ - network_model.VIF(id=None, - address='DE:AD:BE:EF:00:00', - network=network, - type=None, - devname=None, - ovs_interfaceid=None, - rxtx_cap=3) - ])[0] - vif.get_network_ref(self.session, self.cluster, self.vif, False) - - def test_get_network_ref_bridge_from_opaque(self): - opaque_networks = [{'opaqueNetworkId': 'bridge_id', - 'opaqueNetworkName': 'name', - 'opaqueNetworkType': 'OpaqueNetwork'}] - network_ref = vif._get_network_ref_from_opaque(opaque_networks, - 'integration_bridge', 'bridge_id') - self.assertEqual('bridge_id', network_ref['network-id']) - - def test_get_network_ref_multiple_bridges_from_opaque(self): - opaque_networks = [{'opaqueNetworkId': 'bridge_id1', - 'opaqueNetworkName': 'name1', - 'opaqueNetworkType': 'OpaqueNetwork'}, - {'opaqueNetworkId': 'bridge_id2', - 'opaqueNetworkName': 'name2', - 'opaqueNetworkType': 'OpaqueNetwork'}] - network_ref = vif._get_network_ref_from_opaque(opaque_networks, - 'integration_bridge', 'bridge_id2') - self.assertEqual('bridge_id2', network_ref['network-id']) - - def test_get_network_ref_integration(self): - opaque_networks = [{'opaqueNetworkId': 'integration_bridge', - 'opaqueNetworkName': 'name', - 'opaqueNetworkType': 'OpaqueNetwork'}] - network_ref = vif._get_network_ref_from_opaque(opaque_networks, - 'integration_bridge', 'bridge_id') - self.assertEqual('integration_bridge', network_ref['network-id']) - - def test_get_network_ref_bridge_none(self): - opaque_networks = [{'opaqueNetworkId': 'bridge_id1', - 'opaqueNetworkName': 'name1', - 'opaqueNetworkType': 'OpaqueNetwork'}, - {'opaqueNetworkId': 'bridge_id2', - 'opaqueNetworkName': 'name2', - 'opaqueNetworkType': 'OpaqueNetwork'}] - network_ref = vif._get_network_ref_from_opaque(opaque_networks, - 'integration_bridge', 'bridge_id') - self.assertIsNone(network_ref) - - def test_get_network_ref_integration_multiple(self): - opaque_networks = [{'opaqueNetworkId': 'bridge_id1', - 'opaqueNetworkName': 'name1', - 'opaqueNetworkType': 'OpaqueNetwork'}, - {'opaqueNetworkId': 'integration_bridge', - 'opaqueNetworkName': 'name2', - 'opaqueNetworkType': 'OpaqueNetwork'}] - network_ref = vif._get_network_ref_from_opaque(opaque_networks, - 'integration_bridge', 'bridge_id') - self.assertIsNone(network_ref) - - def test_get_neutron_network(self): - self.mox.StubOutWithMock(vm_util, 'get_host_ref') - self.mox.StubOutWithMock(self.session, '_call_method') - self.mox.StubOutWithMock(vif, '_get_network_ref_from_opaque') - vm_util.get_host_ref(self.session, - self.cluster).AndReturn('fake-host') - opaque = fake.DataObject() - opaque.HostOpaqueNetworkInfo = ['fake-network-info'] - self.session._call_method(vim_util, "get_dynamic_property", - 'fake-host', 'HostSystem', - 'config.network.opaqueNetwork').AndReturn(opaque) - vif._get_network_ref_from_opaque(opaque.HostOpaqueNetworkInfo, - CONF.vmware.integration_bridge, - self.vif['network']['id']).AndReturn('fake-network-ref') - self.mox.ReplayAll() - network_ref = vif.get_neutron_network(self.session, - self.vif['network']['id'], - self.cluster, - self.vif) - self.assertEqual(network_ref, 'fake-network-ref') - - def test_get_neutron_network_opaque_network_not_found(self): - self.mox.StubOutWithMock(vm_util, 'get_host_ref') - self.mox.StubOutWithMock(self.session, '_call_method') - self.mox.StubOutWithMock(vif, '_get_network_ref_from_opaque') - vm_util.get_host_ref(self.session, - self.cluster).AndReturn('fake-host') - opaque = fake.DataObject() - opaque.HostOpaqueNetworkInfo = ['fake-network-info'] - self.session._call_method(vim_util, "get_dynamic_property", - 'fake-host', 'HostSystem', - 'config.network.opaqueNetwork').AndReturn(opaque) - vif._get_network_ref_from_opaque(opaque.HostOpaqueNetworkInfo, - CONF.vmware.integration_bridge, - self.vif['network']['id']).AndReturn(None) - self.mox.ReplayAll() - self.assertRaises(exception.NetworkNotFoundForBridge, - vif.get_neutron_network, self.session, - self.vif['network']['id'], self.cluster, self.vif) - - def test_get_neutron_network_bridge_network_not_found(self): - self.mox.StubOutWithMock(vm_util, 'get_host_ref') - self.mox.StubOutWithMock(self.session, '_call_method') - self.mox.StubOutWithMock(network_util, 'get_network_with_the_name') - vm_util.get_host_ref(self.session, - self.cluster).AndReturn('fake-host') - opaque = fake.DataObject() - opaque.HostOpaqueNetworkInfo = ['fake-network-info'] - self.session._call_method(vim_util, "get_dynamic_property", - 'fake-host', 'HostSystem', - 'config.network.opaqueNetwork').AndReturn(None) - network_util.get_network_with_the_name(self.session, 0, - self.cluster).AndReturn(None) - self.mox.ReplayAll() - self.assertRaises(exception.NetworkNotFoundForBridge, - vif.get_neutron_network, self.session, - self.vif['network']['id'], self.cluster, self.vif) - - def test_create_port_group_already_exists(self): - def fake_call_method(module, method, *args, **kwargs): - if method == 'AddPortGroup': - raise vexc.AlreadyExistsException() - - with contextlib.nested( - mock.patch.object(vm_util, 'get_add_vswitch_port_group_spec'), - mock.patch.object(vm_util, 'get_host_ref'), - mock.patch.object(self.session, '_call_method', - fake_call_method) - ) as (_add_vswitch, _get_host, _call_method): - network_util.create_port_group(self.session, 'pg_name', - 'vswitch_name', vlan_id=0, - cluster=None) - - def test_create_port_group_exception(self): - def fake_call_method(module, method, *args, **kwargs): - if method == 'AddPortGroup': - raise vexc.VMwareDriverException() - - with contextlib.nested( - mock.patch.object(vm_util, 'get_add_vswitch_port_group_spec'), - mock.patch.object(vm_util, 'get_host_ref'), - mock.patch.object(self.session, '_call_method', - fake_call_method) - ) as (_add_vswitch, _get_host, _call_method): - self.assertRaises(vexc.VMwareDriverException, - network_util.create_port_group, - self.session, 'pg_name', - 'vswitch_name', vlan_id=0, - cluster=None) - - def test_get_neutron_network_invalid_property(self): - def fake_call_method(module, method, *args, **kwargs): - if method == 'get_dynamic_property': - raise vexc.InvalidPropertyException() - - with contextlib.nested( - mock.patch.object(vm_util, 'get_host_ref'), - mock.patch.object(self.session, '_call_method', - fake_call_method), - mock.patch.object(network_util, 'get_network_with_the_name') - ) as (_get_host, _call_method, _get_name): - vif.get_neutron_network(self.session, 'network_name', - 'cluster', self.vif) - - def test_get_vif_info_none(self): - vif_info = vif.get_vif_info('fake_session', 'fake_cluster', - 'is_neutron', 'fake_model', None) - self.assertEqual([], vif_info) - - def test_get_vif_info_empty_list(self): - vif_info = vif.get_vif_info('fake_session', 'fake_cluster', - 'is_neutron', 'fake_model', []) - self.assertEqual([], vif_info) - - @mock.patch.object(vif, 'get_network_ref', return_value='fake_ref') - def test_get_vif_info(self, mock_get_network_ref): - network_info = utils.get_test_network_info() - vif_info = vif.get_vif_info('fake_session', 'fake_cluster', - 'is_neutron', 'fake_model', network_info) - expected = [{'iface_id': 'vif-xxx-yyy-zzz', - 'mac_address': 'fake', - 'network_name': 'fake', - 'network_ref': 'fake_ref', - 'vif_model': 'fake_model'}] - self.assertEqual(expected, vif_info) diff --git a/nova/tests/virt/vmwareapi/test_vim_util.py b/nova/tests/virt/vmwareapi/test_vim_util.py deleted file mode 100644 index 0eb9a096f3..0000000000 --- a/nova/tests/virt/vmwareapi/test_vim_util.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright (c) 2013 VMware, 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 collections - -import fixtures -import mock - -from nova import test -from nova.tests.virt.vmwareapi import fake -from nova.tests.virt.vmwareapi import stubs -from nova.virt.vmwareapi import driver -from nova.virt.vmwareapi import vim_util - - -def _fake_get_object_properties(vim, collector, mobj, - type, properties): - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(fake.ObjectContent(None)) - return fake_objects - - -def _fake_get_object_properties_missing(vim, collector, mobj, - type, properties): - fake_objects = fake.FakeRetrieveResult() - ml = [fake.MissingProperty()] - fake_objects.add_object(fake.ObjectContent(None, missing_list=ml)) - return fake_objects - - -class VMwareVIMUtilTestCase(test.NoDBTestCase): - - def setUp(self): - super(VMwareVIMUtilTestCase, self).setUp() - fake.reset() - self.vim = fake.FakeVim() - self.vim._login() - - def test_get_dynamic_properties_missing(self): - self.useFixture(fixtures.MonkeyPatch( - 'nova.virt.vmwareapi.vim_util.get_object_properties', - _fake_get_object_properties)) - res = vim_util.get_dynamic_property('fake-vim', 'fake-obj', - 'fake-type', 'fake-property') - self.assertIsNone(res) - - def test_get_dynamic_properties_missing_path_exists(self): - self.useFixture(fixtures.MonkeyPatch( - 'nova.virt.vmwareapi.vim_util.get_object_properties', - _fake_get_object_properties_missing)) - res = vim_util.get_dynamic_property('fake-vim', 'fake-obj', - 'fake-type', 'fake-property') - self.assertIsNone(res) - - def test_get_dynamic_properties_with_token(self): - ObjectContent = collections.namedtuple('ObjectContent', ['propSet']) - DynamicProperty = collections.namedtuple('Property', ['name', 'val']) - - # Add a token to our results, indicating that more are available - result = fake.FakeRetrieveResult(token='fake_token') - - # We expect these properties to be returned - result.add_object(ObjectContent(propSet=[ - DynamicProperty(name='name1', val='value1'), - DynamicProperty(name='name2', val='value2') - ])) - - # These properties should be ignored - result.add_object(ObjectContent(propSet=[ - DynamicProperty(name='name3', val='value3') - ])) - - retrievePropertiesEx = mock.MagicMock(name='RetrievePropertiesEx') - retrievePropertiesEx.return_value = result - - calls = {'RetrievePropertiesEx': retrievePropertiesEx} - with stubs.fake_suds_context(calls): - session = driver.VMwareAPISession(host_ip='localhost') - - service_content = session.vim.service_content - props = session._call_method(vim_util, "get_dynamic_properties", - service_content.propertyCollector, - 'fake_type', None) - - self.assertEqual(props, { - 'name1': 'value1', - 'name2': 'value2' - }) - - @mock.patch.object(vim_util, 'get_object_properties', return_value=None) - def test_get_dynamic_properties_no_objects(self, mock_get_object_props): - res = vim_util.get_dynamic_properties('fake-vim', 'fake-obj', - 'fake-type', 'fake-property') - self.assertEqual({}, res) - - def test_get_inner_objects(self): - property = ['summary.name'] - # Get the fake datastores directly from the cluster - cluster_refs = fake._get_object_refs('ClusterComputeResource') - cluster = fake._get_object(cluster_refs[0]) - expected_ds = cluster.datastore.ManagedObjectReference - # Get the fake datastores using inner objects utility method - result = vim_util.get_inner_objects( - self.vim, cluster_refs[0], 'datastore', 'Datastore', property) - datastores = [oc.obj for oc in result.objects] - self.assertEqual(expected_ds, datastores) diff --git a/nova/tests/virt/vmwareapi/test_vm_util.py b/nova/tests/virt/vmwareapi/test_vm_util.py deleted file mode 100644 index 4e4e141ca6..0000000000 --- a/nova/tests/virt/vmwareapi/test_vm_util.py +++ /dev/null @@ -1,1069 +0,0 @@ -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# Copyright 2013 Canonical Corp. -# All Rights Reserved. -# -# 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 collections -import contextlib -import re - -import mock -from oslo.vmware import exceptions as vexc - -from nova import context -from nova import exception -from nova.network import model as network_model -from nova.openstack.common import uuidutils -from nova import test -from nova.tests import fake_instance -from nova.tests.virt.vmwareapi import fake -from nova.tests.virt.vmwareapi import stubs -from nova.virt.vmwareapi import driver -from nova.virt.vmwareapi import vm_util - - -class partialObject(object): - def __init__(self, path='fake-path'): - self.path = path - self.fault = fake.DataObject() - - -class VMwareVMUtilTestCase(test.NoDBTestCase): - def setUp(self): - super(VMwareVMUtilTestCase, self).setUp() - fake.reset() - stubs.set_stubs(self.stubs) - vm_util.vm_refs_cache_reset() - - def _test_get_stats_from_cluster(self, connection_state="connected", - maintenance_mode=False): - ManagedObjectRefs = [fake.ManagedObjectReference("host1", - "HostSystem"), - fake.ManagedObjectReference("host2", - "HostSystem")] - hosts = fake._convert_to_array_of_mor(ManagedObjectRefs) - respool = fake.ManagedObjectReference("resgroup-11", "ResourcePool") - prop_dict = {'host': hosts, 'resourcePool': respool} - - hardware = fake.DataObject() - hardware.numCpuCores = 8 - hardware.numCpuThreads = 16 - hardware.vendor = "Intel" - hardware.cpuModel = "Intel(R) Xeon(R)" - - runtime_host_1 = fake.DataObject() - runtime_host_1.connectionState = "connected" - runtime_host_1.inMaintenanceMode = False - - runtime_host_2 = fake.DataObject() - runtime_host_2.connectionState = connection_state - runtime_host_2.inMaintenanceMode = maintenance_mode - - prop_list_host_1 = [fake.Prop(name="hardware_summary", val=hardware), - fake.Prop(name="runtime_summary", - val=runtime_host_1)] - prop_list_host_2 = [fake.Prop(name="hardware_summary", val=hardware), - fake.Prop(name="runtime_summary", - val=runtime_host_2)] - - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(fake.ObjectContent("prop_list_host1", - prop_list_host_1)) - fake_objects.add_object(fake.ObjectContent("prop_list_host1", - prop_list_host_2)) - - respool_resource_usage = fake.DataObject() - respool_resource_usage.maxUsage = 5368709120 - respool_resource_usage.overallUsage = 2147483648 - - def fake_call_method(*args): - if "get_dynamic_properties" in args: - return prop_dict - elif "get_properties_for_a_collection_of_objects" in args: - return fake_objects - else: - return respool_resource_usage - - session = fake.FakeSession() - with mock.patch.object(session, '_call_method', fake_call_method): - result = vm_util.get_stats_from_cluster(session, "cluster1") - cpu_info = {} - mem_info = {} - if connection_state == "connected" and not maintenance_mode: - cpu_info['vcpus'] = 32 - cpu_info['cores'] = 16 - cpu_info['vendor'] = ["Intel", "Intel"] - cpu_info['model'] = ["Intel(R) Xeon(R)", - "Intel(R) Xeon(R)"] - else: - cpu_info['vcpus'] = 16 - cpu_info['cores'] = 8 - cpu_info['vendor'] = ["Intel"] - cpu_info['model'] = ["Intel(R) Xeon(R)"] - mem_info['total'] = 5120 - mem_info['free'] = 3072 - expected_stats = {'cpu': cpu_info, 'mem': mem_info} - self.assertEqual(expected_stats, result) - - def test_get_stats_from_cluster_hosts_connected_and_active(self): - self._test_get_stats_from_cluster() - - def test_get_stats_from_cluster_hosts_disconnected_and_active(self): - self._test_get_stats_from_cluster(connection_state="disconnected") - - def test_get_stats_from_cluster_hosts_connected_and_maintenance(self): - self._test_get_stats_from_cluster(maintenance_mode=True) - - def test_get_host_ref_no_hosts_in_cluster(self): - self.assertRaises(exception.NoValidHost, - vm_util.get_host_ref, - fake.FakeObjectRetrievalSession(""), 'fake_cluster') - - def test_get_resize_spec(self): - fake_instance = {'id': 7, 'name': 'fake!', - 'uuid': 'bda5fb9e-b347-40e8-8256-42397848cb00', - 'vcpus': 2, 'memory_mb': 2048} - result = vm_util.get_vm_resize_spec(fake.FakeFactory(), - fake_instance) - expected = """{'memoryMB': 2048, - 'numCPUs': 2, - 'obj_name': 'ns0:VirtualMachineConfigSpec'}""" - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_get_cdrom_attach_config_spec(self): - - result = vm_util.get_cdrom_attach_config_spec(fake.FakeFactory(), - fake.Datastore(), - "/tmp/foo.iso", - 200, 0) - expected = """{ - 'deviceChange': [ - { - 'device': { - 'connectable': { - 'allowGuestControl': False, - 'startConnected': True, - 'connected': True, - 'obj_name': 'ns0: VirtualDeviceConnectInfo' - }, - 'backing': { - 'datastore': { - "summary.maintenanceMode": "normal", - "summary.type": "VMFS", - "summary.accessible":true, - "summary.name": "fake-ds", - "summary.capacity": 1099511627776, - "summary.freeSpace": 536870912000, - "browser": "" - }, - 'fileName': '/tmp/foo.iso', - 'obj_name': 'ns0: VirtualCdromIsoBackingInfo' - }, - 'controllerKey': 200, - 'unitNumber': 0, - 'key': -1, - 'obj_name': 'ns0: VirtualCdrom' - }, - 'operation': 'add', - 'obj_name': 'ns0: VirtualDeviceConfigSpec' - } - ], - 'obj_name': 'ns0: VirtualMachineConfigSpec' -} -""" - - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_lsilogic_controller_spec(self): - # Test controller spec returned for lsiLogic sas adapter type - config_spec = vm_util.create_controller_spec(fake.FakeFactory(), -101, - adapter_type="lsiLogicsas") - self.assertEqual("ns0:VirtualLsiLogicSASController", - config_spec.device.obj_name) - - def test_paravirtual_controller_spec(self): - # Test controller spec returned for paraVirtual adapter type - config_spec = vm_util.create_controller_spec(fake.FakeFactory(), -101, - adapter_type="paraVirtual") - self.assertEqual("ns0:ParaVirtualSCSIController", - config_spec.device.obj_name) - - def _vmdk_path_and_adapter_type_devices(self, filename, parent=None): - # Test the adapter_type returned for a lsiLogic sas controller - controller_key = 1000 - disk = fake.VirtualDisk() - disk.controllerKey = controller_key - disk_backing = fake.VirtualDiskFlatVer2BackingInfo() - disk_backing.fileName = filename - if parent: - disk_backing.parent = parent - disk.backing = disk_backing - controller = fake.VirtualLsiLogicSASController() - controller.key = controller_key - devices = [disk, controller] - return devices - - def test_get_vmdk_path(self): - uuid = '00000000-0000-0000-0000-000000000000' - filename = '[test_datastore] %s/%s.vmdk' % (uuid, uuid) - devices = self._vmdk_path_and_adapter_type_devices(filename) - session = fake.FakeSession() - - with mock.patch.object(session, '_call_method', - return_value=devices): - instance = {'uuid': uuid} - vmdk_path = vm_util.get_vmdk_path(session, None, instance) - self.assertEqual(filename, vmdk_path) - - def test_get_vmdk_path_and_adapter_type(self): - filename = '[test_datastore] test_file.vmdk' - devices = self._vmdk_path_and_adapter_type_devices(filename) - vmdk_info = vm_util.get_vmdk_path_and_adapter_type(devices) - adapter_type = vmdk_info[1] - self.assertEqual('lsiLogicsas', adapter_type) - self.assertEqual(vmdk_info[0], filename) - - def test_get_vmdk_path_and_adapter_type_with_match(self): - n_filename = '[test_datastore] uuid/uuid.vmdk' - devices = self._vmdk_path_and_adapter_type_devices(n_filename) - vmdk_info = vm_util.get_vmdk_path_and_adapter_type( - devices, uuid='uuid') - adapter_type = vmdk_info[1] - self.assertEqual('lsiLogicsas', adapter_type) - self.assertEqual(n_filename, vmdk_info[0]) - - def test_get_vmdk_path_and_adapter_type_with_nomatch(self): - n_filename = '[test_datastore] diuu/diuu.vmdk' - devices = self._vmdk_path_and_adapter_type_devices(n_filename) - vmdk_info = vm_util.get_vmdk_path_and_adapter_type( - devices, uuid='uuid') - adapter_type = vmdk_info[1] - self.assertEqual('lsiLogicsas', adapter_type) - self.assertIsNone(vmdk_info[0]) - - def test_get_vmdk_adapter_type(self): - # Test for the adapter_type to be used in vmdk descriptor - # Adapter type in vmdk descriptor is same for LSI-SAS, LSILogic - # and ParaVirtual - vmdk_adapter_type = vm_util.get_vmdk_adapter_type("lsiLogic") - self.assertEqual("lsiLogic", vmdk_adapter_type) - vmdk_adapter_type = vm_util.get_vmdk_adapter_type("lsiLogicsas") - self.assertEqual("lsiLogic", vmdk_adapter_type) - vmdk_adapter_type = vm_util.get_vmdk_adapter_type("paraVirtual") - self.assertEqual("lsiLogic", vmdk_adapter_type) - vmdk_adapter_type = vm_util.get_vmdk_adapter_type("dummyAdapter") - self.assertEqual("dummyAdapter", vmdk_adapter_type) - - def test_find_allocated_slots(self): - disk1 = fake.VirtualDisk(200, 0) - disk2 = fake.VirtualDisk(200, 1) - disk3 = fake.VirtualDisk(201, 1) - ide0 = fake.VirtualIDEController(200) - ide1 = fake.VirtualIDEController(201) - scsi0 = fake.VirtualLsiLogicController(key=1000, scsiCtlrUnitNumber=7) - devices = [disk1, disk2, disk3, ide0, ide1, scsi0] - taken = vm_util._find_allocated_slots(devices) - self.assertEqual([0, 1], sorted(taken[200])) - self.assertEqual([1], taken[201]) - self.assertEqual([7], taken[1000]) - - def test_allocate_controller_key_and_unit_number_ide_default(self): - # Test that default IDE controllers are used when there is a free slot - # on them - disk1 = fake.VirtualDisk(200, 0) - disk2 = fake.VirtualDisk(200, 1) - ide0 = fake.VirtualIDEController(200) - ide1 = fake.VirtualIDEController(201) - devices = [disk1, disk2, ide0, ide1] - (controller_key, unit_number, - controller_spec) = vm_util.allocate_controller_key_and_unit_number( - None, - devices, - 'ide') - self.assertEqual(201, controller_key) - self.assertEqual(0, unit_number) - self.assertIsNone(controller_spec) - - def test_allocate_controller_key_and_unit_number_ide(self): - # Test that a new controller is created when there is no free slot on - # the default IDE controllers - ide0 = fake.VirtualIDEController(200) - ide1 = fake.VirtualIDEController(201) - devices = [ide0, ide1] - for controller_key in [200, 201]: - for unit_number in [0, 1]: - disk = fake.VirtualDisk(controller_key, unit_number) - devices.append(disk) - factory = fake.FakeFactory() - (controller_key, unit_number, - controller_spec) = vm_util.allocate_controller_key_and_unit_number( - factory, - devices, - 'ide') - self.assertEqual(-101, controller_key) - self.assertEqual(0, unit_number) - self.assertIsNotNone(controller_spec) - - def test_allocate_controller_key_and_unit_number_scsi(self): - # Test that we allocate on existing SCSI controller if there is a free - # slot on it - devices = [fake.VirtualLsiLogicController(1000, scsiCtlrUnitNumber=7)] - for unit_number in range(7): - disk = fake.VirtualDisk(1000, unit_number) - devices.append(disk) - factory = fake.FakeFactory() - (controller_key, unit_number, - controller_spec) = vm_util.allocate_controller_key_and_unit_number( - factory, - devices, - 'lsiLogic') - self.assertEqual(1000, controller_key) - self.assertEqual(8, unit_number) - self.assertIsNone(controller_spec) - - def _test_get_vnc_config_spec(self, port): - - result = vm_util.get_vnc_config_spec(fake.FakeFactory(), - port) - return result - - def test_get_vnc_config_spec(self): - result = self._test_get_vnc_config_spec(7) - expected = """{'extraConfig': [ - {'value': 'true', - 'key': 'RemoteDisplay.vnc.enabled', - 'obj_name': 'ns0:OptionValue'}, - {'value': 7, - 'key': 'RemoteDisplay.vnc.port', - 'obj_name': 'ns0:OptionValue'}], - 'obj_name': 'ns0:VirtualMachineConfigSpec'}""" - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def _create_fake_vms(self): - fake_vms = fake.FakeRetrieveResult() - OptionValue = collections.namedtuple('OptionValue', ['key', 'value']) - for i in range(10): - vm = fake.ManagedObject() - opt_val = OptionValue(key='', value=5900 + i) - vm.set(vm_util.VNC_CONFIG_KEY, opt_val) - fake_vms.add_object(vm) - return fake_vms - - def test_get_vnc_port(self): - fake_vms = self._create_fake_vms() - self.flags(vnc_port=5900, group='vmware') - self.flags(vnc_port_total=10000, group='vmware') - actual = vm_util.get_vnc_port( - fake.FakeObjectRetrievalSession(fake_vms)) - self.assertEqual(actual, 5910) - - def test_get_vnc_port_exhausted(self): - fake_vms = self._create_fake_vms() - self.flags(vnc_port=5900, group='vmware') - self.flags(vnc_port_total=10, group='vmware') - self.assertRaises(exception.ConsolePortRangeExhausted, - vm_util.get_vnc_port, - fake.FakeObjectRetrievalSession(fake_vms)) - - def test_get_all_cluster_refs_by_name_none(self): - fake_objects = fake.FakeRetrieveResult() - refs = vm_util.get_all_cluster_refs_by_name( - fake.FakeObjectRetrievalSession(fake_objects), ['fake_cluster']) - self.assertEqual({}, refs) - - def test_get_all_cluster_refs_by_name_exists(self): - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(fake.ClusterComputeResource(name='cluster')) - refs = vm_util.get_all_cluster_refs_by_name( - fake.FakeObjectRetrievalSession(fake_objects), ['cluster']) - self.assertEqual(1, len(refs)) - - def test_get_all_cluster_refs_by_name_missing(self): - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(partialObject(path='cluster')) - refs = vm_util.get_all_cluster_refs_by_name( - fake.FakeObjectRetrievalSession(fake_objects), ['cluster']) - self.assertEqual({}, refs) - - def test_propset_dict_simple(self): - ObjectContent = collections.namedtuple('ObjectContent', ['propSet']) - DynamicProperty = collections.namedtuple('Property', ['name', 'val']) - - object = ObjectContent(propSet=[ - DynamicProperty(name='foo', val="bar")]) - propdict = vm_util.propset_dict(object.propSet) - self.assertEqual("bar", propdict['foo']) - - def test_propset_dict_complex(self): - ObjectContent = collections.namedtuple('ObjectContent', ['propSet']) - DynamicProperty = collections.namedtuple('Property', ['name', 'val']) - MoRef = collections.namedtuple('Val', ['value']) - - object = ObjectContent(propSet=[ - DynamicProperty(name='foo', val="bar"), - DynamicProperty(name='some.thing', - val=MoRef(value='else')), - DynamicProperty(name='another.thing', val='value')]) - - propdict = vm_util.propset_dict(object.propSet) - self.assertEqual("bar", propdict['foo']) - self.assertTrue(hasattr(propdict['some.thing'], 'value')) - self.assertEqual("else", propdict['some.thing'].value) - self.assertEqual("value", propdict['another.thing']) - - def _test_detach_virtual_disk_spec(self, destroy_disk=False): - virtual_device_config = vm_util.detach_virtual_disk_spec( - fake.FakeFactory(), - 'fake_device', - destroy_disk) - self.assertEqual('remove', virtual_device_config.operation) - self.assertEqual('fake_device', virtual_device_config.device) - self.assertEqual('ns0:VirtualDeviceConfigSpec', - virtual_device_config.obj_name) - if destroy_disk: - self.assertEqual('destroy', virtual_device_config.fileOperation) - else: - self.assertFalse(hasattr(virtual_device_config, 'fileOperation')) - - def test_detach_virtual_disk_spec(self): - self._test_detach_virtual_disk_spec(destroy_disk=False) - - def test_detach_virtual_disk_destroy_spec(self): - self._test_detach_virtual_disk_spec(destroy_disk=True) - - def test_get_vm_create_spec(self): - instance_uuid = uuidutils.generate_uuid() - fake_instance = {'id': 7, 'name': 'fake!', - 'uuid': instance_uuid, - 'vcpus': 2, 'memory_mb': 2048} - result = vm_util.get_vm_create_spec(fake.FakeFactory(), - fake_instance, instance_uuid, - 'fake-datastore', []) - expected = """{ - 'files': {'vmPathName': '[fake-datastore]', - 'obj_name': 'ns0:VirtualMachineFileInfo'}, - 'instanceUuid': '%(instance_uuid)s', - 'name': '%(instance_uuid)s', 'deviceChange': [], - 'extraConfig': [{'value': '%(instance_uuid)s', - 'key': 'nvp.vm-uuid', - 'obj_name': 'ns0:OptionValue'}], - 'memoryMB': 2048, - 'managedBy': {'extensionKey': 'org.openstack.compute', - 'type': 'instance', - 'obj_name': 'ns0:ManagedByInfo'}, - 'obj_name': 'ns0:VirtualMachineConfigSpec', - 'guestId': 'otherGuest', - 'tools': {'beforeGuestStandby': True, - 'beforeGuestReboot': True, - 'beforeGuestShutdown': True, - 'afterResume': True, - 'afterPowerOn': True, - 'obj_name': 'ns0:ToolsConfigInfo'}, - 'numCPUs': 2}""" % {'instance_uuid': instance_uuid} - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_get_vm_create_spec_with_allocations(self): - instance_uuid = uuidutils.generate_uuid() - fake_instance = {'id': 7, 'name': 'fake!', - 'uuid': instance_uuid, - 'vcpus': 2, 'memory_mb': 2048} - result = vm_util.get_vm_create_spec(fake.FakeFactory(), - fake_instance, instance_uuid, - 'fake-datastore', [], - allocations={'cpu_limit': 7, - 'cpu_reservation': 6}) - expected = """{ - 'files': {'vmPathName': '[fake-datastore]', - 'obj_name': 'ns0:VirtualMachineFileInfo'}, - 'instanceUuid': '%(instance_uuid)s', - 'name': '%(instance_uuid)s', 'deviceChange': [], - 'extraConfig': [{'value': '%(instance_uuid)s', - 'key': 'nvp.vm-uuid', - 'obj_name': 'ns0:OptionValue'}], - 'memoryMB': 2048, - 'managedBy': {'extensionKey': 'org.openstack.compute', - 'type': 'instance', - 'obj_name': 'ns0:ManagedByInfo'}, - 'obj_name': 'ns0:VirtualMachineConfigSpec', - 'guestId': 'otherGuest', - 'tools': {'beforeGuestStandby': True, - 'beforeGuestReboot': True, - 'beforeGuestShutdown': True, - 'afterResume': True, - 'afterPowerOn': True, - 'obj_name': 'ns0:ToolsConfigInfo'}, - 'cpuAllocation': {'reservation': 6, - 'limit': 7, - 'obj_name': 'ns0:ResourceAllocationInfo'}, - 'numCPUs': 2}""" % {'instance_uuid': instance_uuid} - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_get_vm_create_spec_with_limit(self): - instance_uuid = uuidutils.generate_uuid() - fake_instance = {'id': 7, 'name': 'fake!', - 'uuid': instance_uuid, - 'vcpus': 2, 'memory_mb': 2048} - result = vm_util.get_vm_create_spec(fake.FakeFactory(), - fake_instance, instance_uuid, - 'fake-datastore', [], - allocations={'cpu_limit': 7}) - expected = """{ - 'files': {'vmPathName': '[fake-datastore]', - 'obj_name': 'ns0:VirtualMachineFileInfo'}, - 'instanceUuid': '%(instance_uuid)s', - 'name': '%(instance_uuid)s', 'deviceChange': [], - 'extraConfig': [{'value': '%(instance_uuid)s', - 'key': 'nvp.vm-uuid', - 'obj_name': 'ns0:OptionValue'}], - 'memoryMB': 2048, - 'managedBy': {'extensionKey': 'org.openstack.compute', - 'type': 'instance', - 'obj_name': 'ns0:ManagedByInfo'}, - 'obj_name': 'ns0:VirtualMachineConfigSpec', - 'guestId': 'otherGuest', - 'tools': {'beforeGuestStandby': True, - 'beforeGuestReboot': True, - 'beforeGuestShutdown': True, - 'afterResume': True, - 'afterPowerOn': True, - 'obj_name': 'ns0:ToolsConfigInfo'}, - 'cpuAllocation': {'limit': 7, - 'obj_name': 'ns0:ResourceAllocationInfo'}, - 'numCPUs': 2}""" % {'instance_uuid': instance_uuid} - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_get_vm_create_spec_with_share(self): - instance_uuid = uuidutils.generate_uuid() - fake_instance = {'id': 7, 'name': 'fake!', - 'uuid': instance_uuid, - 'vcpus': 2, 'memory_mb': 2048} - shares = {'cpu_shares_level': 'high'} - result = vm_util.get_vm_create_spec(fake.FakeFactory(), - fake_instance, instance_uuid, - 'fake-datastore', [], - allocations=shares) - expected = """{ - 'files': {'vmPathName': '[fake-datastore]', - 'obj_name': 'ns0:VirtualMachineFileInfo'}, - 'instanceUuid': '%(instance_uuid)s', - 'name': '%(instance_uuid)s', 'deviceChange': [], - 'extraConfig': [{'value': '%(instance_uuid)s', - 'key': 'nvp.vm-uuid', - 'obj_name': 'ns0:OptionValue'}], - 'memoryMB': 2048, - 'managedBy': {'extensionKey': 'org.openstack.compute', - 'type': 'instance', - 'obj_name': 'ns0:ManagedByInfo'}, - 'obj_name': 'ns0:VirtualMachineConfigSpec', - 'guestId': 'otherGuest', - 'tools': {'beforeGuestStandby': True, - 'beforeGuestReboot': True, - 'beforeGuestShutdown': True, - 'afterResume': True, - 'afterPowerOn': True, - 'obj_name': 'ns0:ToolsConfigInfo'}, - 'cpuAllocation': {'shares': {'level': 'high', - 'shares': 0, - 'obj_name':'ns0:SharesInfo'}, - 'obj_name':'ns0:ResourceAllocationInfo'}, - 'numCPUs': 2}""" % {'instance_uuid': instance_uuid} - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_get_vm_create_spec_with_share_custom(self): - instance_uuid = uuidutils.generate_uuid() - fake_instance = {'id': 7, 'name': 'fake!', - 'uuid': instance_uuid, - 'vcpus': 2, 'memory_mb': 2048} - shares = {'cpu_shares_level': 'custom', - 'cpu_shares_share': 1948} - result = vm_util.get_vm_create_spec(fake.FakeFactory(), - fake_instance, instance_uuid, - 'fake-datastore', [], - allocations=shares) - expected = """{ - 'files': {'vmPathName': '[fake-datastore]', - 'obj_name': 'ns0:VirtualMachineFileInfo'}, - 'instanceUuid': '%(instance_uuid)s', - 'name': '%(instance_uuid)s', 'deviceChange': [], - 'extraConfig': [{'value': '%(instance_uuid)s', - 'key': 'nvp.vm-uuid', - 'obj_name': 'ns0:OptionValue'}], - 'memoryMB': 2048, - 'managedBy': {'extensionKey': 'org.openstack.compute', - 'type': 'instance', - 'obj_name': 'ns0:ManagedByInfo'}, - 'obj_name': 'ns0:VirtualMachineConfigSpec', - 'guestId': 'otherGuest', - 'tools': {'beforeGuestStandby': True, - 'beforeGuestReboot': True, - 'beforeGuestShutdown': True, - 'afterResume': True, - 'afterPowerOn': True, - 'obj_name': 'ns0:ToolsConfigInfo'}, - 'cpuAllocation': {'shares': {'level': 'custom', - 'shares': 1948, - 'obj_name':'ns0:SharesInfo'}, - 'obj_name':'ns0:ResourceAllocationInfo'}, - 'numCPUs': 2}""" % {'instance_uuid': instance_uuid} - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_create_vm(self): - - method_list = ['CreateVM_Task', 'get_dynamic_property'] - - def fake_call_method(module, method, *args, **kwargs): - expected_method = method_list.pop(0) - self.assertEqual(expected_method, method) - if (expected_method == 'CreateVM_Task'): - return 'fake_create_vm_task' - elif (expected_method == 'get_dynamic_property'): - task_info = mock.Mock(state="success", result="fake_vm_ref") - return task_info - else: - self.fail('Should not get here....') - - def fake_wait_for_task(self, *args): - task_info = mock.Mock(state="success", result="fake_vm_ref") - return task_info - - session = fake.FakeSession() - fake_instance = mock.MagicMock() - fake_call_mock = mock.Mock(side_effect=fake_call_method) - fake_wait_mock = mock.Mock(side_effect=fake_wait_for_task) - with contextlib.nested( - mock.patch.object(session, '_wait_for_task', - fake_wait_mock), - mock.patch.object(session, '_call_method', - fake_call_mock) - ) as (wait_for_task, call_method): - vm_ref = vm_util.create_vm( - session, - fake_instance, - 'fake_vm_folder', - 'fake_config_spec', - 'fake_res_pool_ref') - self.assertEqual('fake_vm_ref', vm_ref) - - call_method.assert_called_once_with(mock.ANY, 'CreateVM_Task', - 'fake_vm_folder', config='fake_config_spec', - pool='fake_res_pool_ref') - wait_for_task.assert_called_once_with('fake_create_vm_task') - - @mock.patch.object(vm_util.LOG, 'warning') - def test_create_vm_invalid_guestid(self, mock_log_warn): - """Ensure we warn when create_vm() fails after we passed an - unrecognised guestId - """ - - found = [False] - - def fake_log_warn(msg, values): - if not isinstance(values, dict): - return - if values.get('ostype') == 'invalid_os_type': - found[0] = True - mock_log_warn.side_effect = fake_log_warn - - instance_values = {'id': 7, 'name': 'fake-name', - 'uuid': uuidutils.generate_uuid(), - 'vcpus': 2, 'memory_mb': 2048} - instance = fake_instance.fake_instance_obj( - context.RequestContext('fake', 'fake', is_admin=False), - **instance_values) - - session = driver.VMwareAPISession() - - config_spec = vm_util.get_vm_create_spec( - session.vim.client.factory, - instance, instance.name, 'fake-datastore', [], - os_type='invalid_os_type') - - self.assertRaises(vexc.VMwareDriverException, - vm_util.create_vm, session, instance, 'folder', - config_spec, 'res-pool') - self.assertTrue(found[0]) - - def test_convert_vif_model(self): - expected = "VirtualE1000" - result = vm_util.convert_vif_model(network_model.VIF_MODEL_E1000) - self.assertEqual(expected, result) - expected = "VirtualE1000e" - result = vm_util.convert_vif_model(network_model.VIF_MODEL_E1000E) - self.assertEqual(expected, result) - types = ["VirtualE1000", "VirtualE1000e", "VirtualPCNet32", - "VirtualVmxnet"] - for type in types: - self.assertEqual(type, - vm_util.convert_vif_model(type)) - self.assertRaises(exception.Invalid, - vm_util.convert_vif_model, - "InvalidVifModel") - - def test_power_on_instance_with_vm_ref(self): - session = fake.FakeSession() - fake_instance = mock.MagicMock() - with contextlib.nested( - mock.patch.object(session, "_call_method", - return_value='fake-task'), - mock.patch.object(session, "_wait_for_task"), - ) as (fake_call_method, fake_wait_for_task): - vm_util.power_on_instance(session, fake_instance, - vm_ref='fake-vm-ref') - fake_call_method.assert_called_once_with(session.vim, - "PowerOnVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - - def test_power_on_instance_without_vm_ref(self): - session = fake.FakeSession() - fake_instance = mock.MagicMock() - with contextlib.nested( - mock.patch.object(vm_util, "get_vm_ref", - return_value='fake-vm-ref'), - mock.patch.object(session, "_call_method", - return_value='fake-task'), - mock.patch.object(session, "_wait_for_task"), - ) as (fake_get_vm_ref, fake_call_method, fake_wait_for_task): - vm_util.power_on_instance(session, fake_instance) - fake_get_vm_ref.assert_called_once_with(session, fake_instance) - fake_call_method.assert_called_once_with(session.vim, - "PowerOnVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - - def test_power_on_instance_with_exception(self): - session = fake.FakeSession() - fake_instance = mock.MagicMock() - with contextlib.nested( - mock.patch.object(session, "_call_method", - return_value='fake-task'), - mock.patch.object(session, "_wait_for_task", - side_effect=exception.NovaException('fake')), - ) as (fake_call_method, fake_wait_for_task): - self.assertRaises(exception.NovaException, - vm_util.power_on_instance, - session, fake_instance, - vm_ref='fake-vm-ref') - fake_call_method.assert_called_once_with(session.vim, - "PowerOnVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - - def test_power_on_instance_with_power_state_exception(self): - session = fake.FakeSession() - fake_instance = mock.MagicMock() - with contextlib.nested( - mock.patch.object(session, "_call_method", - return_value='fake-task'), - mock.patch.object( - session, "_wait_for_task", - side_effect=vexc.InvalidPowerStateException), - ) as (fake_call_method, fake_wait_for_task): - vm_util.power_on_instance(session, fake_instance, - vm_ref='fake-vm-ref') - fake_call_method.assert_called_once_with(session.vim, - "PowerOnVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - - def test_create_virtual_disk(self): - session = fake.FakeSession() - dm = session.vim.service_content.virtualDiskManager - with contextlib.nested( - mock.patch.object(vm_util, "get_vmdk_create_spec", - return_value='fake-spec'), - mock.patch.object(session, "_call_method", - return_value='fake-task'), - mock.patch.object(session, "_wait_for_task"), - ) as (fake_get_spec, fake_call_method, fake_wait_for_task): - vm_util.create_virtual_disk(session, 'fake-dc-ref', - 'fake-adapter-type', 'fake-disk-type', - 'fake-path', 7) - fake_get_spec.assert_called_once_with( - session.vim.client.factory, 7, - 'fake-adapter-type', - 'fake-disk-type') - fake_call_method.assert_called_once_with( - session.vim, - "CreateVirtualDisk_Task", - dm, - name='fake-path', - datacenter='fake-dc-ref', - spec='fake-spec') - fake_wait_for_task.assert_called_once_with('fake-task') - - def test_copy_virtual_disk(self): - session = fake.FakeSession() - dm = session.vim.service_content.virtualDiskManager - with contextlib.nested( - mock.patch.object(session, "_call_method", - return_value='fake-task'), - mock.patch.object(session, "_wait_for_task"), - ) as (fake_call_method, fake_wait_for_task): - vm_util.copy_virtual_disk(session, 'fake-dc-ref', - 'fake-source', 'fake-dest') - fake_call_method.assert_called_once_with( - session.vim, - "CopyVirtualDisk_Task", - dm, - sourceName='fake-source', - sourceDatacenter='fake-dc-ref', - destName='fake-dest') - fake_wait_for_task.assert_called_once_with('fake-task') - - def _create_fake_vm_objects(self): - fake_objects = fake.FakeRetrieveResult() - fake_objects.add_object(fake.VirtualMachine()) - return fake_objects - - def test_get_values(self): - objects = self._create_fake_vm_objects() - query = vm_util.get_values_from_object_properties( - fake.FakeObjectRetrievalSession(objects), objects) - self.assertEqual('poweredOn', query['runtime.powerState']) - self.assertEqual('guestToolsRunning', - query['summary.guest.toolsRunningStatus']) - self.assertEqual('toolsOk', query['summary.guest.toolsStatus']) - - def test_reconfigure_vm(self): - session = fake.FakeSession() - with contextlib.nested( - mock.patch.object(session, '_call_method', - return_value='fake_reconfigure_task'), - mock.patch.object(session, '_wait_for_task') - ) as (_call_method, _wait_for_task): - vm_util.reconfigure_vm(session, 'fake-ref', 'fake-spec') - _call_method.assert_called_once_with(mock.ANY, - 'ReconfigVM_Task', 'fake-ref', spec='fake-spec') - _wait_for_task.assert_called_once_with( - 'fake_reconfigure_task') - - def test_get_network_attach_config_spec_opaque(self): - vif_info = {'network_name': 'br-int', - 'mac_address': '00:00:00:ca:fe:01', - 'network_ref': {'type': 'OpaqueNetwork', - 'network-id': 'fake-network-id', - 'network-type': 'opaque'}, - 'iface_id': 7, - 'vif_model': 'VirtualE1000'} - result = vm_util.get_network_attach_config_spec( - fake.FakeFactory(), vif_info, 1) - card = 'ns0:VirtualEthernetCardOpaqueNetworkBackingInfo' - expected = """{ - 'extraConfig': [{'value': 7, - 'key': 'nvp.iface-id.1', - 'obj_name':'ns0:OptionValue'}], - 'deviceChange': [ - {'device': { - 'macAddress':'00:00:00:ca:fe:01', - 'addressType': 'manual', - 'connectable': { - 'allowGuestControl':True, - 'startConnected': True, - 'connected': True, - 'obj_name':'ns0:VirtualDeviceConnectInfo'}, - 'backing': { - 'opaqueNetworkType': 'opaque', - 'opaqueNetworkId': 'fake-network-id', - 'obj_name': '%(card)s'}, - 'key': -47, - 'obj_name': 'ns0:VirtualE1000', - 'wakeOnLanEnabled': True}, - 'operation': 'add', - 'obj_name': 'ns0:VirtualDeviceConfigSpec'}], - 'obj_name':'ns0:VirtualMachineConfigSpec'}""" % {'card': card} - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_get_network_attach_config_spec_dvs(self): - vif_info = {'network_name': 'br100', - 'mac_address': '00:00:00:ca:fe:01', - 'network_ref': {'type': 'DistributedVirtualPortgroup', - 'dvsw': 'fake-network-id', - 'dvpg': 'fake-group'}, - 'iface_id': 7, - 'vif_model': 'VirtualE1000'} - result = vm_util.get_network_attach_config_spec( - fake.FakeFactory(), vif_info, 1) - port = 'ns0:DistributedVirtualSwitchPortConnection' - backing = 'ns0:VirtualEthernetCardDistributedVirtualPortBackingInfo' - expected = """{ - 'extraConfig': [{'value': 7, - 'key': 'nvp.iface-id.1', - 'obj_name': 'ns0:OptionValue'}], - 'deviceChange': [ - {'device': {'macAddress': '00:00:00:ca:fe:01', - 'addressType': 'manual', - 'connectable': { - 'allowGuestControl': True, - 'startConnected': True, - 'connected': True, - 'obj_name': 'ns0:VirtualDeviceConnectInfo'}, - 'backing': { - 'port': { - 'portgroupKey': 'fake-group', - 'switchUuid': 'fake-network-id', - 'obj_name': '%(obj_name_port)s'}, - 'obj_name': '%(obj_name_backing)s'}, - 'key': -47, - 'obj_name': 'ns0:VirtualE1000', - 'wakeOnLanEnabled': True}, - 'operation': 'add', - 'obj_name': 'ns0:VirtualDeviceConfigSpec'}], - 'obj_name':'ns0:VirtualMachineConfigSpec'}""" % { - 'obj_name_backing': backing, - 'obj_name_port': port} - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - def test_get_network_detach_config_spec(self): - result = vm_util.get_network_detach_config_spec( - fake.FakeFactory(), 'fake-device', 2) - expected = """{ - 'extraConfig': [{'value': 'free', - 'key': 'nvp.iface-id.2', - 'obj_name': 'ns0:OptionValue'}], - 'deviceChange': [{'device': 'fake-device', - 'operation': 'remove', - 'obj_name': 'ns0:VirtualDeviceConfigSpec'}], - 'obj_name':'ns0:VirtualMachineConfigSpec'}""" - expected = re.sub(r'\s+', '', expected) - result = re.sub(r'\s+', '', repr(result)) - self.assertEqual(expected, result) - - @mock.patch.object(vm_util, "get_vm_ref") - def test_power_off_instance(self, fake_get_ref): - session = fake.FakeSession() - fake_instance = mock.MagicMock() - with contextlib.nested( - mock.patch.object(session, '_call_method', - return_value='fake-task'), - mock.patch.object(session, '_wait_for_task') - ) as (fake_call_method, fake_wait_for_task): - vm_util.power_off_instance(session, fake_instance, 'fake-vm-ref') - fake_call_method.assert_called_once_with(session.vim, - "PowerOffVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - self.assertFalse(fake_get_ref.called) - - @mock.patch.object(vm_util, "get_vm_ref", return_value="fake-vm-ref") - def test_power_off_instance_no_vm_ref(self, fake_get_ref): - session = fake.FakeSession() - fake_instance = mock.MagicMock() - with contextlib.nested( - mock.patch.object(session, '_call_method', - return_value='fake-task'), - mock.patch.object(session, '_wait_for_task') - ) as (fake_call_method, fake_wait_for_task): - vm_util.power_off_instance(session, fake_instance) - fake_get_ref.assert_called_once_with(session, fake_instance) - fake_call_method.assert_called_once_with(session.vim, - "PowerOffVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - - @mock.patch.object(vm_util, "get_vm_ref") - def test_power_off_instance_with_exception(self, fake_get_ref): - session = fake.FakeSession() - fake_instance = mock.MagicMock() - with contextlib.nested( - mock.patch.object(session, '_call_method', - return_value='fake-task'), - mock.patch.object(session, '_wait_for_task', - side_effect=exception.NovaException('fake')) - ) as (fake_call_method, fake_wait_for_task): - self.assertRaises(exception.NovaException, - vm_util.power_off_instance, - session, fake_instance, 'fake-vm-ref') - fake_call_method.assert_called_once_with(session.vim, - "PowerOffVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - self.assertFalse(fake_get_ref.called) - - @mock.patch.object(vm_util, "get_vm_ref") - def test_power_off_instance_power_state_exception(self, fake_get_ref): - session = fake.FakeSession() - fake_instance = mock.MagicMock() - with contextlib.nested( - mock.patch.object(session, '_call_method', - return_value='fake-task'), - mock.patch.object( - session, '_wait_for_task', - side_effect=vexc.InvalidPowerStateException) - ) as (fake_call_method, fake_wait_for_task): - vm_util.power_off_instance(session, fake_instance, 'fake-vm-ref') - fake_call_method.assert_called_once_with(session.vim, - "PowerOffVM_Task", - 'fake-vm-ref') - fake_wait_for_task.assert_called_once_with('fake-task') - self.assertFalse(fake_get_ref.called) - - -@mock.patch.object(driver.VMwareAPISession, 'vim', stubs.fake_vim_prop) -class VMwareVMUtilGetHostRefTestCase(test.NoDBTestCase): - # N.B. Mocking on the class only mocks test_*(), but we need - # VMwareAPISession.vim to be mocked in both setUp and tests. Not mocking in - # setUp causes object initialisation to fail. Not mocking in tests results - # in vim calls not using FakeVim. - @mock.patch.object(driver.VMwareAPISession, 'vim', stubs.fake_vim_prop) - def setUp(self): - super(VMwareVMUtilGetHostRefTestCase, self).setUp() - fake.reset() - vm_util.vm_refs_cache_reset() - - self.session = driver.VMwareAPISession() - - # Create a fake VirtualMachine running on a known host - self.host_ref = fake._db_content['HostSystem'].keys()[0] - self.vm_ref = fake.create_vm(host_ref=self.host_ref) - - @mock.patch.object(vm_util, 'get_vm_ref') - def test_get_host_ref_for_vm(self, mock_get_vm_ref): - mock_get_vm_ref.return_value = self.vm_ref - - ret = vm_util.get_host_ref_for_vm(self.session, 'fake-instance') - - mock_get_vm_ref.assert_called_once_with(self.session, 'fake-instance') - self.assertEqual(self.host_ref, ret) - - @mock.patch.object(vm_util, 'get_vm_ref') - def test_get_host_name_for_vm(self, mock_get_vm_ref): - mock_get_vm_ref.return_value = self.vm_ref - - host = fake._get_object(self.host_ref) - - ret = vm_util.get_host_name_for_vm(self.session, 'fake-instance') - - mock_get_vm_ref.assert_called_once_with(self.session, 'fake-instance') - self.assertEqual(host.name, ret) diff --git a/nova/tests/virt/vmwareapi/test_vmops.py b/nova/tests/virt/vmwareapi/test_vmops.py deleted file mode 100644 index dde695455c..0000000000 --- a/nova/tests/virt/vmwareapi/test_vmops.py +++ /dev/null @@ -1,1293 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# All Rights Reserved. -# -# 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 contextlib - -import mock -from oslo.utils import units -from oslo.vmware import exceptions as vexc - -from nova.compute import power_state -from nova import context -from nova import db -from nova import exception -from nova.network import model as network_model -from nova import objects -from nova.openstack.common import uuidutils -from nova import test -from nova.tests import fake_instance -import nova.tests.image.fake -from nova.tests.virt.vmwareapi import fake as vmwareapi_fake -from nova.tests.virt.vmwareapi import stubs -from nova.virt.vmwareapi import constants -from nova.virt.vmwareapi import driver -from nova.virt.vmwareapi import ds_util -from nova.virt.vmwareapi import images -from nova.virt.vmwareapi import vim_util -from nova.virt.vmwareapi import vm_util -from nova.virt.vmwareapi import vmops - - -class DsPathMatcher: - def __init__(self, expected_ds_path_str): - self.expected_ds_path_str = expected_ds_path_str - - def __eq__(self, ds_path_param): - return str(ds_path_param) == self.expected_ds_path_str - - -class VMwareVMOpsTestCase(test.NoDBTestCase): - def setUp(self): - super(VMwareVMOpsTestCase, self).setUp() - vmwareapi_fake.reset() - stubs.set_stubs(self.stubs) - self.flags(image_cache_subdirectory_name='vmware_base', - my_ip='', - flat_injected=True, - vnc_enabled=True) - self._context = context.RequestContext('fake_user', 'fake_project') - self._session = driver.VMwareAPISession() - - self._virtapi = mock.Mock() - self._vmops = vmops.VMwareVMOps(self._session, self._virtapi, None) - - self._image_id = nova.tests.image.fake.get_valid_image_id() - self._instance_values = { - 'name': 'fake_name', - 'uuid': 'fake_uuid', - 'vcpus': 1, - 'memory_mb': 512, - 'image_ref': self._image_id, - 'root_gb': 10, - 'node': 'respool-1001(MyResPoolName)', - 'expected_attrs': ['system_metadata'], - } - self._instance = fake_instance.fake_instance_obj( - self._context, **self._instance_values) - - fake_ds_ref = vmwareapi_fake.ManagedObjectReference('fake-ds') - self._ds = ds_util.Datastore( - ref=fake_ds_ref, name='fake_ds', - capacity=10 * units.Gi, - freespace=10 * units.Gi) - self._dc_info = vmops.DcInfo( - ref='fake_dc_ref', name='fake_dc', - vmFolder='fake_vm_folder') - - subnet_4 = network_model.Subnet(cidr='192.168.0.1/24', - dns=[network_model.IP('192.168.0.1')], - gateway= - network_model.IP('192.168.0.1'), - ips=[ - network_model.IP('192.168.0.100')], - routes=None) - subnet_6 = network_model.Subnet(cidr='dead:beef::1/64', - dns=None, - gateway= - network_model.IP('dead:beef::1'), - ips=[network_model.IP( - 'dead:beef::dcad:beff:feef:0')], - routes=None) - network = network_model.Network(id=0, - bridge='fa0', - label='fake', - subnets=[subnet_4, subnet_6], - vlan=None, - bridge_interface=None, - injected=True) - self._network_values = { - 'id': None, - 'address': 'DE:AD:BE:EF:00:00', - 'network': network, - 'type': None, - 'devname': None, - 'ovs_interfaceid': None, - 'rxtx_cap': 3 - } - self.network_info = network_model.NetworkInfo([ - network_model.VIF(**self._network_values) - ]) - pure_IPv6_network = network_model.Network(id=0, - bridge='fa0', - label='fake', - subnets=[subnet_6], - vlan=None, - bridge_interface=None, - injected=True) - self.pure_IPv6_network_info = network_model.NetworkInfo([ - network_model.VIF(id=None, - address='DE:AD:BE:EF:00:00', - network=pure_IPv6_network, - type=None, - devname=None, - ovs_interfaceid=None, - rxtx_cap=3) - ]) - - def test_get_machine_id_str(self): - result = vmops.VMwareVMOps._get_machine_id_str(self.network_info) - self.assertEqual('DE:AD:BE:EF:00:00;192.168.0.100;255.255.255.0;' - '192.168.0.1;192.168.0.255;192.168.0.1#', result) - result = vmops.VMwareVMOps._get_machine_id_str( - self.pure_IPv6_network_info) - self.assertEqual('DE:AD:BE:EF:00:00;;;;;#', result) - - def _setup_create_folder_mocks(self): - ops = vmops.VMwareVMOps(mock.Mock(), mock.Mock(), mock.Mock()) - base_name = 'folder' - ds_name = "datastore" - ds_ref = mock.Mock() - ds_ref.value = 1 - dc_ref = mock.Mock() - ops._datastore_dc_mapping[ds_ref.value] = vmops.DcInfo( - ref=dc_ref, - name='fake-name', - vmFolder='fake-folder') - path = ds_util.DatastorePath(ds_name, base_name) - return ds_name, ds_ref, ops, path, dc_ref - - @mock.patch.object(ds_util, 'mkdir') - def test_create_folder_if_missing(self, mock_mkdir): - ds_name, ds_ref, ops, path, dc = self._setup_create_folder_mocks() - ops._create_folder_if_missing(ds_name, ds_ref, 'folder') - mock_mkdir.assert_called_with(ops._session, path, dc) - - @mock.patch.object(ds_util, 'mkdir') - def test_create_folder_if_missing_exception(self, mock_mkdir): - ds_name, ds_ref, ops, path, dc = self._setup_create_folder_mocks() - ds_util.mkdir.side_effect = vexc.FileAlreadyExistsException() - ops._create_folder_if_missing(ds_name, ds_ref, 'folder') - mock_mkdir.assert_called_with(ops._session, path, dc) - - @mock.patch.object(ds_util, 'file_exists', return_value=True) - def test_check_if_folder_file_exists_with_existing(self, - mock_exists): - ops = vmops.VMwareVMOps(mock.Mock(), mock.Mock(), mock.Mock()) - ops._create_folder_if_missing = mock.Mock() - mock_ds_ref = mock.Mock() - ops._check_if_folder_file_exists(mock.Mock(), mock_ds_ref, "datastore", - "folder", "some_file") - ops._create_folder_if_missing.assert_called_once_with('datastore', - mock_ds_ref, - 'vmware_base') - - @mock.patch.object(ds_util, 'file_exists', return_value=False) - def test_check_if_folder_file_exists_no_existing(self, mock_exists): - ops = vmops.VMwareVMOps(mock.Mock(), mock.Mock(), mock.Mock()) - ops._create_folder_if_missing = mock.Mock() - mock_ds_ref = mock.Mock() - ops._check_if_folder_file_exists(mock.Mock(), mock_ds_ref, "datastore", - "folder", "some_file") - ops._create_folder_if_missing.assert_called_once_with('datastore', - mock_ds_ref, - 'vmware_base') - - def test_get_valid_vms_from_retrieve_result(self): - ops = vmops.VMwareVMOps(mock.Mock(), mock.Mock(), mock.Mock()) - fake_objects = vmwareapi_fake.FakeRetrieveResult() - fake_objects.add_object(vmwareapi_fake.VirtualMachine()) - fake_objects.add_object(vmwareapi_fake.VirtualMachine()) - fake_objects.add_object(vmwareapi_fake.VirtualMachine()) - vms = ops._get_valid_vms_from_retrieve_result(fake_objects) - self.assertEqual(3, len(vms)) - - def test_get_valid_vms_from_retrieve_result_with_invalid(self): - ops = vmops.VMwareVMOps(mock.Mock(), mock.Mock(), mock.Mock()) - fake_objects = vmwareapi_fake.FakeRetrieveResult() - fake_objects.add_object(vmwareapi_fake.VirtualMachine()) - invalid_vm1 = vmwareapi_fake.VirtualMachine() - invalid_vm1.set('runtime.connectionState', 'orphaned') - invalid_vm2 = vmwareapi_fake.VirtualMachine() - invalid_vm2.set('runtime.connectionState', 'inaccessible') - fake_objects.add_object(invalid_vm1) - fake_objects.add_object(invalid_vm2) - vms = ops._get_valid_vms_from_retrieve_result(fake_objects) - self.assertEqual(1, len(vms)) - - def test_delete_vm_snapshot(self): - def fake_call_method(module, method, *args, **kwargs): - self.assertEqual('RemoveSnapshot_Task', method) - self.assertEqual('fake_vm_snapshot', args[0]) - self.assertFalse(kwargs['removeChildren']) - self.assertTrue(kwargs['consolidate']) - return 'fake_remove_snapshot_task' - - with contextlib.nested( - mock.patch.object(self._session, '_wait_for_task'), - mock.patch.object(self._session, '_call_method', fake_call_method) - ) as (_wait_for_task, _call_method): - self._vmops._delete_vm_snapshot(self._instance, - "fake_vm_ref", "fake_vm_snapshot") - _wait_for_task.assert_has_calls([ - mock.call('fake_remove_snapshot_task')]) - - def test_create_vm_snapshot(self): - - method_list = ['CreateSnapshot_Task', 'get_dynamic_property'] - - def fake_call_method(module, method, *args, **kwargs): - expected_method = method_list.pop(0) - self.assertEqual(expected_method, method) - if (expected_method == 'CreateSnapshot_Task'): - self.assertEqual('fake_vm_ref', args[0]) - self.assertFalse(kwargs['memory']) - self.assertTrue(kwargs['quiesce']) - return 'fake_snapshot_task' - elif (expected_method == 'get_dynamic_property'): - task_info = mock.Mock() - task_info.result = "fake_snapshot_ref" - self.assertEqual(('fake_snapshot_task', 'Task', 'info'), args) - return task_info - - with contextlib.nested( - mock.patch.object(self._session, '_wait_for_task'), - mock.patch.object(self._session, '_call_method', fake_call_method) - ) as (_wait_for_task, _call_method): - snap = self._vmops._create_vm_snapshot(self._instance, - "fake_vm_ref") - self.assertEqual("fake_snapshot_ref", snap) - _wait_for_task.assert_has_calls([ - mock.call('fake_snapshot_task')]) - - def test_update_instance_progress(self): - instance = objects.Instance(context=mock.MagicMock(), uuid='fake-uuid') - with mock.patch.object(instance, 'save') as mock_save: - self._vmops._update_instance_progress(instance._context, - instance, 5, 10) - mock_save.assert_called_once_with() - self.assertEqual(50, instance.progress) - - @mock.patch.object(vm_util, 'get_vm_ref', return_value='fake_ref') - @mock.patch.object(driver.VMwareAPISession, '_call_method') - def test_get_info(self, mock_call, mock_get_vm_ref): - props = ['summary.config.numCpu', 'summary.config.memorySizeMB', - 'runtime.powerState'] - prop_cpu = vmwareapi_fake.Prop(props[0], 4) - prop_mem = vmwareapi_fake.Prop(props[1], 128) - prop_state = vmwareapi_fake.Prop(props[2], 'poweredOn') - prop_list = [prop_state, prop_mem, prop_cpu] - obj_content = vmwareapi_fake.ObjectContent(None, prop_list=prop_list) - result = vmwareapi_fake.FakeRetrieveResult() - result.add_object(obj_content) - mock_call.return_value = result - info = self._vmops.get_info(self._instance) - mock_call.assert_called_once_with(vim_util, - 'get_object_properties', None, 'fake_ref', 'VirtualMachine', - props) - mock_get_vm_ref.assert_called_once_with(self._session, - self._instance) - self.assertEqual(power_state.RUNNING, info['state']) - self.assertEqual(128 * 1024, info['max_mem']) - self.assertEqual(128 * 1024, info['mem']) - self.assertEqual(4, info['num_cpu']) - self.assertEqual(0, info['cpu_time']) - - @mock.patch.object(vm_util, 'get_vm_ref', return_value='fake_ref') - @mock.patch.object(driver.VMwareAPISession, '_call_method') - def test_get_info_when_ds_unavailable(self, mock_call, mock_get_vm_ref): - props = ['summary.config.numCpu', 'summary.config.memorySizeMB', - 'runtime.powerState'] - prop_state = vmwareapi_fake.Prop(props[2], 'poweredOff') - # when vm's ds not available, only power state can be received - prop_list = [prop_state] - obj_content = vmwareapi_fake.ObjectContent(None, prop_list=prop_list) - result = vmwareapi_fake.FakeRetrieveResult() - result.add_object(obj_content) - mock_call.return_value = result - info = self._vmops.get_info(self._instance) - mock_call.assert_called_once_with(vim_util, - 'get_object_properties', None, 'fake_ref', 'VirtualMachine', - props) - mock_get_vm_ref.assert_called_once_with(self._session, - self._instance) - self.assertEqual(power_state.SHUTDOWN, info['state']) - self.assertEqual(0, info['max_mem']) - self.assertEqual(0, info['mem']) - self.assertEqual(0, info['num_cpu']) - self.assertEqual(0, info['cpu_time']) - - def _test_get_datacenter_ref_and_name(self, ds_ref_exists=False): - instance_ds_ref = mock.Mock() - instance_ds_ref.value = "ds-1" - _vcvmops = vmops.VMwareVMOps(self._session, None, None) - if ds_ref_exists: - ds_ref = mock.Mock() - ds_ref.value = "ds-1" - else: - ds_ref = None - - def fake_call_method(module, method, *args, **kwargs): - fake_object1 = vmwareapi_fake.FakeRetrieveResult() - fake_object1.add_object(vmwareapi_fake.Datacenter( - ds_ref=ds_ref)) - if not ds_ref: - # Token is set for the fake_object1, so it will continue to - # fetch the next object. - setattr(fake_object1, 'token', 'token-0') - if method == "continue_to_get_objects": - fake_object2 = vmwareapi_fake.FakeRetrieveResult() - fake_object2.add_object(vmwareapi_fake.Datacenter()) - return fake_object2 - - return fake_object1 - - with mock.patch.object(self._session, '_call_method', - side_effect=fake_call_method) as fake_call: - dc_info = _vcvmops.get_datacenter_ref_and_name(instance_ds_ref) - - if ds_ref: - self.assertEqual(1, len(_vcvmops._datastore_dc_mapping)) - fake_call.assert_called_once_with(vim_util, "get_objects", - "Datacenter", ["name", "datastore", "vmFolder"]) - self.assertEqual("ha-datacenter", dc_info.name) - else: - calls = [mock.call(vim_util, "get_objects", "Datacenter", - ["name", "datastore", "vmFolder"]), - mock.call(vim_util, "continue_to_get_objects", - "token-0")] - fake_call.assert_has_calls(calls) - self.assertIsNone(dc_info) - - def test_get_datacenter_ref_and_name(self): - self._test_get_datacenter_ref_and_name(ds_ref_exists=True) - - def test_get_datacenter_ref_and_name_with_no_datastore(self): - self._test_get_datacenter_ref_and_name() - - def test_unrescue_power_on(self): - self._test_unrescue(True) - - def test_unrescue_power_off(self): - self._test_unrescue(False) - - def _test_unrescue(self, power_on): - self._vmops._volumeops = mock.Mock() - vm_rescue_ref = mock.Mock() - vm_ref = mock.Mock() - - args_list = [(vm_ref, 'VirtualMachine', - 'config.hardware.device'), - (vm_rescue_ref, 'VirtualMachine', - 'config.hardware.device')] - - def fake_call_method(module, method, *args, **kwargs): - expected_args = args_list.pop(0) - self.assertEqual('get_dynamic_property', method) - self.assertEqual(expected_args, args) - - path = mock.Mock() - path_and_type = (path, mock.Mock(), mock.Mock()) - with contextlib.nested( - mock.patch.object(vm_util, 'get_vmdk_path_and_adapter_type', - return_value=path_and_type), - mock.patch.object(vm_util, 'get_vmdk_volume_disk'), - mock.patch.object(vm_util, 'power_on_instance'), - mock.patch.object(vm_util, 'get_vm_ref', return_value=vm_ref), - mock.patch.object(vm_util, 'get_vm_ref_from_name', - return_value=vm_rescue_ref), - mock.patch.object(self._session, '_call_method', - fake_call_method), - mock.patch.object(vm_util, 'power_off_instance'), - mock.patch.object(self._vmops, '_destroy_instance'), - ) as (_get_vmdk_path_and_adapter_type, _get_vmdk_volume_disk, - _power_on_instance, _get_vm_ref, _get_vm_ref_from_name, - _call_method, _power_off, _destroy_instance): - self._vmops.unrescue(self._instance, power_on=power_on) - - _get_vmdk_path_and_adapter_type.assert_called_once_with( - None, uuid='fake_uuid') - _get_vmdk_volume_disk.assert_called_once_with(None, path=path) - if power_on: - _power_on_instance.assert_called_once_with(self._session, - self._instance, - vm_ref=vm_ref) - else: - self.assertFalse(_power_on_instance.called) - _get_vm_ref.assert_called_once_with(self._session, - self._instance) - _get_vm_ref_from_name.assert_called_once_with(self._session, - 'fake_uuid-rescue') - _power_off.assert_called_once_with(self._session, self._instance, - vm_rescue_ref) - _destroy_instance.assert_called_once_with(self._instance, - instance_name='fake_uuid-rescue') - - def _test_finish_migration(self, power_on=True, resize_instance=False): - """Tests the finish_migration method on vmops.""" - if resize_instance: - self._instance.system_metadata = {'old_instance_type_root_gb': '0'} - datastore = ds_util.Datastore(ref='fake-ref', name='fake') - dc_info = vmops.DcInfo(ref='fake_ref', name='fake', - vmFolder='fake_folder') - with contextlib.nested( - mock.patch.object(self._session, "_call_method", - return_value='fake-task'), - mock.patch.object(self._vmops, "_update_instance_progress"), - mock.patch.object(self._session, "_wait_for_task"), - mock.patch.object(vm_util, "get_vm_resize_spec", - return_value='fake-spec'), - mock.patch.object(ds_util, "get_datastore", - return_value=datastore), - mock.patch.object(self._vmops, 'get_datacenter_ref_and_name', - return_value=dc_info), - mock.patch.object(self._vmops, '_extend_virtual_disk'), - mock.patch.object(vm_util, "power_on_instance") - ) as (fake_call_method, fake_update_instance_progress, - fake_wait_for_task, fake_vm_resize_spec, - fake_get_datastore, fake_get_datacenter_ref_and_name, - fake_extend_virtual_disk, fake_power_on): - self._vmops.finish_migration(context=self._context, - migration=None, - instance=self._instance, - disk_info=None, - network_info=None, - block_device_info=None, - resize_instance=resize_instance, - image_meta=None, - power_on=power_on) - if resize_instance: - fake_vm_resize_spec.assert_called_once_with( - self._session.vim.client.factory, - self._instance) - fake_call_method.assert_has_calls(mock.call( - self._session.vim, - "ReconfigVM_Task", - 'f', - spec='fake-spec')) - fake_wait_for_task.assert_called_once_with('fake-task') - fake_extend_virtual_disk.assert_called_once_with( - self._instance, self._instance['root_gb'] * units.Mi, - None, dc_info.ref) - else: - self.assertFalse(fake_vm_resize_spec.called) - self.assertFalse(fake_wait_for_task.called) - self.assertFalse(fake_extend_virtual_disk.called) - - if power_on: - fake_power_on.assert_called_once_with(self._session, - self._instance, - vm_ref='f') - else: - self.assertFalse(fake_power_on.called) - fake_update_instance_progress.called_once_with( - self._context, self._instance, 4, vmops.RESIZE_TOTAL_STEPS) - - def test_finish_migration_power_on(self): - self._test_finish_migration(power_on=True, resize_instance=False) - - def test_finish_migration_power_off(self): - self._test_finish_migration(power_on=False, resize_instance=False) - - def test_finish_migration_power_on_resize(self): - self._test_finish_migration(power_on=True, resize_instance=True) - - @mock.patch.object(vm_util, 'associate_vmref_for_instance') - @mock.patch.object(vm_util, 'power_on_instance') - def _test_finish_revert_migration(self, fake_power_on, - fake_associate_vmref, power_on): - """Tests the finish_revert_migration method on vmops.""" - - # setup the test instance in the database - self._vmops.finish_revert_migration(self._context, - instance=self._instance, - network_info=None, - block_device_info=None, - power_on=power_on) - fake_associate_vmref.assert_called_once_with(self._session, - self._instance, - suffix='-orig') - if power_on: - fake_power_on.assert_called_once_with(self._session, - self._instance) - else: - self.assertFalse(fake_power_on.called) - - def test_finish_revert_migration_power_on(self): - self._test_finish_revert_migration(power_on=True) - - def test_finish_revert_migration_power_off(self): - self._test_finish_revert_migration(power_on=False) - - @mock.patch.object(vmops.VMwareVMOps, '_attach_cdrom_to_vm') - @mock.patch.object(vmops.VMwareVMOps, '_create_config_drive') - def test_configure_config_drive(self, - mock_create_config_drive, - mock_attach_cdrom_to_vm): - injected_files = mock.Mock() - admin_password = mock.Mock() - vm_ref = mock.Mock() - mock_create_config_drive.return_value = "fake_iso_path" - self._vmops._configure_config_drive( - self._instance, vm_ref, self._dc_info, self._ds, - injected_files, admin_password) - - upload_iso_path = self._ds.build_path("fake_iso_path") - mock_create_config_drive.assert_called_once_with(self._instance, - injected_files, admin_password, self._ds.name, - self._dc_info.name, self._instance.uuid, "Fake-CookieJar") - mock_attach_cdrom_to_vm.assert_called_once_with( - vm_ref, self._instance, self._ds.ref, str(upload_iso_path)) - - @mock.patch.object(vmops.LOG, 'debug') - @mock.patch.object(vmops.VMwareVMOps, '_get_vm_config_info') - @mock.patch.object(vmops.VMwareVMOps, 'build_virtual_machine') - def test_spawn_mask_block_device_info_password(self, - mock_build_virtual_machine, - mock_get_vm_config_info, - mock_debug): - # Very simple test that just ensures block_device_info auth_password - # is masked when logged; the rest of the test just fails out early. - data = {'auth_password': 'scrubme'} - bdm = [{'connection_info': {'data': data}}] - bdi = {'block_device_mapping': bdm} - - self.password_logged = False - - # Tests that the parameters to the to_xml method are sanitized for - # passwords when logged. - def fake_debug(*args, **kwargs): - if 'auth_password' in args[0]: - self.password_logged = True - self.assertNotIn('scrubme', args[0]) - - mock_debug.side_effect = fake_debug - self.flags(flat_injected=False, vnc_enabled=False) - - # Call spawn(). We don't care what it does as long as it generates - # the log message, which we check below. - with mock.patch.object(self._vmops, '_volumeops') as mock_vo: - mock_vo.attach_root_volume.side_effect = test.TestingException - try: - self._vmops.spawn( - self._context, self._instance, {}, - injected_files=None, admin_password=None, - network_info=[], block_device_info=bdi - ) - except test.TestingException: - pass - - # Check that the relevant log message was generated, and therefore - # that we checked it was scrubbed - self.assertTrue(self.password_logged) - - def test_get_ds_browser(self): - cache = self._vmops._datastore_browser_mapping - ds_browser = mock.Mock() - moref = vmwareapi_fake.ManagedObjectReference('datastore-100') - self.assertIsNone(cache.get(moref.value)) - mock_call_method = mock.Mock(return_value=ds_browser) - with mock.patch.object(self._session, '_call_method', - mock_call_method): - ret = self._vmops._get_ds_browser(moref) - mock_call_method.assert_called_once_with(vim_util, - 'get_dynamic_property', moref, 'Datastore', 'browser') - self.assertIs(ds_browser, ret) - self.assertIs(ds_browser, cache.get(moref.value)) - - @mock.patch.object( - vmops.VMwareVMOps, '_sized_image_exists', return_value=False) - @mock.patch.object(vmops.VMwareVMOps, '_extend_virtual_disk') - @mock.patch.object(vm_util, 'copy_virtual_disk') - def _test_use_disk_image_as_linked_clone(self, - mock_copy_virtual_disk, - mock_extend_virtual_disk, - mock_sized_image_exists, - flavor_fits_image=False): - file_size = 10 * units.Gi if flavor_fits_image else 5 * units.Gi - image_info = images.VMwareImage( - image_id=self._image_id, - file_size=file_size, - linked_clone=False) - - cache_root_folder = self._ds.build_path("vmware_base", self._image_id) - mock_imagecache = mock.Mock() - mock_imagecache.get_image_cache_folder.return_value = cache_root_folder - vi = vmops.VirtualMachineInstanceConfigInfo( - self._instance, "fake_uuid", image_info, - self._ds, self._dc_info, mock_imagecache) - - sized_cached_image_ds_loc = cache_root_folder.join( - "%s.%s.vmdk" % (self._image_id, vi.root_gb)) - - self._vmops._volumeops = mock.Mock() - mock_attach_disk_to_vm = self._vmops._volumeops.attach_disk_to_vm - - self._vmops._use_disk_image_as_linked_clone("fake_vm_ref", vi) - - mock_copy_virtual_disk.assert_called_once_with( - self._session, self._dc_info.ref, - str(vi.cache_image_path), - str(sized_cached_image_ds_loc)) - - if not flavor_fits_image: - mock_extend_virtual_disk.assert_called_once_with( - self._instance, vi.root_gb * units.Mi, - str(sized_cached_image_ds_loc), - self._dc_info.ref) - - mock_attach_disk_to_vm.assert_called_once_with( - "fake_vm_ref", self._instance, vi.ii.adapter_type, - vi.ii.disk_type, - str(sized_cached_image_ds_loc), - vi.root_gb * units.Mi, False) - - def test_use_disk_image_as_linked_clone(self): - self._test_use_disk_image_as_linked_clone() - - def test_use_disk_image_as_linked_clone_flavor_fits_image(self): - self._test_use_disk_image_as_linked_clone(flavor_fits_image=True) - - @mock.patch.object(vmops.VMwareVMOps, '_extend_virtual_disk') - @mock.patch.object(vm_util, 'copy_virtual_disk') - def _test_use_disk_image_as_full_clone(self, - mock_copy_virtual_disk, - mock_extend_virtual_disk, - flavor_fits_image=False): - file_size = 10 * units.Gi if flavor_fits_image else 5 * units.Gi - image_info = images.VMwareImage( - image_id=self._image_id, - file_size=file_size, - linked_clone=False) - - cache_root_folder = self._ds.build_path("vmware_base", self._image_id) - mock_imagecache = mock.Mock() - mock_imagecache.get_image_cache_folder.return_value = cache_root_folder - vi = vmops.VirtualMachineInstanceConfigInfo( - self._instance, "fake_uuid", image_info, - self._ds, self._dc_info, mock_imagecache) - - self._vmops._volumeops = mock.Mock() - mock_attach_disk_to_vm = self._vmops._volumeops.attach_disk_to_vm - - self._vmops._use_disk_image_as_full_clone("fake_vm_ref", vi) - - mock_copy_virtual_disk.assert_called_once_with( - self._session, self._dc_info.ref, - str(vi.cache_image_path), - '[fake_ds] fake_uuid/fake_uuid.vmdk') - - if not flavor_fits_image: - mock_extend_virtual_disk.assert_called_once_with( - self._instance, vi.root_gb * units.Mi, - '[fake_ds] fake_uuid/fake_uuid.vmdk', self._dc_info.ref) - - mock_attach_disk_to_vm.assert_called_once_with( - "fake_vm_ref", self._instance, vi.ii.adapter_type, - vi.ii.disk_type, '[fake_ds] fake_uuid/fake_uuid.vmdk', - vi.root_gb * units.Mi, False) - - def test_use_disk_image_as_full_clone(self): - self._test_use_disk_image_as_full_clone() - - def test_use_disk_image_as_full_clone_image_too_big(self): - self._test_use_disk_image_as_full_clone(flavor_fits_image=True) - - @mock.patch.object(vmops.VMwareVMOps, '_attach_cdrom_to_vm') - @mock.patch.object(vm_util, 'create_virtual_disk') - def _test_use_iso_image(self, - mock_create_virtual_disk, - mock_attach_cdrom, - with_root_disk): - image_info = images.VMwareImage( - image_id=self._image_id, - file_size=10 * units.Mi, - linked_clone=True) - - cache_root_folder = self._ds.build_path("vmware_base", self._image_id) - mock_imagecache = mock.Mock() - mock_imagecache.get_image_cache_folder.return_value = cache_root_folder - vi = vmops.VirtualMachineInstanceConfigInfo( - self._instance, "fake_uuid", image_info, - self._ds, self._dc_info, mock_imagecache) - - self._vmops._volumeops = mock.Mock() - mock_attach_disk_to_vm = self._vmops._volumeops.attach_disk_to_vm - - self._vmops._use_iso_image("fake_vm_ref", vi) - - mock_attach_cdrom.assert_called_once_with( - "fake_vm_ref", self._instance, self._ds.ref, - str(vi.cache_image_path)) - - if with_root_disk: - mock_create_virtual_disk.assert_called_once_with( - self._session, self._dc_info.ref, - vi.ii.adapter_type, vi.ii.disk_type, - '[fake_ds] fake_uuid/fake_uuid.vmdk', - vi.root_gb * units.Mi) - linked_clone = False - mock_attach_disk_to_vm.assert_called_once_with( - "fake_vm_ref", self._instance, - vi.ii.adapter_type, vi.ii.disk_type, - '[fake_ds] fake_uuid/fake_uuid.vmdk', - vi.root_gb * units.Mi, linked_clone) - - def test_use_iso_image_with_root_disk(self): - self._test_use_iso_image(with_root_disk=True) - - def test_use_iso_image_without_root_disk(self): - self._test_use_iso_image(with_root_disk=False) - - def _verify_spawn_method_calls(self, mock_call_method): - # TODO(vui): More explicit assertions of spawn() behavior - # are waiting on additional refactoring pertaining to image - # handling/manipulation. Till then, we continue to assert on the - # sequence of VIM operations invoked. - expected_methods = ['get_dynamic_property', - 'SearchDatastore_Task', - 'CreateVirtualDisk_Task', - 'DeleteDatastoreFile_Task', - 'MoveDatastoreFile_Task', - 'DeleteDatastoreFile_Task', - 'SearchDatastore_Task', - 'ExtendVirtualDisk_Task', - ] - - recorded_methods = [c[1][1] for c in mock_call_method.mock_calls] - self.assertEqual(expected_methods, recorded_methods) - - @mock.patch( - 'nova.virt.vmwareapi.vmops.VMwareVMOps._configure_config_drive') - @mock.patch('nova.virt.vmwareapi.ds_util.get_datastore') - @mock.patch( - 'nova.virt.vmwareapi.vmops.VMwareVMOps.get_datacenter_ref_and_name') - @mock.patch('nova.virt.vmwareapi.vm_util.get_mo_id_from_instance', - return_value='fake_node_mo_id') - @mock.patch('nova.virt.vmwareapi.vm_util.get_res_pool_ref', - return_value='fake_rp_ref') - @mock.patch('nova.virt.vmwareapi.vif.get_vif_info', - return_value=[]) - @mock.patch('nova.utils.is_neutron', - return_value=False) - @mock.patch('nova.virt.vmwareapi.vm_util.get_vm_create_spec', - return_value='fake_create_spec') - @mock.patch('nova.virt.vmwareapi.vm_util.create_vm', - return_value='fake_vm_ref') - @mock.patch('nova.virt.vmwareapi.ds_util.mkdir') - @mock.patch('nova.virt.vmwareapi.vmops.VMwareVMOps._set_machine_id') - @mock.patch( - 'nova.virt.vmwareapi.imagecache.ImageCacheManager.enlist_image') - @mock.patch.object(vmops.VMwareVMOps, '_get_and_set_vnc_config') - @mock.patch('nova.virt.vmwareapi.vm_util.power_on_instance') - @mock.patch('nova.virt.vmwareapi.vm_util.copy_virtual_disk') - # TODO(dims): Need to add tests for create_virtual_disk after the - # disk/image code in spawn gets refactored - def _test_spawn(self, - mock_copy_virtual_disk, - mock_power_on_instance, - mock_get_and_set_vnc_config, - mock_enlist_image, - mock_set_machine_id, - mock_mkdir, - mock_create_vm, - mock_get_create_spec, - mock_is_neutron, - mock_get_vif_info, - mock_get_res_pool_ref, - mock_get_mo_id_for_instance, - mock_get_datacenter_ref_and_name, - mock_get_datastore, - mock_configure_config_drive, - block_device_info=None, - power_on=True, - allocations=None, - config_drive=False): - - self._vmops._volumeops = mock.Mock() - image = { - 'id': 'fake-image-d', - 'disk_format': 'vmdk', - 'size': 1 * units.Gi, - } - network_info = mock.Mock() - mock_get_datastore.return_value = self._ds - mock_get_datacenter_ref_and_name.return_value = self._dc_info - mock_call_method = mock.Mock(return_value='fake_task') - - with contextlib.nested( - mock.patch.object(self._session, '_wait_for_task'), - mock.patch.object(self._session, '_call_method', - mock_call_method), - mock.patch.object(uuidutils, 'generate_uuid', - return_value='tmp-uuid'), - mock.patch.object(images, 'fetch_image') - ) as (_wait_for_task, _call_method, _generate_uuid, _fetch_image): - self._vmops.spawn(self._context, self._instance, image, - injected_files='fake_files', - admin_password='password', - network_info=network_info, - block_device_info=block_device_info, - power_on=power_on) - - mock_is_neutron.assert_called_once_with() - - expected_mkdir_calls = 2 - if block_device_info and len(block_device_info.get( - 'block_device_mapping', [])) > 0: - # if block_device_info contains key 'block_device_mapping' - # with any information, method mkdir wouldn't be called in - # method self._vmops.spawn() - expected_mkdir_calls = 0 - - self.assertEqual(expected_mkdir_calls, len(mock_mkdir.mock_calls)) - - mock_get_mo_id_for_instance.assert_called_once_with(self._instance) - mock_get_res_pool_ref.assert_called_once_with( - self._session, None, 'fake_node_mo_id') - mock_get_vif_info.assert_called_once_with( - self._session, None, False, - constants.DEFAULT_VIF_MODEL, network_info) - if allocations is None: - allocations = {} - mock_get_create_spec.assert_called_once_with( - self._session.vim.client.factory, - self._instance, - 'fake_uuid', - 'fake_ds', - [], - 'otherGuest', - allocations=allocations) - mock_create_vm.assert_called_once_with( - self._session, - self._instance, - 'fake_vm_folder', - 'fake_create_spec', - 'fake_rp_ref') - mock_get_and_set_vnc_config.assert_called_once_with( - self._session.vim.client.factory, - self._instance) - mock_set_machine_id.assert_called_once_with( - self._session.vim.client.factory, - self._instance, - network_info) - if power_on: - mock_power_on_instance.assert_called_once_with( - self._session, self._instance, vm_ref='fake_vm_ref') - else: - self.assertFalse(mock_power_on_instance.called) - - if block_device_info: - root_disk = block_device_info['block_device_mapping'][0] - mock_attach = self._vmops._volumeops.attach_root_volume - mock_attach.assert_called_once_with( - root_disk['connection_info'], self._instance, 'vda', - self._ds.ref) - self.assertFalse(_wait_for_task.called) - self.assertFalse(_fetch_image.called) - self.assertFalse(_call_method.called) - else: - mock_enlist_image.assert_called_once_with( - self._image_id, self._ds, self._dc_info.ref) - - upload_file_name = 'vmware_temp/tmp-uuid/%s/%s-flat.vmdk' % ( - self._image_id, self._image_id) - _fetch_image.assert_called_once_with( - self._context, - self._instance, - self._session._host, - self._dc_info.name, - self._ds.name, - upload_file_name, - cookies='Fake-CookieJar') - self.assertTrue(len(_wait_for_task.mock_calls) > 0) - self._verify_spawn_method_calls(_call_method) - - dc_ref = 'fake_dc_ref' - source_file = unicode('[fake_ds] vmware_base/%s/%s.vmdk' % - (self._image_id, self._image_id)) - dest_file = unicode('[fake_ds] vmware_base/%s/%s.%d.vmdk' % - (self._image_id, self._image_id, - self._instance['root_gb'])) - # TODO(dims): add more tests for copy_virtual_disk after - # the disk/image code in spawn gets refactored - mock_copy_virtual_disk.assert_called_with(self._session, - dc_ref, - source_file, - dest_file) - if config_drive: - mock_configure_config_drive.assert_called_once_with( - self._instance, 'fake_vm_ref', self._dc_info, - self._ds, 'fake_files', 'password') - - @mock.patch.object(ds_util, 'get_datastore') - @mock.patch.object(vmops.VMwareVMOps, 'get_datacenter_ref_and_name') - def _test_get_spawn_vm_config_info(self, - mock_get_datacenter_ref_and_name, - mock_get_datastore, - image_size_bytes=0, - instance_name=None): - image_info = images.VMwareImage( - image_id=self._image_id, - file_size=image_size_bytes, - linked_clone=True) - - mock_get_datastore.return_value = self._ds - mock_get_datacenter_ref_and_name.return_value = self._dc_info - - vi = self._vmops._get_vm_config_info( - self._instance, image_info, instance_name=instance_name) - self.assertEqual(image_info, vi.ii) - self.assertEqual(self._ds, vi.datastore) - self.assertEqual(self._instance.root_gb, vi.root_gb) - self.assertEqual(self._instance, vi.instance) - if instance_name is not None: - self.assertEqual(instance_name, vi.instance_name) - else: - self.assertEqual(self._instance.uuid, vi.instance_name) - - cache_image_path = '[%s] vmware_base/%s/%s.vmdk' % ( - self._ds.name, self._image_id, self._image_id) - self.assertEqual(cache_image_path, str(vi.cache_image_path)) - - cache_image_folder = '[%s] vmware_base/%s' % ( - self._ds.name, self._image_id) - self.assertEqual(cache_image_folder, str(vi.cache_image_folder)) - - def test_get_spawn_vm_config_info(self): - image_size = (self._instance.root_gb) * units.Gi / 2 - self._test_get_spawn_vm_config_info(image_size_bytes=image_size) - - def test_get_spawn_vm_config_info_image_too_big(self): - image_size = (self._instance.root_gb + 1) * units.Gi - self.assertRaises(exception.InstanceUnacceptable, - self._test_get_spawn_vm_config_info, - image_size_bytes=image_size) - - def test_get_spawn_vm_config_info_with_instance_name(self): - image_size = (self._instance.root_gb) * units.Gi / 2 - self._test_get_spawn_vm_config_info( - image_size_bytes=image_size, - instance_name="foo_instance_name") - - def test_spawn(self): - self._test_spawn() - - def test_spawn_config_drive_enabled(self): - self.flags(force_config_drive=True) - self._test_spawn(config_drive=True) - - def test_spawn_no_power_on(self): - self._test_spawn(power_on=False) - - def test_spawn_with_block_device_info(self): - block_device_info = { - 'block_device_mapping': [{'connection_info': 'fake'}] - } - self._test_spawn(block_device_info=block_device_info) - - def test_spawn_with_block_device_info_with_config_drive(self): - self.flags(force_config_drive=True) - block_device_info = { - 'block_device_mapping': [{'connection_info': 'fake'}] - } - self._test_spawn(block_device_info=block_device_info, - config_drive=True) - - def test_build_virtual_machine(self): - image_id = nova.tests.image.fake.get_valid_image_id() - image = images.VMwareImage(image_id=image_id) - - vm_ref = self._vmops.build_virtual_machine(self._instance, - 'fake-instance-name', - image, self._dc_info, - self._ds, self.network_info) - - vm = vmwareapi_fake._get_object(vm_ref) - - # Test basic VM parameters - self.assertEqual('fake-instance-name', vm.name) - # NOTE(mdbooth): The instanceUuid behaviour below is apparently - # deliberate. - self.assertEqual('fake-instance-name', - vm.get('summary.config.instanceUuid')) - self.assertEqual(self._instance_values['vcpus'], - vm.get('summary.config.numCpu')) - self.assertEqual(self._instance_values['memory_mb'], - vm.get('summary.config.memorySizeMB')) - - # Test NSX config - for optval in vm.get('config.extraConfig').OptionValue: - if optval.key == 'nvp.vm-uuid': - self.assertEqual(self._instance_values['uuid'], optval.value) - break - else: - self.fail('nvp.vm-uuid not found in extraConfig') - - # Test that the VM is associated with the specified datastore - datastores = vm.datastore.ManagedObjectReference - self.assertEqual(1, len(datastores)) - - datastore = vmwareapi_fake._get_object(datastores[0]) - self.assertEqual(self._ds.name, datastore.get('summary.name')) - - # Test that the VM's network is configured as specified - devices = vm.get('config.hardware.device').VirtualDevice - for device in devices: - if device.obj_name != 'ns0:VirtualE1000': - continue - self.assertEqual(self._network_values['address'], - device.macAddress) - break - else: - self.fail('NIC not configured') - - def test_spawn_cpu_limit(self): - def _fake_flavor_get(context, id): - flavor = stubs._fake_flavor_get(context, id) - flavor['extra_specs'].update({'quota:cpu_limit': 7}) - return flavor - - with mock.patch.object(db, 'flavor_get', _fake_flavor_get): - self._test_spawn(allocations={'cpu_limit': 7}) - - def test_spawn_cpu_reservation(self): - def _fake_flavor_get(context, id): - flavor = stubs._fake_flavor_get(context, id) - flavor['extra_specs'].update({'quota:cpu_reservation': 7}) - return flavor - - with mock.patch.object(db, 'flavor_get', _fake_flavor_get): - self._test_spawn(allocations={'cpu_reservation': 7}) - - def test_spawn_cpu_allocations(self): - def _fake_flavor_get(context, id): - flavor = stubs._fake_flavor_get(context, id) - flavor['extra_specs'].update({'quota:cpu_limit': 7, - 'quota:cpu_reservation': 6}) - return flavor - - with mock.patch.object(db, 'flavor_get', _fake_flavor_get): - self._test_spawn(allocations={'cpu_limit': 7, - 'cpu_reservation': 6}) - - def test_spawn_cpu_shares_level(self): - def _fake_flavor_get(context, id): - flavor = stubs._fake_flavor_get(context, id) - flavor['extra_specs'].update({'quota:cpu_shares_level': 'high'}) - return flavor - - with mock.patch.object(db, 'flavor_get', _fake_flavor_get): - self._test_spawn(allocations={'cpu_shares_level': 'high'}) - - def test_spawn_cpu_shares_custom(self): - def _fake_flavor_get(context, id): - flavor = stubs._fake_flavor_get(context, id) - flavor['extra_specs'].update({'quota:cpu_shares_level': 'custom', - 'quota:cpu_shares_share': 1948}) - return flavor - - with mock.patch.object(db, 'flavor_get', _fake_flavor_get): - self._test_spawn(allocations={'cpu_shares_level': 'custom', - 'cpu_shares_share': 1948}) - - def _make_vm_config_info(self, is_iso=False, is_sparse_disk=False): - disk_type = (constants.DISK_TYPE_SPARSE if is_sparse_disk - else constants.DEFAULT_DISK_TYPE) - file_type = (constants.DISK_FORMAT_ISO if is_iso - else constants.DEFAULT_DISK_FORMAT) - - image_info = images.VMwareImage( - image_id=self._image_id, - file_size=10 * units.Mi, - file_type=file_type, - disk_type=disk_type, - linked_clone=True) - cache_root_folder = self._ds.build_path("vmware_base", self._image_id) - mock_imagecache = mock.Mock() - mock_imagecache.get_image_cache_folder.return_value = cache_root_folder - vi = vmops.VirtualMachineInstanceConfigInfo( - self._instance, "fake_uuid", image_info, - self._ds, self._dc_info, mock_imagecache) - return vi - - @mock.patch.object(vmops.VMwareVMOps, 'check_cache_folder') - @mock.patch.object(vmops.VMwareVMOps, '_fetch_image_as_file') - @mock.patch.object(vmops.VMwareVMOps, '_prepare_iso_image') - @mock.patch.object(vmops.VMwareVMOps, '_prepare_sparse_image') - @mock.patch.object(vmops.VMwareVMOps, '_prepare_flat_image') - @mock.patch.object(vmops.VMwareVMOps, '_cache_iso_image') - @mock.patch.object(vmops.VMwareVMOps, '_cache_sparse_image') - @mock.patch.object(vmops.VMwareVMOps, '_cache_flat_image') - @mock.patch.object(vmops.VMwareVMOps, '_delete_datastore_file') - def _test_fetch_image_if_missing(self, - mock_delete_datastore_file, - mock_cache_flat_image, - mock_cache_sparse_image, - mock_cache_iso_image, - mock_prepare_flat_image, - mock_prepare_sparse_image, - mock_prepare_iso_image, - mock_fetch_image_as_file, - mock_check_cache_folder, - is_iso=False, - is_sparse_disk=False): - - tmp_dir_path = mock.Mock() - tmp_image_path = mock.Mock() - if is_iso: - mock_prepare = mock_prepare_iso_image - mock_cache = mock_cache_iso_image - elif is_sparse_disk: - mock_prepare = mock_prepare_sparse_image - mock_cache = mock_cache_sparse_image - else: - mock_prepare = mock_prepare_flat_image - mock_cache = mock_cache_flat_image - mock_prepare.return_value = tmp_dir_path, tmp_image_path - - vi = self._make_vm_config_info(is_iso, is_sparse_disk) - self._vmops._fetch_image_if_missing(self._context, vi) - - mock_check_cache_folder.assert_called_once_with( - self._ds.name, self._ds.ref) - mock_prepare.assert_called_once_with(vi) - mock_fetch_image_as_file.assert_called_once_with( - self._context, vi, tmp_image_path) - mock_cache.assert_called_once_with(vi, tmp_image_path) - mock_delete_datastore_file.assert_called_once_with( - str(tmp_dir_path), self._dc_info.ref) - - def test_fetch_image_if_missing(self): - self._test_fetch_image_if_missing() - - def test_fetch_image_if_missing_with_sparse(self): - self._test_fetch_image_if_missing( - is_sparse_disk=True) - - def test_fetch_image_if_missing_with_iso(self): - self._test_fetch_image_if_missing( - is_iso=True) - - @mock.patch.object(images, 'fetch_image') - def test_fetch_image_as_file(self, mock_fetch_image): - vi = self._make_vm_config_info() - image_ds_loc = mock.Mock() - self._vmops._fetch_image_as_file(self._context, vi, image_ds_loc) - mock_fetch_image.assert_called_once_with( - self._context, - vi.instance, - self._session._host, - self._dc_info.name, - self._ds.name, - image_ds_loc.rel_path, - cookies='Fake-CookieJar') - - @mock.patch.object(uuidutils, 'generate_uuid', return_value='tmp-uuid') - def test_prepare_iso_image(self, mock_generate_uuid): - vi = self._make_vm_config_info(is_iso=True) - tmp_dir_loc, tmp_image_ds_loc = self._vmops._prepare_iso_image(vi) - - expected_tmp_dir_path = '[%s] vmware_temp/tmp-uuid' % (self._ds.name) - expected_image_path = '[%s] vmware_temp/tmp-uuid/%s/%s.iso' % ( - self._ds.name, self._image_id, self._image_id) - - self.assertEqual(str(tmp_dir_loc), expected_tmp_dir_path) - self.assertEqual(str(tmp_image_ds_loc), expected_image_path) - - @mock.patch.object(uuidutils, 'generate_uuid', return_value='tmp-uuid') - def test_prepare_sparse_image(self, mock_generate_uuid): - vi = self._make_vm_config_info(is_sparse_disk=True) - tmp_dir_loc, tmp_image_ds_loc = self._vmops._prepare_sparse_image(vi) - - expected_tmp_dir_path = '[%s] vmware_temp/tmp-uuid' % (self._ds.name) - expected_image_path = '[%s] vmware_temp/tmp-uuid/%s/%s' % ( - self._ds.name, self._image_id, "tmp-sparse.vmdk") - - self.assertEqual(str(tmp_dir_loc), expected_tmp_dir_path) - self.assertEqual(str(tmp_image_ds_loc), expected_image_path) - - @mock.patch.object(ds_util, 'mkdir') - @mock.patch.object(vm_util, 'create_virtual_disk') - @mock.patch.object(vmops.VMwareVMOps, '_delete_datastore_file') - @mock.patch.object(uuidutils, 'generate_uuid', return_value='tmp-uuid') - def test_prepare_flat_image(self, - mock_generate_uuid, - mock_delete_datastore_file, - mock_create_virtual_disk, - mock_mkdir): - vi = self._make_vm_config_info() - tmp_dir_loc, tmp_image_ds_loc = self._vmops._prepare_flat_image(vi) - - expected_tmp_dir_path = '[%s] vmware_temp/tmp-uuid' % (self._ds.name) - expected_image_path = '[%s] vmware_temp/tmp-uuid/%s/%s-flat.vmdk' % ( - self._ds.name, self._image_id, self._image_id) - expected_image_path_parent = '[%s] vmware_temp/tmp-uuid/%s' % ( - self._ds.name, self._image_id) - expected_path_to_create = '[%s] vmware_temp/tmp-uuid/%s/%s.vmdk' % ( - self._ds.name, self._image_id, self._image_id) - - mock_mkdir.assert_called_once_with( - self._session, DsPathMatcher(expected_image_path_parent), - self._dc_info.ref) - - self.assertEqual(str(tmp_dir_loc), expected_tmp_dir_path) - self.assertEqual(str(tmp_image_ds_loc), expected_image_path) - - image_info = vi.ii - mock_create_virtual_disk.assert_called_once_with( - self._session, self._dc_info.ref, - image_info.adapter_type, - image_info.disk_type, - DsPathMatcher(expected_path_to_create), - image_info.file_size_in_kb) - mock_delete_datastore_file.assert_called_once_with( - DsPathMatcher(expected_image_path), - self._dc_info.ref) - - @mock.patch.object(ds_util, 'file_move') - def test_cache_iso_image(self, mock_file_move): - vi = self._make_vm_config_info(is_iso=True) - tmp_image_ds_loc = mock.Mock() - - self._vmops._cache_iso_image(vi, tmp_image_ds_loc) - - mock_file_move.assert_called_once_with( - self._session, self._dc_info.ref, - tmp_image_ds_loc.parent, - DsPathMatcher('[fake_ds] vmware_base/%s' % self._image_id)) - - @mock.patch.object(ds_util, 'file_move') - def test_cache_flat_image(self, mock_file_move): - vi = self._make_vm_config_info() - tmp_image_ds_loc = mock.Mock() - - self._vmops._cache_flat_image(vi, tmp_image_ds_loc) - - mock_file_move.assert_called_once_with( - self._session, self._dc_info.ref, - tmp_image_ds_loc.parent, - DsPathMatcher('[fake_ds] vmware_base/%s' % self._image_id)) - - @mock.patch.object(ds_util, 'file_move') - @mock.patch.object(vm_util, 'copy_virtual_disk') - @mock.patch.object(vmops.VMwareVMOps, '_delete_datastore_file') - def test_cache_sparse_image(self, - mock_delete_datastore_file, - mock_copy_virtual_disk, - mock_file_move): - vi = self._make_vm_config_info(is_sparse_disk=True) - - sparse_disk_path = "[%s] vmware_temp/tmp-uuid/%s/tmp-sparse.vmdk" % ( - self._ds.name, self._image_id) - tmp_image_ds_loc = ds_util.DatastorePath.parse(sparse_disk_path) - - self._vmops._cache_sparse_image(vi, tmp_image_ds_loc) - - target_disk_path = "[%s] vmware_temp/tmp-uuid/%s/%s.vmdk" % ( - self._ds.name, - self._image_id, self._image_id) - mock_copy_virtual_disk.assert_called_once_with( - self._session, self._dc_info.ref, - sparse_disk_path, - DsPathMatcher(target_disk_path)) diff --git a/nova/tests/virt/vmwareapi/test_volumeops.py b/nova/tests/virt/vmwareapi/test_volumeops.py deleted file mode 100644 index 1d05843a54..0000000000 --- a/nova/tests/virt/vmwareapi/test_volumeops.py +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright 2013 IBM Corp. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import contextlib - -import mock - -from nova import test -from nova.tests.virt.vmwareapi import fake as vmwareapi_fake -from nova.tests.virt.vmwareapi import stubs -from nova.virt.vmwareapi import driver -from nova.virt.vmwareapi import volumeops - - -class VMwareVolumeOpsTestCase(test.NoDBTestCase): - - def setUp(self): - - super(VMwareVolumeOpsTestCase, self).setUp() - vmwareapi_fake.reset() - stubs.set_stubs(self.stubs) - self._session = driver.VMwareAPISession() - - self._volumeops = volumeops.VMwareVolumeOps(self._session) - self.instance = {'name': 'fake_name', 'uuid': 'fake_uuid'} - - def _test_detach_disk_from_vm(self, destroy_disk=False): - def fake_call_method(module, method, *args, **kwargs): - vmdk_detach_config_spec = kwargs.get('spec') - virtual_device_config = vmdk_detach_config_spec.deviceChange[0] - self.assertEqual('remove', virtual_device_config.operation) - self.assertEqual('ns0:VirtualDeviceConfigSpec', - virtual_device_config.obj_name) - if destroy_disk: - self.assertEqual('destroy', - virtual_device_config.fileOperation) - else: - self.assertFalse(hasattr(virtual_device_config, - 'fileOperation')) - return 'fake_configure_task' - with contextlib.nested( - mock.patch.object(self._session, '_wait_for_task'), - mock.patch.object(self._session, '_call_method', - fake_call_method) - ) as (_wait_for_task, _call_method): - fake_device = vmwareapi_fake.DataObject() - fake_device.backing = vmwareapi_fake.DataObject() - fake_device.backing.fileName = 'fake_path' - fake_device.key = 'fake_key' - self._volumeops.detach_disk_from_vm('fake_vm_ref', self.instance, - fake_device, destroy_disk) - _wait_for_task.assert_has_calls([ - mock.call('fake_configure_task')]) - - def test_detach_with_destroy_disk_from_vm(self): - self._test_detach_disk_from_vm(destroy_disk=True) - - def test_detach_without_destroy_disk_from_vm(self): - self._test_detach_disk_from_vm(destroy_disk=False) - - def _fake_call_get_dynamic_property(self, uuid, result): - def fake_call_method(vim, method, vm_ref, type, prop): - expected_prop = 'config.extraConfig["volume-%s"]' % uuid - self.assertEqual('VirtualMachine', type) - self.assertEqual(expected_prop, prop) - return result - return fake_call_method - - def test_get_volume_uuid(self): - vm_ref = mock.Mock() - uuid = '1234' - opt_val = vmwareapi_fake.OptionValue('volume-%s' % uuid, 'volume-val') - fake_call = self._fake_call_get_dynamic_property(uuid, opt_val) - with mock.patch.object(self._session, "_call_method", fake_call): - val = self._volumeops._get_volume_uuid(vm_ref, uuid) - self.assertEqual('volume-val', val) - - def test_get_volume_uuid_not_found(self): - vm_ref = mock.Mock() - uuid = '1234' - fake_call = self._fake_call_get_dynamic_property(uuid, None) - with mock.patch.object(self._session, "_call_method", fake_call): - val = self._volumeops._get_volume_uuid(vm_ref, uuid) - self.assertIsNone(val) |