def run_multi_disk(test, params, env): """ Test multi disk suport of guest, this case will: 1) Create disks image in configuration file. 2) Start the guest with those disks. 3) Checks qtree vs. test params. 4) Format those disks. 5) Copy file into / out of those disks. 6) Compare the original file and the copied file using md5 or fc comand. 7) Repeat steps 3-5 if needed. @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ def _add_param(name, value): """ Converts name+value to stg_params string """ if value: value = re.sub(' ', '\\ ', value) return " %s:%s " % (name, value) else: return '' stg_image_num = 0 stg_params = params.get("stg_params", "") # Compatibility stg_params += _add_param("image_size", params.get("stg_image_size")) stg_params += _add_param("image_format", params.get("stg_image_format")) stg_params += _add_param("image_boot", params.get("stg_image_boot")) stg_params += _add_param("drive_format", params.get("stg_drive_format")) if params.get("stg_assign_index") != "no": # Assume 0 and 1 are already occupied (hd0 and cdrom) stg_params += _add_param("drive_index", 'range(2,n)') param_matrix = {} stg_params = stg_params.split(' ') i = 0 while i < len(stg_params) - 1: if not stg_params[i].strip(): i += 1 continue if stg_params[i][-1] == '\\': stg_params[i] = '%s %s' % (stg_params[i][:-1], stg_params.pop(i + 1)) i += 1 rerange = [] has_name = False for i in xrange(len(stg_params)): if not stg_params[i].strip(): continue (cmd, parm) = stg_params[i].split(':', 1) if cmd == "image_name": has_name = True if _RE_RANGE1.match(parm): parm = _range(parm) if parm == False: raise error.TestError("Incorrect cfg: stg_params %s looks " "like range(..) but doesn't contain " "numbers." % cmd) param_matrix[cmd] = parm if type(parm) is str: # When we know the stg_image_num, substitute it. rerange.append(cmd) continue else: # ',' separated list of values parm = parm.split(',') j = 0 while j < len(parm) - 1: if parm[j][-1] == '\\': parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1)) j += 1 param_matrix[cmd] = parm stg_image_num = max(stg_image_num, len(parm)) stg_image_num = int(params.get('stg_image_num', stg_image_num)) for cmd in rerange: param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num) # param_table* are for pretty print of param_matrix param_table = [] param_table_header = ['name'] if not has_name: param_table_header.append('image_name') for _ in param_matrix: param_table_header.append(_) stg_image_name = params.get('stg_image_name', '%s') for i in xrange(stg_image_num): name = "stg%d" % i params['images'] += " %s" % name param_table.append([]) param_table[-1].append(name) if not has_name: params["image_name_%s" % name] = stg_image_name % name param_table[-1].append(params.get("image_name_%s" % name)) for parm in param_matrix.iteritems(): params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])]) param_table[-1].append(params.get('%s_%s' % (parm[0], name))) if params.get("multi_disk_params_only") == 'yes': # Only print the test param_matrix and finish logging.info('Newly added disks:\n%s', utils.matrix_to_string(param_table, param_table_header)) return # Always recreate VM (disks are already marked for deletion virt_env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.create(timeout=max(10, stg_image_num)) session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) images = params.get("images").split() n_repeat = int(params.get("n_repeat", "1")) image_num = len(images) file_system = params.get("file_system").split() fs_num = len(file_system) cmd_timeout = float(params.get("cmd_timeout", 360)) re_str = params.get("re_str") black_list = params.get("black_list").split() error.context("verifying qtree vs. test params") err = 0 qtree = kvm_qtree.QtreeContainer() qtree.parse_info_qtree(vm.monitor.info('qtree')) disks = kvm_qtree.QtreeDisksContainer(qtree.get_nodes()) (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info('block')) err += tmp1 + tmp2 err += disks.generate_params() err += disks.check_disk_params(params, vm.root_dir) (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi( session.cmd_output('cat /proc/scsi/scsi')) err += tmp1 + tmp2 if err: raise error.TestFail("%s errors occurred while verifying qtree vs. " "params" % err) if params.get('multi_disk_only_qtree') == 'yes': return try: if params.get("clean_cmd"): cmd = params.get("clean_cmd") session.cmd_status_output(cmd) if params.get("pre_cmd"): cmd = params.get("pre_cmd") error.context("creating partition on test disk") session.cmd(cmd, timeout=cmd_timeout) cmd = params.get("list_volume_command") output = session.cmd_output(cmd, timeout=cmd_timeout) disks = re.findall(re_str, output) disks = map(string.strip, disks) disks.sort() logging.debug("Volume list that meets regular expressions: '%s'", disks) if len(disks) < image_num: raise error.TestFail("Fail to list all the volumes!") if params.get("os_type") == "linux": df_output = session.cmd_output("df") li = re.findall("^/dev/(.*?)[ \d]", df_output, re.M) if li: black_list.extend(li) exclude_list = [d for d in disks if d in black_list] f = lambda d: logging.info("No need to check volume '%s'", d) map(f, exclude_list) disks = [d for d in disks if d not in exclude_list] for i in range(n_repeat): logging.info("iterations: %s", (i + 1)) for disk in disks: disk = disk.strip() logging.info("Format disk: %s...", disk) index = random.randint(0, fs_num - 1) # Random select one file system from file_system fs = file_system[index].strip() cmd = params.get("format_command") % (fs, disk) error.context("formatting test disk") session.cmd(cmd, timeout=cmd_timeout) if params.get("mount_command"): cmd = params.get("mount_command") % (disk, disk, disk) session.cmd(cmd, timeout=cmd_timeout) for disk in disks: disk = disk.strip() logging.info("Performing I/O on disk: %s...", disk) cmd_list = params.get("cmd_list").split() for cmd_l in cmd_list: if params.get(cmd_l): cmd = params.get(cmd_l) % disk session.cmd(cmd, timeout=cmd_timeout) cmd = params.get("compare_command") output = session.cmd_output(cmd) key_word = params.get("check_result_key_word") if key_word and key_word in output: logging.debug("Guest's virtual disk %s works fine", disk) elif key_word: raise error.TestFail("Files on guest os root fs and disk " "differ") else: raise error.TestError( "Param check_result_key_word was not " "specified! Please check your config") if params.get("umount_command"): cmd = params.get("show_mount_cmd") output = session.cmd_output(cmd) disks = re.findall(re_str, output) disks.sort() for disk in disks: disk = disk.strip() cmd = params.get("umount_command") % (disk, disk) error.context("unmounting test disk") session.cmd(cmd) finally: if params.get("post_cmd"): cmd = params.get("post_cmd") session.cmd(cmd) session.close()
def run_multi_disk(test, params, env): """ Test multi disk suport of guest, this case will: 1) Create disks image in configuration file. 2) Start the guest with those disks. 3) Checks qtree vs. test params. 4) Format those disks. 5) Copy file into / out of those disks. 6) Compare the original file and the copied file using md5 or fc comand. 7) Repeat steps 3-5 if needed. @param test: kvm test object @param params: Dictionary with the test parameters @param env: Dictionary with test environment. """ def _add_param(name, value): """ Converts name+value to stg_params string """ if value: value = re.sub(' ', '\\ ', value) return " %s:%s " % (name, value) else: return '' stg_image_num = 0 stg_params = params.get("stg_params", "") # Compatibility stg_params += _add_param("image_size", params.get("stg_image_size")) stg_params += _add_param("image_format", params.get("stg_image_format")) stg_params += _add_param("image_boot", params.get("stg_image_boot")) stg_params += _add_param("drive_format", params.get("stg_drive_format")) if params.get("stg_assign_index") != "no": # Assume 0 and 1 are already occupied (hd0 and cdrom) stg_params += _add_param("drive_index", 'range(2,n)') param_matrix = {} stg_params = stg_params.split(' ') i = 0 while i < len(stg_params) - 1: if not stg_params[i].strip(): i += 1 continue if stg_params[i][-1] == '\\': stg_params[i] = '%s %s' % (stg_params[i][:-1], stg_params.pop(i + 1)) i += 1 rerange = [] has_name = False for i in xrange(len(stg_params)): if not stg_params[i].strip(): continue (cmd, parm) = stg_params[i].split(':', 1) if cmd == "image_name": has_name = True if _RE_RANGE1.match(parm): parm = _range(parm) if parm == False: raise error.TestError("Incorrect cfg: stg_params %s looks " "like range(..) but doesn't contain " "numbers." % cmd) param_matrix[cmd] = parm if type(parm) is str: # When we know the stg_image_num, substitute it. rerange.append(cmd) continue else: # ',' separated list of values parm = parm.split(',') j = 0 while j < len(parm) - 1: if parm[j][-1] == '\\': parm[j] = '%s,%s' % (parm[j][:-1], parm.pop(j + 1)) j += 1 param_matrix[cmd] = parm stg_image_num = max(stg_image_num, len(parm)) stg_image_num = int(params.get('stg_image_num', stg_image_num)) for cmd in rerange: param_matrix[cmd] = _range(param_matrix[cmd], stg_image_num) # param_table* are for pretty print of param_matrix param_table = [] param_table_header = ['name'] if not has_name: param_table_header.append('image_name') for _ in param_matrix: param_table_header.append(_) stg_image_name = params.get('stg_image_name', '%s') for i in xrange(stg_image_num): name = "stg%d" % i params['images'] += " %s" % name param_table.append([]) param_table[-1].append(name) if not has_name: params["image_name_%s" % name] = stg_image_name % name param_table[-1].append(params.get("image_name_%s" % name)) for parm in param_matrix.iteritems(): params['%s_%s' % (parm[0], name)] = str(parm[1][i % len(parm[1])]) param_table[-1].append(params.get('%s_%s' % (parm[0], name))) if params.get("multi_disk_params_only") == 'yes': # Only print the test param_matrix and finish logging.info('Newly added disks:\n%s', utils.matrix_to_string(param_table, param_table_header)) return # Always recreate VM (disks are already marked for deletion virt_env_process.preprocess(test, params, env) vm = env.get_vm(params["main_vm"]) vm.create(timeout=max(10, stg_image_num)) session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) images = params.get("images").split() n_repeat = int(params.get("n_repeat", "1")) image_num = len(images) file_system = params.get("file_system").split() fs_num = len(file_system) cmd_timeout = float(params.get("cmd_timeout", 360)) re_str = params.get("re_str") black_list = params.get("black_list").split() error.context("verifying qtree vs. test params") err = 0 qtree = kvm_qtree.QtreeContainer() qtree.parse_info_qtree(vm.monitor.info('qtree')) disks = kvm_qtree.QtreeDisksContainer(qtree.get_nodes()) (tmp1, tmp2) = disks.parse_info_block(vm.monitor.info('block')) err += tmp1 + tmp2 err += disks.generate_params() err += disks.check_disk_params(params, vm.root_dir) (tmp1, tmp2, _, _) = disks.check_guests_proc_scsi( session.cmd_output('cat /proc/scsi/scsi')) err += tmp1 + tmp2 if err: raise error.TestFail("%s errors occurred while verifying qtree vs. " "params" % err) if params.get('multi_disk_only_qtree') == 'yes': return try: if params.get("clean_cmd"): cmd = params.get("clean_cmd") session.cmd_status_output(cmd) if params.get("pre_cmd"): cmd = params.get("pre_cmd") error.context("creating partition on test disk") session.cmd(cmd, timeout=cmd_timeout) cmd = params.get("list_volume_command") output = session.cmd_output(cmd, timeout=cmd_timeout) disks = re.findall(re_str, output) disks = map(string.strip, disks) disks.sort() logging.debug("Volume list that meets regular expressions: '%s'", disks) if len(disks) < image_num: raise error.TestFail("Fail to list all the volumes!") if params.get("os_type") == "linux": df_output = session.cmd_output("df") li = re.findall("^/dev/(.*?)[ \d]", df_output, re.M) if li: black_list.extend(li) exclude_list = [d for d in disks if d in black_list] f = lambda d: logging.info("No need to check volume '%s'", d) map(f, exclude_list) disks = [d for d in disks if d not in exclude_list] for i in range(n_repeat): logging.info("iterations: %s", (i + 1)) for disk in disks: disk = disk.strip() logging.info("Format disk: %s...", disk) index = random.randint(0, fs_num - 1) # Random select one file system from file_system fs = file_system[index].strip() cmd = params.get("format_command") % (fs, disk) error.context("formatting test disk") session.cmd(cmd, timeout=cmd_timeout) if params.get("mount_command"): cmd = params.get("mount_command") % (disk, disk, disk) session.cmd(cmd, timeout=cmd_timeout) for disk in disks: disk = disk.strip() logging.info("Performing I/O on disk: %s...", disk) cmd_list = params.get("cmd_list").split() for cmd_l in cmd_list: if params.get(cmd_l): cmd = params.get(cmd_l) % disk session.cmd(cmd, timeout=cmd_timeout) cmd = params.get("compare_command") output = session.cmd_output(cmd) key_word = params.get("check_result_key_word") if key_word and key_word in output: logging.debug("Guest's virtual disk %s works fine", disk) elif key_word: raise error.TestFail("Files on guest os root fs and disk " "differ") else: raise error.TestError("Param check_result_key_word was not " "specified! Please check your config") if params.get("umount_command"): cmd = params.get("show_mount_cmd") output = session.cmd_output(cmd) disks = re.findall(re_str, output) disks.sort() for disk in disks: disk = disk.strip() cmd = params.get("umount_command") % (disk, disk) error.context("unmounting test disk") session.cmd(cmd) finally: if params.get("post_cmd"): cmd = params.get("post_cmd") session.cmd(cmd) session.close()
def run_once(self, params): # Convert params to a Params object params = virt_utils.Params(params) # If a dependency test prior to this test has failed, let's fail # it right away as TestNA. if params.get("dependency_failed") == 'yes': raise error.TestNAError("Test dependency failed") # Report the parameters we've received and write them as keyvals logging.debug("Test parameters:") keys = params.keys() keys.sort() for key in keys: logging.debug(" %s = %s", key, params[key]) self.write_test_keyval({key: params[key]}) # Set the log file dir for the logging mechanism used by kvm_subprocess # (this must be done before unpickling env) virt_utils.set_log_file_dir(self.debugdir) # Open the environment file env_filename = os.path.join(self.bindir, params.get("env", "env")) env = virt_utils.Env(env_filename, self.env_version) test_passed = False try: try: try: # Get the test routine corresponding to the specified # test type t_type = params.get("type") subtest_dirs = [] tests_dir = self.job.testdir other_subtests_dirs = params.get("other_tests_dirs", "") for d in other_subtests_dirs.split(): subtestdir = os.path.join(tests_dir, d, "tests") if not os.path.isdir(subtestdir): raise error.TestError("Directory %s not" " exist." % (subtestdir)) subtest_dirs.append(dir) # Verify if we have the correspondent source file for it virt_dir = os.path.dirname(virt_utils.__file__) subtest_dirs.append(os.path.join(virt_dir, "tests")) subtest_dirs.append(os.path.join(self.bindir, "tests")) subtest_dir = None for d in subtest_dirs: module_path = os.path.join(d, "%s.py" % t_type) if os.path.isfile(module_path): subtest_dir = d break if subtest_dir is None: raise error.TestError("Could not find test file %s.py " "on tests dirs %s" % (t_type, subtest_dirs)) # Load the test module f, p, d = imp.find_module(t_type, [subtest_dir]) test_module = imp.load_module(t_type, f, p, d) f.close() # Preprocess try: virt_env_process.preprocess(self, params, env) finally: env.save() # Run the test function run_func = getattr(test_module, "run_%s" % t_type) try: run_func(self, params, env) finally: env.save() test_passed = True except Exception, e: logging.error("Test failed: %s: %s", e.__class__.__name__, e) try: virt_env_process.postprocess_on_error( self, params, env) finally: env.save() raise finally: # Postprocess try: try: virt_env_process.postprocess(self, params, env) except Exception, e: if test_passed: raise logging.error("Exception raised during " "postprocessing: %s", e) finally: env.save() except Exception, e: if params.get("abort_on_error") != "yes": raise # Abort on error logging.info("Aborting job (%s)", e) if params.get("vm_type") == "kvm": for vm in env.get_all_vms(): if vm.is_dead(): continue logging.info("VM '%s' is alive.", vm.name) for m in vm.monitors: logging.info("'%s' has a %s monitor unix socket at: %s", vm.name, m.protocol, m.filename) logging.info("The command line used to start '%s' was:\n%s", vm.name, vm.make_qemu_command()) raise error.JobError("Abort requested (%s)" % e)