Hyper-V: Adds VMOps unit tests (part 2)

The Hyper-V driver oldest tests (test_hypervapi.py) are proving hard to
maintain.

The tests in test_hypervapi.py in particular can also be refactored and
split in separate TestCases, one of each *ops module.

This commit refactors the second part of the VMOps test cases.

Change-Id: I5b68a07fa9a4ab1393710677031496c568623757
This commit is contained in:
Claudiu Belu
2015-03-24 16:59:40 +02:00
parent aad9893c06
commit 54d237d03e
2 changed files with 266 additions and 214 deletions

View File

@@ -24,7 +24,6 @@ import uuid
import mock import mock
from mox3 import mox from mox3 import mox
from nova.api.metadata import base as instance_metadata from nova.api.metadata import base as instance_metadata
from nova.compute import power_state
from nova import context from nova import context
from nova import db from nova import db
from nova import exception from nova import exception
@@ -158,9 +157,6 @@ class HyperVAPIBaseTestCase(test.NoDBTestCase):
self._mox.StubOutWithMock(vmutils.VMUtils, 'create_scsi_controller') self._mox.StubOutWithMock(vmutils.VMUtils, 'create_scsi_controller')
self._mox.StubOutWithMock(vmutils.VMUtils, 'create_nic') self._mox.StubOutWithMock(vmutils.VMUtils, 'create_nic')
self._mox.StubOutWithMock(vmutils.VMUtils, 'set_vm_state') self._mox.StubOutWithMock(vmutils.VMUtils, 'set_vm_state')
self._mox.StubOutWithMock(vmutils.VMUtils, 'list_instances')
self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_summary_info')
self._mox.StubOutWithMock(vmutils.VMUtils, 'set_nic_connection')
self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_scsi_controller') self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_scsi_controller')
self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_ide_controller') self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_ide_controller')
self._mox.StubOutWithMock(vmutils.VMUtils, 'get_attached_disks') self._mox.StubOutWithMock(vmutils.VMUtils, 'get_attached_disks')
@@ -170,8 +166,6 @@ class HyperVAPIBaseTestCase(test.NoDBTestCase):
'get_mounted_disk_by_drive_number') 'get_mounted_disk_by_drive_number')
self._mox.StubOutWithMock(vmutils.VMUtils, 'detach_vm_disk') self._mox.StubOutWithMock(vmutils.VMUtils, 'detach_vm_disk')
self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_storage_paths') self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_storage_paths')
self._mox.StubOutWithMock(vmutils.VMUtils,
'get_controller_volume_paths')
self._mox.StubOutWithMock(vmutils.VMUtils, 'get_free_controller_slot') self._mox.StubOutWithMock(vmutils.VMUtils, 'get_free_controller_slot')
self._mox.StubOutWithMock(vmutils.VMUtils, self._mox.StubOutWithMock(vmutils.VMUtils,
'enable_vm_metrics_collection') 'enable_vm_metrics_collection')
@@ -254,50 +248,6 @@ class HyperVAPITestCase(HyperVAPIBaseTestCase):
def test_public_api_signatures(self): def test_public_api_signatures(self):
self.assertPublicAPISignatures(driver.ComputeDriver(None), self._conn) self.assertPublicAPISignatures(driver.ComputeDriver(None), self._conn)
def test_list_instances(self):
fake_instances = ['fake1', 'fake2']
vmutils.VMUtils.list_instances().AndReturn(fake_instances)
self._mox.ReplayAll()
instances = self._conn.list_instances()
self._mox.VerifyAll()
self.assertEqual(instances, fake_instances)
def test_get_info(self):
self._instance = self._get_instance()
summary_info = {'NumberOfProcessors': 2,
'EnabledState': constants.HYPERV_VM_STATE_ENABLED,
'MemoryUsage': 1000,
'UpTime': 1}
m = vmutils.VMUtils.vm_exists(mox.Func(self._check_instance_name))
m.AndReturn(True)
func = mox.Func(self._check_instance_name)
m = vmutils.VMUtils.get_vm_summary_info(func)
m.AndReturn(summary_info)
self._mox.ReplayAll()
info = self._conn.get_info(self._instance)
self._mox.VerifyAll()
self.assertEqual(info.state, power_state.RUNNING)
def test_get_info_instance_not_found(self):
# Tests that InstanceNotFound is raised if the instance isn't found
# from the vmutils.vm_exists method.
self._instance = self._get_instance()
m = vmutils.VMUtils.vm_exists(mox.Func(self._check_instance_name))
m.AndReturn(False)
self._mox.ReplayAll()
self.assertRaises(exception.InstanceNotFound, self._conn.get_info,
self._instance)
self._mox.VerifyAll()
def _setup_spawn_config_drive_mocks(self, use_cdrom): def _setup_spawn_config_drive_mocks(self, use_cdrom):
instance_metadata.InstanceMetadata(mox.IgnoreArg(), instance_metadata.InstanceMetadata(mox.IgnoreArg(),
content=mox.IsA(list), content=mox.IsA(list),
@@ -336,126 +286,6 @@ class HyperVAPITestCase(HyperVAPIBaseTestCase):
def _check_instance_name(self, vm_name): def _check_instance_name(self, vm_name):
return vm_name == self._instance.name return vm_name == self._instance.name
def _test_vm_state_change(self, action, from_state, to_state):
self._instance = self._get_instance()
vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name),
to_state)
if to_state in (constants.HYPERV_VM_STATE_DISABLED,
constants.HYPERV_VM_STATE_REBOOT):
self._setup_delete_vm_log_mocks()
if to_state in (constants.HYPERV_VM_STATE_ENABLED,
constants.HYPERV_VM_STATE_REBOOT):
self._setup_log_vm_output_mocks()
self._mox.ReplayAll()
action(self._instance)
self._mox.VerifyAll()
def test_pause(self):
self._test_vm_state_change(self._conn.pause, None,
constants.HYPERV_VM_STATE_PAUSED)
def test_pause_already_paused(self):
self._test_vm_state_change(self._conn.pause,
constants.HYPERV_VM_STATE_PAUSED,
constants.HYPERV_VM_STATE_PAUSED)
def test_unpause(self):
self._test_vm_state_change(self._conn.unpause,
constants.HYPERV_VM_STATE_PAUSED,
constants.HYPERV_VM_STATE_ENABLED)
def test_unpause_already_running(self):
self._test_vm_state_change(self._conn.unpause, None,
constants.HYPERV_VM_STATE_ENABLED)
def test_suspend(self):
self._test_vm_state_change(lambda i: self._conn.suspend(self._context,
i),
None,
constants.HYPERV_VM_STATE_SUSPENDED)
def test_suspend_already_suspended(self):
self._test_vm_state_change(lambda i: self._conn.suspend(self._context,
i),
constants.HYPERV_VM_STATE_SUSPENDED,
constants.HYPERV_VM_STATE_SUSPENDED)
def test_resume(self):
self._test_vm_state_change(lambda i: self._conn.resume(self._context,
i, None),
constants.HYPERV_VM_STATE_SUSPENDED,
constants.HYPERV_VM_STATE_ENABLED)
def test_resume_already_running(self):
self._test_vm_state_change(lambda i: self._conn.resume(self._context,
i, None), None,
constants.HYPERV_VM_STATE_ENABLED)
def test_power_off(self):
self._test_vm_state_change(self._conn.power_off, None,
constants.HYPERV_VM_STATE_DISABLED)
def test_power_off_already_powered_off(self):
self._test_vm_state_change(self._conn.power_off,
constants.HYPERV_VM_STATE_DISABLED,
constants.HYPERV_VM_STATE_DISABLED)
def _test_power_on(self, block_device_info):
self._instance = self._get_instance()
network_info = fake_network.fake_get_instance_nw_info(self.stubs)
vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name),
constants.HYPERV_VM_STATE_ENABLED)
if block_device_info:
self._mox.StubOutWithMock(volumeops.VolumeOps,
'fix_instance_volume_disk_paths')
volumeops.VolumeOps.fix_instance_volume_disk_paths(
mox.Func(self._check_instance_name), block_device_info)
self._setup_log_vm_output_mocks()
self._mox.ReplayAll()
self._conn.power_on(self._context, self._instance, network_info,
block_device_info=block_device_info)
self._mox.VerifyAll()
def test_power_on_having_block_devices(self):
block_device_info = db_fakes.get_fake_block_device_info(
self._volume_target_portal, self._volume_id)
self._test_power_on(block_device_info=block_device_info)
def test_power_on_without_block_devices(self):
self._test_power_on(block_device_info=None)
def test_power_on_already_running(self):
self._instance = self._get_instance()
network_info = fake_network.fake_get_instance_nw_info(self.stubs)
vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name),
constants.HYPERV_VM_STATE_ENABLED)
self._setup_log_vm_output_mocks()
self._mox.ReplayAll()
self._conn.power_on(self._context, self._instance, network_info)
self._mox.VerifyAll()
def test_reboot(self):
network_info = fake_network.fake_get_instance_nw_info(self.stubs)
self._instance = self._get_instance()
vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name),
constants.HYPERV_VM_STATE_REBOOT)
self._setup_delete_vm_log_mocks()
self._setup_log_vm_output_mocks()
self._mox.ReplayAll()
self._conn.reboot(self._context, self._instance, network_info,
None)
self._mox.VerifyAll()
def _setup_destroy_mocks(self, destroy_disks=True): def _setup_destroy_mocks(self, destroy_disks=True):
m = vmutils.VMUtils.vm_exists(mox.Func(self._check_instance_name)) m = vmutils.VMUtils.vm_exists(mox.Func(self._check_instance_name))
m.AndReturn(True) m.AndReturn(True)
@@ -473,15 +303,6 @@ class HyperVAPITestCase(HyperVAPIBaseTestCase):
remove_dir=True) remove_dir=True)
m.AndReturn(self._test_instance_dir) m.AndReturn(self._test_instance_dir)
def test_destroy(self):
self._instance = self._get_instance()
self._setup_destroy_mocks()
self._mox.ReplayAll()
self._conn.destroy(self._context, self._instance, None)
self._mox.VerifyAll()
def test_get_instance_disk_info_is_implemented(self): def test_get_instance_disk_info_is_implemented(self):
instance = objects.Instance() instance = objects.Instance()
# Ensure that the method has been implemented in the driver # Ensure that the method has been implemented in the driver
@@ -719,36 +540,6 @@ class HyperVAPITestCase(HyperVAPIBaseTestCase):
constants.HYPERV_VM_STATE_ENABLED) constants.HYPERV_VM_STATE_ENABLED)
self._setup_log_vm_output_mocks() self._setup_log_vm_output_mocks()
def _test_spawn_instance(self, cow=True,
expected_disks=1,
expected_dvds=0,
setup_vif_mocks_func=None,
with_exception=False,
config_drive=False,
use_cdrom=False,
admin_permissions=True,
vhd_format=constants.DISK_FORMAT_VHD,
ephemeral_storage=False):
self._setup_spawn_instance_mocks(cow,
setup_vif_mocks_func,
with_exception,
config_drive=config_drive,
use_cdrom=use_cdrom,
admin_permissions=admin_permissions,
vhd_format=vhd_format,
ephemeral_storage=ephemeral_storage)
self._mox.ReplayAll()
self._spawn_instance(cow, ephemeral_storage=ephemeral_storage)
self._mox.VerifyAll()
self.assertEqual(len(self._instance_disks), expected_disks)
self.assertEqual(len(self._instance_dvds), expected_dvds)
vhd_path = os.path.join(self._test_instance_dir, 'root.' +
vhd_format.lower())
self.assertEqual(vhd_path, self._instance_disks[0])
def _mock_get_mounted_disk_from_lun(self, target_iqn, target_lun, def _mock_get_mounted_disk_from_lun(self, target_iqn, target_lun,
fake_mounted_disk, fake_mounted_disk,
fake_device_number): fake_device_number):
@@ -1317,14 +1108,14 @@ class HyperVAPITestCase(HyperVAPIBaseTestCase):
# Check to make sure the method raises NotImplementedError. # Check to make sure the method raises NotImplementedError.
self.assertRaises(NotImplementedError, self.assertRaises(NotImplementedError,
self._conn.plug_vifs, self._conn.plug_vifs,
instance=self._test_spawn_instance, instance=mock.sentinel.instance,
network_info=None) network_info=None)
def test_unplug_vifs(self): def test_unplug_vifs(self):
# Check to make sure the method raises NotImplementedError. # Check to make sure the method raises NotImplementedError.
self.assertRaises(NotImplementedError, self.assertRaises(NotImplementedError,
self._conn.unplug_vifs, self._conn.unplug_vifs,
instance=self._test_spawn_instance, instance=mock.sentinel.instance,
network_info=None) network_info=None)
def test_refresh_instance_security_rules(self): def test_refresh_instance_security_rules(self):

View File

@@ -17,6 +17,7 @@ import os
from eventlet import timeout as etimeout from eventlet import timeout as etimeout
import mock import mock
from nova import exception from nova import exception
from nova.virt import hardware
from oslo_concurrency import processutils from oslo_concurrency import processutils
from oslo_config import cfg from oslo_config import cfg
from oslo_utils import units from oslo_utils import units
@@ -39,13 +40,12 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
FAKE_ROOT_PATH = 'C:\\path\\to\\fake.%s' FAKE_ROOT_PATH = 'C:\\path\\to\\fake.%s'
FAKE_CONFIG_DRIVE_ISO = 'configdrive.iso' FAKE_CONFIG_DRIVE_ISO = 'configdrive.iso'
FAKE_CONFIG_DRIVE_VHD = 'configdrive.vhd' FAKE_CONFIG_DRIVE_VHD = 'configdrive.vhd'
FAKE_UUID = '4f54fb69-d3a2-45b7-bb9b-b6e6b3d893b3'
FAKE_LOG = 'fake_log'
ISO9660 = 'iso9660' ISO9660 = 'iso9660'
_FAKE_CONFIGDRIVE_PATH = 'C:/fake_instance_dir/configdrive.vhd' _FAKE_CONFIGDRIVE_PATH = 'C:/fake_instance_dir/configdrive.vhd'
def __init__(self, test_case_name):
super(VMOpsTestCase, self).__init__(test_case_name)
def setUp(self): def setUp(self):
super(VMOpsTestCase, self).setUp() super(VMOpsTestCase, self).setUp()
self.context = 'fake-context' self.context = 'fake-context'
@@ -56,6 +56,64 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
self._vmops._pathutils = mock.MagicMock() self._vmops._pathutils = mock.MagicMock()
self._vmops._hostutils = mock.MagicMock() self._vmops._hostutils = mock.MagicMock()
@mock.patch('hyperv.nova.vmops.importutils.import_object')
def test_load_vif_driver_class(self, mock_import_object):
self._vmops._load_vif_driver_class()
mock_import_object.assert_called_once_with(
self._vmops._vif_driver_class_map[CONF.network_api_class])
self.assertEqual(self._vmops._vif_driver,
mock_import_object.return_value)
@mock.patch('hyperv.nova.vmops.importutils.import_object')
def test_load_vif_driver_class_error(self, mock_import_object):
mock_import_object.side_effect = KeyError
self.assertRaises(TypeError, self._vmops._load_vif_driver_class)
def test_list_instances(self):
mock_instance = mock.MagicMock()
self._vmops._vmutils.list_instances.return_value = [mock_instance]
response = self._vmops.list_instances()
self._vmops._vmutils.list_instances.assert_called_once_with()
self.assertEqual(response, [mock_instance])
def _test_get_info(self, vm_exists):
mock_instance = fake_instance.fake_instance_obj(self.context)
mock_info = mock.MagicMock(spec_set=dict)
fake_info = {'EnabledState': 2,
'MemoryUsage': mock.sentinel.FAKE_MEM_KB,
'NumberOfProcessors': mock.sentinel.FAKE_NUM_CPU,
'UpTime': mock.sentinel.FAKE_CPU_NS}
def getitem(key):
return fake_info[key]
mock_info.__getitem__.side_effect = getitem
expected = hardware.InstanceInfo(state=constants.HYPERV_POWER_STATE[2],
max_mem_kb=mock.sentinel.FAKE_MEM_KB,
mem_kb=mock.sentinel.FAKE_MEM_KB,
num_cpu=mock.sentinel.FAKE_NUM_CPU,
cpu_time_ns=mock.sentinel.FAKE_CPU_NS)
self._vmops._vmutils.vm_exists.return_value = vm_exists
self._vmops._vmutils.get_vm_summary_info.return_value = mock_info
if not vm_exists:
self.assertRaises(exception.InstanceNotFound,
self._vmops.get_info, mock_instance)
else:
response = self._vmops.get_info(mock_instance)
self._vmops._vmutils.vm_exists.assert_called_once_with(
mock_instance.name)
self._vmops._vmutils.get_vm_summary_info.assert_called_once_with(
mock_instance.name)
self.assertEqual(response, expected)
def test_get_info(self):
self._test_get_info(vm_exists=True)
def test_get_info_exception(self):
self._test_get_info(vm_exists=False)
def _prepare_create_root_vhd_mocks(self, use_cow_images, vhd_format, def _prepare_create_root_vhd_mocks(self, use_cow_images, vhd_format,
vhd_size): vhd_size):
mock_instance = fake_instance.fake_instance_obj(self.context) mock_instance = fake_instance.fake_instance_obj(self.context)
@@ -291,6 +349,15 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
self._test_spawn(exists=False, boot_from_volume=True, self._test_spawn(exists=False, boot_from_volume=True,
configdrive_required=False, fail=None) configdrive_required=False, fail=None)
def test_spawn_no_admin_permissions(self):
self._vmops._vmutils.check_admin_permissions.side_effect = (
vmutils.HyperVException)
self.assertRaises(vmutils.HyperVException,
self._vmops.spawn,
self.context, mock.DEFAULT, mock.DEFAULT,
[mock.sentinel.FILE], mock.sentinel.PASSWORD,
mock.sentinel.INFO, mock.sentinel.DEV_INFO)
@mock.patch('hyperv.nova.volumeops.VolumeOps' @mock.patch('hyperv.nova.volumeops.VolumeOps'
'.attach_volumes') '.attach_volumes')
@mock.patch.object(vmops.VMOps, '_attach_drive') @mock.patch.object(vmops.VMOps, '_attach_drive')
@@ -553,6 +620,43 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
self._vmops._pathutils.get_instance_dir.assert_called_once_with( self._vmops._pathutils.get_instance_dir.assert_called_once_with(
mock_instance.name, create_dir=False, remove_dir=True) mock_instance.name, create_dir=False, remove_dir=True)
@mock.patch('hyperv.nova.volumeops.VolumeOps.disconnect_volumes')
@mock.patch('hyperv.nova.vmops.VMOps._delete_disk_files')
@mock.patch('hyperv.nova.vmops.VMOps.power_off')
def test_destroy(self, mock_power_off, mock_delete_disk_files,
mock_disconnect_volumes):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops._vmutils.vm_exists.return_value = True
self._vmops.destroy(instance=mock_instance,
block_device_info=mock.sentinel.FAKE_BD_INFO)
self._vmops._vmutils.vm_exists.assert_called_with(
mock_instance.name)
mock_power_off.assert_called_once_with(mock_instance)
self._vmops._vmutils.destroy_vm.assert_called_once_with(
mock_instance.name)
mock_disconnect_volumes.assert_called_once_with(
mock.sentinel.FAKE_BD_INFO)
mock_delete_disk_files.assert_called_once_with(
mock_instance.name)
def test_destroy_inexistent_instance(self):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops._vmutils.vm_exists.return_value = False
self._vmops.destroy(instance=mock_instance)
self.assertFalse(self._vmops._vmutils.destroy_vm.called)
@mock.patch('hyperv.nova.vmops.VMOps.power_off')
def test_destroy_exception(self, mock_power_off):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops._vmutils.destroy_vm.side_effect = vmutils.HyperVException
self._vmops._vmutils.vm_exists.return_value = True
self.assertRaises(vmutils.HyperVException,
self._vmops.destroy, mock_instance)
def test_reboot_hard(self): def test_reboot_hard(self):
self._test_reboot(vmops.REBOOT_TYPE_HARD, self._test_reboot(vmops.REBOOT_TYPE_HARD,
constants.HYPERV_VM_STATE_REBOOT) constants.HYPERV_VM_STATE_REBOOT)
@@ -645,6 +749,34 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
self.assertFalse(result) self.assertFalse(result)
@mock.patch('hyperv.nova.vmops.VMOps._set_vm_state')
def test_pause(self, mock_set_vm_state):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops.pause(instance=mock_instance)
mock_set_vm_state.assert_called_once_with(
mock_instance, constants.HYPERV_VM_STATE_PAUSED)
@mock.patch('hyperv.nova.vmops.VMOps._set_vm_state')
def test_unpause(self, mock_set_vm_state):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops.unpause(instance=mock_instance)
mock_set_vm_state.assert_called_once_with(
mock_instance, constants.HYPERV_VM_STATE_ENABLED)
@mock.patch('hyperv.nova.vmops.VMOps._set_vm_state')
def test_suspend(self, mock_set_vm_state):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops.suspend(instance=mock_instance)
mock_set_vm_state.assert_called_once_with(
mock_instance, constants.HYPERV_VM_STATE_SUSPENDED)
@mock.patch('hyperv.nova.vmops.VMOps._set_vm_state')
def test_resume(self, mock_set_vm_state):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops.resume(instance=mock_instance)
mock_set_vm_state.assert_called_once_with(
mock_instance, constants.HYPERV_VM_STATE_ENABLED)
def _test_power_off(self, timeout): def _test_power_off(self, timeout):
instance = fake_instance.fake_instance_obj(self.context) instance = fake_instance.fake_instance_obj(self.context)
with mock.patch.object(self._vmops, '_set_vm_state') as mock_set_state: with mock.patch.object(self._vmops, '_set_vm_state') as mock_set_state:
@@ -673,6 +805,61 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
instance, 1, vmops.SHUTDOWN_TIME_INCREMENT) instance, 1, vmops.SHUTDOWN_TIME_INCREMENT)
self.assertFalse(mock_set_state.called) self.assertFalse(mock_set_state.called)
@mock.patch('hyperv.nova.vmops.VMOps._set_vm_state')
def test_power_on(self, mock_set_vm_state):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops.power_on(mock_instance)
mock_set_vm_state.assert_called_once_with(
mock_instance, constants.HYPERV_VM_STATE_ENABLED)
@mock.patch('hyperv.nova.volumeops.VolumeOps'
'.fix_instance_volume_disk_paths')
@mock.patch('hyperv.nova.vmops.VMOps._set_vm_state')
def test_power_on_having_block_devices(self, mock_set_vm_state,
mock_fix_instance_vol_paths):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops.power_on(mock_instance, mock.sentinel.block_device_info)
mock_fix_instance_vol_paths.assert_called_once_with(
mock_instance.name, mock.sentinel.block_device_info)
mock_set_vm_state.assert_called_once_with(
mock_instance, constants.HYPERV_VM_STATE_ENABLED)
@mock.patch.object(vmops.VMOps, 'log_vm_serial_output')
@mock.patch.object(vmops.VMOps, '_delete_vm_console_log')
def _test_set_vm_state(self, mock_delete_vm_console_log,
mock_log_vm_output, state):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops._set_vm_state(mock_instance, state)
self._vmops._vmutils.set_vm_state.assert_called_once_with(
mock_instance.name, state)
if state in (constants.HYPERV_VM_STATE_DISABLED,
constants.HYPERV_VM_STATE_REBOOT):
mock_delete_vm_console_log.assert_called_once_with(mock_instance)
if state in (constants.HYPERV_VM_STATE_ENABLED,
constants.HYPERV_VM_STATE_REBOOT):
mock_log_vm_output.assert_called_once_with(mock_instance.name,
mock_instance.uuid)
def test_set_vm_state_disabled(self):
self._test_set_vm_state(state=constants.HYPERV_VM_STATE_DISABLED)
def test_set_vm_state_enabled(self):
self._test_set_vm_state(state=constants.HYPERV_VM_STATE_ENABLED)
def test_set_vm_state_reboot(self):
self._test_set_vm_state(state=constants.HYPERV_VM_STATE_REBOOT)
def test_set_vm_state_exception(self):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops._vmutils.set_vm_state.side_effect = vmutils.HyperVException
self.assertRaises(vmutils.HyperVException, self._vmops._set_vm_state,
mock_instance, mock.sentinel.STATE)
def test_get_vm_state(self): def test_get_vm_state(self):
summary_info = {'EnabledState': constants.HYPERV_VM_STATE_DISABLED} summary_info = {'EnabledState': constants.HYPERV_VM_STATE_DISABLED}
@@ -723,6 +910,38 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
self._vmops._pathutils.copy.assert_called_once_with( self._vmops._pathutils.copy.assert_called_once_with(
mock.sentinel.FAKE_PATH, mock.sentinel.FAKE_REMOTE_PATH) mock.sentinel.FAKE_PATH, mock.sentinel.FAKE_REMOTE_PATH)
@mock.patch.object(vmops.ioutils, 'IOThread')
def test_log_vm_serial_output(self, fake_iothread):
self._vmops._pathutils.get_vm_console_log_paths.return_value = [
mock.sentinel.FAKE_PATH]
self._vmops.log_vm_serial_output(mock.sentinel.FAKE_VM_NAME,
self.FAKE_UUID)
pipe_path = r'\\.\pipe\%s' % self.FAKE_UUID
fake_iothread.assert_called_once_with(
pipe_path, mock.sentinel.FAKE_PATH,
self._vmops._MAX_CONSOLE_LOG_FILE_SIZE)
fake_iothread.return_value.start.assert_called_once_with()
@mock.patch("os.path.exists")
def test_get_console_output(self, fake_path_exists):
mock_instance = fake_instance.fake_instance_obj(self.context)
fake_path_exists.return_value = True
self._vmops._pathutils.get_vm_console_log_paths.return_value = (
mock.sentinel.FAKE_PATH, mock.sentinel.FAKE_PATH_ARCHIVED)
with mock.patch('hyperv.nova.vmops.open',
mock.mock_open(read_data=self.FAKE_LOG), create=True):
instance_log = self._vmops.get_console_output(mock_instance)
# get_vm_console_log_paths returns 2 paths.
self.assertEqual(self.FAKE_LOG * 2, instance_log)
expected_calls = [mock.call(mock.sentinel.FAKE_PATH_ARCHIVED),
mock.call(mock.sentinel.FAKE_PATH)]
fake_path_exists.assert_has_calls(expected_calls, any_order=False)
@mock.patch("__builtin__.open") @mock.patch("__builtin__.open")
@mock.patch("os.path.exists") @mock.patch("os.path.exists")
def test_get_console_output_exception(self, fake_path_exists, fake_open): def test_get_console_output_exception(self, fake_path_exists, fake_open):
@@ -739,6 +958,48 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
self._vmops.get_console_output, self._vmops.get_console_output,
fake_vm) fake_vm)
@mock.patch.object(vmops.fileutils, 'delete_if_exists')
def test_delete_vm_console_log(self, mock_delete_if_exists):
mock_instance = fake_instance.fake_instance_obj(self.context)
self._vmops._pathutils.get_vm_console_log_paths.return_value = (
mock.sentinel.FAKE_PATH, )
mock_log_writer = mock.MagicMock()
self._vmops._vm_log_writers[mock_instance['uuid']] = mock_log_writer
self._vmops._delete_vm_console_log(mock_instance)
mock_log_writer.join.assert_called_once_with()
mock_delete_if_exists.assert_called_once_with(mock.sentinel.FAKE_PATH)
def test_create_vm_com_port_pipe(self):
mock_instance = fake_instance.fake_instance_obj(self.context)
pipe_path = r'\\.\pipe\%s' % mock_instance['uuid']
self._vmops._create_vm_com_port_pipe(mock_instance)
get_vm_serial_port = self._vmops._vmutils.get_vm_serial_port_connection
get_vm_serial_port.assert_called_once_with(mock_instance['name'],
update_connection=pipe_path)
@mock.patch.object(vmops.VMOps, "log_vm_serial_output")
@mock.patch("os.path.basename")
@mock.patch("os.path.exists")
def test_restart_vm_log_writers(self, mock_exists, mock_basename,
mock_log_vm_output):
self._vmops._vmutils.get_active_instances.return_value = [
mock.sentinel.FAKE_VM_NAME, mock.sentinel.FAKE_VM_NAME_OTHER]
mock_exists.side_effect = [True, False]
self._vmops.restart_vm_log_writers()
calls = [mock.call(mock.sentinel.FAKE_VM_NAME),
mock.call(mock.sentinel.FAKE_VM_NAME_OTHER)]
self._vmops._pathutils.get_instance_dir.assert_has_calls(calls)
get_vm_serial_port = self._vmops._vmutils.get_vm_serial_port_connection
get_vm_serial_port.assert_called_once_with(mock.sentinel.FAKE_VM_NAME)
mock_log_vm_output.assert_called_once_with(mock.sentinel.FAKE_VM_NAME,
mock_basename.return_value)
def test_list_instance_uuids(self): def test_list_instance_uuids(self):
fake_uuid = '4f54fb69-d3a2-45b7-bb9b-b6e6b3d893b3' fake_uuid = '4f54fb69-d3a2-45b7-bb9b-b6e6b3d893b3'
with mock.patch.object(self._vmops._vmutils, with mock.patch.object(self._vmops._vmutils,