def test_extend_lun(self): jrest, ctx = self.get_rest(CONFIG_OK) resp = {'data': None, 'error': None, 'code': 201} jbody = { 'size': "2147483648", } jrest.rproxy.pool_request.return_value = resp self.assertIsNone(jrest.extend_lun(jcom.vname(UUID_1), 2 * o_units.Gi)) err = {'message': 'test failure'} resp = {'code': 500, 'data': None, 'error': err} jrest.rproxy.pool_request.return_value = resp self.assertRaises(jexc.JDSSRESTException, jrest.extend_lun, jcom.vname(UUID_1), 2 * o_units.Gi) addr = "/volumes/" + jcom.vname(UUID_1) create_lun_expected = [ mock.call('PUT', addr, json_data=jbody), mock.call('PUT', addr, json_data=jbody)] jrest.rproxy.pool_request.assert_has_calls(create_lun_expected)
def test_gc_delete_not_clone(self): jdssd, ctx = self.get_driver(CONFIG_OK) vol = fake_volume.fake_volume_obj(ctx) vol.id = UUID_1 get_lun_resp = { 'vscan': None, 'full_name': 'Pool-0/' + jcom.vname(UUID_1), 'userrefs': None, 'primarycache': 'all', 'logbias': 'latency', 'creation': '1591543140', 'sync': 'always', 'is_clone': False, 'dedup': 'off', 'sharenfs': None, 'receive_resume_token': None, 'volsize': '1073741824' } jdssd.ra.get_lun.return_value = get_lun_resp jdssd.ra.delete_lun.return_value = None patches = [mock.patch.object(jdssd, "_delete_back_recursively")] self.start_patches(patches) jdssd._gc_delete(jcom.vname(UUID_1)) jdssd._delete_back_recursively.assert_not_called() jdssd.ra.delete_lun.assert_called_once_with(jcom.vname(UUID_1)) self.stop_patches(patches)
def create_cloned_volume(self, volume, src_vref): """Create a clone of the specified volume. :param volume: new volume reference :param src_vref: source volume reference """ cvname = jcom.vname(volume.id) vname = jcom.vname(src_vref.id) LOG.debug('cloned volume %(id)s to %(id_clone)s', { "id": src_vref.id, "id_clone": volume.id }) self._clone_object(vname, cvname) clone_size = 0 try: clone_size = int(self.ra.get_lun(cvname)['volsize']) except jexc.JDSSException as jerr: self._delete_back_recursively(vname, cvname) raise exception.VolumeBackendAPIException( _("Fail in cloning volume %(vol)s to %(clone)s.") % { 'vol': src_vref.id, 'clone': volume.id }) from jerr try: if int(clone_size) < o_units.Gi * int(volume.size): self.extend_volume(volume, int(volume.size)) except exception.VolumeBackendAPIException: # If volume can't be set to a proper size make sure to clean it # before failing try: self._delete_back_recursively(cvname, cvname) except exception.VolumeBackendAPIException as err: LOG.warning( "Because of %s physical snapshot %s of volume" " %s have to be removed manually", err, cvname, vname) raise provider_location = self._get_provider_location(volume.id) provider_auth = self._get_provider_auth() ret = {} if provider_auth: ret['provider_auth'] = provider_auth ret['provider_location'] = provider_location return ret
def test_clone_object(self): jdssd, ctx = self.get_driver(CONFIG_OK) origin = jcom.vname(UUID_1) clone = jcom.vname(UUID_2) jdssd.ra.create_snapshot.return_value = None jdssd.ra.create_volume_from_snapshot.return_value = None jdssd._clone_object(origin, clone) jdssd.ra.create_snapshot.assert_called_once_with(origin, clone) jdssd.ra.create_volume_from_snapshot.assert_called_once_with( clone, clone, origin, sparse=False)
def test_create_lun(self): jrest, ctx = self.get_rest(CONFIG_OK) resp = {'data': { 'vscan': None, 'full_name': 'pool-0/' + jcom.vname(UUID_1), 'userrefs': None, 'primarycache': 'all', 'logbias': 'latency', 'creation': '1591543140', 'sync': 'always', 'is_clone': False, 'dedup': 'off', 'sharenfs': None, 'receive_resume_token': None, 'volsize': '1073741824'}, 'error': None, 'code': 200} jbody = { 'name': jcom.vname(UUID_1), 'size': "1073741824", 'sparse': False } jbody_sparse = { 'name': jcom.vname(UUID_1), 'size': "1073741824", 'sparse': True } jrest.rproxy.pool_request.return_value = resp self.assertIsNone(jrest.create_lun(jcom.vname(UUID_1), o_units.Gi)) err = {'errno': '5', 'message': 'test failure'} resp = {'code': 404, 'data': None, 'error': err} jrest.rproxy.pool_request.return_value = resp self.assertRaises(jexc.JDSSRESTException, jrest.create_lun, jcom.vname(UUID_1), o_units.Gi, sparse=True) addr = "/volumes" create_lun_expected = [ mock.call('POST', addr, json_data=jbody), mock.call('POST', addr, json_data=jbody_sparse)] jrest.rproxy.pool_request.assert_has_calls(create_lun_expected)
def test_clone_object_volume_exists(self): jdssd, ctx = self.get_driver(CONFIG_OK) origin = jcom.vname(UUID_1) clone = jcom.vname(UUID_2) jdssd.ra.create_snapshot.return_value = None jdssd.ra.create_volume_from_snapshot.side_effect = ( jexc.JDSSVolumeExistsException(volume=clone)) self.assertRaises(exception.Duplicate, jdssd._clone_object, origin, clone) jdssd.ra.create_snapshot.assert_called_once_with(origin, clone) jdssd.ra.create_volume_from_snapshot.assert_called_once_with( clone, clone, origin, sparse=CONFIG_OK['san_thin_provision'])
def test_cascade_volume_delete_with_clone(self): # Volume with 2 snapshots and 1 clone # We should delete snapshots and then cal for volume hiding jdssd, ctx = self.get_driver(CONFIG_OK) o_vname = jcom.vname(UUID_1) o_snaps = SNAPSHOTS_CASCADE_2.copy() jdssd.ra.modify_lun.return_value = None jdssd.ra.delete_snapshot.return_value = None jdssd.ra.get_snapshots.side_effect = [SNAPSHOTS_EMPTY, SNAPSHOTS_EMPTY] fake_gc = mock.Mock() fake_hide_object = mock.Mock() gc = mock.patch.object(jdssd, "_gc_delete", new=fake_gc) gc.start() hide = mock.patch.object(jdssd, "_hide_object", new=fake_hide_object) hide.start() jdssd._cascade_volume_delete(o_vname, o_snaps) jdssd._hide_object.assert_called_once_with(o_vname) hide.stop() jdssd._gc_delete.assert_not_called() gc.stop() delete_snapshot_expected = [ mock.call(o_vname, SNAPSHOTS_CASCADE_2[0]["name"], recursively_children=True, recursively_dependents=True, force_umount=True), mock.call(o_vname, SNAPSHOTS_CASCADE_2[2]["name"], recursively_children=True, recursively_dependents=True, force_umount=True) ] jdssd.ra.delete_snapshot.assert_has_calls(delete_snapshot_expected)
def test_cascade_volume_delete_snapshots(self): jdssd, ctx = self.get_driver(CONFIG_OK) o_vname = jcom.vname(UUID_1) # Volume with 3 snapshots and no descendants # We should delete snapshots and then cal for volume deletion o_snaps = SNAPSHOTS_CASCADE_1.copy() jdssd.ra.modify_lun.return_value = None jdssd.ra.delete_snapshot.return_value = None jdssd.ra.get_snapshots.side_effect = [ SNAPSHOTS_EMPTY, SNAPSHOTS_EMPTY, SNAPSHOTS_EMPTY ] with mock.patch.object(jdssd, "_gc_delete", return_value=None) as gc: jdssd._cascade_volume_delete(o_vname, o_snaps) gc.assert_called_once_with(o_vname) delete_snapshot_expected = [ mock.call(o_vname, SNAPSHOTS_CASCADE_1[0]["name"], recursively_children=True, recursively_dependents=True, force_umount=True), mock.call(o_vname, SNAPSHOTS_CASCADE_1[1]["name"], recursively_children=True, recursively_dependents=True, force_umount=True), mock.call(o_vname, SNAPSHOTS_CASCADE_1[2]["name"], recursively_children=True, recursively_dependents=True, force_umount=True) ] jdssd.ra.delete_snapshot.assert_has_calls(delete_snapshot_expected)
def test_create_volume_small_block(self): jdssd, ctx = self.get_driver(CONFIG_BLOCK_SIZE) vol = fake_volume.fake_volume_obj(ctx) vol.id = UUID_1 vol.size = 1 host = CONFIG_OK["san_hosts"][0] port = CONFIG_OK["target_port"] target_name = CONFIG_OK["target_prefix"] + UUID_1 vname = jcom.vname(UUID_1) jdssd.ra.create_lun.return_value = None jdssd.ra.get_active_host.return_value = host ret = jdssd.create_volume(vol) jdssd.ra.create_lun.assert_called_once_with(vname, o_units.Gi, sparse=False, block_size="64K") location = '{host}:{port},1 {name} 0'.format(host=host, port=port, name=target_name) self.assertEqual(location, ret['provider_location']) cred_format = (r"CHAP [0-9,a-z,A-Z]{{{name_len}}} " "[0-9,a-z,A-Z]{{{pass_len}}}").format( name_len=8, pass_len=CONFIG_OK['chap_password_len']) self.assertIsNotNone(re.match(cred_format, ret['provider_auth']))
def _create_target_volume(self, volume): """Creates target and attach volume to it :param volume: volume id :return: """ LOG.debug("create target and attach volume %s to it", volume.id) target_name = self.jovian_target_prefix + volume.id vname = jcom.vname(volume.id) auth = volume.provider_auth if not auth: msg = _("Volume %s is missing provider_auth") % volume.id raise exception.VolumeDriverException(msg) (__, auth_username, auth_secret) = auth.split() chap_cred = {"name": auth_username, "password": auth_secret} # Create target self._create_target(target_name, True) # Attach volume self._attach_target_volume(target_name, vname) # Set credentials self._set_target_credentials(target_name, chap_cred)
def create_volume(self, volume): """Create a volume. :param volume: volume reference :return: model update dict for volume reference """ vname = jcom.vname(volume.id) LOG.debug('creating volume %s.', vname) provider_location = self._get_provider_location(volume.id) provider_auth = self._get_provider_auth() try: self.ra.create_lun(vname, volume.size * o_units.Gi, sparse=self.jovian_sparse, block_size=self.block_size) except jexc.JDSSException as jerr: LOG.error("Create volume error. Because %(err)s", {"err": jerr}) raise exception.VolumeBackendAPIException( _('Failed to create volume %s.') % volume.id) from jerr ret = {} if provider_auth is not None: ret['provider_auth'] = provider_auth ret['provider_location'] = provider_location return ret
def delete_volume(self, volume, cascade=False): """Delete volume :param volume: volume reference :param cascade: remove snapshots of a volume as well """ vname = jcom.vname(volume.id) LOG.debug('deleating volume %s', vname) snapshots = None try: snapshots = self.ra.get_snapshots(vname) except jexc.JDSSResourceNotFoundException: LOG.debug('volume %s dne, it was already ' 'deleted', vname) return except jexc.JDSSException as jerr: raise exception.VolumeBackendAPIException(jerr) snapshots = self._clean_garbage_snapshots(vname, snapshots) if cascade: self._cascade_volume_delete(vname, snapshots) else: if len(snapshots) > 0: self._hide_object(vname) else: self._gc_delete(vname)
def test_clone_object_exists(self): jdssd, ctx = self.get_driver(CONFIG_OK) origin = jcom.vname(UUID_1) clone = jcom.vname(UUID_2) jdssd.ra.create_snapshot.side_effect = ( jexc.JDSSSnapshotExistsException(snapshot=clone)) jdssd.ra.delete_snapshot.side_effect = ( jexc.JDSSSnapshotIsBusyException(snapshot=clone)) self.assertRaises(exception.Duplicate, jdssd._clone_object, origin, clone) jdssd.ra.delete_snapshot.assert_called_once_with(origin, clone) jdssd.ra.create_snapshot.assert_called_once_with(origin, clone)
def test_is_target_lun(self): jrest, ctx = self.get_rest(CONFIG_OK) # lun present tname = CONFIG_OK['iscsi_target_prefix'] + UUID_1 vname = jcom.vname(UUID_1) addr = '/san/iscsi/targets/{target}/luns/{lun}'.format( target=tname, lun=vname) data = { "block_size": 512, "device_handler": "vdisk_fileio", "lun": 0, "mode": "wt", "name": vname, "prod_id": "Storage", "scsi_id": "99e2c883331edf87"} resp = {'data': data, 'error': None, 'code': 200} jrest.rproxy.pool_request.return_value = resp is_target_lun_expected = [mock.call('GET', addr)] self.assertTrue(jrest.is_target_lun(tname, vname)) url = "http://{ip}:{port}/api/v3/pools/Pool-0{addr}" url = url.format(ip=CONFIG_OK['san_hosts'][0], port=CONFIG_OK['san_api_port'], tname=tname, addr=addr) msg = "volume name {lun} is not attached to target {target}" msg = msg.format(lun=vname, target=tname) err = {"class": "opene.exceptions.ItemNotFoundError", "message": msg, "url": url} resp = {'data': None, 'error': err, 'code': 404} jrest.rproxy.pool_request.return_value = resp is_target_lun_expected += [mock.call('GET', addr)] self.assertEqual(False, jrest.is_target_lun(tname, vname)) err = {"class": "some test error", "message": "test error message", "url": url, "errno": 123} resp = {'data': None, 'error': err, 'code': 500} jrest.rproxy.pool_request.return_value = resp is_target_lun_expected += [mock.call('GET', addr)] self.assertRaises(jexc.JDSSException, jrest.is_target_lun, tname, vname) jrest.rproxy.pool_request.assert_has_calls(is_target_lun_expected)
def test_extend_volume(self): jdssd, ctx = self.get_driver(CONFIG_OK) vol = fake_volume.fake_volume_obj(ctx) vol.id = UUID_1 jdssd.ra.extend_lun.return_value = None jdssd.extend_volume(vol, 2) jdssd.ra.extend_lun.assert_called_once_with(jcom.vname(UUID_1), 2147483648)
def test_hide_object(self): jdssd, ctx = self.get_driver(CONFIG_OK) vname = jcom.vname(UUID_1) jdssd.ra.modify_lun.return_value = None jdssd._hide_object(vname) hidden_volume = {"name": jcom.hidden(UUID_1)} jdssd.ra.modify_lun.assert_called_once_with(vname, hidden_volume)
def create_volume_from_snapshot(self, volume, snapshot): """Create a volume from a snapshot. If volume_type extra specs includes 'replication: <is> True' the driver needs to create a volume replica (secondary), and setup replication between the newly created volume and the secondary volume. """ LOG.debug('create volume %(vol)s from snapshot %(snap)s', { 'vol': volume.id, 'snap': snapshot.id }) cvname = jcom.vname(volume.id) sname = jcom.sname(snapshot.id) self._clone_object(sname, cvname) clone_size = 0 try: clone_size = int(self.ra.get_lun(cvname)['volsize']) except jexc.JDSSException as jerr: self._delete_back_recursively(sname, cvname) raise exception.VolumeBackendAPIException( _("Fail in cloning snapshot %(snap)s to %(clone)s.") % { 'snap': snapshot.id, 'clone': volume.id }) from jerr try: if clone_size < o_units.Gi * int(volume.size): self.extend_volume(volume, int(volume.size)) except exception.VolumeBackendAPIException: # If volume can't be set to a proper size make sure to clean it # before failing try: self._delete_back_recursively(cvname, cvname) except exception.VolumeBackendAPIException as err: msg = ("Hidden snapshot %s of volume %s " "have to be removed manualy, " "as automatic removal failed: %s") LOG.warning(msg, cvname, sname, err) raise provider_location = self._get_provider_location(volume.id) provider_auth = self._get_provider_auth() ret = {} if provider_auth is not None: ret['provider_auth'] = provider_auth ret['provider_location'] = provider_location return ret
def test_clone_object_dne(self): jdssd, ctx = self.get_driver(CONFIG_OK) calls = [] origin = jcom.vname(UUID_1) clone = jcom.vname(UUID_2) calls.append(mock.call(origin, clone)) jdssd.ra.create_snapshot.side_effect = ( jexc.JDSSResourceNotFoundException(res=origin)) self.assertRaises(exception.VolumeNotFound, jdssd._clone_object, origin, clone) origin = jcom.sname(UUID_1) calls.append(mock.call(origin, clone)) self.assertRaises(exception.SnapshotNotFound, jdssd._clone_object, origin, clone) jdssd.ra.create_snapshot.assert_has_calls(calls)
def test_detach_target_vol(self): jrest, ctx = self.get_rest(CONFIG_OK) # detach target vol ok tname = CONFIG_OK['iscsi_target_prefix'] + UUID_1 vname = jcom.vname(UUID_1) addr = '/san/iscsi/targets/{tar}/luns/{vol}'.format( tar=tname, vol=vname) resp = {'data': None, 'error': None, 'code': 204} jrest.rproxy.pool_request.return_value = resp detach_target_vol_expected = [ mock.call('DELETE', addr)] self.assertIsNone(jrest.detach_target_vol(tname, vname)) # no such target url = 'http://85.14.118.246:11582/api/v3/pools/Pool-0/{}'.format(addr) msg = 'Target {} not exists.'.format(vname) err = {"class": "opene.exceptions.ItemNotFoundError", "message": msg, "url": url} resp = {'data': None, 'error': err, 'code': 404} jrest.rproxy.pool_request.return_value = resp detach_target_vol_expected += [ mock.call('DELETE', addr)] self.assertRaises(jexc.JDSSResourceNotFoundException, jrest.detach_target_vol, tname, vname) # error unknown url = 'http://85.14.118.246:11582/api/v3/pools/Pool-0/{}'.format(addr) msg = 'Target {} not exists.'.format(vname) err = {"class": "some test error", "message": "test error message", "url": url, "errno": 125} resp = {'data': None, 'error': err, 'code': 500} jrest.rproxy.pool_request.return_value = resp detach_target_vol_expected += [ mock.call('DELETE', addr)] self.assertRaises(jexc.JDSSException, jrest.detach_target_vol, tname, vname) jrest.rproxy.pool_request.assert_has_calls(detach_target_vol_expected)
def test_delete_back_recursively_single_snapshot(self): jdssd, ctx = self.get_driver(CONFIG_OK) opvname = jcom.hidden(UUID_2) opsname = jcom.sname(UUID_3) jdssd.ra.get_snapshots.side_effect = [ SNAPSHOTS_RECURSIVE_CHAIN_1.copy(), SNAPSHOTS_RECURSIVE_CHAIN_2.copy() ] origin = "Pool-0/{vorig}@{sorig}".format(vorig=jcom.vname(UUID_1), sorig=jcom.vname(UUID_2)) get_lun_resp = { 'origin': origin, 'vscan': None, 'full_name': 'Pool-0/' + jcom.hidden(UUID_2), 'userrefs': None, 'primarycache': 'all', 'logbias': 'latency', 'creation': '1591543140', 'sync': 'always', 'is_clone': True, 'dedup': 'off', 'sharenfs': None, 'receive_resume_token': None, 'volsize': '1073741824' } jdssd.ra.get_lun.return_value = get_lun_resp jdssd._delete_back_recursively(opvname, opsname) jdssd.ra.delete_snapshot.assert_called_once_with( jcom.vname(UUID_1), jcom.vname(UUID_2), recursively_children=True, recursively_dependents=True, force_umount=True) get_snapshots_expected = [mock.call(opvname)] jdssd.ra.get_snapshots.assert_has_calls(get_snapshots_expected)
def extend_volume(self, volume, new_size): """Extend an existing volume. :param volume: volume reference :param new_size: volume new size in GB """ LOG.debug("Extend volume %s", volume.id) try: self.ra.extend_lun(jcom.vname(volume.id), new_size * o_units.Gi) except jexc.JDSSException as jerr: raise exception.VolumeBackendAPIException( (_('Failed to extend volume %s.'), volume.id)) from jerr
def test_is_lun(self): jrest, ctx = self.get_rest(CONFIG_OK) resp = {'data': { "vscan": None, "full_name": "pool-0/" + jcom.vname(UUID_1), "userrefs": None, "primarycache": "all", "logbias": "latency", "creation": "1591543140", "sync": "always", "is_clone": False, "dedup": "off", "sharenfs": None, "receive_resume_token": None, "volsize": "1073741824"}, 'error': None, 'code': 200} jrest.rproxy.pool_request.return_value = resp self.assertTrue(jrest.is_lun(jcom.vname(UUID_1))) err = {'errno': 1, 'message': ('Zfs resource: Pool-0/' + jcom.vname(UUID_1) + ' not found in this collection.')} resp = {'code': 500, 'data': None, 'error': err} jrest.rproxy.pool_request.return_value = resp self.assertEqual(False, jrest.is_lun(jcom.vname(UUID_1))) jrest.rproxy.pool_request.side_effect = ( jexc.JDSSRESTProxyException(host='test_host', reason='test')) self.assertRaises(jexc.JDSSRESTProxyException, jrest.is_lun, 'v_' + UUID_1)
def test_delete_back_recursively_res_active(self): jdssd, ctx = self.get_driver(CONFIG_OK) opvname = jcom.vname(UUID_1) opsname = jcom.sname(UUID_2) jdssd._delete_back_recursively(opvname, opsname) jdssd.ra.delete_snapshot.assert_called_once_with( opvname, opsname, recursively_children=True, recursively_dependents=True, force_umount=True)
def _remove_target_volume(self, volume): """_remove_target_volume Ensure that volume is not attached to target and target do not exists. """ target_name = self.jovian_target_prefix + volume.id LOG.debug("remove export") LOG.debug("detach volume:%(vol)s from target:%(targ)s.", { 'vol': volume, 'targ': target_name }) try: self.ra.detach_target_vol(target_name, jcom.vname(volume.id)) except jexc.JDSSResourceNotFoundException as jerrrnf: LOG.debug('failed to remove resource %(t)s because of %(err)s', { 't': target_name, 'err': jerrrnf.args[0] }) except jexc.JDSSException as jerr: LOG.debug( 'failed to Terminate_connection for target %(targ)s ' 'because of: %(err)s', { 'targ': target_name, 'err': jerr.args[0] }) raise exception.VolumeBackendAPIException(jerr) LOG.debug("delete target: %s", target_name) try: self.ra.delete_target(target_name) except jexc.JDSSResourceNotFoundException as jerrrnf: LOG.debug( 'failed to remove resource %(target)s because ' 'of %(err)s', { 'target': target_name, 'err': jerrrnf.args[0] }) except jexc.JDSSException as jerr: LOG.debug( 'Failed to Terminate_connection for target %(targ)s ' 'because of: %(err)s ', { 'targ': target_name, 'err': jerr.args[0] }) raise exception.VolumeBackendAPIException(jerr)
def test_remove_target_volume(self): jdssd, ctx = self.get_driver(CONFIG_OK) vol = fake_volume.fake_volume_obj(ctx) vol.id = UUID_1 target_name = CONFIG_OK['target_prefix'] + UUID_1 jdssd.ra.detach_target_vol.return_value = None jdssd.ra.delete_target.return_value = None jdssd._remove_target_volume(vol) jdssd.ra.detach_target_vol.assert_called_once_with( target_name, jcom.vname(UUID_1)) jdssd.ra.delete_target.assert_called_with(target_name)
def test_clean_garbage_snapshots(self): jdssd, ctx = self.get_driver(CONFIG_OK) o_vname = jcom.vname(UUID_1) o_snaps = SNAPSHOTS_GARBAGE.copy() jdssd.ra.delete_snapshot.return_value = None jdssd._clean_garbage_snapshots(o_vname, o_snaps) jdssd.ra.delete_snapshot.assert_called_once_with( o_vname, SNAPSHOTS_GARBAGE[1]["name"]) # Test exception handling for exc in get_jdss_exceptions(): o_snaps = SNAPSHOTS_GARBAGE.copy() jdssd.ra.delete_snapshot.side_effect = exc try: jdssd._clean_garbage_snapshots(o_vname, o_snaps) except Exception as err: self.assertIsInstance(err, exception.VolumeBackendAPIException)
def test_remove_target_volume_fail_to_delete(self): jdssd, ctx = self.get_driver(CONFIG_OK) vol = fake_volume.fake_volume_obj(ctx) vol.id = UUID_1 target_name = CONFIG_OK['target_prefix'] + UUID_1 jdssd.ra.detach_target_vol.return_value = None jdssd.ra.delete_target.side_effect = (jexc.JDSSRESTException( reason='running test', request='test')) self.assertRaises(exception.VolumeBackendAPIException, jdssd._remove_target_volume, vol) jdssd.ra.detach_target_vol.assert_called_once_with( target_name, jcom.vname(UUID_1)) jdssd.ra.delete_target.assert_called_with(target_name)
def test_remove_target_volume_no_target(self): jdssd, ctx = self.get_driver(CONFIG_OK) vol = fake_volume.fake_volume_obj(ctx) vol.id = UUID_1 target_name = CONFIG_OK['target_prefix'] + UUID_1 jdssd.ra.detach_target_vol.return_value = None jdssd.ra.detach_target_vol.side_effect = ( jexc.JDSSResourceNotFoundException(res=target_name)) jdssd.ra.delete_target.return_value = None jdssd._remove_target_volume(vol) jdssd.ra.detach_target_vol.assert_called_once_with( target_name, jcom.vname(UUID_1)) jdssd.ra.delete_target.assert_called_with(target_name)
def _ensure_target_volume(self, volume): """Checks if target configured properly and volume is attached to it param: volume: volume structure """ LOG.debug("ensure volume %s assigned to a proper target", volume.id) target_name = self.jovian_target_prefix + volume.id auth = volume.provider_auth if not auth: msg = _("volume {} is missing provider_auth").format(volume.id) raise exception.VolumeDriverException(msg) (__, auth_username, auth_secret) = auth.split() chap_cred = {"name": auth_username, "password": auth_secret} if not self.ra.is_target(target_name): self._create_target_volume(volume) return if not self.ra.is_target_lun(target_name, volume.id): vname = jcom.vname(volume.id) self._attach_target_volume(target_name, vname) try: users = self.ra.get_target_user(target_name) if len(users) == 1: if users[0]['name'] == chap_cred['name']: return self.ra.delete_target_user( target_name, users[0]['name']) for user in users: self.ra.delete_target_user( target_name, user['name']) self._set_target_credentials(target_name, chap_cred) except jexc.JDSSException as err: self.ra.delete_target(target_name) raise exception.VolumeBackendAPIException(err)
def test_create_snapshot(self): jdssd, ctx = self.get_driver(CONFIG_OK) vname = jcom.vname(UUID_1) sname = jcom.sname(UUID_2) snap = fake_snapshot.fake_snapshot_obj(ctx, id=UUID_2) snap.volume_id = UUID_1 patches = [ mock.patch.object(jdssd, "_clone_object", return_value=None) ] self.start_patches(patches) jdssd.create_snapshot(snap) jdssd._clone_object.assert_called_once_with(vname, sname) self.stop_patches(patches)