def test_disconnect_image_disk(self, mock_active_vioses, mock_rm_maps): # vio_to_vg is a single-entry response. Wrap it and put it in a list # to act as the feed for FeedTaskFx and FeedTask. feed = [pvm_vios.VIOS.wrap(self.vio_to_vg)] mock_active_vioses.return_value = feed ft_fx = pvm_fx.FeedTaskFx(feed) self.useFixture(ft_fx) # The mock return values mock_rm_maps.return_value = True # Need the driver to return the actual UUID of the VIOS in the feed, # to match the FeedTask. self.mock_vg_uuid.return_value = (feed[0].uuid, 'vg_uuid') # Create the feed task local = self.get_ls(self.apt) inst = mock.Mock(uuid=fx.FAKE_INST_UUID) # As initialized above, remove_maps returns True to trigger update. local.disconnect_image_disk(mock.MagicMock(), inst, stg_ftsk=None, disk_type=[disk_dvr.DiskType.BOOT]) self.assertEqual(1, mock_rm_maps.call_count) self.assertEqual(1, ft_fx.patchers['update'].mock.call_count) mock_rm_maps.assert_called_once_with(feed[0], fx.FAKE_INST_UUID_PVM, match_func=mock.ANY)
def test_dlt_vopt_no_map(self, mock_vop_valid, mock_vm_id, rm_vg_stor): feed = [pvm_vios.VIOS.wrap(self.vio_to_vg)] ft_fx = pvm_fx.FeedTaskFx(feed) self.useFixture(ft_fx) # Set up the mock data. self.apt.read.side_effect = [self.vio_to_vg, self.vg_to_vio] mock_vm_id.return_value = '2' def validate_remove_stor(vg_w, vopts=None): vopts = {} if vopts is None else vopts self.assertIsInstance(vg_w, pvm_stor.VG) self.assertEqual(1, len(vopts)) self.assertIsInstance(vopts[0], pvm_stor.VOptMedia) rm_vg_stor.side_effect = validate_remove_stor # Count the number of SCSI mappings beforehand num_maps_before = len(feed[0].scsi_mappings) # Invoke the operation cfg_dr = m.ConfigDrivePowerVM(self.apt, 'fake_host') cfg_dr.vios_uuid = feed[0].uuid cfg_dr.dlt_vopt('2', remove_mappings=False) # The storage should have been removed self.assertTrue(rm_vg_stor.called) # The mappings should have changed self.assertTrue(ft_fx.patchers['update'].mock.called) # But the number should be the same (the vopt mapping was replaced) self.assertEqual(num_maps_before, len(feed[0].scsi_mappings))
def test_attach_vopt(self, mock_validate, mock_build_map, mock_add_map): # to act as the feed for FeedTaskFx and FeedTask. feed = [pvm_vios.VIOS.wrap(self.vio_to_vg)] ft_fx = pvm_fx.FeedTaskFx(feed) self.useFixture(ft_fx) mock_instance = mock.MagicMock(name='fake-instance') cfg_dr_builder = m.ConfigDrivePowerVM(self.apt, 'fake_host') cfg_dr_builder.vios_uuid = feed[0].uuid vopt = mock.Mock() self.apt.read.return_value = self.vio_to_vg def validate_build(host_uuid, vios_w, lpar_uuid, vopt_elem): self.assertEqual('fake_host', host_uuid) self.assertIsInstance(vios_w, pvm_vios.VIOS) self.assertEqual('lpar_uuid', lpar_uuid) self.assertEqual(vopt, vopt_elem) return 'map' mock_build_map.side_effect = validate_build def validate_add(vios_w, mapping): self.assertIsInstance(vios_w, pvm_vios.VIOS) self.assertEqual(mapping, 'map') return 'added' mock_add_map.side_effect = validate_add cfg_dr_builder._attach_vopt(mock_instance, 'lpar_uuid', vopt) # Make sure they were called and validated self.assertEqual(1, mock_build_map.call_count) self.assertEqual(1, mock_add_map.call_count) self.assertEqual(1, ft_fx.patchers['update'].mock.call_count)
def test_connect_image_disk_no_update(self, mock_active_vioses, mock_add_map, mock_build_map): # vio_to_vg is a single-entry response. Wrap it and put it in a list # to act as the feed for FeedTaskFx and FeedTask. feed = [pvm_vios.VIOS.wrap(self.vio_to_vg)] mock_active_vioses.return_value = feed ft_fx = pvm_fx.FeedTaskFx(feed) self.useFixture(ft_fx) # The mock return values mock_add_map.return_value = False self.mock_vg_uuid.return_value = (feed[0].uuid, 'vg_uuid') mock_build_map.return_value = 'fake_map' # Need the driver to return the actual UUID of the VIOS in the feed, # to match the FeedTask. local = self.get_ls(self.apt) inst = mock.Mock(uuid=fx.FAKE_INST_UUID) # As initialized above, remove_maps returns True to trigger update. local.connect_disk(mock.MagicMock(), inst, mock.MagicMock(), stg_ftsk=None) self.assertEqual(1, mock_add_map.call_count) mock_add_map.assert_called_once_with(feed[0], 'fake_map') self.assertEqual(0, ft_fx.patchers['update'].mock.call_count)
def test_post_exec(self): def log_func(msg): def _log(*a, **k): ftfx.log(msg) return _log def log_task(msg): return tf_task.FunctorTask(log_func(msg), name='functor_%s' % msg) # Limit the feed to two to keep the logging sane ftfx = self.useFixture(fx.FeedTaskFx(self.entries[:2])) # Make the logging predictable by limiting to one thread ftsk = tx.FeedTask('post_exec', lpar.LPAR.getter(None), max_workers=1) # First prove that a FeedTask with *only* post-execs can run. ftsk.add_post_execute(log_task('post1')) ftsk.add_post_execute(log_task('post2')) ftsk.execute() # Note that no GETs or locks happen self.assertEqual(['post1', 'post2'], ftfx.get_log()) # Now add regular subtasks ftfx.reset_log() ftsk.add_functor_subtask(log_func('main1')) ftsk.add_functor_subtask(log_func('main2')) ftsk.execute() # One GET, up front. Posts happen at the end. self.assertEqual([ 'get', 'lock', 'main1', 'main2', 'unlock', 'lock', 'main1', 'main2', 'unlock', 'post1', 'post2' ], ftfx.get_log())
def setUp(self): super(TestScrub3, self).setUp() self.adpt = self.useFixture(fx.AdapterFx()).adpt self.vio_feed = [vios.VIOS.wrap(tju.load_file(VIOS_ENTRY2, self.adpt))] self.txfx = self.useFixture(fx.FeedTaskFx(self.vio_feed)) self.logfx = self.useFixture(fx.LoggingFx()) self.ftsk = tx.FeedTask('scrub', self.vio_feed)
def setUp(self): super(TestNPIVAdapter, self).setUp() self.adpt = self.useFixture(pvm_fx.AdapterFx()).adpt def resp(file_name): return pvmhttp.load_pvm_resp(file_name, adapter=self.adpt).get_response() self.vios_feed_resp = resp(VIOS_FEED) self.wwpn1 = '21000024FF649104' self.wwpn2 = '21000024FF649107' self.vios_uuid = '3443DB77-AED1-47ED-9AA5-3DB9C6CF7089' self.slot_mgr = mock.Mock() # Set up the transaction manager feed = pvm_vios.VIOS.wrap(self.vios_feed_resp) self.ft_fx = pvm_fx.FeedTaskFx(feed) self.useFixture(self.ft_fx) # Set up the mocks for the internal volume driver name = 'nova_powervm.virt.powervm.volume.npiv.NPIVVolumeAdapter.' self.mock_port_count_p = mock.patch(name + '_ports_per_fabric') self.mock_port_count = self.mock_port_count_p.start() self.mock_port_count.return_value = 1 self.mock_fabric_names_p = mock.patch(name + '_fabric_names') self.mock_fabric_names = self.mock_fabric_names_p.start() self.mock_fabric_names.return_value = ['A'] self.mock_fabric_ports_p = mock.patch(name + '_fabric_ports') self.mock_fabric_ports = self.mock_fabric_ports_p.start() self.mock_fabric_ports.return_value = [self.wwpn1, self.wwpn2] @mock.patch('pypowervm.wrappers.virtual_io_server.VIOS.getter') @mock.patch('nova_powervm.virt.powervm.vm.get_pvm_uuid') def init_vol_adpt(mock_pvm_uuid, mock_getter): con_info = { 'serial': 'id', 'data': { 'initiator_target_map': { 'i1': ['t1'], 'i2': ['t2', 't3'] }, 'target_lun': '1' } } mock_inst = mock.MagicMock() mock_pvm_uuid.return_value = '1234' # The getter can just return the VIOS values (to remove a read # that would otherwise need to be mocked). mock_getter.return_value = feed return npiv.NPIVVolumeAdapter(self.adpt, 'host_uuid', mock_inst, con_info) self.vol_drv = init_vol_adpt()
def setUp(self): super(TestISCSIAdapter, self).setUp() self.adpt = self.useFixture(pvm_fx.AdapterFx()).adpt self.vios_feed_resp = load_file(VIOS_FEED) self.feed = pvm_vios.VIOS.wrap(self.vios_feed_resp) self.ft_fx = pvm_fx.FeedTaskFx(self.feed) self.useFixture(self.ft_fx) self.adpt.read.return_value = self.vios_feed_resp @mock.patch('pypowervm.wrappers.virtual_io_server.VIOS', autospec=True) @mock.patch('nova_powervm.virt.powervm.vm.get_pvm_uuid') @mock.patch('pypowervm.tasks.partition.get_mgmt_partition', autospec=True) @mock.patch('pypowervm.tasks.hdisk.discover_iscsi_initiator', autospec=True) def init_vol_adpt(mock_initiator, mock_mgmt_part, mock_pvm_uuid, mock_vios): self.trans_type = 'iscsi' self.iqn = 'iqn.2016-08.bar.foo:target' self.lun = '1' self.host_ip = '10.0.0.1' self.user = '******' self.password = '******' self.serial = 'f042c68a-c5a5-476a-ba34-2f6d43f4226c' con_info = { 'serial': self.serial, 'driver_volume_type': self.trans_type, 'data': { 'target_iqn': self.iqn, 'target_lun': self.lun, 'target_portal': self.host_ip, 'auth_username': self.user, 'auth_password': self.password }, } mock_inst = mock.MagicMock() mock_pvm_uuid.return_value = '1234' mock_initiator.return_value = 'initiatior iqn' # The getter can just return the VIOS values (to remove a read # that would otherwise need to be mocked). mock_vios.getter.return_value = self.feed return iscsi.IscsiVolumeAdapter(self.adpt, 'host_uuid', mock_inst, con_info) self.vol_drv = init_vol_adpt() # setup system_metadata tests self.devname = "/dev/fake" self.slot_mgr = mock.Mock() self.slot_mgr.build_map.get_vscsi_slot.return_value = 62, 'the_lua'
def setUp(self): super(TestFileIOVolumeAdapter, self).setUp() # Needed for the volume adapter self.adpt = self.useFixture(pvm_fx.AdapterFx()).adpt mock_inst = mock.MagicMock(uuid='2BC123') self.vol_drv = FakeFileIOVolAdapter(self.adpt, 'host_uuid', mock_inst, dict(serial='volid1')) self.fake_vios = pvm_vios.VIOS.bld( self.adpt, 'vios1', pvm_bp.PartitionMemoryConfiguration.bld(self.adpt, 1024), pvm_bp.PartitionMemoryConfiguration.bld(self.adpt, 0.1, 1)) self.feed = [pvm_vios.VIOS.wrap(self.fake_vios.entry)] ftskfx = pvm_fx.FeedTaskFx(self.feed) self.useFixture(ftskfx)
def test_disconnect_disk(self, mock_active_vioses, mock_build_map, mock_remove_maps, mock_find_maps, mock_vio_uuids): # vio is a single-entry response. Wrap it and put it in a list # to act as the feed for FeedTaskFx and FeedTask. feed = [self.vio_wrap] ft_fx = pvm_fx.FeedTaskFx(feed) mock_active_vioses.return_value = feed self.useFixture(ft_fx) # The mock return values mock_build_map.return_value = 'fake_map' # Need the driver to return the actual UUID of the VIOS in the feed, # to match the FeedTask. ssp = self._get_ssp_stor() mock_vio_uuids.return_value = [self.vio_wrap.uuid] # Make the LU's to remove def mklu(udid): lu = pvm_stg.LU.bld(None, 'lu_%s' % udid, 1) lu._udid('27%s' % udid) return lu lu1 = mklu('abc') lu2 = mklu('def') def remove_resp(vios_w, client_lpar_id, match_func=None, include_orphans=False): return [ mock.Mock(backing_storage=lu1), mock.Mock(backing_storage=lu2) ] mock_remove_maps.side_effect = remove_resp mock_find_maps.side_effect = remove_resp # As initialized above, remove_maps returns True to trigger update. lu_list = ssp.disconnect_disk(self.instance, stg_ftsk=None) self.assertEqual({lu1, lu2}, set(lu_list)) mock_remove_maps.assert_called_once_with(self.vio_wrap, fx.FAKE_INST_UUID_PVM, match_func=mock.ANY) self.vio_wrap.update.assert_called_once_with(timeout=mock.ANY)
def setUp(self, vios_feed_file, p_wwpn1, p_wwpn2): super(BaseVSCSITest, self).setUp() self.adpt = self.useFixture(pvm_fx.AdapterFx()).adpt def resp(file_name): return pvmhttp.load_pvm_resp(file_name, adapter=self.adpt).get_response() self.vios_feed_resp = resp(vios_feed_file) self.feed = pvm_vios.VIOS.wrap(self.vios_feed_resp) self.ft_fx = pvm_fx.FeedTaskFx(self.feed) self.useFixture(self.ft_fx) self.adpt.read.return_value = self.vios_feed_resp @mock.patch('pypowervm.wrappers.virtual_io_server.VIOS.getter') @mock.patch('nova_powervm.virt.powervm.vm.get_pvm_uuid') def init_vol_adpt(mock_pvm_uuid, mock_getter): con_info = { 'serial': 'id', 'data': { 'initiator_target_map': { p_wwpn1: ['t1'], p_wwpn2: ['t2', 't3'] }, 'target_lun': '1', 'volume_id': 'a_volume_identifier', 'pg83NAA': '4567' }, } mock_inst = mock.MagicMock() mock_pvm_uuid.return_value = '1234' # The getter can just return the VIOS values (to remove a read # that would otherwise need to be mocked). mock_getter.return_value = self.feed return vscsi.PVVscsiFCVolumeAdapter(self.adpt, 'host_uuid', mock_inst, con_info) self.vol_drv = init_vol_adpt()
def test_dlt_vopt(self, mock_vop_valid, mock_vm_id, rm_vg_stor): feed = [pvm_vios.VIOS.wrap(self.vio_to_vg)] ft_fx = pvm_fx.FeedTaskFx(feed) self.useFixture(ft_fx) # Set up the mock data. self.apt.read.side_effect = [self.vio_to_vg, self.vg_to_vio] mock_vm_id.return_value = '2' # Make sure that the first update is a VIO and doesn't have the vopt # mapping def validate_update(*kargs, **kwargs): vol_grp = kargs[0] # This is the VG update. Make sure there are no optical medias # anymore. self.assertEqual(0, len(vol_grp.vmedia_repos[0].optical_media)) return vol_grp.entry self.apt.update_by_path.side_effect = validate_update def validate_remove_stor(vg_w, vopts=None): vopts = {} if vopts is None else vopts self.assertIsInstance(vg_w, pvm_stor.VG) self.assertEqual(1, len(vopts)) self.assertIsInstance(vopts[0], pvm_stor.VOptMedia) rm_vg_stor.side_effect = validate_remove_stor # Count the number of SCSI mappings beforehand num_maps_before = len(feed[0].scsi_mappings) # Invoke the operation cfg_dr = m.ConfigDrivePowerVM(self.apt, 'fake_host') cfg_dr.vios_uuid = feed[0].uuid cfg_dr.dlt_vopt('2') self.assertEqual(num_maps_before - 1, len(feed[0].scsi_mappings)) self.assertTrue(ft_fx.patchers['update'].mock.called) self.assertTrue(rm_vg_stor.called)
def test_connect_disk_no_update(self, mock_active_vioses, mock_add_map, mock_build_map, mock_vio_uuids): # vio is a single-entry response. Wrap it and put it in a list # to act as the feed for FeedTaskFx and FeedTask. feed = [self.vio_wrap] mock_active_vioses.return_value = feed ft_fx = pvm_fx.FeedTaskFx(feed) self.useFixture(ft_fx) # The mock return values mock_add_map.return_value = None mock_build_map.return_value = 'fake_map' # Need the driver to return the actual UUID of the VIOS in the feed, # to match the FeedTask. ssp = self._get_ssp_stor() mock_vio_uuids.return_value = [self.vio_wrap.uuid] inst = mock.Mock(uuid=fx.FAKE_INST_UUID) # As initialized above, add_maps returns False to skip update. ssp.connect_disk(inst, mock.Mock(), stg_ftsk=None) mock_add_map.assert_called_once_with(self.vio_wrap, 'fake_map') self.vio_wrap.update.assert_not_called()
def setUp(self): super(TestRBDVolumeAdapter, self).setUp() # Needed for the volume adapter self.adpt = self.useFixture(pvm_fx.AdapterFx()).adpt mock_inst = mock.MagicMock(uuid='2BC123') self.vol_drv = FakeRBDVolAdapter( self.adpt, 'host_uuid', mock_inst, { 'data': { 'name': 'pool/image', 'volume_id': 'a_vol_id' }, 'serial': 'volid1' }) self.fake_vios = pvm_vios.VIOS.bld( self.adpt, 'vios1', pvm_bp.PartitionMemoryConfiguration.bld(self.adpt, 1024), pvm_bp.PartitionMemoryConfiguration.bld(self.adpt, 0.1, 1)) self.feed = [pvm_vios.VIOS.wrap(self.fake_vios.entry)] ftskfx = pvm_fx.FeedTaskFx(self.feed) self.useFixture(ftskfx)
def test_wrapper_task_rets(self): # Limit the feed to two to keep the return size sane ftfx = self.useFixture(fx.FeedTaskFx(self.entries[:2])) ftsk = tx.FeedTask('subtask_rets', lpar.LPAR.getter(None), update_timeout=123) exp_wtr = { wrp.uuid: { 'wrapper': wrp, 'the_id': wrp.id, 'the_name': wrp.name } for wrp in ftsk.feed } called = [] def return_wrapper_name(wrapper): return wrapper.name def return_wrapper_id(wrapper): return wrapper.id def verify_rets_implicit(wrapper_task_rets): called.append('implicit') self.assertEqual(exp_wtr, wrapper_task_rets) return 'verify_rets_implicit_return' def verify_rets_explicit(**kwargs): called.append('explicit') self.assertEqual(exp_wtr, kwargs['wrapper_task_rets']) return 'verify_rets_explicit_return' ftsk.add_functor_subtask(return_wrapper_name, provides='the_name') ftsk.add_functor_subtask(return_wrapper_id, provides='the_id') # Execute once here to make sure the return is in the right shape when # there are no post-execs self.assertEqual( { 'wrapper_task_rets': { self.entries[0].uuid: { 'the_name': self.entries[0].name, 'the_id': self.entries[0].id, 'wrapper': self.entries[0] }, self.entries[1].uuid: { 'the_name': self.entries[1].name, 'the_id': self.entries[1].id, 'wrapper': self.entries[1] } } }, ftsk.execute()) ftsk.add_post_execute( tf_task.FunctorTask(verify_rets_implicit, provides='post_exec_implicit')) ftsk.add_post_execute( tf_task.FunctorTask(verify_rets_explicit, requires='wrapper_task_rets', provides='post_exec_explicit')) ret = ftsk.execute() # Make sure the post-execs actually ran (to guarantee their internal # assertions passed). self.assertEqual(['implicit', 'explicit'], called) ftfx.patchers['update'].mock.assert_called_with(mock.ANY, timeout=123) # Verify that we got the returns from the subtasks AND the post-execs self.assertEqual( { 'wrapper_task_rets': { self.entries[0].uuid: { 'the_name': self.entries[0].name, 'the_id': self.entries[0].id, 'wrapper': self.entries[0] }, self.entries[1].uuid: { 'the_name': self.entries[1].name, 'the_id': self.entries[1].id, 'wrapper': self.entries[1] } }, 'post_exec_implicit': 'verify_rets_implicit_return', 'post_exec_explicit': 'verify_rets_explicit_return' }, ret)