Files
nova-powervm/nova_powervm/tests/virt/powervm/test_live_migration.py
venkatamahesh b9f012e14a Fix spell typos
Change-Id: I497eb5b2b0a388c242a452bddc39c2bc39648f7a
2016-02-03 23:31:48 +05:30

241 lines
10 KiB
Python

# Copyright 2015 IBM 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 mock
from nova import exception
from nova import objects
from nova import test
from nova_powervm.tests.virt import powervm
from nova_powervm.tests.virt.powervm import fixtures as fx
from nova_powervm.virt.powervm import live_migration as lpm
class TestLPM(test.TestCase):
def setUp(self):
super(TestLPM, self).setUp()
self.flags(disk_driver='localdisk', group='powervm')
self.drv_fix = self.useFixture(fx.PowerVMComputeDriver())
self.drv = self.drv_fix.drv
self.apt = self.drv.adapter
self.inst = objects.Instance(**powervm.TEST_INSTANCE)
self.lpmsrc = lpm.LiveMigrationSrc(self.drv, self.inst, {})
self.lpmdst = lpm.LiveMigrationDest(self.drv, self.inst)
@mock.patch('pypowervm.tasks.storage.ScrubOrphanStorageForLpar')
@mock.patch('nova_powervm.virt.powervm.media.ConfigDrivePowerVM')
@mock.patch('nova_powervm.virt.powervm.vm.get_instance_wrapper')
@mock.patch('pypowervm.tasks.vterm.close_vterm')
@mock.patch('pypowervm.wrappers.managed_system.System.migration_data',
new_callable=mock.PropertyMock, name='MigDataProp')
def test_lpm_source(self, mock_migrdata, mock_vterm_close, mock_get_wrap,
mock_cd, mock_scrub):
migr_data = {'active_migrations_supported': 4,
'active_migrations_in_progress': 2}
mock_migrdata.return_value = migr_data
with mock.patch.object(
self.lpmsrc, '_check_migration_ready', return_value=None):
# Test the bad path first, then patch in values to make succeed
self.lpmsrc.dest_data = {'dest_proc_compat': 'a,b,c'}
mock_wrap = mock.Mock(id=123)
mock_get_wrap.return_value = mock_wrap
self.assertRaises(exception.MigrationPreCheckError,
self.lpmsrc.check_source, 'context',
'block_device_info', [])
# Patch the proc compat fields, to get further
pm = mock.PropertyMock(return_value='b')
type(mock_wrap).proc_compat_mode = pm
self.assertRaises(exception.MigrationPreCheckError,
self.lpmsrc.check_source, 'context',
'block_device_info', [])
pm = mock.PropertyMock(return_value='Not_Migrating')
type(mock_wrap).migration_state = pm
# Get a volume driver.
mock_vol_drv = mock.MagicMock()
# Finally, good path.
self.lpmsrc.check_source('context', 'block_device_info',
[mock_vol_drv])
# Ensure we built a scrubber.
mock_scrub.assert_called_with(mock.ANY, 123)
# Ensure we added the subtasks to remove the vopts.
mock_cd.return_value.dlt_vopt.assert_called_once_with(
mock.ANY, stg_ftsk=mock_scrub.return_value,
remove_mappings=False)
# And ensure the scrubber was executed
mock_scrub.return_value.execute.assert_called_once_with()
mock_vol_drv.pre_live_migration_on_source.assert_called_once_with(
{'public_key': None})
# Ensure migration counts are validated
migr_data['active_migrations_in_progress'] = 4
self.assertRaises(exception.MigrationPreCheckError,
self.lpmsrc.check_source, 'context',
'block_device_info', [])
# Ensure the vterm was closed
mock_vterm_close.assert_called_once_with(
self.apt, mock_wrap.uuid)
@mock.patch('pypowervm.wrappers.managed_system.System.migration_data',
new_callable=mock.PropertyMock, name='MigDataProp')
def test_lpm_dest(self, mock_migrdata):
src_compute_info = {'stats': {'memory_region_size': 1}}
dst_compute_info = {'stats': {'memory_region_size': 1}}
migr_data = {'active_migrations_supported': 4,
'active_migrations_in_progress': 2}
mock_migrdata.return_value = migr_data
with mock.patch.object(self.drv.host_wrapper, 'refresh') as mock_rfh:
self.lpmdst.check_destination(
'context', src_compute_info, dst_compute_info)
mock_rfh.assert_called_once_with()
self.assertEqual(2, mock_migrdata.call_count)
# Ensure migration counts are validated
migr_data['active_migrations_in_progress'] = 4
self.assertRaises(exception.MigrationPreCheckError,
self.lpmdst.check_destination, 'context',
src_compute_info, dst_compute_info)
# Repair the stat
migr_data['active_migrations_in_progress'] = 2
# Ensure diff memory sizes raises an exception
dst_compute_info['stats']['memory_region_size'] = 2
self.assertRaises(exception.MigrationPreCheckError,
self.lpmdst.check_destination, 'context',
src_compute_info, dst_compute_info)
@mock.patch('pypowervm.tasks.storage.ComprehensiveScrub')
def test_pre_live_mig(self, mock_scrub):
mock_vol_drv = mock.MagicMock()
resp = self.lpmdst.pre_live_migration(
'context', 'block_device_info', 'network_info', 'disk_info',
{}, [mock_vol_drv])
# Make sure we get something back, and that the volume driver was
# invoked.
self.assertIsNotNone(resp)
mock_vol_drv.pre_live_migration_on_destination.assert_called_once_with(
{}, {})
self.assertEqual(1, mock_scrub.call_count)
# Ensure we save the data for later use.
self.assertIsNotNone(getattr(self.lpmdst, 'pre_live_data', None))
@mock.patch('pypowervm.tasks.management_console.add_authorized_key')
def test_pre_live_mig2(self, mock_add_key):
vol_drv = mock.Mock()
raising_vol_drv = mock.Mock()
raising_vol_drv.pre_live_migration_on_destination.side_effect = (
Exception('foo'))
self.assertRaises(
exception.MigrationPreCheckError, self.lpmdst.pre_live_migration,
'context', 'block_device_info', 'network_info', 'disk_info',
{'migrate_data': {'public_key': 'abc123'}},
[vol_drv, raising_vol_drv])
mock_add_key.assert_called_once_with(self.apt, 'abc123')
vol_drv.pre_live_migration_on_destination.assert_called_once_with(
{'public_key': 'abc123'}, {})
(raising_vol_drv.pre_live_migration_on_destination.
assert_called_once_with({'public_key': 'abc123'}, {}))
def test_src_cleanup(self):
vol_drv = mock.Mock()
self.lpmdst.pre_live_data = {}
self.lpmdst.cleanup_volume(vol_drv)
# Ensure the volume driver was called to clean up the volume.
vol_drv.cleanup_volume_at_destination.assert_called_once_with({})
@mock.patch('pypowervm.tasks.migration.migrate_lpar')
def test_live_migration(self, mock_migr):
self.lpmsrc.lpar_w = mock.Mock()
self.lpmsrc.dest_data = dict(
dest_sys_name='a', dest_ip='1', dest_user_id='neo')
self.lpmsrc.live_migration('context', {})
mock_migr.called_once_with('context')
# Test that we raise errors received during migration
mock_migr.side_effect = ValueError()
self.assertRaises(ValueError, self.lpmsrc.live_migration, 'context',
{})
mock_migr.called_once_with('context')
def test_post_live_mig_src(self):
self.lpmsrc.post_live_migration_at_source('network_info')
def test_post_live_mig_dest(self):
self.lpmdst.post_live_migration_at_destination('network_info', [])
@mock.patch('pypowervm.tasks.migration.migrate_recover')
def test_rollback(self, mock_migr):
self.lpmsrc.lpar_w = mock.Mock()
# Test no need to rollback
self.lpmsrc.lpar_w.migration_state = 'Not_Migrating'
self.lpmsrc.rollback_live_migration('context')
self.assertTrue(self.lpmsrc.lpar_w.refresh.called)
self.assertFalse(mock_migr.called)
# Test calling the rollback
self.lpmsrc.lpar_w.reset_mock()
self.lpmsrc.lpar_w.migration_state = 'Pretend its Migrating'
self.lpmsrc.rollback_live_migration('context')
self.assertTrue(self.lpmsrc.lpar_w.refresh.called)
mock_migr.assert_called_once_with(self.lpmsrc.lpar_w, force=True)
# Test exception from rollback
mock_migr.reset_mock()
self.lpmsrc.lpar_w.reset_mock()
mock_migr.side_effect = ValueError()
self.lpmsrc.rollback_live_migration('context')
self.assertTrue(self.lpmsrc.lpar_w.refresh.called)
mock_migr.assert_called_once_with(self.lpmsrc.lpar_w, force=True)
def test_check_migration_ready(self):
lpar_w, host_w = mock.Mock(), mock.Mock()
lpar_w.can_lpm.return_value = (True, None)
self.lpmsrc._check_migration_ready(lpar_w, host_w)
lpar_w.can_lpm.assert_called_once_with(host_w, migr_data=None)
lpar_w.can_lpm.return_value = (False, 'This is the reason message.')
self.assertRaises(exception.MigrationPreCheckError,
self.lpmsrc._check_migration_ready, lpar_w, host_w)
@mock.patch('pypowervm.tasks.migration.migrate_abort')
def test_migration_abort(self, mock_mig_abort):
self.lpmsrc.lpar_w = mock.Mock()
self.lpmsrc.migration_abort()
mock_mig_abort.called_once_with(self.lpmsrc.lpar_w)
@mock.patch('pypowervm.tasks.migration.migrate_recover')
def test_migration_recover(self, mock_mig_recover):
self.lpmsrc.lpar_w = mock.Mock()
self.lpmsrc.migration_recover()
mock_mig_recover.called_once_with(self.lpmsrc.lpar_w, force=True)