diff --git a/nova_powervm/tests/virt/powervm/test_slot.py b/nova_powervm/tests/virt/powervm/test_slot.py index 9edfb31b..3b41eaf9 100644 --- a/nova_powervm/tests/virt/powervm/test_slot.py +++ b/nova_powervm/tests/virt/powervm/test_slot.py @@ -54,7 +54,7 @@ class TestSwiftSlotManager(test.TestCase): super(TestSwiftSlotManager, self).setUp() self.store_api = mock.MagicMock() self.store_api.fetch_slot_map = mock.MagicMock(return_value=None) - self.inst = mock.MagicMock(uuid='uuid1') + self.inst = mock.MagicMock(uuid='a2e71b38-160f-4650-bbdc-2a10cd507e2b') self.slot_mgr = slot.SwiftSlotManager(self.store_api, instance=self.inst) @@ -63,7 +63,8 @@ class TestSwiftSlotManager(test.TestCase): self.slot_mgr.load() # Validate the call - self.store_api.fetch_slot_map.assert_called_with('uuid1_slot_map') + self.store_api.fetch_slot_map.assert_called_with( + self.inst.uuid + '_slot_map') def test_save(self): # Mock the call @@ -74,7 +75,7 @@ class TestSwiftSlotManager(test.TestCase): # Validate the call self.store_api.store_slot_map.assert_called_once_with( - 'uuid1_slot_map', mock.ANY) + self.inst.uuid + '_slot_map', mock.ANY) def test_delete(self): # Mock the call @@ -85,22 +86,35 @@ class TestSwiftSlotManager(test.TestCase): # Validate the call self.store_api.delete_slot_map.assert_called_once_with( - 'uuid1_slot_map') + self.inst.uuid + '_slot_map') @mock.patch('pypowervm.tasks.slot_map.RebuildSlotMap') - @mock.patch('pypowervm.wrappers.virtual_io_server.VIOS.get') - def test_init_recreate_map(self, mock_vios_get, mock_rebuild_slot): + @mock.patch('nova_powervm.virt.powervm.vm.get_vm_id') + @mock.patch('pypowervm.tasks.storage.add_lpar_storage_scrub_tasks') + @mock.patch('pypowervm.tasks.storage.ComprehensiveScrub') + def test_init_recreate_map(self, mock_ftsk, mock_alsst, mock_vm_id, + mock_rebuild_slot): vios1, vios2 = mock.Mock(uuid='uuid1'), mock.Mock(uuid='uuid2') - mock_vios_get.return_value = [vios1, vios2] + mock_ftsk.return_value.feed = [vios1, vios2] self.slot_mgr.init_recreate_map(mock.Mock(), self._vol_drv_iter()) + # get_vm_id called with converted UUID + mock_vm_id.assert_called_once_with( + mock.ANY, '22E71B38-160F-4650-BBDC-2A10CD507E2B') + self.assertEqual(1, mock_ftsk.call_count) + mock_alsst.assert_called_once_with( + [mock_vm_id.return_value], mock_ftsk.return_value, + lpars_exist=True) mock_rebuild_slot.assert_called_once_with( self.slot_mgr, mock.ANY, {'udid': ['uuid2']}, ['a', 'b']) @mock.patch('pypowervm.tasks.slot_map.RebuildSlotMap') - @mock.patch('pypowervm.wrappers.virtual_io_server.VIOS.get') - def test_init_recreate_map_fails(self, mock_vios_get, mock_rebuild_slot): + @mock.patch('nova_powervm.virt.powervm.vm.get_vm_id', new=mock.Mock()) + @mock.patch('pypowervm.tasks.storage.add_lpar_storage_scrub_tasks', + new=mock.Mock()) + @mock.patch('pypowervm.tasks.storage.ComprehensiveScrub') + def test_init_recreate_map_fails(self, mock_ftsk, mock_rebuild_slot): vios1, vios2 = mock.Mock(uuid='uuid1'), mock.Mock(uuid='uuid2') - mock_vios_get.return_value = [vios1, vios2] + mock_ftsk.return_value.feed = [vios1, vios2] mock_rebuild_slot.side_effect = ( pvm_exc.InvalidHostForRebuildNotEnoughVIOS(udid='udid56')) self.assertRaises( diff --git a/nova_powervm/virt/powervm/slot.py b/nova_powervm/virt/powervm/slot.py index 7842b305..ace169c4 100644 --- a/nova_powervm/virt/powervm/slot.py +++ b/nova_powervm/virt/powervm/slot.py @@ -18,14 +18,13 @@ import six from oslo_log import log as logging -from pypowervm import const as c from pypowervm import exceptions as pvm_exc from pypowervm.tasks import slot_map -from pypowervm.wrappers import virtual_io_server as pvm_vios +from pypowervm.tasks import storage as pvm_tstor from nova_powervm.virt.powervm import exception as p_exc from nova_powervm.virt.powervm.i18n import _LW - +from nova_powervm.virt.powervm import vm LOG = logging.getLogger(__name__) @@ -112,11 +111,18 @@ class NovaSlotManager(slot_map.SlotMapStore): :param adapter: The pypowervm adapter. :param vol_drv_iter: An iterator of the volume drivers. """ - # Get the VIOSes first. Be greedy, this should only be called on a - # rebuild. For the rebuild we need to focus on being correct first. - # Performance is secondary. - self._vios_wraps = pvm_vios.VIOS.get( - adapter, xag=[c.XAG.VIO_STOR, c.XAG.VIO_FMAP, c.XAG.VIO_SMAP]) + # This should only be called on a rebuild. Focus on being correct + # first. Performance is secondary. + + # We need to scrub existing stale mappings, including those for the VM + # we're creating. It is critical that this happen *before* we create + # any of the mappings we actually want this VM to have. + scrub_ftsk = pvm_tstor.ComprehensiveScrub(adapter) + lpar_id = vm.get_vm_id(adapter, vm.get_pvm_uuid(self.instance)) + pvm_tstor.add_lpar_storage_scrub_tasks([lpar_id], scrub_ftsk, + lpars_exist=True) + scrub_ftsk.execute() + self._vios_wraps = scrub_ftsk.feed pv_vscsi_vol_to_vio = {} fabric_names = []