def test_get_linked_clone_image_path(self): image_path = self.vm_manager.get_linked_clone_image_path # VM not found vm = MagicMock(return_value=None) self.vm_manager.vim_client.get_vm_in_cache = vm assert_that(image_path("vm1"), is_(None)) # disks is None vm = MagicMock(return_value=VmCache(disks=None)) self.vm_manager.vim_client.get_vm_in_cache = vm assert_that(image_path("vm1"), is_(None)) # disks is an empty list vm = MagicMock(return_value=VmCache(disks=[])) self.vm_manager.vim_client.get_vm_in_cache = vm assert_that(image_path("vm1"), is_(None)) # no image disk vm = MagicMock(return_value=VmCache(disks=["a", "b", "c"])) self.vm_manager.vim_client.get_vm_in_cache = vm assert_that(image_path("vm1"), is_(None)) # image found image = "[ds1] image_ttylinux/ttylinux.vmdk" vm = MagicMock(return_value=VmCache(disks=["a", "b", image])) self.vm_manager.vim_client.get_vm_in_cache = vm assert_that(image_path("vm1"), is_(datastore_to_os_path(image)))
def test_get_resources(self): """ Test that get_resources excludes VMs/disks if it can't find their corresponding datastore UUIDs. """ self.vm_manager.vim_client.get_vms_in_cache = MagicMock(return_value=[ VmCache(path="vm_path_a", disks=["disk_a", "disk_b", "disk_c"]), VmCache(path="vm_path_b", disks=["disk_b", "disk_c", "disk_d"]), VmCache(path="vm_path_c", disks=["disk_c", "disk_d", "disk_e"]), ]) def normalize(name): if name == "vm_path_b" or name == "disk_b": raise DatastoreNotFoundException() return name def mock_get_name(path): return path def mock_get_state(power_state): return State.STOPPED self.vm_manager._ds_manager.normalize.side_effect = normalize self.vm_manager._get_datastore_name_from_ds_path = mock_get_name self.vm_manager._power_state_to_resource_state = mock_get_state # vm_path_b and disk_b are not included in the get_resources response. resources = self.vm_manager.get_resources() assert_that(len(resources), equal_to(2)) assert_that(len(resources[0].disks), equal_to(2)) assert_that(len(resources[1].disks), equal_to(3))
def test_used_memory(self): self.vm_manager.vim_client.get_vms_in_cache = MagicMock(return_value=[ VmCache(memory_mb=1024), VmCache(), VmCache(memory_mb=2048) ]) memory = self.vm_manager.get_used_memory_mb() self.assertEqual(memory, 2048 + 1024)
def _add_or_modify_vm_cache(self, object): # Type of object.obj is vim.VirtualMachine. str(object.obj) is moref # id, something like 'vim.VirtualMachine:1227'. moref id is the unique # representation of all objects in esx. if str(object.obj) not in self._vm_cache: vm = VmCache() else: vm = self._vm_cache[str(object.obj)] for change in object.changeSet: # We are not interested in ops other than assign. # Other operations e.g. add/remove/indirectRemove, only appears # when a property is added/removed. However the changes we # watched are all static. if change.op != "assign": continue # None value is not updated if change.val is None: continue if change.name == "name": vm.name = change.val self._logger.debug("cache update: add vm name %s" % vm.name) self._vm_name_to_ref[change.val] = str(object.obj) elif change.name == "runtime.powerState": vm.power_state = PowerState._NAMES_TO_VALUES[change.val] elif change.name == "config": vm.memory_mb = change.val.hardware.memoryMB vm.num_cpu = change.val.hardware.numCPU # files is an optional field, which could be None. if change.val.files: vm.path = change.val.files.vmPathName for e in change.val.extraConfig: if e.key == "photon_controller.vminfo.tenant": vm.tenant_id = e.value elif e.key == "photon_controller.vminfo.project": vm.project_id = e.value elif change.name == "layout.disk": disks = [] for disk in change.val: if disk.diskFile: for disk_file in disk.diskFile: disks.append(disk_file) vm.disks = disks self._logger.debug("cache update: update vm [%s] => %s" % (str( object.obj), vm)) if str(object.obj) not in self._vm_cache: self._vm_cache[str(object.obj)] = vm
def _update_vm_cache(self, object): # Type of object.obj is vim.VirtualMachine. str(object.obj) is moref # id, something like 'vim.VirtualMachine:1227'. moref id is the unique # representation of all objects in esx. if str(object.obj) not in self._vm_cache: vm = VmCache() else: vm = self._vm_cache[str(object.obj)] for change in object.changeSet: # We are not interested in ops other than assign. # Other operations e.g. add/remove/indirectRemove, only appears # when a property is added/removed. However the changes we # watched are all static. if change.op != "assign": continue # None value is not updated if change.val is None: continue if change.name == "name": vm.name = change.val self._logger.debug("cache update: add vm name %s" % vm.name) self._vm_name_to_ref[change.val] = str(object.obj) elif change.name == "runtime.powerState": if change.val == "poweredOff": vm.power_state = VmPowerState.STOPPED elif change.val == "poweredOn": vm.power_state = VmPowerState.STARTED elif change.val == "suspended": vm.power_state = VmPowerState.SUSPENDED elif change.name == "config": vm.memory_mb = change.val.hardware.memoryMB vm.num_cpu = change.val.hardware.numCPU vm.location_id = change.val.locationId # files is an optional field, which could be None. if change.val.files: vm.path = change.val.files.vmPathName elif change.name == "layout.disk": disks = [] for disk in change.val: if disk.diskFile: for disk_file in disk.diskFile: disks.append(disk_file) vm.disks = disks self._logger.debug("cache update: update vm [%s] => %s" % (str(object.obj), vm)) if str(object.obj) not in self._vm_cache: self._vm_cache[str(object.obj)] = vm
def get_vm_in_cache(self, vm_id): vm = self._client.GetCachedVm(self._session, vm_id) return VmCache(name=vm.name, path=vm.path, disks=vm.disks, location_id=vm.location_id, power_state=vm.power_state, memory_mb=vm.memoryMB, num_cpu=vm.nCPU)
def get_vms_in_cache(self): vms = [] for vm_id in self._client.GetCachedVMs(self._session): vm = self._client.GetCachedVm(self._session, vm_id) vms.append( VmCache(name=vm.name, path=vm.path, disks=vm.disks, location_id=vm.location_id, power_state=vm.power_state, memory_mb=vm.memoryMB, num_cpu=vm.nCPU)) return vms