From 1690a1ae8f2fdddebfb8ae50a8492aedf466b8e3 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Wed, 29 May 2013 21:12:04 -0700 Subject: Add power_on flag to virt driver finish/revert migration methods This patch adds a boolean power_on flag to the virt driver finish_migration and finish_revert_migration methods to indicate whether or not to power on the instance as part of the resize/migrate operation. The default is to power on the instance. Related to bug 1177811 Change-Id: I76c7d6912eda2c333554855a8956bd0fbb1e8b6d --- nova/tests/virt/hyperv/test_hypervapi.py | 31 ++++++--- nova/tests/virt/libvirt/test_libvirt.py | 45 ++++++++++--- nova/tests/virt/powervm/test_powervm.py | 32 ++++++--- nova/tests/virt/vmwareapi/test_vmwareapi.py | 100 +++++++++++++++++++++++++++- nova/tests/virt/xenapi/test_xenapi.py | 29 ++++++-- 5 files changed, 204 insertions(+), 33 deletions(-) (limited to 'nova/tests') diff --git a/nova/tests/virt/hyperv/test_hypervapi.py b/nova/tests/virt/hyperv/test_hypervapi.py index b6df2ea31..cfc79c388 100644 --- a/nova/tests/virt/hyperv/test_hypervapi.py +++ b/nova/tests/virt/hyperv/test_hypervapi.py @@ -1159,7 +1159,7 @@ class HyperVAPITestCase(test.TestCase): instance_type, network_info) self._mox.VerifyAll() - def test_finish_migration(self): + def _test_finish_migration(self, power_on): self._instance_data = self._get_instance_data() instance = db.instance_create(self._context, self._instance_data) instance['system_metadata'] = {} @@ -1198,14 +1198,21 @@ class HyperVAPITestCase(test.TestCase): self._set_vm_name(instance['name']) self._setup_create_instance_mocks(None, False) - vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name), - constants.HYPERV_VM_STATE_ENABLED) + if power_on: + vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name), + constants.HYPERV_VM_STATE_ENABLED) self._mox.ReplayAll() self._conn.finish_migration(self._context, None, instance, "", - network_info, None, False, None) + network_info, None, False, None, power_on) self._mox.VerifyAll() + def test_finish_migration_power_on(self): + self._test_finish_migration(True) + + def test_finish_migration_power_off(self): + self._test_finish_migration(False) + def test_confirm_migration(self): self._instance_data = self._get_instance_data() instance = db.instance_create(self._context, self._instance_data) @@ -1218,7 +1225,7 @@ class HyperVAPITestCase(test.TestCase): self._conn.confirm_migration(None, instance, network_info) self._mox.VerifyAll() - def test_finish_revert_migration(self): + def _test_finish_revert_migration(self, power_on): self._instance_data = self._get_instance_data() instance = db.instance_create(self._context, self._instance_data) network_info = fake_network.fake_get_instance_nw_info( @@ -1246,9 +1253,17 @@ class HyperVAPITestCase(test.TestCase): self._set_vm_name(instance['name']) self._setup_create_instance_mocks(None, False) - vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name), - constants.HYPERV_VM_STATE_ENABLED) + if power_on: + vmutils.VMUtils.set_vm_state(mox.Func(self._check_instance_name), + constants.HYPERV_VM_STATE_ENABLED) self._mox.ReplayAll() - self._conn.finish_revert_migration(instance, network_info, None) + self._conn.finish_revert_migration(instance, network_info, None, + power_on) self._mox.VerifyAll() + + def test_finish_revert_migration_power_on(self): + self._test_finish_revert_migration(True) + + def test_finish_revert_migration_power_off(self): + self._test_finish_revert_migration(False) diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py index f72c37cd1..6b70fe1c6 100644 --- a/nova/tests/virt/libvirt/test_libvirt.py +++ b/nova/tests/virt/libvirt/test_libvirt.py @@ -4951,7 +4951,7 @@ class LibvirtDriverTestCase(test.TestCase): self.libvirtconnection._wait_for_running({'name': 'else', 'uuid': 'other_uuid'}) - def test_finish_migration(self): + def _test_finish_migration(self, power_on): """Test for nova.virt.libvirt.libvirt_driver.LivirtConnection .finish_migration. """ @@ -4960,6 +4960,8 @@ class LibvirtDriverTestCase(test.TestCase): {'type': 'raw', 'path': '/test/disk.local', 'local_gb': 10, 'backing_file': '/base/disk.local'}] disk_info_text = jsonutils.dumps(disk_info) + powered_on = power_on + self.fake_create_domain_called = False def fake_can_resize_fs(path, size, use_cow=False): return False @@ -4981,7 +4983,9 @@ class LibvirtDriverTestCase(test.TestCase): block_device_info=None): pass - def fake_create_domain(xml, instance=None): + def fake_create_domain(xml, instance=None, power_on=True): + self.fake_create_domain_called = True + self.assertEqual(powered_on, power_on) return None def fake_enable_hairpin(instance): @@ -4991,7 +4995,10 @@ class LibvirtDriverTestCase(test.TestCase): pass def fake_get_info(instance): - return {'state': power_state.RUNNING} + if powered_on: + return {'state': power_state.RUNNING} + else: + return {'state': power_state.SHUTDOWN} self.flags(use_cow_images=True) self.stubs.Set(libvirt_driver.disk, 'extend', fake_extend) @@ -5015,11 +5022,20 @@ class LibvirtDriverTestCase(test.TestCase): self.libvirtconnection.finish_migration( context.get_admin_context(), None, ins_ref, - disk_info_text, None, None, None) + disk_info_text, None, None, None, None, power_on) + self.assertTrue(self.fake_create_domain_called) + + def test_finish_migration_power_on(self): + self._test_finish_migration(True) + + def test_finish_migration_power_off(self): + self._test_finish_migration(False) - def test_finish_revert_migration(self): + def _test_finish_revert_migration(self, power_on): """Test for nova.virt.libvirt.libvirt_driver.LivirtConnection .finish_revert_migration. """ + powered_on = power_on + self.fake_create_domain_called = False def fake_execute(*args, **kwargs): pass @@ -5027,14 +5043,19 @@ class LibvirtDriverTestCase(test.TestCase): def fake_plug_vifs(instance, network_info): pass - def fake_create_domain(xml, instance=None): + def fake_create_domain(xml, instance=None, power_on=True): + self.fake_create_domain_called = True + self.assertEqual(powered_on, power_on) return None def fake_enable_hairpin(instance): pass def fake_get_info(instance): - return {'state': power_state.RUNNING} + if powered_on: + return {'state': power_state.RUNNING} + else: + return {'state': power_state.SHUTDOWN} def fake_to_xml(instance, network_info, disk_info, image_meta=None, rescue=None, @@ -5063,7 +5084,15 @@ class LibvirtDriverTestCase(test.TestCase): f = open(libvirt_xml_path, 'w') f.close() - self.libvirtconnection.finish_revert_migration(ins_ref, None) + self.libvirtconnection.finish_revert_migration(ins_ref, None, + None, power_on) + self.assertTrue(self.fake_create_domain_called) + + def test_finish_revert_migration_power_on(self): + self._test_finish_revert_migration(True) + + def test_finish_revert_migration_power_off(self): + self._test_finish_revert_migration(False) def _test_finish_revert_migration_after_crash(self, backup_made, new_made): class FakeLoopingCall: diff --git a/nova/tests/virt/powervm/test_powervm.py b/nova/tests/virt/powervm/test_powervm.py index a923d52ff..3781c6738 100644 --- a/nova/tests/virt/powervm/test_powervm.py +++ b/nova/tests/virt/powervm/test_powervm.py @@ -380,7 +380,9 @@ class PowerVMDriverTestCase(test.TestCase): expected_path = '/some/file/path/filename' self.assertEqual(joined_path, expected_path) - def _test_finish_revert_migration_after_crash(self, backup_made, new_made): + def _test_finish_revert_migration_after_crash(self, backup_made, + new_made, + power_on): inst = {'name': 'foo'} network_info = [] network_info.append({'address': 'fa:89:f0:8b:9b:39'}) @@ -404,21 +406,24 @@ class PowerVMDriverTestCase(test.TestCase): 'foo') self.powervm_connection._powervm._operator.set_lpar_mac_base_value( 'foo', 'fa:89:f0:8b:9b:39') - self.powervm_connection._powervm.power_on('foo') + if power_on: + self.powervm_connection._powervm.power_on('foo') self.mox.ReplayAll() self.powervm_connection.finish_revert_migration(inst, network_info, - block_device_info=None) + block_device_info=None, + power_on=power_on) def test_finish_revert_migration_after_crash(self): - self._test_finish_revert_migration_after_crash(True, True) + self._test_finish_revert_migration_after_crash(True, True, True) def test_finish_revert_migration_after_crash_before_new(self): - self._test_finish_revert_migration_after_crash(True, False) + self._test_finish_revert_migration_after_crash(True, False, True) def test_finish_revert_migration_after_crash_before_backup(self): - self._test_finish_revert_migration_after_crash(False, False) + # NOTE(mriedem): tests the power_on=False case also + self._test_finish_revert_migration_after_crash(False, False, False) def test_migrate_volume_use_instance_name(self): inst_name = 'instance-00000000' @@ -457,7 +462,7 @@ class PowerVMDriverTestCase(test.TestCase): expected_path = 'some/image/path/logical-vol-name_rsz.gz' self.assertEqual(file_path, expected_path) - def test_deploy_from_migrated_file(self): + def _test_deploy_from_migrated_file(self, power_on): instance = self.instance context = 'fake_context' network_info = [] @@ -469,9 +474,10 @@ class PowerVMDriverTestCase(test.TestCase): self.flags(powervm_mgr=dest) fake_op = self.powervm_connection._powervm self.deploy_from_vios_file_called = False + self.power_on = power_on def fake_deploy_from_vios_file(lpar, file_path, size, - decompress): + decompress, power_on): exp_file_path = 'some/file/path.gz' exp_size = 40 * 1024 ** 3 exp_decompress = True @@ -479,15 +485,23 @@ class PowerVMDriverTestCase(test.TestCase): self.assertEqual(exp_file_path, file_path) self.assertEqual(exp_size, size) self.assertEqual(exp_decompress, decompress) + self.assertEqual(self.power_on, power_on) self.stubs.Set(fake_op, '_deploy_from_vios_file', fake_deploy_from_vios_file) self.powervm_connection.finish_migration(context, None, instance, disk_info, network_info, None, resize_instance=True, - block_device_info=None) + block_device_info=None, + power_on=power_on) self.assertEqual(self.deploy_from_vios_file_called, True) + def test_deploy_from_migrated_file_power_on(self): + self._test_deploy_from_migrated_file(True) + + def test_deploy_from_migrated_file_power_off(self): + self._test_deploy_from_migrated_file(False) + def test_set_lpar_mac_base_value(self): instance = self.instance context = 'fake_context' diff --git a/nova/tests/virt/vmwareapi/test_vmwareapi.py b/nova/tests/virt/vmwareapi/test_vmwareapi.py index 9508a5805..2691857fe 100644 --- a/nova/tests/virt/vmwareapi/test_vmwareapi.py +++ b/nova/tests/virt/vmwareapi/test_vmwareapi.py @@ -35,10 +35,12 @@ from nova.tests import matchers from nova.tests import utils from nova.tests.virt.vmwareapi import db_fakes from nova.tests.virt.vmwareapi import stubs +from nova.virt import fake from nova.virt.vmwareapi import driver from nova.virt.vmwareapi import fake as vmwareapi_fake from nova.virt.vmwareapi import vim from nova.virt.vmwareapi import vm_util +from nova.virt.vmwareapi import vmops class fake_vm_ref(object): @@ -113,7 +115,7 @@ class VMwareAPIVMTestCase(test.TestCase): vmwareapi_fake.reset() db_fakes.stub_out_db_instance_api(self.stubs) stubs.set_stubs(self.stubs) - self.conn = driver.VMwareESXDriver(None, False) + self.conn = driver.VMwareVCDriver(fake.FakeVirtAPI) # NOTE(vish): none of the network plugging code is actually # being tested self.network_info = utils.get_test_network_info(legacy_model=False) @@ -381,6 +383,102 @@ class VMwareAPIVMTestCase(test.TestCase): self.mox.ReplayAll() self.conn.get_console_output(self.instance) + def _test_finish_migration(self, power_on): + """ + Tests the finish_migration method on vmops via the + VMwareVCDriver. Results are checked against whether or not + the underlying instance should have been powered on. + """ + + self.power_on_called = False + + def fake_power_on(instance): + self.assertEquals(self.instance, instance) + self.power_on_called = True + + def fake_vmops_update_instance_progress(context, instance, step, + total_steps): + self.assertEquals(self.context, context) + self.assertEquals(self.instance, instance) + self.assertEquals(4, step) + self.assertEqual(vmops.RESIZE_TOTAL_STEPS, total_steps) + + self.stubs.Set(self.conn._vmops, "power_on", fake_power_on) + self.stubs.Set(self.conn._vmops, "_update_instance_progress", + fake_vmops_update_instance_progress) + + # setup the test instance in the database + self._create_vm() + # perform the migration on our stubbed methods + self.conn.finish_migration(context=self.context, + migration=None, + instance=self.instance, + disk_info=None, + network_info=None, + image_meta=None, + power_on=power_on) + # verify the results + self.assertEquals(power_on, self.power_on_called) + + 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_revert_migration(self, power_on): + """ + Tests the finish_revert_migration method on vmops via the + VMwareVCDriver. Results are checked against whether or not + the underlying instance should have been powered on. + """ + + # setup the test instance in the database + self._create_vm() + + self.power_on_called = False + self.vm_name = str(self.instance['name']) + '-orig' + + def fake_power_on(instance): + self.assertEquals(self.instance, instance) + self.power_on_called = True + + def fake_get_orig_vm_name_label(instance): + self.assertEquals(self.instance, instance) + return self.vm_name + + def fake_get_vm_ref_from_name(session, vm_name): + self.assertEquals(self.vm_name, vm_name) + return vmwareapi_fake._get_objects("VirtualMachine")[0] + + def fake_call_method(*args, **kwargs): + pass + + def fake_wait_for_task(*args, **kwargs): + pass + + self.stubs.Set(self.conn._vmops, "power_on", fake_power_on) + self.stubs.Set(self.conn._vmops, "_get_orig_vm_name_label", + fake_get_orig_vm_name_label) + self.stubs.Set(vm_util, "get_vm_ref_from_name", + fake_get_vm_ref_from_name) + self.stubs.Set(self.conn._session, "_call_method", fake_call_method) + self.stubs.Set(self.conn._session, "_wait_for_task", + fake_wait_for_task) + + # perform the revert on our stubbed methods + self.conn.finish_revert_migration(instance=self.instance, + network_info=None, + power_on=power_on) + # verify the results + self.assertEquals(power_on, self.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) + class VMwareAPIHostTestCase(test.TestCase): """Unit tests for Vmware API host calls.""" diff --git a/nova/tests/virt/xenapi/test_xenapi.py b/nova/tests/virt/xenapi/test_xenapi.py index 538752cf2..4fbaa2ace 100644 --- a/nova/tests/virt/xenapi/test_xenapi.py +++ b/nova/tests/virt/xenapi/test_xenapi.py @@ -1069,7 +1069,8 @@ class XenAPIVMTestCase(stubs.XenAPITestBase): def __init__(self): self.finish_revert_migration_called = False - def finish_revert_migration(self, instance, block_info): + def finish_revert_migration(self, instance, block_info, + power_on): self.finish_revert_migration_called = True conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False) @@ -1391,7 +1392,7 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase): self.context, instance, '127.0.0.1', instance_type, None) - def test_revert_migrate(self): + def _test_revert_migrate(self, power_on): instance = create_instance_with_system_metadata(self.context, self.instance_values) self.called = False @@ -1426,14 +1427,21 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase): cow_uuid = xenapi_fake.get_record('VDI', cow)['uuid'] conn.finish_migration(self.context, self.migration, instance, dict(base_copy=base_uuid, cow=cow_uuid), - network_info, image_meta, resize_instance=True) + network_info, image_meta, resize_instance=True, + block_device_info=None, power_on=power_on) self.assertEqual(self.called, True) - self.assertEqual(self.fake_vm_start_called, True) + self.assertEqual(self.fake_vm_start_called, power_on) conn.finish_revert_migration(instance, network_info) self.assertEqual(self.fake_finish_revert_migration_called, True) - def test_finish_migrate(self): + def test_revert_migrate_power_on(self): + self._test_revert_migrate(True) + + def test_revert_migrate_power_off(self): + self._test_revert_migrate(False) + + def _test_finish_migrate(self, power_on): instance = create_instance_with_system_metadata(self.context, self.instance_values) self.called = False @@ -1458,9 +1466,16 @@ class XenAPIMigrateInstance(stubs.XenAPITestBase): image_meta = {'id': instance['image_ref'], 'disk_format': 'vhd'} conn.finish_migration(self.context, self.migration, instance, dict(base_copy='hurr', cow='durr'), - network_info, image_meta, resize_instance=True) + network_info, image_meta, resize_instance=True, + block_device_info=None, power_on=power_on) self.assertEqual(self.called, True) - self.assertEqual(self.fake_vm_start_called, True) + self.assertEqual(self.fake_vm_start_called, power_on) + + def test_finish_migrate_power_on(self): + self._test_finish_migrate(True) + + def test_finish_migrate_power_off(self): + self._test_finish_migrate(False) def test_finish_migrate_no_local_storage(self): tiny_type = flavors.get_instance_type_by_name('m1.tiny') -- cgit