Files
compute-hyperv/hyperv/tests/unit/test_vmutils.py
Lucian Petrut a08aa6a2c0 Hyper-V: restart serial console workers after instance power change
At the moment, the only way the Hyper-V handles unexpected power
state changes is via the manager periodic task. The issue is that
unexpected instance reboots are not handled at all.

After an instance is stopped, suspended or paused, the console log
workers are stopped as well as the serial console pipe is closed.
Those workers are never restarted unless a power change is triggered
by the manager.

This patch proposes an instance state event listener, emiting events
that can be handled by the manager, similar to the Libvirt driver
workflow.

Change-Id: Ia0a875707a7a37224efb333feab1503e83449cc4
Closes-Bug: #1428505
2015-05-13 05:39:30 -07:00

832 lines
35 KiB
Python

# Copyright 2014 Cloudbase Solutions Srl
# 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 mock
from nova import exception
from hyperv.nova import constants
from hyperv.nova import vmutils
from hyperv.tests import test
class VMUtilsTestCase(test.NoDBTestCase):
"""Unit tests for the Hyper-V VMUtils class."""
_FAKE_VM_NAME = 'fake_vm'
_FAKE_MEMORY_MB = 2
_FAKE_VCPUS_NUM = 4
_FAKE_JOB_PATH = 'fake_job_path'
_FAKE_RET_VAL = 0
_FAKE_RET_VAL_BAD = -1
_FAKE_PATH = "fake_path"
_FAKE_CTRL_PATH = 'fake_ctrl_path'
_FAKE_CTRL_ADDR = 0
_FAKE_DRIVE_ADDR = 0
_FAKE_MOUNTED_DISK_PATH = 'fake_mounted_disk_path'
_FAKE_VM_PATH = "fake_vm_path"
_FAKE_VHD_PATH = "fake_vhd_path"
_FAKE_DVD_PATH = "fake_dvd_path"
_FAKE_VOLUME_DRIVE_PATH = "fake_volume_drive_path"
_FAKE_VM_UUID = "04e79212-39bc-4065-933c-50f6d48a57f6"
_FAKE_INSTANCE = {"name": _FAKE_VM_NAME,
"uuid": _FAKE_VM_UUID}
_FAKE_SNAPSHOT_PATH = "fake_snapshot_path"
_FAKE_RES_DATA = "fake_res_data"
_FAKE_HOST_RESOURCE = "fake_host_resource"
_FAKE_CLASS = "FakeClass"
_FAKE_RES_PATH = "fake_res_path"
_FAKE_RES_NAME = 'fake_res_name'
_FAKE_ADDRESS = "fake_address"
_FAKE_JOB_STATUS_DONE = 7
_FAKE_JOB_STATUS_BAD = -1
_FAKE_JOB_DESCRIPTION = "fake_job_description"
_FAKE_ERROR = "fake_error"
_FAKE_ELAPSED_TIME = 0
_CONCRETE_JOB = "Msvm_ConcreteJob"
_FAKE_DYNAMIC_MEMORY_RATIO = 1.0
_FAKE_SUMMARY_INFO = {'NumberOfProcessors': 4,
'EnabledState': 2,
'MemoryUsage': 2,
'UpTime': 1}
_DEFINE_SYSTEM = 'DefineVirtualSystem'
_DESTROY_SYSTEM = 'DestroyVirtualSystem'
_DESTROY_SNAPSHOT = 'RemoveVirtualSystemSnapshot'
_ADD_RESOURCE = 'AddVirtualSystemResources'
_REMOVE_RESOURCE = 'RemoveVirtualSystemResources'
_SETTING_TYPE = 'SettingType'
_VM_GEN = constants.VM_GEN_1
_VIRTUAL_SYSTEM_TYPE_REALIZED = 3
def setUp(self):
self._vmutils = vmutils.VMUtils()
self._vmutils._conn = mock.MagicMock()
super(VMUtilsTestCase, self).setUp()
def test_enable_vm_metrics_collection(self):
self.assertRaises(NotImplementedError,
self._vmutils.enable_vm_metrics_collection,
self._FAKE_VM_NAME)
def test_get_vm_summary_info(self):
self._lookup_vm()
mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
mock_summary = mock.MagicMock()
mock_svc.GetSummaryInformation.return_value = (self._FAKE_RET_VAL,
[mock_summary])
for (key, val) in self._FAKE_SUMMARY_INFO.items():
setattr(mock_summary, key, val)
summary = self._vmutils.get_vm_summary_info(self._FAKE_VM_NAME)
self.assertEqual(self._FAKE_SUMMARY_INFO, summary)
def _lookup_vm(self):
mock_vm = mock.MagicMock()
self._vmutils._lookup_vm_check = mock.MagicMock(
return_value=mock_vm)
mock_vm.path_.return_value = self._FAKE_VM_PATH
return mock_vm
def test_lookup_vm_ok(self):
mock_vm = mock.MagicMock()
self._vmutils._conn.Msvm_ComputerSystem.return_value = [mock_vm]
vm = self._vmutils._lookup_vm_check(self._FAKE_VM_NAME)
self.assertEqual(mock_vm, vm)
def test_lookup_vm_multiple(self):
mockvm = mock.MagicMock()
self._vmutils._conn.Msvm_ComputerSystem.return_value = [mockvm, mockvm]
self.assertRaises(vmutils.HyperVException,
self._vmutils._lookup_vm_check,
self._FAKE_VM_NAME)
def test_lookup_vm_none(self):
self._vmutils._conn.Msvm_ComputerSystem.return_value = []
self.assertRaises(exception.NotFound,
self._vmutils._lookup_vm_check,
self._FAKE_VM_NAME)
def test_set_vm_memory_static(self):
self._test_set_vm_memory_dynamic(1.0)
def test_set_vm_memory_dynamic(self):
self._test_set_vm_memory_dynamic(2.0)
def _test_set_vm_memory_dynamic(self, dynamic_memory_ratio):
mock_vm = self._lookup_vm()
mock_s = self._vmutils._conn.Msvm_VirtualSystemSettingData()[0]
mock_s.SystemType = 3
mock_vmsetting = mock.MagicMock()
mock_vmsetting.associators.return_value = [mock_s]
self._vmutils._modify_virt_resource = mock.MagicMock()
self._vmutils._set_vm_memory(mock_vm, mock_vmsetting,
self._FAKE_MEMORY_MB,
dynamic_memory_ratio)
self._vmutils._modify_virt_resource.assert_called_with(
mock_s, self._FAKE_VM_PATH)
if dynamic_memory_ratio > 1:
self.assertTrue(mock_s.DynamicMemoryEnabled)
else:
self.assertFalse(mock_s.DynamicMemoryEnabled)
def test_soft_shutdown_vm(self):
mock_vm = self._lookup_vm()
mock_shutdown = mock.MagicMock()
mock_shutdown.InitiateShutdown.return_value = (self._FAKE_RET_VAL, )
mock_vm.associators.return_value = [mock_shutdown]
with mock.patch.object(self._vmutils, 'check_ret_val') as mock_check:
self._vmutils.soft_shutdown_vm(self._FAKE_VM_NAME)
mock_shutdown.InitiateShutdown.assert_called_once_with(
Force=False, Reason=mock.ANY)
mock_check.assert_called_once_with(self._FAKE_RET_VAL, None)
def test_soft_shutdown_vm_no_component(self):
mock_vm = self._lookup_vm()
mock_vm.associators.return_value = []
with mock.patch.object(self._vmutils, 'check_ret_val') as mock_check:
self._vmutils.soft_shutdown_vm(self._FAKE_VM_NAME)
self.assertFalse(mock_check.called)
@mock.patch('hyperv.nova.vmutils.VMUtils._get_vm_disks')
def test_get_vm_storage_paths(self, mock_get_vm_disks):
self._lookup_vm()
mock_rasds = self._create_mock_disks()
mock_get_vm_disks.return_value = ([mock_rasds[0]], [mock_rasds[1]])
storage = self._vmutils.get_vm_storage_paths(self._FAKE_VM_NAME)
(disk_files, volume_drives) = storage
self.assertEqual([self._FAKE_VHD_PATH], disk_files)
self.assertEqual([self._FAKE_VOLUME_DRIVE_PATH], volume_drives)
def test_get_vm_disks(self):
mock_vm = self._lookup_vm()
mock_vmsettings = [mock.MagicMock()]
mock_vm.associators.return_value = mock_vmsettings
mock_rasds = self._create_mock_disks()
mock_vmsettings[0].associators.return_value = mock_rasds
(disks, volumes) = self._vmutils._get_vm_disks(mock_vm)
mock_vm.associators.assert_called_with(
wmi_result_class=self._vmutils._VIRTUAL_SYSTEM_SETTING_DATA_CLASS)
mock_vmsettings[0].associators.assert_called_with(
wmi_result_class=self._vmutils._RESOURCE_ALLOC_SETTING_DATA_CLASS)
self.assertEqual([mock_rasds[0]], disks)
self.assertEqual([mock_rasds[1]], volumes)
def _create_mock_disks(self):
mock_rasd1 = mock.MagicMock()
mock_rasd1.ResourceSubType = self._vmutils._HARD_DISK_RES_SUB_TYPE
mock_rasd1.HostResource = [self._FAKE_VHD_PATH]
mock_rasd1.Connection = [self._FAKE_VHD_PATH]
mock_rasd1.Parent = self._FAKE_CTRL_PATH
mock_rasd1.Address = self._FAKE_ADDRESS
mock_rasd1.HostResource = [self._FAKE_VHD_PATH]
mock_rasd2 = mock.MagicMock()
mock_rasd2.ResourceSubType = self._vmutils._PHYS_DISK_RES_SUB_TYPE
mock_rasd2.HostResource = [self._FAKE_VOLUME_DRIVE_PATH]
return [mock_rasd1, mock_rasd2]
@mock.patch.object(vmutils.VMUtils, '_set_vm_vcpus')
@mock.patch.object(vmutils.VMUtils, '_set_vm_memory')
@mock.patch.object(vmutils.VMUtils, '_get_wmi_obj')
def test_create_vm(self, mock_get_wmi_obj, mock_set_mem, mock_set_vcpus):
mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
getattr(mock_svc, self._DEFINE_SYSTEM).return_value = (
None, self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
mock_vm = mock_get_wmi_obj.return_value
self._vmutils._conn.Msvm_ComputerSystem.return_value = [mock_vm]
mock_s = mock.MagicMock()
setattr(mock_s,
self._SETTING_TYPE,
self._VIRTUAL_SYSTEM_TYPE_REALIZED)
mock_vm.associators.return_value = [mock_s]
self._vmutils.create_vm(self._FAKE_VM_NAME, self._FAKE_MEMORY_MB,
self._FAKE_VCPUS_NUM, False,
self._FAKE_DYNAMIC_MEMORY_RATIO,
self._VM_GEN,
mock.sentinel.instance_path)
self.assertTrue(getattr(mock_svc, self._DEFINE_SYSTEM).called)
mock_set_mem.assert_called_with(mock_vm, mock_s, self._FAKE_MEMORY_MB,
self._FAKE_DYNAMIC_MEMORY_RATIO)
mock_set_vcpus.assert_called_with(mock_vm, mock_s,
self._FAKE_VCPUS_NUM,
False)
def test_get_vm_scsi_controller(self):
self._prepare_get_vm_controller(self._vmutils._SCSI_CTRL_RES_SUB_TYPE)
path = self._vmutils.get_vm_scsi_controller(self._FAKE_VM_NAME)
self.assertEqual(self._FAKE_RES_PATH, path)
@mock.patch("hyperv.nova.vmutils.VMUtils.get_attached_disks")
def test_get_free_controller_slot(self, mock_get_attached_disks):
mock_disk = mock.MagicMock()
mock_disk.AddressOnParent = 3
mock_get_attached_disks.return_value = [mock_disk]
response = self._vmutils.get_free_controller_slot(
self._FAKE_CTRL_PATH)
mock_get_attached_disks.assert_called_once_with(
self._FAKE_CTRL_PATH)
self.assertEqual(response, 0)
def test_get_free_controller_slot_exception(self):
fake_drive = mock.MagicMock()
type(fake_drive).AddressOnParent = mock.PropertyMock(
side_effect=xrange(constants.SCSI_CONTROLLER_SLOTS_NUMBER))
with mock.patch.object(self._vmutils,
'get_attached_disks') as fake_get_attached_disks:
fake_get_attached_disks.return_value = (
[fake_drive] * constants.SCSI_CONTROLLER_SLOTS_NUMBER)
self.assertRaises(vmutils.HyperVException,
self._vmutils.get_free_controller_slot,
mock.sentinel.scsi_controller_path)
def test_get_vm_ide_controller(self):
self._prepare_get_vm_controller(self._vmutils._IDE_CTRL_RES_SUB_TYPE)
path = self._vmutils.get_vm_ide_controller(self._FAKE_VM_NAME,
self._FAKE_ADDRESS)
self.assertEqual(self._FAKE_RES_PATH, path)
def test_get_vm_ide_controller_none(self):
self._prepare_get_vm_controller(self._vmutils._IDE_CTRL_RES_SUB_TYPE)
path = self._vmutils.get_vm_ide_controller(
mock.sentinel.FAKE_VM_NAME, mock.sentinel.FAKE_NOT_FOUND_ADDR)
self.assertNotEqual(self._FAKE_RES_PATH, path)
def _prepare_get_vm_controller(self, resource_sub_type):
mock_vm = self._lookup_vm()
mock_vm_settings = mock.MagicMock()
mock_rasds = mock.MagicMock()
mock_rasds.path_.return_value = self._FAKE_RES_PATH
mock_rasds.ResourceSubType = resource_sub_type
mock_rasds.Address = self._FAKE_ADDRESS
mock_vm_settings.associators.return_value = [mock_rasds]
mock_vm.associators.return_value = [mock_vm_settings]
def _prepare_resources(self, mock_path, mock_subtype, mock_vm_settings):
mock_rasds = mock_vm_settings.associators.return_value[0]
mock_rasds.path_.return_value = mock_path
mock_rasds.ResourceSubType = mock_subtype
return mock_rasds
@mock.patch("hyperv.nova.vmutils.VMUtils.get_free_controller_slot")
@mock.patch("hyperv.nova.vmutils.VMUtils._get_vm_scsi_controller")
def test_attach_scsi_drive(self, mock_get_vm_scsi_controller,
mock_get_free_controller_slot):
mock_vm = self._lookup_vm()
mock_get_vm_scsi_controller.return_value = self._FAKE_CTRL_PATH
mock_get_free_controller_slot.return_value = self._FAKE_DRIVE_ADDR
with mock.patch.object(self._vmutils,
'attach_drive') as mock_attach_drive:
self._vmutils.attach_scsi_drive(mock_vm, self._FAKE_PATH,
constants.DISK)
mock_get_vm_scsi_controller.assert_called_once_with(mock_vm)
mock_get_free_controller_slot.assert_called_once_with(
self._FAKE_CTRL_PATH)
mock_attach_drive.assert_called_once_with(
mock_vm, self._FAKE_PATH, self._FAKE_CTRL_PATH,
self._FAKE_DRIVE_ADDR, constants.DISK)
@mock.patch.object(vmutils.VMUtils, '_get_new_resource_setting_data')
@mock.patch.object(vmutils.VMUtils, '_get_vm_ide_controller')
def test_attach_ide_drive(self, mock_get_ide_ctrl, mock_get_new_rsd):
mock_vm = self._lookup_vm()
mock_rsd = mock_get_new_rsd.return_value
with mock.patch.object(self._vmutils,
'_add_virt_resource') as mock_add_virt_res:
self._vmutils.attach_ide_drive(self._FAKE_VM_NAME,
self._FAKE_CTRL_PATH,
self._FAKE_CTRL_ADDR,
self._FAKE_DRIVE_ADDR)
mock_add_virt_res.assert_called_with(mock_rsd,
mock_vm.path_.return_value)
mock_get_ide_ctrl.assert_called_with(mock_vm, self._FAKE_CTRL_ADDR)
self.assertTrue(mock_get_new_rsd.called)
@mock.patch.object(vmutils.VMUtils, '_get_new_resource_setting_data')
def test_create_scsi_controller(self, mock_get_new_rsd):
mock_vm = self._lookup_vm()
with mock.patch.object(self._vmutils,
'_add_virt_resource') as mock_add_virt_res:
self._vmutils.create_scsi_controller(self._FAKE_VM_NAME)
mock_add_virt_res.assert_called_with(mock_get_new_rsd.return_value,
mock_vm.path_.return_value)
@mock.patch.object(vmutils.VMUtils, '_get_new_resource_setting_data')
def test_attach_volume_to_controller(self, mock_get_new_rsd):
mock_vm = self._lookup_vm()
with mock.patch.object(self._vmutils,
'_add_virt_resource') as mock_add_virt_res:
self._vmutils.attach_volume_to_controller(
self._FAKE_VM_NAME, self._FAKE_CTRL_PATH, self._FAKE_CTRL_ADDR,
self._FAKE_MOUNTED_DISK_PATH)
mock_add_virt_res.assert_called_with(mock_get_new_rsd.return_value,
mock_vm.path_.return_value)
@mock.patch.object(vmutils.VMUtils, '_modify_virt_resource')
@mock.patch.object(vmutils.VMUtils, '_get_nic_data_by_name')
def test_set_nic_connection(self, mock_get_nic_conn, mock_modify_virt_res):
self._lookup_vm()
mock_nic = mock_get_nic_conn.return_value
self._vmutils.set_nic_connection(self._FAKE_VM_NAME, None, None)
mock_modify_virt_res.assert_called_with(mock_nic, self._FAKE_VM_PATH)
@mock.patch.object(vmutils.VMUtils, '_get_new_setting_data')
def test_create_nic(self, mock_get_new_virt_res):
self._lookup_vm()
mock_nic = mock_get_new_virt_res.return_value
with mock.patch.object(self._vmutils,
'_add_virt_resource') as mock_add_virt_res:
self._vmutils.create_nic(
self._FAKE_VM_NAME, self._FAKE_RES_NAME, self._FAKE_ADDRESS)
mock_add_virt_res.assert_called_with(mock_nic, self._FAKE_VM_PATH)
@mock.patch.object(vmutils.VMUtils, '_get_nic_data_by_name')
def test_destroy_nic(self, mock_get_nic_data_by_name):
self._lookup_vm()
fake_nic_data = mock_get_nic_data_by_name.return_value
with mock.patch.object(self._vmutils,
'_remove_virt_resource') as mock_rem_virt_res:
self._vmutils.destroy_nic(self._FAKE_VM_NAME,
mock.sentinel.FAKE_NIC_NAME)
mock_rem_virt_res.assert_called_once_with(fake_nic_data,
self._FAKE_VM_PATH)
def test_set_vm_state(self):
mock_vm = self._lookup_vm()
mock_vm.RequestStateChange.return_value = (
self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
self._vmutils.set_vm_state(self._FAKE_VM_NAME,
constants.HYPERV_VM_STATE_ENABLED)
mock_vm.RequestStateChange.assert_called_with(
constants.HYPERV_VM_STATE_ENABLED)
def test_destroy_vm(self):
self._lookup_vm()
mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
getattr(mock_svc, self._DESTROY_SYSTEM).return_value = (
self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
self._vmutils.destroy_vm(self._FAKE_VM_NAME)
getattr(mock_svc, self._DESTROY_SYSTEM).assert_called_with(
self._FAKE_VM_PATH)
@mock.patch.object(vmutils.VMUtils, '_wait_for_job')
def test_check_ret_val_ok(self, mock_wait_for_job):
self._vmutils.check_ret_val(constants.WMI_JOB_STATUS_STARTED,
self._FAKE_JOB_PATH)
mock_wait_for_job.assert_called_once_with(self._FAKE_JOB_PATH)
def test_check_ret_val_exception(self):
self.assertRaises(vmutils.HyperVException,
self._vmutils.check_ret_val,
self._FAKE_RET_VAL_BAD,
self._FAKE_JOB_PATH)
def test_wait_for_job_done(self):
mockjob = self._prepare_wait_for_job(constants.WMI_JOB_STATE_COMPLETED)
job = self._vmutils._wait_for_job(self._FAKE_JOB_PATH)
self.assertEqual(mockjob, job)
def test_wait_for_job_exception_concrete_job(self):
mock_job = self._prepare_wait_for_job()
mock_job.path.return_value.Class = self._CONCRETE_JOB
self.assertRaises(vmutils.HyperVException,
self._vmutils._wait_for_job,
self._FAKE_JOB_PATH)
def test_wait_for_job_exception_with_error(self):
mock_job = self._prepare_wait_for_job()
mock_job.GetError.return_value = (self._FAKE_ERROR, self._FAKE_RET_VAL)
self.assertRaises(vmutils.HyperVException,
self._vmutils._wait_for_job,
self._FAKE_JOB_PATH)
def test_wait_for_job_exception_no_error(self):
mock_job = self._prepare_wait_for_job()
mock_job.GetError.return_value = (None, None)
self.assertRaises(vmutils.HyperVException,
self._vmutils._wait_for_job,
self._FAKE_JOB_PATH)
def _prepare_wait_for_job(self, state=_FAKE_JOB_STATUS_BAD):
mock_job = mock.MagicMock()
mock_job.JobState = state
mock_job.Description = self._FAKE_JOB_DESCRIPTION
mock_job.ElapsedTime = self._FAKE_ELAPSED_TIME
self._vmutils._get_wmi_obj = mock.MagicMock(return_value=mock_job)
return mock_job
def test_add_virt_resource(self):
mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
getattr(mock_svc, self._ADD_RESOURCE).return_value = (
self._FAKE_JOB_PATH, mock.MagicMock(), self._FAKE_RET_VAL)
mock_res_setting_data = mock.MagicMock()
mock_res_setting_data.GetText_.return_value = self._FAKE_RES_DATA
self._vmutils._add_virt_resource(mock_res_setting_data,
self._FAKE_VM_PATH)
self._assert_add_resources(mock_svc)
def test_modify_virt_resource(self):
mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
mock_svc.ModifyVirtualSystemResources.return_value = (
self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
mock_res_setting_data = mock.MagicMock()
mock_res_setting_data.GetText_.return_value = self._FAKE_RES_DATA
self._vmutils._modify_virt_resource(mock_res_setting_data,
self._FAKE_VM_PATH)
mock_svc.ModifyVirtualSystemResources.assert_called_with(
ResourceSettingData=[self._FAKE_RES_DATA],
ComputerSystem=self._FAKE_VM_PATH)
def test_remove_virt_resource(self):
mock_svc = self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
getattr(mock_svc, self._REMOVE_RESOURCE).return_value = (
self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
mock_res_setting_data = mock.MagicMock()
mock_res_setting_data.path_.return_value = self._FAKE_RES_PATH
self._vmutils._remove_virt_resource(mock_res_setting_data,
self._FAKE_VM_PATH)
self._assert_remove_resources(mock_svc)
def test_set_disk_host_resource(self):
self._lookup_vm()
mock_rasds = self._create_mock_disks()
self._vmutils._get_vm_disks = mock.MagicMock(
return_value=([mock_rasds[0]], [mock_rasds[1]]))
self._vmutils._modify_virt_resource = mock.MagicMock()
self._vmutils._get_disk_resource_address = mock.MagicMock(
return_value=self._FAKE_ADDRESS)
self._vmutils.set_disk_host_resource(
self._FAKE_VM_NAME,
self._FAKE_CTRL_PATH,
self._FAKE_ADDRESS,
mock.sentinel.fake_new_mounted_disk_path)
self._vmutils._get_disk_resource_address.assert_called_with(
mock_rasds[0])
self._vmutils._modify_virt_resource.assert_called_with(
mock_rasds[0], self._FAKE_VM_PATH)
self.assertEqual(
mock.sentinel.fake_new_mounted_disk_path,
mock_rasds[0].HostResource[0])
@mock.patch.object(vmutils, 'wmi', create=True)
@mock.patch.object(vmutils.VMUtils, 'check_ret_val')
def test_take_vm_snapshot(self, mock_check_ret_val, mock_wmi):
self._lookup_vm()
mock_svc = self._get_snapshot_service()
mock_svc.CreateVirtualSystemSnapshot.return_value = (
self._FAKE_JOB_PATH, self._FAKE_RET_VAL, mock.MagicMock())
self._vmutils.take_vm_snapshot(self._FAKE_VM_NAME)
mock_svc.CreateVirtualSystemSnapshot.assert_called_with(
self._FAKE_VM_PATH)
mock_check_ret_val.assert_called_once_with(self._FAKE_RET_VAL,
self._FAKE_JOB_PATH)
def test_remove_vm_snapshot(self):
mock_svc = self._get_snapshot_service()
getattr(mock_svc, self._DESTROY_SNAPSHOT).return_value = (
self._FAKE_JOB_PATH, self._FAKE_RET_VAL)
self._vmutils.remove_vm_snapshot(self._FAKE_SNAPSHOT_PATH)
getattr(mock_svc, self._DESTROY_SNAPSHOT).assert_called_with(
self._FAKE_SNAPSHOT_PATH)
def test_detach_vm_disk(self):
self._lookup_vm()
mock_disk = self._prepare_mock_disk()
with mock.patch.object(self._vmutils,
'_remove_virt_resource') as mock_rm_virt_res:
self._vmutils.detach_vm_disk(self._FAKE_VM_NAME,
self._FAKE_HOST_RESOURCE)
mock_rm_virt_res.assert_called_with(mock_disk, self._FAKE_VM_PATH)
def test_get_mounted_disk_resource_from_path(self):
mock_disk_1 = mock.MagicMock()
mock_disk_2 = mock.MagicMock()
mock_disk_2.HostResource = [self._FAKE_MOUNTED_DISK_PATH]
self._vmutils._conn.query.return_value = [mock_disk_1, mock_disk_2]
physical_disk = self._vmutils._get_mounted_disk_resource_from_path(
self._FAKE_MOUNTED_DISK_PATH, True)
self.assertEqual(mock_disk_2, physical_disk)
def test_get_controller_volume_paths(self):
self._prepare_mock_disk()
mock_disks = {self._FAKE_RES_PATH: self._FAKE_HOST_RESOURCE}
disks = self._vmutils.get_controller_volume_paths(self._FAKE_RES_PATH)
self.assertEqual(mock_disks, disks)
def _prepare_mock_disk(self):
mock_disk = mock.MagicMock()
mock_disk.HostResource = [self._FAKE_HOST_RESOURCE]
mock_disk.path.return_value.RelPath = self._FAKE_RES_PATH
mock_disk.ResourceSubType = self._vmutils._HARD_DISK_RES_SUB_TYPE
self._vmutils._conn.query.return_value = [mock_disk]
return mock_disk
def _get_snapshot_service(self):
return self._vmutils._conn.Msvm_VirtualSystemManagementService()[0]
def _assert_add_resources(self, mock_svc):
getattr(mock_svc, self._ADD_RESOURCE).assert_called_with(
[self._FAKE_RES_DATA], self._FAKE_VM_PATH)
def _assert_remove_resources(self, mock_svc):
getattr(mock_svc, self._REMOVE_RESOURCE).assert_called_with(
[self._FAKE_RES_PATH], self._FAKE_VM_PATH)
def test_get_active_instances(self):
fake_vm = mock.MagicMock()
type(fake_vm).ElementName = mock.PropertyMock(
side_effect=['active_vm', 'inactive_vm'])
type(fake_vm).EnabledState = mock.PropertyMock(
side_effect=[constants.HYPERV_VM_STATE_ENABLED,
constants.HYPERV_VM_STATE_DISABLED])
self._vmutils.list_instances = mock.MagicMock(
return_value=[mock.sentinel.fake_vm_name] * 2)
self._vmutils._lookup_vm = mock.MagicMock(side_effect=[fake_vm] * 2)
active_instances = self._vmutils.get_active_instances()
self.assertEqual(['active_vm'], active_instances)
def test_get_vm_serial_ports(self):
mock_vm = self._lookup_vm()
mock_vmsettings = [mock.MagicMock()]
mock_vm.associators.return_value = mock_vmsettings
fake_serial_port = mock.MagicMock()
fake_serial_port.ResourceSubType = (
self._vmutils._SERIAL_PORT_RES_SUB_TYPE)
mock_rasds = [fake_serial_port]
mock_vmsettings[0].associators.return_value = mock_rasds
ret_val = self._vmutils._get_vm_serial_ports(mock_vm)
self.assertEqual(mock_rasds, ret_val)
def test_set_vm_serial_port_conn(self):
mock_vm = self._lookup_vm()
mock_com_1 = mock.Mock()
mock_com_2 = mock.Mock()
self._vmutils._get_vm_serial_ports = mock.Mock(
return_value=[mock_com_1, mock_com_2])
self._vmutils._modify_virt_resource = mock.Mock()
self._vmutils.set_vm_serial_port_connection(
mock.sentinel.vm_name,
port_number=1,
pipe_path=mock.sentinel.pipe_path)
self.assertEqual([mock.sentinel.pipe_path], mock_com_1.Connection)
self._vmutils._modify_virt_resource.assert_called_once_with(
mock_com_1, mock_vm.path_())
def test_get_serial_port_conns(self):
self._lookup_vm()
mock_com_1 = mock.Mock()
mock_com_1.Connection = []
mock_com_2 = mock.Mock()
mock_com_2.Connection = [mock.sentinel.pipe_path]
self._vmutils._get_vm_serial_ports = mock.Mock(
return_value=[mock_com_1, mock_com_2])
ret_val = self._vmutils.get_vm_serial_port_connections(
mock.sentinel.vm_name)
expected_ret_val = [mock.sentinel.pipe_path]
self.assertEqual(expected_ret_val, ret_val)
def test_list_instance_notes(self):
vs = mock.MagicMock()
attrs = {'ElementName': 'fake_name',
'Notes': '4f54fb69-d3a2-45b7-bb9b-b6e6b3d893b3'}
vs.configure_mock(**attrs)
vs2 = mock.MagicMock(ElementName='fake_name2', Notes=None)
self._vmutils._conn.Msvm_VirtualSystemSettingData.return_value = [vs,
vs2]
response = self._vmutils.list_instance_notes()
self.assertEqual([(attrs['ElementName'], [attrs['Notes']])], response)
self._vmutils._conn.Msvm_VirtualSystemSettingData.assert_called_with(
['ElementName', 'Notes'],
SettingType=self._vmutils._VIRTUAL_SYSTEM_CURRENT_SETTINGS)
@mock.patch('hyperv.nova.vmutils.VMUtils.check_ret_val')
def test_modify_virtual_system(self, mock_check_ret_val):
mock_vs_man_svc = mock.MagicMock()
mock_vmsetting = mock.MagicMock()
fake_path = 'fake path'
fake_job_path = 'fake job path'
fake_ret_val = 'fake return value'
mock_vs_man_svc.ModifyVirtualSystem.return_value = (0, fake_job_path,
fake_ret_val)
self._vmutils._modify_virtual_system(vs_man_svc=mock_vs_man_svc,
vm_path=fake_path,
vmsetting=mock_vmsetting)
mock_vs_man_svc.ModifyVirtualSystem.assert_called_once_with(
ComputerSystem=fake_path,
SystemSettingData=mock_vmsetting.GetText_(1))
mock_check_ret_val.assert_called_once_with(fake_ret_val, fake_job_path)
@mock.patch('hyperv.nova.vmutils.VMUtils.check_ret_val')
@mock.patch('hyperv.nova.vmutils.VMUtils._get_wmi_obj')
@mock.patch('hyperv.nova.vmutils.VMUtils._modify_virtual_system')
@mock.patch('hyperv.nova.vmutils.VMUtils._get_vm_setting_data')
def test_create_vm_obj(self, mock_get_vm_setting_data,
mock_modify_virtual_system,
mock_get_wmi_obj, mock_check_ret_val):
mock_vs_man_svc = mock.MagicMock()
mock_vs_gs_data = mock.MagicMock()
fake_vm_path = 'fake vm path'
fake_job_path = 'fake job path'
fake_ret_val = 'fake return value'
_conn = self._vmutils._conn.Msvm_VirtualSystemGlobalSettingData
_conn.new.return_value = mock_vs_gs_data
mock_vs_man_svc.DefineVirtualSystem.return_value = (fake_vm_path,
fake_job_path,
fake_ret_val)
response = self._vmutils._create_vm_obj(
vs_man_svc=mock_vs_man_svc,
vm_name='fake vm', vm_gen='fake vm gen',
notes='fake notes', dynamic_memory_ratio=1.0,
instance_path=mock.sentinel.instance_path)
_conn.new.assert_called_once_with()
self.assertEqual(mock_vs_gs_data.ElementName, 'fake vm')
mock_vs_man_svc.DefineVirtualSystem.assert_called_once_with(
[], None, mock_vs_gs_data.GetText_(1))
mock_check_ret_val.assert_called_once_with(fake_ret_val, fake_job_path)
self.assertEqual(mock.sentinel.instance_path,
mock_vs_gs_data.ExternalDataRoot)
self.assertEqual(mock.sentinel.instance_path,
mock_vs_gs_data.SnapshotDataRoot)
mock_get_wmi_obj.assert_called_with(fake_vm_path)
mock_get_vm_setting_data.assert_called_once_with(mock_get_wmi_obj())
mock_modify_virtual_system.assert_called_once_with(
mock_vs_man_svc, fake_vm_path, mock_get_vm_setting_data())
self.assertEqual(mock_get_vm_setting_data().Notes,
'\n'.join('fake notes'))
self.assertEqual(response, mock_get_wmi_obj())
def test_list_instances(self):
vs = mock.MagicMock()
attrs = {'ElementName': 'fake_name'}
vs.configure_mock(**attrs)
self._vmutils._conn.Msvm_VirtualSystemSettingData.return_value = [vs]
response = self._vmutils.list_instances()
self.assertEqual([(attrs['ElementName'])], response)
self._vmutils._conn.Msvm_VirtualSystemSettingData.assert_called_with(
['ElementName'],
SettingType=self._vmutils._VIRTUAL_SYSTEM_CURRENT_SETTINGS)
@mock.patch.object(vmutils.VMUtils, "_clone_wmi_obj")
def _test_check_clone_wmi_obj(self, mock_clone_wmi_obj, clone_objects):
mock_obj = mock.MagicMock()
self._vmutils._clone_wmi_objs = clone_objects
response = self._vmutils._check_clone_wmi_obj(class_name="fakeClass",
obj=mock_obj)
if not clone_objects:
self.assertEqual(mock_obj, response)
else:
mock_clone_wmi_obj.assert_called_once_with("fakeClass", mock_obj)
self.assertEqual(mock_clone_wmi_obj.return_value, response)
def test_check_clone_wmi_obj_true(self):
self._test_check_clone_wmi_obj(clone_objects=True)
def test_check_clone_wmi_obj_false(self):
self._test_check_clone_wmi_obj(clone_objects=False)
def test_clone_wmi_obj(self):
mock_obj = mock.MagicMock()
mock_value = mock.MagicMock()
mock_value.Value = mock.sentinel.fake_value
mock_obj._properties = [mock.sentinel.property]
mock_obj.Properties_.Item.return_value = mock_value
response = self._vmutils._clone_wmi_obj(
class_name="FakeClass", obj=mock_obj)
compare = self._vmutils._conn.FakeClass.new()
self.assertEqual(mock.sentinel.fake_value,
compare.Properties_.Item().Value)
self.assertEqual(compare, response)
def test_get_attached_disks(self):
mock_scsi_ctrl_path = mock.MagicMock()
expected_query = ("SELECT * FROM %(class_name)s "
"WHERE (ResourceSubType='%(res_sub_type)s' OR "
"ResourceSubType='%(res_sub_type_virt)s')"
" AND Parent='%(parent)s'" %
{"class_name":
self._vmutils._RESOURCE_ALLOC_SETTING_DATA_CLASS,
"res_sub_type":
self._vmutils._PHYS_DISK_RES_SUB_TYPE,
"res_sub_type_virt":
self._vmutils._DISK_DRIVE_RES_SUB_TYPE,
"parent":
mock_scsi_ctrl_path.replace("'", "''")})
expected_disks = self._vmutils._conn.query.return_value
ret_disks = self._vmutils.get_attached_disks(mock_scsi_ctrl_path)
self._vmutils._conn.query.assert_called_once_with(expected_query)
self.assertEqual(expected_disks, ret_disks)
def _get_fake_instance_notes(self):
return self._FAKE_VM_UUID
def test_instance_notes(self):
self._lookup_vm()
mock_vm_settings = mock.Mock()
mock_vm_settings.Notes = self._get_fake_instance_notes()
self._vmutils._get_vm_setting_data = mock.Mock(
return_value=mock_vm_settings)
notes = self._vmutils._get_instance_notes(mock.sentinel.vm_name)
self.assertEqual(notes[0], self._FAKE_VM_UUID)