class TestISCSIMulpath(test.Test): """ Module for testing ISCSI Multipath related operations. """ def __init__(self, params, env): self.params = params self.body = {} self.env = env self.rbd_client = None self.iscsi_client = None self.pool_client = None self.control_server_ip = self.params.get('ceph_management_url') self.control_server_ip = self.control_server_ip.split(':')[1].strip( '/') self.control_username = self.params.get('ceph_server_ssh_username', 'root') self.control_password = self.params.get('ceph_server_ssh_password') self.initiator_ip = self.params.get('ceph_node_ip') self.initiator_username = self.params.get('ceph_node_ssh_username') self.initiator_password = self.params.get('ceph_node_ssh_password') self.target_ip = self.params.get('ceph_node_ip') self.dirtypoint = "This is an example to check multipath" self.mulpath_mountpoint = "/mnt/multipath" self.mulpath_filename = "example.txt" self.rbd_name = None self.rbd_id = None self.iscsi_target_id = None self.iscsi_target_name = None self.iscsi_target_hostip = [] self.lun_id = None self.pool_name = None self.pool_id = None self.cluster_id = None def setup(self): if 'cluster' in self.env: self.cluster_id = self.env['cluster'] elif self.params.get('cluster_id'): self.cluster_id = self.params.get('cluster_id') else: clusters = test_utils.get_available_clusters(self.params) if len(clusters) > 0: self.cluster_id = clusters[0]['id'] self.params['cluster_id'] = self.cluster_id self.pool_client = PoolsClient(self.params) if 'pool_name' in self.env: self.pool_name = self.env['pool_name'] else: self.pool_name = self.params.get('pool_name', 'rbd') self.params['pool_name'] = self.pool_name if self.pool_name is not None: resp = self.pool_client.query() for i in range(len(resp)): if resp[i]['name'] == self.pool_name: self.pool_id = resp[i]['id'] else: self.pool_id = test_utils.create_pool(self.params) LOG.info("Created pool that id is %s" % self.pool_id) self.params['pool_id'] = self.pool_id self.rbd_client = RbdClient(self.params) self.iscsi_client = ISCSIClient(self.params) def _create_iscsi_target(self): self.iscsi_target_name = "cloudtest" + \ utils.utils_misc.generate_random_string(6) body = { 'initiator_ips': self.initiator_ip, 'target_name': self.iscsi_target_name, 'multipath': self.params.get('multipath', '3') } resp = self.iscsi_client.create(**body) if not resp and utils.verify_response(body, resp): raise exceptions.TestFail("Create target failed: %s" % body) self.iscsi_target_hostip = resp['host_ip'].split(',') return resp.body['target_id'] def _create_iscsi_lun(self, target_id, rbd_id): body = { 'target_id': target_id, 'pool_id': self.pool_id, 'rbd_id': rbd_id } resp = self.iscsi_client.add_lun(**body) return resp.body['lun_id'] def _delete_iscsi_lun(self, target_id, lun_id): body = {'target_id': target_id, 'lun_id': lun_id} self.iscsi_client.delete_lun(**body) def _delete_target(self, target_id): """ Test that deletion of delete target """ self.iscsi_client.delete_iscsitarget(target_id) resp = self.iscsi_client.query() for i in range(len(resp)): if resp[i]['target_id'] == target_id: raise exceptions.TestFail("Delete target failed") def _delete_rbd(self, pool_id, rbd_id): """ Test that deletion of specified rdb """ # delete the rbd created in the right pool resp = self.rbd_client.delete_rbd(self.pool_id, rbd_id) if not len(resp) > 0: raise exceptions.TestFail("Delete rbd failed") def get_rbd_id(self, pool_id, rbd_name): """ Query a specified rbd in a definitely pool """ resp = self.rbd_client.query(pool_id) if not len(resp) > 0: raise exceptions.TestFail("No specified rbd found in the pool") for i in range(len(resp)): if resp[i]['name'] == rbd_name: return resp[i]['id'] return None def get_rbd_name(self, pool_id, rbd_id): """ Query a specified rbd in a definitely pool """ resp = self.rbd_client.query(pool_id) if not len(resp) > 0: raise exceptions.TestFail("No specified rbd found in the pool") for i in range(len(resp)): if resp[i]['id'] == rbd_id: return resp[i]['name'] return None def hit_target(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password): for i in range(len(self.iscsi_target_hostip)): cmd = ('iscsiadm -m discovery -t st -p %s; ' % self.iscsi_target_hostip[i]) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) if buff.find(self.iscsi_target_name) == -1: raise exceptions.TestFail("No specified target found for %s" % self.iscsi_target_hostip[i]) def do_iscsi_login(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, target_ip): cmd = ('iscsiadm -m node -T %s -p %s --login; ' % (self.iscsi_target_name, target_ip)) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) def do_iscsi_logout(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, target_ip): cmd = ('iscsiadm -m node -T %s -p %s --logout; ' % (self.iscsi_target_name, target_ip)) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) def get_iscsi_count(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password): retval = 0 cmd = ('lsblk -S | wc -l; ') find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) _lines = buff.split('\n') retval = string.atoi(_lines[1], 10) return retval def get_iscsi_multipath(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password): cmd = 'multipath -l; ' find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) return find, buff def get_chars(self, str): _str = "" for i in str: if ((i >= 'a' and i <= 'z') or i == '/' or i == ' ' or (i >= 'A' and i <= 'Z')): _str += i return _str def make_iscsi_dirty(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password): cmd = 'ls --color=never /dev/mapper/mpath*' find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) _lines = buff.split('\n') if len(_lines) < 2: raise exceptions.TestFail("Did not get any mapper device") mapper_device = self.get_chars(_lines[1]) if len(mapper_device) == 0: raise exceptions.TestFail("Did not get a valid mapper device name") cmd = 'mkdir %s' % (mapper_device) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) cmd = 'mkfs.ext4 %s' % mapper_device find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) cmd = 'mount %s %s' % (mapper_device, self.mulpath_mountpoint) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) cmd = 'echo "%s" > %s/%s' % (self.dirtypoint, self.mulpath_mountpoint, self.mulpath_filename) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) cmd = 'cat %s/%s' % (self.mulpath_mountpoint, self.mulpath_filename) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) def start_iscsi_tgt(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password): cmd = 'service tgtd start' find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) def stop_iscsi_tgt(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password): cmd = 'service tgtd stop' find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) def check_iscsi_dirty(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password): cmd = 'cat %s/%s' % (self.mulpath_mountpoint, self.mulpath_filename) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) _lines = buff.split('\n') if len(_lines) < 2: raise exceptions.TestFail("Did not get info for validation") info_val = self.get_chars(_lines[1]) if self.dirtypoint == info_val: LOG.info("Find %s under %s!" % (self.mulpath_filename, self.mulpath_mountpoint)) else: raise exceptions.TestFail( "%s not found under %s" % (self.mulpath_filename, self.mulpath_mountpoint)) cmd = 'rm -rf %s/%s' % (self.mulpath_mountpoint, self.mulpath_filename) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) cmd = '[ -f %s/%s ] || echo removed' % (self.mulpath_mountpoint, self.mulpath_filename) find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) _lines = buff.split('\n') info_val = self.get_chars(_lines[1]) if info_val == "removed": LOG.info("Removed %s successfully!" % self.mulpath_filename) else: raise exceptions.TestFail("Removed %s fault!" % self.mulpath_filename) def clean_iscsi_dirty(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password): cmd = 'umount %s' % self.mulpath_mountpoint find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) def iscsi_actions(self, control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, target_ip): cmd = 'yum -y install iscsi-initiator-utils ; ' find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) if not (find): raise exceptions.TestFail("Install iscsi-initiator-utils fault") cmd = 'yum -y install device-mapper-multipath ; ' find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) if not (find): raise exceptions.TestFail("Install device-mapper-multipath fault") multipathconf="""defaults{\n user_friendly_names yes\n""" \ """ polling_interval 10\n checker_timeout 120\n """ \ """queue_without_daemon no\n}\nblacklist {\n""" \ """ devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"\n""" \ """ devnode "^hd[a-z]"\n}\ndevices {\n device{\n """ \ """path_grouping_policy failover\n }\n}""" cmd = 'echo \'%s\' > /etc/multipath.conf' % multipathconf find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) cmd = 'systemctl start multipathd ' find, buff = utils.sshclient_execmd(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, cmd) if not find: raise exceptions.TestFail("Start multipath service fault") self.hit_target(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) iscsi_count1 = self.get_iscsi_count(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) #Login iscsi self.do_iscsi_login(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, self.iscsi_target_hostip[0]) time.sleep(1) iscsi_count2 = self.get_iscsi_count(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) #Check lsblk if iscsi_count2 <= iscsi_count1: raise exceptions.TestFail("Login target to be first iscsi fault") self.do_iscsi_login(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, self.iscsi_target_hostip[1]) time.sleep(1) iscsi_count3 = self.get_iscsi_count(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) #Check lsblk if iscsi_count3 <= iscsi_count2: raise exceptions.TestFail("Login target to be second iscsi fault") #Get Multipath find, buff = self.get_iscsi_multipath(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) #Check Multipath #make iscsi dirty self.make_iscsi_dirty(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) time.sleep(1) #Stop one tgt self.stop_iscsi_tgt(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) time.sleep(1) #Check iscsi dirty self.check_iscsi_dirty(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) time.sleep(1) #Start one tgt self.start_iscsi_tgt(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) time.sleep(1) #Clean iscsi dirty self.clean_iscsi_dirty(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password) #Logout iscsi self.do_iscsi_logout(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, self.iscsi_target_hostip[1]) time.sleep(1) self.do_iscsi_logout(control_server_ip, control_username, control_password, initiator_ip, initiator_username, initiator_password, self.iscsi_target_hostip[0]) time.sleep(1) def test(self): # Create rbd in the pool self.rbd_id = test_utils.create_rbd(self.pool_id, self.params) if self.rbd_id == None: raise exceptions.TestFail("rbd is not existed") else: LOG.info("RBD id is %d" % self.rbd_id) # Create iscsi self.iscsi_target_id = self._create_iscsi_target() time.sleep(1) target_multipath = len(self.iscsi_target_hostip) if target_multipath <= 2: raise exceptions.TestFail("Multipath is %d" % target_multipath) # Bind iscsi to rbd self.lun_id = self._create_iscsi_lun(self.iscsi_target_id, self.rbd_id) time.sleep(1) self.iscsi_actions(self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.target_ip) def teardown(self): if self.lun_id is not None: self._delete_iscsi_lun(self.iscsi_target_id, self.lun_id) if self.iscsi_target_id is not None: self._delete_target(self.iscsi_target_id) if self.rbd_id is not None: self._delete_rbd(self.pool_id, self.rbd_id)
class TestIscsi(test.Test): """ Module for testing iscsi related operations. """ def __init__(self, params, env): self.params = params self.body = {} self.env = env self.rbd_client = RbdClient(params) self.iscsi_client = ISCSIClient(params) self.control_server_ip = self.params.get('ceph_management_url') self.control_server_ip = self.control_server_ip.split(':')[1].strip( '/') self.control_username = self.params.get('ceph_server_ssh_username', 'root') self.control_password = self.params.get('ceph_server_ssh_password') self.initiator_username = self.params.get('ceph_node_ssh_username') self.initiator_password = self.params.get('ceph_node_ssh_password') self.old_config_list = [] self.old_config_list.append( self.params.get('iscsi_config_authmethod', '#node.session.auth.authmethod = CHAP')) self.old_config_list.append( self.params.get('iscsi_config_username', '#node.session.auth.username = username')) self.old_config_list.append( self.params.get('iscsi_config_password', '#node.session.auth.password = password')) self.old_config_list.append( self.params.get('iscsi_config_username_in', '#node.session.auth.username_in = username_in')) self.old_config_list.append( self.params.get('iscsi_config_password_in', '#node.session.auth.password_in = password_in')) self.iscsi_config_file = self.params.get('iscsi_config_file', r'/etc/iscsi/iscsid.conf') self.rbd_id = None self.target_id = None self.lun_id = None self.target_ip = None def setup(self): if 'cluster' in self.env: self.cluster_id = self.env['cluster'] elif self.params.get('cluster_id'): self.cluster_id = self.params.get('cluster_id') if self.params.get('pool_id'): self.pool_id = self.params.get('pool_id') else: self.pool_id = test_utils.create_pool(self.params) LOG.info("pool_id is %s" % self.pool_id) if self.params.get('initiator_ip'): self.initiator_ip = test_utils.get_available_host_ip(self.params) def _create_iscsi_target(self): self.iscsi_target_name = "cloudtest" + \ data_factory.generate_random_string(6) body = { 'initiator_ips': self.initiator_ip, 'target_name': self.iscsi_target_name, 'multipath': self.params.get('multipath', '2') } resp = self.iscsi_client.create(**body) if not resp and utils.verify_response(body, resp): raise exceptions.TestFail("Create target failed: %s" % body) return resp.body['target_id'] def _query_specified_target(self, target_id): resp = self.iscsi_client.query() if len(resp) < 0: raise exceptions.TestFail("Query iscsi target failed") LOG.info("Got all iscsi targets %s" % resp) for i in range(len(resp)): if resp[i]['target_id'] == self.target_id: return resp[i]['target_name'] def _create_iscsi_lun(self, target_id, rbd_id): body = { 'target_id': target_id, 'pool_id': self.pool_id, 'rbd_id': rbd_id } resp = self.iscsi_client.add_lun(**body) return resp.body['lun_id'] def _get_lun_info(self): resp = self.iscsi_client.get_lun_info() LOG.info("Got all iscsi lun info %s" % resp) def _delete_iscsi_lun(self, target_id, lun_id): body = {'target_id': target_id, 'lun_id': lun_id} resp = self.iscsi_client.delete_lun(**body) def _delete_target(self, target_id): """ Test that deletion of delete target """ self.iscsi_client.delete_iscsitarget(target_id) resp = self.iscsi_client.query() for i in range(len(resp)): if resp[i]['target_id'] == target_id: raise exceptions.TestFail("Delete target failed") def _create_account_group(self, account_type): """ Execute the test of creating account group """ account_name = data_factory.generate_random_string(6) account_pass = data_factory.generate_random_string(12) account_out_name = data_factory.generate_random_string(6) account_out_pass = data_factory.generate_random_string(12) resp = self.iscsi_client.create_account_group(account_name, account_pass, account_type, account_out_name, account_out_pass) if not resp and utils.verify_response(self.body, resp): raise exceptions.TestFail("Create account group failed: %s") return resp['group_id'] def _query_account_group(self, account_group_id): """ Execute the test of creating account group """ resp = self.iscsi_client.query_account_group() LOG.info("Got all iscsi account group %s" % resp) if not len(resp) > 0: raise exceptions.TestFail("Query iscsi account failed") for i in range(len(resp)): if resp[i]['group_id'] == account_group_id: return resp[i]['username'], resp[i]['password'], \ resp[i]['username_out'], resp[i]['password_out'] def _delete_account_group(self, account_id): """ Test that deletion of account group """ LOG.info("Try to delete account group with ID: %d" % account_id) self.iscsi_client.delete_account(account_id) resp = self.iscsi_client.query_account_group() for i in range(len(resp)): if resp[i]['group_id'] == account_id: raise exceptions.TestFail("Delete account group failed") def _modify_account_group(self, account_id, account_name, account_pass, account_name_out, account_pass_out): """ Modify account group """ resp = self.iscsi_client.modify_account_group(account_id, account_name, account_pass, account_name_out, account_pass_out) LOG.info('Rest Response: %s' % resp) if not resp and utils.verify_response(self.body, resp): raise exceptions.TestFail("Modify account group failed: %s" % self.body) def _bind_account_operation(self, account_ops, account_group_id, target_id): """ Test to bind or unbind account group to target """ LOG.info("Try to %s account %s to target %s" % (account_ops, account_group_id, target_id)) if 'unbind' in account_ops: resp = self.iscsi_client.unbind_account(target_id, account_group_id) if not len(resp) > 0: raise exceptions.TestFail("Unbind account group '%s' failed" % account_group_id) elif 'bind' in account_ops: resp = self.iscsi_client.bind_account(target_id, account_group_id) if not len(resp) > 0: raise exceptions.TestFail("Bind account group '%s' failed" % account_group_id) else: raise exceptions.TestNotFoundError('Did not find test for bind ' 'account operation') def _query_login_initiator(self, target_id): resp = self.iscsi_client.query_login_initiator() LOG.info("Got all login initiator %s" % resp) def _create_new_config_list(self, username, password, username_out, password_out, old_config_list): new_config_list = [] self.find_username_in = 'username_in' self.find_password_in = 'password_in' self.find_username = '******' self.find_password = '******' for i in range(len(old_config_list)): tmp = old_config_list[i].strip('#') sub = tmp[0:tmp.find('=') + 1] if self.find_username_in in tmp: tmp = sub + username new_config_list.append(tmp) self.find_username_in = username continue elif self.find_password_in in tmp: tmp = sub + password new_config_list.append(tmp) self.find_password_in = password continue elif self.find_username in tmp: tmp = sub + username_out new_config_list.append(tmp) self.find_username = username_out continue elif self.find_password in tmp: tmp = sub + password_out new_config_list.append(tmp) self.find_password = password_out else: new_config_list.append(tmp) return new_config_list def _verify_login_iscsi_with_account(self, username, password, username_out, password_out, old_config_list, expect_login): new_config_list = [] new_config_list = self._create_new_config_list(username, password, username_out, password_out, old_config_list) LOG.info("new_config_list is %s" % new_config_list) # Modify file /etc/iscsi/iscsid.conf test_utils.modify_file(self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_config_file, old_config_list, new_config_list) login = test_utils.iscsi_login_with_account( self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_target_name, self.target_ip) #self._query_login_initiator(self.target_id) test_utils._logout_iscsi(self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, None, self.iscsi_target_name, self.target_ip) if login == expect_login: LOG.info("Login status is expected!") else: LOG.info("Login status is NOT expected!") def test_iscsi_chap(self): # Create rbd in the pool self.rbd_id = test_utils.create_rbd(self.pool_id, self.params) # Create iscsi self.target_id = self._create_iscsi_target() target_name = self._query_specified_target(self.target_id) if target_name not in self.iscsi_target_name: LOG.info("Target name %s is not expected. " "The target name created is %s" % (target_name, self.iscsi_target_name)) # Get the first target ip via target id self.target_ip = test_utils.get_specified_targetip( self.params, self.target_id, 0) # Bind iscsi to rbd self.lun_id = self._create_iscsi_lun(self.target_id, self.rbd_id) self._get_lun_info() # Create count1 and count2(single way chap) self.account_group_id1 = self._create_account_group("two") self.account_group_id2 = self._create_account_group("two") self.username1, self.password1, self.username_out1, self.password_out1\ = self._query_account_group(self.account_group_id1) LOG.info("username1: %s, password1: %s, username_out1: %s, " "password_out1: %s" % (self.username1, self.password1, self.username_out1, self.password_out1)) self.username2, self.password2, self.username_out2, self.password_out2\ = self._query_account_group(self.account_group_id2) LOG.info("username2: %s, password2: %s, username_out2: %s, " "password_out2: %s" % (self.username2, self.password2, self.username_out2, self.password_out2)) self._bind_account_operation('bind', self.account_group_id2, self.target_id) self._delete_account_group(self.account_group_id1) # There are bugs about iscsi modify function '''account_name_out = data_factory.generate_random_string( 6) account_pass_out = data_factory.generate_random_string(6) self._modify_account_group(self.account_group_id2, self.username2, self.password2, account_name_out, account_pass_out) self.username2, self.password2, self.username_out2, self.password_out2 \ = self._query_account_group(self.account_group_id2) LOG.info("username2: %s, password2: %s, username_out2: %s, " "password_out2: %s" % (self.username2, self.password2, self.username_out2, self.password_out2))''' LOG.info("old_config_list is %s" % self.old_config_list) self._verify_login_iscsi_with_account(self.username2, self.password2, self.username_out2, self.password_out2, self.old_config_list, True) self.password_out2 = 'test' self._verify_login_iscsi_with_account(self.username2, self.password2, self.username_out2, self.password_out2, self.old_config_list, False) # There is bug relatived to unbind account. #self._bind_account_operation('unbind', self.account_group_id2, #self.target_id) def teardown(self): if self.lun_id is not None: self._delete_iscsi_lun(self.target_id, self.lun_id) if self.target_id is not None: self._delete_target(self.target_id) if self.rbd_id is not None: test_utils.delete_rbd(self.pool_id, self.rbd_id, self.params) if self.account_group_id2 is not None: self._delete_account_group(self.account_group_id2)
class TestRBDRemoteBackup(test.Test): """ Module for testing RBD remote backup scenarios """ def __init__(self, params, env): self.params = params self.env = env self.body = {} self.create_servers_body = {} self.cluster_id = None self.pool_id = None self.target_id = None self.rbd_id = None self.clusters_client = ClustersClient(self.params) def setup(self): """ Set up before executing test 1. to check if two clusters are available 2. create one pool: testpool 3. configure remote backup in the testpool """ # to check if two cluster are available clusters = test_utils.get_available_clusters(self.params) if len(clusters) < 1: raise exceptions.TestSetupFail( 'There are not enough clusters!') elif len(clusters) < 2: LOG.info('There are not enough clusters, try to create cluster!') self.cluster_id = self._create_cluster() self.params['cluster_id'] = self.cluster_id self.servers_client = ServersClient(self.params) for k, v in self.params.items(): if 'rest_arg_cluster2_' in k: new_key = k.split('rest_arg_cluster2_')[1] self.create_servers_body[new_key] = v self._add_three_hosts() self._deploy_cluster() clusters = test_utils.get_available_clusters(self.params) if len(clusters) < 2: raise exceptions.TestSetupFail( 'There are not enough clusters!') self.cluster_id = clusters[1]['id'] self.params['cluster_id'] = self.cluster_id for cluster in clusters: if cluster['id'] != self.cluster_id: self.des_cluster_id = cluster['id'] self.body['des_cluster_id'] = self.des_cluster_id break src_host = test_utils.get_available_server_info(self.params, self.cluster_id) self.src_ip = src_host['publicip'] self.body['src_ip'] = self.src_ip self.src_host_id = src_host['id'] self.body['src_host_id'] = self.src_host_id des_host = test_utils.get_available_server_info(self.params, self.des_cluster_id) self.des_ip = des_host['publicip'] self.body['des_ip'] = self.des_ip self.des_host_id = des_host['id'] self.body['des_host_id'] = self.des_host_id if self.params.get('pool_id'): self.pool_id = self.params.get('pool_id') else: self.pool_id = test_utils.create_pool(self.params) pool_client = PoolsClient(self.params) if not test_utils.wait_for_pool_in_state(self.pool_id, pool_client, 'ready'): raise exceptions.TestSetupFail("Failed to creating test pool!") self.params['pool_id'] = self.pool_id # configure remote backup in testpool LOG.info("Try to configure remote backup in pool %s : %s" % (self.pool_id, self.body)) self.client = RemoteBackupClient(self.params) self.client.configure_rbpolicy(**self.body) # other pre-conditions self.control_server_ip = self.params.get('ceph_management_url') self.control_server_ip = self.control_server_ip.split(':')[1].strip( '/') self.control_username = self.params.get('ceph_server_ssh_username', 'root') self.control_password = self.params.get('ceph_server_ssh_password', 'lenovo') self.initiator_ip = self.params.get('initiator_ip', self.src_ip) self.initiator_username = self.params.get('ceph_node_ssh_username', 'root') self.initiator_password = self.params.get('ceph_node_ssh_password', 'lenovo') # create iscsi client self.iscsi_client = ISCSIClient(self.params) def _create_cluster(self): create_cluster = {'name': self.params.get('cluster_name', 'cloudtest_cluster_2'), 'addr': self.params.get('cluster_addr', 'vm')} resp = self.clusters_client.create(**create_cluster) if not resp and utils.verify_response(create_cluster, resp): raise exceptions.TestSetupFail( "Create cluster failed: %s" % create_cluster) return resp.body.get('id') def _create_server(self, request_body): if not request_body.get('parent_bucket'): group_id, parent_id = \ test_utils.get_available_group_bucket(self.params) request_body.update({'parent_bucket': parent_id}) resp_body = self.servers_client.create(**request_body) body = resp_body.body status = test_utils.wait_for_server_in_status( 'servername', request_body['servername'], self.servers_client, 'added', 1, int(self.params.get('add_host_timeout', 600))) if not status: raise exceptions.TestFail("Failed to add server %s" % request_body['servername']) LOG.info('Create server %s successfully!' % body['properties'].get('name')) def _add_three_hosts(self): parent_bucket = self.create_servers_body.get('parent_bucket') i = 1 threads = [] while self.create_servers_body.get('servername_%d' % i): tmp = 'servername_%d' % i servername = self.create_servers_body.get(tmp, 'cloudtest_server_%d' % i) tmp = 'username_%d' % i username = self.create_servers_body.get(tmp, 'root') tmp = 'password_%d' % i password = self.create_servers_body.get(tmp, 'lenovo') tmp = 'publicip_%d' % i publicip = self.create_servers_body.get(tmp) tmp = 'clusterip_%d' % i clusterip = self.create_servers_body.get(tmp) create_server_body = {'servername': servername, 'username': username, 'passwd': password, 'publicip': publicip, 'clusterip': clusterip, 'parent_bucket': parent_bucket} t = threading.Thread(target=self._create_server, args=[create_server_body]) threads.append(t) i = i + 1 # waiting for all servers ready for t in threads: t.setDaemon(True) t.start() for i in range(0, len(threads)): try: threads[i].join(600) except Exception as details: LOG.exception('Caught exception waiting for server %d added : %s' % (i, details)) def _deploy_cluster(self): self.clusters_client.deploy_cluster(self.cluster_id) status = test_utils.wait_for_cluster_in_status(self.cluster_id, self.clusters_client, 'deployed', int(self.params.get('deploy_host_timeout', 900))) if not status: raise exceptions.TestFail("Failed to deploy cluster %d" % self.cluster_id) LOG.info("Deploy cluster %d successfully!" % self.cluster_id) def _start_rbtask(self, rbd_id): rbtask_body = {} rbtask_body['rbd_id'] = rbd_id resp_body = self.client.start_rbtask(**rbtask_body) body = resp_body.body LOG.info("Create remote backup %s for rbd %s" % (body.get('id'), rbd_id)) time.sleep(30) return body.get('id') def _create_iscsi_target(self): self.iscsi_target_name = "cloudtest" + \ utils.utils_misc.generate_random_string(6) create_body = {'initiator_ips': self.initiator_ip, 'target_name': self.iscsi_target_name, 'multipath': self.params.get('multipath', 3)} resp = self.iscsi_client.create(**create_body) if not resp and utils.verify_response(create_body, resp): raise exceptions.TestFail("Create target failed: %s " % create_body) return resp.body['target_id'] def _create_iscsi_lun(self, target_id, rbd_id): create_body = {'target_id': target_id, 'pool_id': self.pool_id, 'rbd_id': rbd_id} resp = self.iscsi_client.add_lun(**create_body) return resp.body['lun_id'] def _delete_iscsi_lun(self, target_id, lun_id): body = { 'target_id': target_id, 'lun_id': lun_id} self.iscsi_client.delete_lun(**body) def _delete_target(self, target_id): """ Test that deletion of delete target """ self.iscsi_client.delete_iscsitarget(target_id) resp = self.iscsi_client.query() for i in range(len(resp)): if resp[i]['target_id'] == target_id: raise exceptions.TestFail("Delete target failed") def _create_and_bind_ISCSI_to_rbd(self, rbd_id): self.target_id = self._create_iscsi_target() self.lun_id = self._create_iscsi_lun(self.target_id, rbd_id) def _start_restore(self, rbd_id, timestamp): restore_body = {} restore_body['snap_time'] = timestamp resp_body = self.client.start_restore(rbd_id, **restore_body) LOG.info("Try to recover to remote backup %s!" % timestamp) time.sleep(30) body = resp_body.body return body.get('id') def _verify_task_successfully(self, rbtask_id, state): extra_url = '/list_rbtasks?count=1024&begin_index=0' rbtasks = self.client.list_rbtasks(extra_url) rb_record = None for rbtask in rbtasks: if rbtask['id'] == rbtask_id: rb_record = rbtask['properties']['timestamp'] break if rb_record: status = test_utils.wait_for_remote_backup_or_restore_complete(rbtask_id, self.client, state, 60) if status: LOG.info("%s successfully, the timestamp is %s" % (state, rb_record)) return rb_record raise exceptions.TestFail("Failed to %s!" % state) @staticmethod def _verify_file_exist(file_name, mount_point, actual, expected): if actual: LOG.info("Find %s under %s!" % (file_name, mount_point)) if actual != expected: raise exceptions.TestFail("Expected not find the file %s." % file_name) else: LOG.info("%s not found under %s" % (file_name, mount_point)) if actual != expected: raise exceptions.TestFail("Expected can find the file %s." % file_name) def test_rbd_remote_backup(self): """ This test basically performs following steps: 1. create rbd in testpool 2. format disk 3. create remote backup for this rbd(e.g.record1) 4. write data to this rbd via ISCSI, include 1->11 steps 5. create remote backup for this rbd(e.g.record2) 6. recover rbd from record1 7. repeat step3: sub-step 2)3)4)5)7) 8. check testfile.txt does not exist 9. do recover rbd from record2 10. check testfile.txt exists """ mount_point = self.params.get('mount_point', '/mnt') file_name = self.params.get('file_name', 'testfile.txt') # step1 create rbd in testpool self.rbd_id = test_utils.create_rbd(self.pool_id, self.params) LOG.info("Create rbd %s in pool %s" % (self.rbd_id, self.pool_id)) # step2 format disk self._create_and_bind_ISCSI_to_rbd(self.rbd_id) time.sleep(60) need_mk = True create_data = False find = test_utils.operate_iscsi(self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_target_name, self.initiator_ip, mount_point, file_name, need_mk, create_data) self._verify_file_exist(file_name, mount_point, find, False) self._delete_iscsi_lun(self.target_id, self.lun_id) time.sleep(60) # step3 create remote backup for this rbd rbtask_id_1 = self._start_rbtask(self.rbd_id) rb_record_1 = self._verify_task_successfully(rbtask_id_1, 'backed_up') # step4 write data to this rbd via ISCSI self.lun_id = self._create_iscsi_lun(self.target_id, self.rbd_id) time.sleep(60) need_mk = False create_data = True # step4: sub-step 2)-10) find = test_utils.operate_iscsi(self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_target_name, self.initiator_ip, mount_point, file_name, need_mk, create_data) self._verify_file_exist(file_name, mount_point, find, True) # step4: sub-step 11) self._delete_iscsi_lun(self.target_id, self.lun_id) time.sleep(60) # step 5 create remote backup for this rbd rbtask_id_2 = self._start_rbtask(self.rbd_id) rb_record_2 = self._verify_task_successfully(rbtask_id_2, 'backed_up') # step 6 recover rbd from rb_record_1 restore_id = self._start_restore(self.rbd_id, rb_record_1) self._verify_task_successfully(restore_id, 'restored') # step 7 self.lun_id = self._create_iscsi_lun(self.target_id, self.rbd_id) time.sleep(60) need_mk = False create_data = False find = test_utils.operate_iscsi(self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_target_name, self.initiator_ip, mount_point, file_name, need_mk, create_data) # step 8 check testfile.txt does not exist self._verify_file_exist(file_name, mount_point, find, False) self._delete_iscsi_lun(self.target_id, self.lun_id) time.sleep(60) # step 9 do recover rbd from record2 restore_id = self._start_restore(self.rbd_id, rb_record_2) self._verify_task_successfully(restore_id, 'restored') # step 10 verify testfile.txt exists self.lun_id = self._create_iscsi_lun(self.target_id, self.rbd_id) time.sleep(60) need_mk = False create_data = False find = test_utils.operate_iscsi(self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_target_name, self.initiator_ip, mount_point, file_name, need_mk, create_data) self._verify_file_exist(file_name, mount_point, find, True) self._delete_iscsi_lun(self.target_id, self.lun_id) def teardown(self): if self.target_id: self._delete_target(self.target_id) if self.rbd_id: try: test_utils.delete_rbd(self.pool_id, self.rbd_id, self.params) except exceptions.UnexpectedResponseCode, e: pass
class TestRBDMigration(test.Test): """ Module for rbd migration """ def __init__(self, params, env): self.params = params self.env = env self.body = {} self.rbd_client = RbdClient(params) self.iscsi_client = ISCSIClient(self.params) self.control_server_ip = self.params.get('ceph_management_url') self.control_server_ip = self.control_server_ip.split(':')[1].strip( '/') self.control_username = self.params.get('ceph_server_ssh_username', 'root') self.control_password = self.params.get('ceph_server_ssh_password') self.initiator_username = self.params.get('ceph_node_ssh_username') self.initiator_password = self.params.get('ceph_node_ssh_password') self.cluster_id = None self.pool_id = None self.target_pool = None self.rbd_id = None self.rbd_name = None self.iscsi_id = None self.initiator_ip = None self.iscsi_to_delete = [] self.env['pool_tmp_id'] = None def setup(self): """Set up before execute test""" if 'cluster' in self.env: self.cluster_id = self.env['cluster'] elif self.params.get('cluster_id'): self.cluster_id = self.params.get('cluster_id') if self.params.get("pool_id"): self.pool_id = self.params.get('pool_id') else: self.pool_id = test_utils.create_pool(self.params) LOG.info("pool_id id %s " % self.pool_id) if self.params.get('initiator_ip'): self.initiator_ip = self.params.get('initiator_ip') else: self.initiator_ip = test_utils.get_available_host_ip(self.params) for k, v in self.params.items(): if 'rest_arg_' in k: new_key = k.split('rest_arg_')[1] self.body[new_key] = v def _create_rbd(self): RBD_CAPACITY = 1024 * 1024 self.pool_id = test_utils.create_pool(self.params) self.rbd_response = test_utils.create_rbd_with_capacity(self.pool_id, self.params, RBD_CAPACITY) self.rbd_id = self.rbd_response.get('id') self.rbd_name = self.rbd_response.get('name') def _write_to_rbd(self): """This part is common for three case, use other's method Write data to this rbd via ISCSI, ISCSI write data method 1)Create iscsi > bind iscsi to the rbd 2)In target: tgtadm --lld iscsi --mode target --op show 3)Initator: iscsiadm -m discovery -t st -p 127.0.0.1 (target address) 4)iscsiadm -m node -T iqn.2017-04.com.lenovo:devsdb6 -p 127.0.0.1(target address) --login 5)One iscsi device (like sda) will be in the initator device list via command "lsblk" 6)mkfs -t ext3 -c /dev/sda 7)mount /dev/sda /mnt 8)Create a new file(e.g. testfile.txt) in /mnt > write data to this file 9)Umount /mnt 10)Iscsiadm -m node -T iqn.2017-04.com.lenovo:devsdb6 -p 127.0.0.1(target address) --logout 11)Unbind iscsi from the rbd""" self._redo_some_step(create_iscsi=True, need_mk=True, create_data=True) def __create_iscsi(self): self.iscsi_name = 'iscsi' + \ utils.utils_misc.generate_random_string(6) body = {'initiator_ips': self.initiator_ip, 'target_name': self.iscsi_name, 'multipath': self.params.get('multipath', '1')} LOG.info("Try to create iscsi %s" % self.iscsi_name) resp = self.iscsi_client.create(**body) # LOG.info("Try to create resp %s" % resp) time.sleep(30) if resp.response['status'] == '200': self.iscsi_id = resp.body['target_id'] self.iscsi_to_delete.append(self.iscsi_id) LOG.info('Create iscsi target Succeed :%s!' % self.iscsi_id) return raise exceptions.TestFail("Create iscsi target failed!") def __bind_iscsi(self): LOG.info("Start bind iscsi to rbd ! ") body = {'target_id': self.iscsi_id, 'pool_id': self.pool_id, 'rbd_id': self.rbd_id} resp = self.iscsi_client.add_lun(**body) time.sleep(20) # LOG.info("Add lun info resp %s" % resp) if resp.response['status'] != '200': raise exceptions.TestFail("Bind iscsi to failed %s!" % resp) self.lun_id = resp.body['lun_id'] LOG.info("Bind iscsi to rbd info success!") def __unbind_iscsi(self): LOG.info("Start unbind iscsi to rbd ! ") body = { 'target_id': self.iscsi_id, 'lun_id': self.lun_id} resp = self.iscsi_client.delete_lun(**body) if resp.response['status'] != '200': raise exceptions.TestFail("Migrate rbd failed: %s" % self.body) LOG.info('unbind iscsi succeed!') def _migrate_rbd(self): """Migrate this rbd to target pool""" LOG.info("Start migrate rbd to new pool!") self.target_pool = test_utils.create_pool(self.params) move_rbd = {'target_pool': str(self.target_pool)} resp = self.rbd_client.migrate(self.pool_id, self.rbd_id, **move_rbd) # LOG.info('Rest Response: %s' % resp) time.sleep(60) if resp.response['status'] != '200': raise exceptions.TestFail("Migrate rbd failed: %s" % self.body) self.env['pool_tmp_id'] = self.target_pool self.pool_id, self.target_pool = self.target_pool, self.pool_id LOG.info("Migrate rbd to new pool success!") def _redo_some_step(self, create_iscsi=False, need_mk=False, create_data=False): LOG.info("Start repeat some steps in case2,create_iscsi:%s " "need_mk:%s create_data:%s " % ( create_iscsi, need_mk, create_data)) if create_iscsi: self.__create_iscsi() self.__bind_iscsi() LOG.info("Start write data to iscsi via rbd !") mount_point = self.params.get('mount_point', '/mnt') file_name = self.params.get('file_name', 'testfile.txt') find = test_utils.operate_iscsi(self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_name, self.initiator_ip, mount_point, file_name, need_mk, create_data) if find: LOG.info("Find %s under %s!" % (file_name, mount_point)) else: LOG.error("%s not found under %s" % (file_name, mount_point)) time.sleep(20) self.__unbind_iscsi() time.sleep(20) def _migrate_rbd_back(self): self.pool_id, self.target_pool = self.target_pool, self.pool_id LOG.info("Start migrate rbd back to old pool!") rbd_id = self.rbd_id target_pool = self.pool_id pool_id = self.env['pool_tmp_id'] move_rbd = {'target_pool': str(target_pool)} resp = self.rbd_client.migrate(pool_id, rbd_id, **move_rbd) time.sleep(60) # LOG.info('Rest Response: %s' % resp) if resp.response['status'] != '200': raise exceptions.TestFail("Migrate rbd failed: %s" % self.body) LOG.info("Migrate rbd back to old pool succeed!") def _check_file(self): pass def _repeat_steps(self): pass def test_rbd_migration(self): """ This test basically performs following steps: 1. Create rbd in test pool (e.g. test rbd) 2. Write data to this rbd via ISCSI, ISCSI write data method Repeat step 1->11 in case2 3. Migrate this rbd to target pool 4. Repeat step 1->5, step7 in case2 5. Check testfile.txt is exists or not 6. Migrate this rbd back to original pool 7. Repeat step 1->5, step7 in case2 8. Check testfile.txt is exists or not """ self._create_rbd() self._write_to_rbd() self._migrate_rbd() self._redo_some_step() self._migrate_rbd_back() self._redo_some_step(create_iscsi=False, need_mk=False, create_data=False) def teardown(self): LOG.info('Delete the resource we create!') time.sleep(10) for iscsi_id in self.iscsi_to_delete: self.iscsi_client.delete_iscsitarget(iscsi_id) time.sleep(20) if self.rbd_id: self.rbd_client.delete_rbd(self.pool_id, self.rbd_id) time.sleep(30) if self.env['pool_tmp_id']: test_utils.delete_pool(self.env['pool_tmp_id'], self.params)
class TestISCSI(test.Test): """ ISCSI related tests. """ def __init__(self, params, env): self.params = params self.body = {} self.env = env self.created_resources = {} self.clusters_client = ClustersClient(self.params) self.cluster_id = None self.lun_id = None self.gateway_id = None def setup(self): """ Set up before executing test """ if 'cluster' in self.env: self.cluster_id = self.env['cluster'] elif self.params.get('cluster_id'): self.cluster_id = self.params.get('cluster_id') self.client = ISCSIClient(self.params) self.gateway_id = test_utils.get_available_gateway(self.params) if self.gateway_id is None: self.gateway_id = test_utils.create_gateway(self.params) def test_create_target(self): """ Execute the test of creating a iscsi target """ iscsi_target_name = utils.utils_misc.generate_random_string(6) delay_time = time.strftime("%Y-%m", time.localtime(time.time())) iscsi_target_name = "iqn." + delay_time + ".com.lenovo:" + iscsi_target_name LOG.info("Target_name is %s" % iscsi_target_name) body = { 'initiator_ips': '192.168.1.30', 'target_name': iscsi_target_name, 'multipath': self.params.get('multipath', '1'), 'gateway_id': self.gateway_id } resp = self.client.create(**body) if not resp and utils.verify_response(self.body, resp): raise exceptions.TestFail("Create target failed: %s" % body) self.env['iscsi_target'] = resp.body def test_query_target(self): resp = self.client.query() if not len(resp) > 0: raise exceptions.TestFail("Query iscsi target failed") LOG.info("Got all iscsi targets %s" % resp) def test_query_specified_target(self): target_id = self.env.get('iscsi_target')['target_id'] resp = self.client.query(target_id) #Fixme if there is not any issue, the api return blank if len(resp) > 0: raise exceptions.TestFail("Query iscsi target failed") LOG.info("Got all iscsi targets %s" % resp) def _lun_ops(self, ops): target_id = self.env.get('iscsi_target')['target_id'] self.rbd_pool_id = test_utils.get_pool_id(self.env, self.params) if self.params.get('rbd_id'): self.rbd_id = self.params.get('rbd_id') else: self.rbd_id = test_utils.create_rbd(self.rbd_pool_id, self.params) if ops in 'add': body = { 'target_id': target_id, 'pool_id': self.rbd_pool_id, 'rbd_id': self.rbd_id } resp = self.client.add_lun(**body) self.env['iscsi_target_lun'] = resp.body return resp elif ops in 'delete': body = {'target_id': target_id, 'lun_id': self.lun_id} return self.client.delete_lun(**body) def test_lun_ops(self): ops = self.params.get('lun_ops') if ops in 'add': if not self._lun_ops('add'): raise exceptions.TestFail('Test of add lun failed') elif ops in 'delete': if not self.lun_id: self.lun_id = self.env['iscsi_target_lun']['lun_id'] if not self._lun_ops('delete'): raise exceptions.TestFail('Test of delete lun failed') elif ops in 'get_lun_info': resp = self.client.get_lun_info() if not len(resp) > 0: raise exceptions.TestFail("Test of get_lun_info failed") else: raise exceptions.TestNotFoundError( 'Did not find test for operation') def test_modify_iscsi(self): """ Modify iscsi targets's initiator ip """ target_id = self.env.get('iscsi_target')['target_id'] modify_iscsi = { 'initiator_ips': "192.168.1.34", 'old_initiator_ip': "192.168.1.30" } resp = self.client.modify_iscsi(target_id, **modify_iscsi) LOG.info('Rest Response: %s' % resp) if not resp and utils.verify_response(self.body, resp): raise exceptions.TestFail( "Modify iscsi target export host failed: %s" % self.body) def test_create_account_group(self): """ Execute the test of creating account group """ account_name = utils.utils_misc.generate_random_string(6) account_pass = utils.utils_misc.generate_random_string(12) gateway_id = self.gateway_id resp = self.client.create_account_group(account_name, account_pass, "single", str(gateway_id)) if not resp and utils.verify_response(self.body, resp): raise exceptions.TestFail("Create account group failed: %s") self.env['iscsi_accountgroup'] = resp.body def test_query_account_group(self): """ Execute the test of creating account group """ resp = self.client.query_account_group() if not len(resp) > 0: raise exceptions.TestFail("Query iscsi target failed") LOG.info("Got all iscsi targets %s" % resp) def test_modify_account_group(self): """ Modify account group """ account_id = self.env.get('iscsi_accountgroup')['group_id'] account_name = utils.utils_misc.generate_random_string(6) account_pass = utils.utils_misc.generate_random_string(6) resp = self.client.modify_account_group(account_id, account_name, account_pass) LOG.info('Rest Response: %s' % resp) if not resp and utils.verify_response(self.body, resp): raise exceptions.TestFail("Modify account group failed: %s" % self.body) def test_bind_account_operation(self): """ Test to bind or unbind account group to target """ account_ops = self.params.get('account_operation') target_id = self.env.get('iscsi_target')['target_id'] account_group_id = self.env.get('iscsi_accountgroup')['group_id'] LOG.info("Try to %s account %s to target %s" % (account_ops, account_group_id, target_id)) if 'unbind' in account_ops: resp = self.client.unbind_account(target_id, account_group_id) if not len(resp) > 0: raise exceptions.TestFail("Unbind account group '%s' failed" % account_group_id) elif 'bind' in account_ops: resp = self.client.bind_account(target_id, account_group_id) if not len(resp) > 0: raise exceptions.TestFail("Bind account group '%s' failed" % account_group_id) else: raise exceptions.TestNotFoundError('Did not find test for bind ' 'account operation') def test_query_login_initiator(self): resp = self.client.query_login_initiator() #Fixme it returns blank #if not len(resp) > 0: #raise exceptions.TestFail("Query login initiator failed") LOG.info("Got all login initiator %s" % resp) def test_delete_account_group(self): """ Test that deletion of account group """ account_id = self.env.get('iscsi_accountgroup')['group_id'] LOG.info("Try to delete account group with ID: %d" % account_id) self.client.delete_account(account_id) resp = self.client.query_account_group() for i in range(len(resp)): if resp[i]['group_id'] == account_id: raise exceptions.TestFail("Delete account group failed") def test_delete_target(self): """ Test that deletion of delete target """ target_id = self.env.get('iscsi_target')['target_id'] LOG.info("Try to delete iscsi_target with ID: %d" % target_id) self.client.delete_iscsitarget(target_id) resp = self.client.query() if len(resp['items']) != 0: for i in range(len(resp['items'])): if resp['items'][i]['target_id'] == target_id: raise exceptions.TestFail("Delete target failed") def teardown(self): """ Some clean up work will be done here. """ pass
class TestSnapshot(test.Test): """ Module for testing snapshot related operations. """ def __init__(self, params, env): self.params = params self.body = {} self.env = env self.rbd_client = RbdClient(params) self.snapshot_client = SnapshotsClient(params) self.iscsi_client = ISCSIClient(params) self.control_server_ip = self.params.get('ceph_management_url') self.control_server_ip = self.control_server_ip.split(':')[1].strip( '/') self.control_username = self.params.get('ceph_server_ssh_username', 'root') self.control_password = self.params.get('ceph_server_ssh_password') self.initiator_username = self.params.get('ceph_node_ssh_username') self.initiator_password = self.params.get('ceph_node_ssh_password') self.rbd_id = None self.snapshot_id = None self.target_id = None self.lun_id = None def setup(self): if 'cluster' in self.env: self.cluster_id = self.env['cluster'] elif self.params.get('cluster_id'): self.cluster_id = self.params.get('cluster_id') if self.params.get('pool_id'): self.pool_id = self.params.get('pool_id') else: self.pool_id = test_utils.create_pool(self.params) LOG.info("pool_id is %s" % self.pool_id) if self.params.get('initiator_ip'): self.initiator_ip = test_utils.get_available_host_ip(self.params) def _create_snapshot(self, rbd_id): self.body['cluster_id'] = self.cluster_id self.body['pool_id'] = self.pool_id self.body['rbd_id'] = rbd_id self.body['snapshot_name'] = 'cloudtest_snapshot' + \ utils.utils_misc.generate_random_string(6) resp = self.snapshot_client.create(**self.body) resp = resp.body if resp.get('success') is False: raise exceptions.TestFail("Create snapshot failed: %s" % self.body) return resp.get('results')['id'] def _snapshot_rollback(self, rbd_id, snapshot_id): self.body['to_snapshot'] = snapshot_id self.body['rbd_id'] = rbd_id resp = self.snapshot_client.rollback(**self.body) resp = resp.body if resp.get('success') is not True: raise exceptions.TestFail("Rollback snapshot failed: %s" % self.body) def _create_iscsi_target(self): self.iscsi_target_name = "cloudtest" + \ utils.utils_misc.generate_random_string(6) body = { 'initiator_ips': self.initiator_ip, 'target_name': self.iscsi_target_name, 'multipath': self.params.get('multipath', '3') } resp = self.iscsi_client.create(**body) if not resp and utils.verify_response(body, resp): raise exceptions.TestFail("Create target failed: %s" % body) return resp.body['target_id'] def _create_iscsi_lun(self, target_id, rbd_id): body = { 'target_id': target_id, 'pool_id': self.pool_id, 'rbd_id': rbd_id } resp = self.iscsi_client.add_lun(**body) return resp.body['lun_id'] def _delete_iscsi_lun(self, target_id, lun_id): body = {'target_id': target_id, 'lun_id': lun_id} resp = self.iscsi_client.delete_lun(**body) def _delete_target(self, target_id): """ Test that deletion of delete target """ self.iscsi_client.delete_iscsitarget(target_id) resp = self.iscsi_client.query() for i in range(len(resp)): if resp[i]['target_id'] == target_id: raise exceptions.TestFail("Delete target failed") def _delete_snapshot(self, snapshot_id): """ Test that deletion of specified snapshot. """ resp = self.snapshot_client.delete_snapshot(self.snapshot_id) resp = resp.body if resp.get('success') is not True: raise exceptions.TestFail("Delete snapshot failed!") def _delete_rbd(self, pool_id, rbd_id): """ Test that deletion of specified rdb """ # delete the rbd created in the right pool resp = self.rbd_client.delete_rbd(self.pool_id, rbd_id) if not len(resp) > 0: raise exceptions.TestFail("Delete rbd failed") def test(self): # Create rbd in the pool self.rbd_id = test_utils.create_rbd(self.pool_id, self.params) # Create iscsi self.target_id = self._create_iscsi_target() # Bind iscsi to rbd self.lun_id = self._create_iscsi_lun(self.target_id, self.rbd_id) mount_point = self.params.get('mount_point', '/mnt') file_name = self.params.get('file_name', 'testfile.txt') self.target_ip = test_utils.get_specified_targetip( self.params, self.target_id, 0) need_mk = True create_data = True find = test_utils.operate_iscsi( self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_target_name, self.target_ip, mount_point, file_name, need_mk, create_data) if find: LOG.info("Find %s under %s!" % (file_name, mount_point)) else: LOG.error("%s not found under %s" % (file_name, mount_point)) # Unbind iscsi from the rbd self._delete_iscsi_lun(self.target_id, self.lun_id) time.sleep(30) # Create snapshot with the rbd self.snapshot_id = self._create_snapshot(self.rbd_id) need_mk = False create_data = True file_name_2 = self.params.get('file_name_2', 'testfile2.txt') find = test_utils.operate_iscsi( self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_target_name, self.target_ip, mount_point, file_name_2, need_mk, create_data) if find: LOG.info("Find %s under %s!" % (file_name_2, mount_point)) else: LOG.error("%s not found under %s" % (file_name_2, mount_point)) time.sleep(30) # Rollback snapshot to this rbd self._snapshot_rollback(self.rbd_id, self.snapshot_id) # Bind iscsi to the rbd self.lun_id = self._create_iscsi_lun(self.target_id, self.rbd_id) time.sleep(30) need_mk = False create_data = False find = test_utils.operate_iscsi( self.control_server_ip, self.control_username, self.control_password, self.initiator_ip, self.initiator_username, self.initiator_password, self.iscsi_target_name, self.target_ip, mount_point, file_name_2, need_mk, create_data) if find: LOG.error("Find %s under %s!" % (file_name_2, mount_point)) else: LOG.info("%s not found under %s is expected!" % (file_name_2, mount_point)) def teardown(self): if self.lun_id is not None: self._delete_iscsi_lun(self.target_id, self.lun_id) if self.target_id is not None: self._delete_target(self.target_id) if self.snapshot_id is not None: self._delete_snapshot(self.snapshot_id) if self.rbd_id is not None: try: self._delete_rbd(self.pool_id, self.rbd_id) except exceptions.UnexpectedResponseCode, e: pass