Exemple #1
0
def run(test, params, env):
    """
    Run qemu-io blkdebug tests:
    1. Create image with given parameters
    2. Write the blkdebug config file
    3. Try to do operate in image with qemu-io and get the error message
    4. Get the error message from os.strerror by error number set in config file
    5. Compare the error message

    :param test:   QEMU test object
    :param params: Dictionary with the test parameters
    :param env:    Dictionary with test environment.
    """
    if params.get("blkdebug_event_name_separator") == 'underscore':
        blkdebug_event = params.get('err_event')
        if "." in blkdebug_event:
            params['err_event'] = blkdebug_event.replace(".", "_")
    tmp_dir = params.get("tmp_dir", "/tmp")
    blkdebug_cfg = utils_misc.get_path(tmp_dir, params.get("blkdebug_cfg",
                                                           "blkdebug.cfg"))
    err_command = params["err_command"]
    err_event = params["err_event"]
    errn_list = re.split("\s+", params["errn_list"].strip())
    test_timeout = int(params.get("test_timeout", "60"))
    pre_err_commands = params.get("pre_err_commands")
    image = params.get("images")
    blkdebug_default = params.get("blkdebug_default")
    session_reload = params.get("session_reload", "no") == "yes"
    pre_snapshot = params.get("pre_snapshot", "no") == "yes"
    del_snapshot = params.get("del_snapshot", "no") == "yes"

    error.context("Create image", logging.info)
    image_io = QemuImg(
        params.object_params(image), data_dir.get_data_dir(), image)
    image_name, _ = image_io.create(params.object_params(image))

    template_name = utils_misc.get_path(test.virtdir, blkdebug_default)
    template = ConfigParser.ConfigParser()
    template.read(template_name)

    for errn in errn_list:
        log_filename = utils_misc.get_path(test.outputdir,
                                           "qemu-io-log-%s" % errn)
        error.context("Write the blkdebug config file", logging.info)
        template.set("inject-error", "event", '"%s"' % err_event)
        template.set("inject-error", "errno", '"%s"' % errn)

        error.context("Write blkdebug config file", logging.info)
        blkdebug = None
        try:
            blkdebug = open(blkdebug_cfg, 'w')
            template.write(blkdebug)
        finally:
            if blkdebug is not None:
                blkdebug.close()

        error.context("Create image", logging.info)
        image_io = QemuImg(params.object_params(
            image), data_dir.get_data_dir(), image)
        image_name = image_io.create(params.object_params(image))[0]

        error.context("Operate in qemu-io to trigger the error", logging.info)
        session = qemu_io.QemuIOShellSession(test, params, image_name,
                                             blkdebug_cfg=blkdebug_cfg,
                                             log_filename=log_filename)
        if pre_err_commands:
            for cmd in re.split(",", pre_err_commands.strip()):
                session.cmd_output(cmd, timeout=test_timeout)
        if session_reload or pre_snapshot:
            session.close()
            if pre_snapshot:
                image_io.snapshot_create()
                image_sn = image_io.snapshot_tag
            session = qemu_io.QemuIOShellSession(test, params, image_name,
                                                 blkdebug_cfg=blkdebug_cfg,
                                                 log_filename=log_filename)

        if not del_snapshot:
            output = session.cmd_output(err_command, timeout=test_timeout)
            session.close()
        else:
            session.close()
            try:
                image_io.snapshot_del(blkdebug_cfg=blkdebug_cfg)
                output = ""
            except process.CmdError, err:
                output = err.result.stderr

        # Remove the snapshot and base image after a round of test
        image_io.remove()
        if pre_snapshot and not del_snapshot:
            params_sn = params.object_params(image_sn)
            image_snapshot = QemuImg(
                params_sn, data_dir.get_data_dir(), image_sn)
            image_snapshot.remove()

        error.context("Get error message", logging.info)
        try:
            std_msg = os.strerror(int(errn))
        except ValueError:
            raise error.TestError("Can not find error message:\n"
                                  "    error code is %s" % errn)

        session.close()
        error.context("Compare the error message", logging.info)
        if std_msg in output:
            logging.info("Error message is correct in qemu-io")
        else:
            fail_log = "The error message is mismatch:\n"
            fail_log += "    qemu-io reports: '%s',\n" % output
            fail_log += "    os.strerror reports: '%s'" % std_msg
            raise error.TestFail(fail_log)
def run(test, params, env):
    """
    Run qemu-io blkdebug tests:
    1. Create image with given parameters
    2. Write the blkdebug config file
    3. Try to do operate in image with qemu-io and get the error message
    4. Get the error message from os.strerror by error number set in config file
    5. Compare the error message

    :param test:   QEMU test object
    :param params: Dictionary with the test parameters
    :param env:    Dictionary with test environment.
    """
    if params.get("blkdebug_event_name_separator") == 'underscore':
        blkdebug_event = params.get('err_event')
        if "." in blkdebug_event:
            params['err_event'] = blkdebug_event.replace(".", "_")
    tmp_dir = params.get("tmp_dir", "/tmp")
    blkdebug_cfg = utils_misc.get_path(tmp_dir, params.get("blkdebug_cfg",
                                                           "blkdebug.cfg"))
    err_command = params["err_command"]
    err_event = params["err_event"]
    errn_list = re.split(r"\s+", params["errn_list"].strip())
    test_timeout = int(params.get("test_timeout", "60"))
    pre_err_commands = params.get("pre_err_commands")
    image = params.get("images")
    blkdebug_default = params.get("blkdebug_default")
    session_reload = params.get("session_reload", "no") == "yes"
    pre_snapshot = params.get("pre_snapshot", "no") == "yes"
    del_snapshot = params.get("del_snapshot", "no") == "yes"

    error_context.context("Create image", logging.info)
    image_io = QemuImg(
        params.object_params(image), data_dir.get_data_dir(), image)
    image_name, _ = image_io.create(params.object_params(image))

    template_name = utils_misc.get_path(test.virtdir, blkdebug_default)
    template = ConfigParser()
    template.read(template_name)

    for errn in errn_list:
        log_filename = utils_misc.get_path(test.outputdir,
                                           "qemu-io-log-%s" % errn)
        error_context.context("Write the blkdebug config file", logging.info)
        template.set("inject-error", "event", '"%s"' % err_event)
        template.set("inject-error", "errno", '"%s"' % errn)

        error_context.context("Write blkdebug config file", logging.info)
        blkdebug = None
        try:
            blkdebug = open(blkdebug_cfg, 'w')
            template.write(blkdebug)
        finally:
            if blkdebug is not None:
                blkdebug.close()

        error_context.context("Create image", logging.info)
        image_io = QemuImg(params.object_params(
            image), data_dir.get_data_dir(), image)
        image_name = image_io.create(params.object_params(image))[0]

        error_context.context("Operate in qemu-io to trigger the error",
                              logging.info)
        session = qemu_io.QemuIOShellSession(test, params, image_name,
                                             blkdebug_cfg=blkdebug_cfg,
                                             log_filename=log_filename)
        if pre_err_commands:
            for cmd in re.split(",", pre_err_commands.strip()):
                session.cmd_output(cmd, timeout=test_timeout)
        if session_reload or pre_snapshot:
            session.close()
            if pre_snapshot:
                image_io.snapshot_create()
                image_sn = image_io.snapshot_tag
            session = qemu_io.QemuIOShellSession(test, params, image_name,
                                                 blkdebug_cfg=blkdebug_cfg,
                                                 log_filename=log_filename)

        if not del_snapshot:
            output = session.cmd_output(err_command, timeout=test_timeout)
            session.close()
        else:
            session.close()
            try:
                image_io.snapshot_del(blkdebug_cfg=blkdebug_cfg)
                output = ""
            except process.CmdError as err:
                output = err.result.stderr

        # Remove the snapshot and base image after a round of test
        image_io.remove()
        if pre_snapshot and not del_snapshot:
            params_sn = params.object_params(image_sn)
            image_snapshot = QemuImg(
                params_sn, data_dir.get_data_dir(), image_sn)
            image_snapshot.remove()

        error_context.context("Get error message", logging.info)
        try:
            std_msg = os.strerror(int(errn))
        except ValueError:
            test.error("Can not find error message:\n"
                       "    error code is %s" % errn)

        session.close()
        error_context.context("Compare the error message", logging.info)
        if std_msg in output:
            logging.info("Error message is correct in qemu-io")
        else:
            fail_log = "The error message is mismatch:\n"
            fail_log += "    qemu-io reports: '%s',\n" % output
            fail_log += "    os.strerror reports: '%s'" % std_msg
            test.fail(fail_log)
Exemple #3
0
def run(test, params, env):
    """
    Test if VM paused when image NFS shutdown, the drive option 'werror' should
    be stop, the drive option 'cache' should be none.

    1) Setup NFS service on host
    2) Boot up a VM using another disk on NFS server and write the disk by dd
    3) Check if VM status is 'running'
    4) Reject NFS connection on host
    5) Check if VM status is 'paused'
    6) Accept NFS connection on host and continue VM by monitor command
    7) Check if VM status is 'running'

    :param test: kvm test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def get_nfs_devname(params, session):
        """
        Get the possbile name of nfs storage dev name in guest.

        :param params: Test params dictionary.
        :param session: An SSH session object.
        """
        image1_type = params.object_params("image1").get("drive_format")
        stg_type = params.object_params("stg").get("drive_format")
        cmd = ""
        # Seems we can get correct 'stg' devname even if the 'stg' image
        # has a different type from main image (we call it 'image1' in
        # config file) with these 'if' sentences.
        if image1_type == stg_type:
            cmd = "ls /dev/[hsv]d[a-z]"
        elif stg_type == "virtio":
            cmd = "ls /dev/vd[a-z]"
        else:
            cmd = "ls /dev/[sh]d[a-z]"

        cmd += " | tail -n 1"
        return session.cmd_output(cmd).rstrip()

    def check_vm_status(vm, status):
        """
        Check if VM has the given status or not.

        :param vm: VM object.
        :param status: String with desired status.
        :return: True if VM status matches our desired status.
        :return: False if VM status does not match our desired status.
        """
        try:
            vm.verify_status(status)
        except (virt_vm.VMStatusError, qemu_monitor.MonitorLockError):
            return False
        else:
            return True

    error_context.context("Setup NFS Server on local host", logging.info)
    host_ip = utils_net.get_host_ip_address(params)
    try:
        config = NFSCorruptConfig(test, params, host_ip)
        config.setup()
    except NFSCorruptError as e:
        test.error(str(e))

    image_stg_dir = config.mnt_dir
    stg_params = params.object_params("stg")
    stg_img = QemuImg(stg_params, image_stg_dir, "stg")
    stg_img.create(stg_params)

    error_context.context("Boot vm with image on NFS server", logging.info)
    image_name = os.path.join(image_stg_dir, "nfs_corrupt")
    params["image_name_stg"] = image_name

    vm = env.get_vm(params["main_vm"])
    try:
        vm.create(params=params)
    except Exception:
        stg_img.remove()
        config.cleanup()
        test.error("failed to create VM")
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))

    nfs_devname = get_nfs_devname(params, session)
    # Write disk on NFS server
    error_context.context("Write disk that image on NFS", logging.info)
    write_disk_cmd = "dd if=/dev/zero of=%s oflag=direct" % nfs_devname
    logging.info("dd with command: %s", write_disk_cmd)
    session.sendline(write_disk_cmd)
    try:
        # Read some command output, it will timeout
        session.read_up_to_prompt(timeout=30)
    except Exception:
        pass

    try:
        error_context.context("Make sure guest is running before test",
                              logging.info)
        vm.resume()
        vm.verify_status("running")

        try:
            error_context.context("Reject NFS connection on host",
                                  logging.info)
            process.system(config.iptables_rule_gen('A'))

            error_context.context("Check if VM status is 'paused'",
                                  logging.info)
            if not utils_misc.wait_for(
                    lambda: check_vm_status(vm, "paused"),
                    int(params.get('wait_paused_timeout', 240))):
                test.error("Guest is not paused after stop NFS")
        finally:
            error_context.context("Accept NFS connection on host",
                                  logging.info)
            process.system(config.iptables_rule_gen('D'))

        error_context.context("Ensure nfs is resumed", logging.info)
        nfs_resume_timeout = int(params.get('nfs_resume_timeout', 240))
        if not utils_misc.wait_for(config.is_mounted_dir_acessible,
                                   nfs_resume_timeout):
            test.error("NFS connection does not resume")

        error_context.context("Continue guest", logging.info)
        vm.resume()

        error_context.context("Check if VM status is 'running'", logging.info)
        if not utils_misc.wait_for(lambda: check_vm_status(vm, "running"), 20):
            test.error("Guest does not restore to 'running' status")

    finally:
        session.close()
        vm.destroy(gracefully=True)
        stg_img.check_image(params, image_stg_dir)
        stg_img.remove()
        config.cleanup()