def run(test, params, env):
    """
    'qemu-img' lock tests.

    Verify it supports to get information of a running image.
    Including three tests:
    1. Create a raw image.
       Boot vm using this image.
       'qemu-info' the image.
    2. Create a base qcow2 image.
       Create an external snapshot.
       Boot vm using the base.
       'qemu-info' the snapshot.
    3. Create a base qcow2 image.
       Create an external snapshot.
       Boot vm using the snapshot.
       'qemu-info' the base.

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _boot_vm(boot_img):
        error_context.context("Boot vm with %s." % boot_img, logging.info)
        vm.params["images"] = boot_img
        vm.create()
        vm.verify_alive()

    def _qemu_img_info(info_img):
        error_context.context("Check qemu-img info with %s." % info_img,
                              logging.info)
        img_param = params.object_params(info_img)
        img = QemuImg(img_param, data_dir.get_data_dir(), info_img)
        try:
            img.info()
        except process.CmdError:
            test.fail("qemu-img info %s failed." % info_img)

    def _qemu_img_info_while_vm_running(boot_img, info_img):
        _boot_vm(boot_img)
        _qemu_img_info(info_img)

    vm = env.get_vm(params["main_vm"])
    if params.get("create_snapshot", "no") == "yes":
        # create an external snapshot
        gen = generate_base_snapshot_pair(params["image_chain"])
        base_snapshot_pair = base, snapshot = next(gen)
        # workaround to assign system disk's image_name to image_name_image1
        params["image_name_image1"] = params["image_name"]
        qit = QemuImgTest(test, params, env, snapshot)
        qit.create_snapshot()

        if params.get("boot_with_snapshot", "no") == "yes":
            # reverse base snap pair, so boot vm with snapshot
            base_snapshot_pair.reverse()
        _qemu_img_info_while_vm_running(*base_snapshot_pair)
    else:
        # boot and info same img, raw only
        _qemu_img_info_while_vm_running("image1", "image1")
예제 #2
0
 def _create_os_snapshot():
     """Crate one external snapshot based on the os image."""
     logging.info("Create a qcow2 snapshot based on the os image.")
     # workaround to asign syetem disk's image_name to image_name_image1
     params["image_name_image1"] = params["image_name"]
     gen = generate_base_snapshot_pair(params["image_chain"])
     _, snapshot = next(gen)
     QemuImgTest(test, params, env, snapshot).create_snapshot()
예제 #3
0
def run(test, params, env):
    """
    Create snapshot based on the target qcow2 image converted from raw image.

    1. boot a guest up with an initial raw image
    2. create a file on the initial image disk, calculate its md5sum
    3. shut the guest down
    4. convert initial raw image to a qcow2 image tgt, and check the tgt
    5. create a snapshot based on tgt
    6. boot a guest from the snapshot and check whether the
       file's md5sum stays same

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _get_img_obj_and_params(tag):
        """Get an QemuImg object and its params based on the tag."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), tag)
        return img, img_param

    file = params["guest_file_name"]
    initial_tag = params["images"].split()[0]
    c_tag = params["image_convert"]

    logging.info("Boot a guest up with initial image: %s, and create a"
                 " file %s on the disk." % (initial_tag, file))
    base_qit = QemuImgTest(test, params, env, initial_tag)
    base_qit.start_vm()
    md5 = base_qit.save_file(file)
    logging.info("Got %s's md5 %s from the initial image disk." % (file, md5))
    base_qit.destroy_vm()

    logging.info("Convert initial image %s to %s" % (initial_tag, c_tag))
    img, img_param = _get_img_obj_and_params(initial_tag)
    img.convert(params.object_params(c_tag), data_dir.get_data_dir())

    logging.info("Check image %s." % (c_tag))
    tgt = {"image_name_%s" % c_tag: params["convert_name_%s" % c_tag],
           "image_format_%s" % c_tag: params["convert_format_%s" % c_tag]}
    params.update(tgt)
    tgt, tgt_img_param = _get_img_obj_and_params(c_tag)
    tgt.check_image(tgt_img_param, data_dir.get_data_dir())

    gen = generate_base_snapshot_pair(params["image_chain"])
    _, snapshot = next(gen)
    logging.info("Create a snapshot %s based on %s." % (snapshot, c_tag))
    sn_qit = QemuImgTest(test, params, env, snapshot)
    sn_qit.create_snapshot()
    sn_qit.start_vm()
    if not sn_qit.check_file(file, md5):
        test.fail("The file %s's md5 on initial image and"
                  " snapshot are different." % file)
    for qit in (base_qit, sn_qit):
        qit.clean()
예제 #4
0
def run(test, params, env):
    """
    Check thin write in qemu-img commit.

    1) write 0x1 into the entire base image through qemu-io
    2) create a external snapshot sn of the base
    3) write specific length zeros at the beginning of the snapshot
    4) commit sn back to base
    5) make sure the zeros have been committed into the base image

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _get_image_object(tag):
        """Get QemuImg object by tag."""
        img_param = params.object_params(tag)
        return QemuImg(img_param, img_root_dir, tag)

    def _create_external_snapshot(tag):
        """Create an external snapshot based on tag."""
        logging.info("Create external snapshot %s.", tag)
        qit = QemuImgTest(test, params, env, snapshot)
        qit.create_snapshot()

    def _qemu_io(img, cmd):
        """Run qemu-io cmd to a given img."""
        logging.info("Run qemu-io %s", img.image_filename)
        q = QemuIOSystem(test, params, img.image_filename)
        q.cmd_output(cmd, 120)

    def _verify_map_output(output):
        """"Verify qemu map output."""
        expected = {
            "length": int(utils_numeric.normalize_data_size(
                params["write_size"], "B")),
            "start": 0, "depth": 0, "zero": True, "data": False}
        if expected not in json.loads(output.stdout_text):
            test.fail("Commit failed, data from 0 to %s are not zero" %
                      params["write_size"])

    gen = generate_base_snapshot_pair(params["image_chain"])
    img_root_dir = data_dir.get_data_dir()
    base, snapshot = next(gen)

    img_base = _get_image_object(base)
    _qemu_io(img_base, 'write -P 1 0 %s' % params["image_size_base"])

    _create_external_snapshot(snapshot)
    img_sn = _get_image_object(snapshot)
    _qemu_io(img_sn, 'write -z 0 %s' % params["write_size"])

    img_sn.commit()
    _verify_map_output(img_base.map(output="json"))
예제 #5
0
def run(test, params, env):
    """
    qemu-img create a snapshot on a running base image.

    1. boot a guest up from a base image
    2. create a file on the base image disk, calculate its md5sum
    3. create a snapshot on the running base image
    4. shut the guest down and boot a guest from the snapshot
    5. check whether the file's md5sum stays same

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    gen = generate_base_snapshot_pair(params["image_chain"])
    base, snapshot = next(gen)
    file = params["guest_file_name"]

    logging.info("Boot a guest up from base image: %s, and create a"
                 " file %s on the disk." % (base, file))
    base_qit = QemuImgTest(test, params, env, base)
    base_qit.start_vm()
    md5 = base_qit.save_file(file)
    logging.info("Got %s's md5 %s from the base image disk." % (file, md5))

    logging.info("Create a snapshot %s on the running base image." % snapshot)
    params["image_name_image1"] = params["image_name"]
    sn_qit = QemuImgTest(test, params, env, snapshot)
    sn_qit.create_snapshot()

    base_qit.destroy_vm()
    logging.info("Boot the guest up from snapshot image: %s, and verify the"
                 " file %s's md5 on the disk." % (snapshot, file))
    sn_qit.start_vm()
    if not sn_qit.check_file(file, md5):
        test.fail("The file %s's md5 on base and"
                  " snapshot are different." % file)

    for qit in (base_qit, sn_qit):
        qit.clean()
예제 #6
0
def run(test, params, env):
    """
    Rebase a second qcow2 snapshot to a raw base file.

    1. create a qcow2 snapshot base -> sn1
    2. boot the guest from the sn1
    3. create a file in the snapshot disk,  calculate its md5sum
    4. shut the guest down
    5. create a qcow2 snapshot sn1 -> sn2
    6. rebase the sn2 to the base
    7. remove the sn1, optional
    8. boot the guest from the sn2 and check whether the
       file's md5sum stays same

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _get_img_obj_and_params(tag):
        """Get an QemuImg object and its params based on the tag."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), tag)
        return img, img_param

    def _get_compat_version():
        """Get snapshot compat version."""
        if params.get("image_extra_params") is None:
            # default compat version for now is 1.1
            return "1.1"
        return params.get("image_extra_params").split("=")[1]

    def _verify_qemu_img_info_backing_chain(output, b_fmt, b_name):
        """Verify qemu-img info output for this case."""
        logging.info("Verify snapshot's backing file information.")
        res = json.loads(output)[:-1]
        for idx, backing in enumerate(res):
            if (backing["backing-filename-format"] != b_fmt[idx]
                    or backing["backing-filename"] != b_name[idx]):
                test.fail("Backing file information is not correct,"
                          " got %s." % b_name[idx])
            compat = backing["format-specific"]["data"]["compat"]
            expected = _get_compat_version()
            if (compat != expected):
                test.fail("Snapshot's compat mode is not correct,"
                          " got %s, expected %s." % (compat, expected))

    file = params["guest_file_name"]
    gen = generate_base_snapshot_pair(params["image_chain"])
    base, sn1 = next(gen)
    base_img, _ = _get_img_obj_and_params(base)
    sn1_img, _ = _get_img_obj_and_params(sn1)

    logging.info("Create a snapshot %s based on %s." % (sn1, base))
    # workaround to assign system disk's image_name to image_name_image1
    params["image_name_image1"] = params["image_name"]
    sn1_qit = QemuImgTest(test, params, env, sn1)
    sn1_qit.create_snapshot()
    _verify_qemu_img_info_backing_chain(sn1_img.info(output="json"),
                                        [base_img.image_format],
                                        [base_img.image_filename])
    sn1_qit.start_vm()
    md5 = sn1_qit.save_file(file)
    logging.info("Got %s's md5 %s from the initial image disk." % (file, md5))
    sn1_qit.destroy_vm()

    sn1, sn2 = next(gen)
    sn2_img, sn2_img_params = _get_img_obj_and_params(sn2)
    logging.info("Create a snapshot %s based on %s." % (sn2, sn1))
    sn2_qit = QemuImgTest(test, params, env, sn2)
    sn2_qit.create_snapshot()
    _verify_qemu_img_info_backing_chain(
        sn2_img.info(output="json"),
        [sn1_img.image_format, base_img.image_format],
        [sn1_img.image_filename, base_img.image_filename])

    cache_mode = params.get("cache_mode")
    if cache_mode:
        logging.info("Rebase the snapshot %s to %s with cache %s." %
                     (sn2, base, params["cache_mode"]))
    else:
        logging.info("Rebase the snapshot %s to %s." % (sn2, base))
    sn2_img.base_image_filename = base_img.image_filename
    sn2_img.base_format = base_img.image_format
    sn2_img.rebase(sn2_img_params, cache_mode)
    _verify_qemu_img_info_backing_chain(sn2_img.info(output="json"),
                                        [base_img.image_format],
                                        [base_img.image_filename])

    if params.get("remove_sn1", "no") == "yes":
        logging.info("Remove the snapshot %s." % sn1)
        os.unlink(sn1_img.image_filename)

    sn2_qit.start_vm()
    if not sn2_qit.check_file(file, md5):
        test.fail("The file %s's md5 on initial image and"
                  " target file are different." % file)
    sn2_qit.destroy_vm()
예제 #7
0
def run(test, params, env):
    """
    Unsafe rebase a qcow2 snapshot to a none existing the raw backing file.

    1. create a qcow2 snapshot based on a raw image with compat mode 0.10/1.1
    2. rebase the snapshot to a none exist the raw backing file
    3. check the snapshot

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _get_img_obj_and_params(tag):
        """Get an QemuImg object and its params based on the tag."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), tag)
        return img, img_param

    def _get_compat_version():
        """Get snapshot compat version."""
        if params.get("image_extra_params") is None:
            # default compat version for now is 1.1
            return "1.1"
        return params.get("image_extra_params").split("=")[1]

    def _verify_qemu_img_info(output, b_fmt, b_name):
        """Verify qemu-img info output for this case."""
        logging.info("Verify snapshot's backing file information.")
        res = json.loads(output)
        if (res["backing-filename-format"] != b_fmt
                or res["backing-filename"] != b_name):
            test.fail("Backing file information is not correct,"
                      " got %s." % b_name)
        compat = res["format-specific"]["data"]["compat"]
        expected = _get_compat_version()
        if (compat != expected):
            test.fail("Snapshot's compat mode is not correct,"
                      " got %s, expected %s." % (compat, expected))

    def _verify_unsafe_rebase(img):
        """Verify qemu-img check output for this case."""
        logging.info("Verify snapshot's unsafe check information.")
        res = process.run("%s check %s" % (img.image_cmd, img.image_filename),
                          ignore_status=True)
        expected = [
            "Could not open backing file", img.base_image_filename,
            "No such file or directory"
        ]
        for msg in expected:
            if msg not in res.stderr_text:
                test.fail("The %s should not exist." % img.base_image_filename)

    gen = generate_base_snapshot_pair(params["image_chain"])
    base, snapshot = next(gen)
    base_img, _ = _get_img_obj_and_params(base)
    sn_img, sn_img_params = _get_img_obj_and_params(snapshot)

    logging.info("Create a snapshot %s based on %s." % (snapshot, base))
    # workaround to assign system disk's image_name to image_name_image1
    params["image_name_image1"] = params["image_name"]
    QemuImgTest(test, params, env, snapshot).create_snapshot()
    _verify_qemu_img_info(sn_img.info(output="json"), base_img.image_format,
                          base_img.image_filename)

    sn_img.base_image_filename = params["none_existing_image_name"]
    sn_img.base_format = sn_img.base_image_filename.split('.')[-1]
    sn_img.rebase(sn_img_params)
    _verify_qemu_img_info(sn_img.info(output="json"), sn_img.base_format,
                          sn_img.base_image_filename)

    _verify_unsafe_rebase(sn_img)
예제 #8
0
def run(test, params, env):
    """
    'qemu-img' lock tests.

    Verify it rejects to get information due to image lock.
    Including two tests:
    1. Create a base qcow2 image.
       Create an external snapshot.
       Boot vm using the base.
       'qemu-info' the snapshot with option "--backing-chain".
       'qemu-info' the snapshot with option "--backing-chain" and "-U".

    2. Create a base qcow2 image.
       Boot vm using the base.
       'qemu-info' the base.
       'qemu-info' the base with option "-U".

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _boot_vm(boot_img):
        error_context.context("Boot vm with %s." % boot_img, logging.info)
        vm.params["images"] = boot_img
        vm.create()
        vm.verify_alive()

    def _qemu_img_info(info_img, force_share=False):
        error_context.context("Check qemu-img info with %s." % info_img,
                              logging.info)
        img_param = params.object_params(info_img)
        img = QemuImg(img_param, data_dir.get_data_dir(), info_img)
        img.info(force_share)

    def _verify_write_lock_err_msg(e, img_tag):
        error_context.context("Verify qemu-img write lock err msg.",
                              logging.info)
        img_param = params.object_params(img_tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), img_tag)
        msgs = ['"write" lock',
                'Is another process using the image',
                img.image_filename]
        if not all(msg in e.result.stderr.decode() for msg in msgs):
            test.fail("Image lock information is not as expected.")

    def _qemu_img_info_to_verify_image_lock(boot_img, info_img, img_tag):
        _boot_vm(boot_img)
        try:
            _qemu_img_info(info_img)
        except process.CmdError as e:
            _verify_write_lock_err_msg(e, img_tag)
        else:
            test.fail("The image %s is not locked." % img_tag)
        try:
            _qemu_img_info(info_img, True)
        except process.CmdError:
            test.fail("qemu-img info %s failed." % info_img)

    vm = env.get_vm(params["main_vm"])
    if params.get("create_snapshot", "no") == "yes":
        gen = generate_base_snapshot_pair(params["image_chain"])
        base, snapshot = next(gen)
        # workaround to assign system disk's image_name to image_name_image1
        params["image_name_image1"] = params["image_name"]
        qit = QemuImgTest(test, params, env, snapshot)
        qit.create_snapshot()

        _qemu_img_info_to_verify_image_lock(base, snapshot, base)
    else:
        _qemu_img_info_to_verify_image_lock("image1", "image1", "image1")
예제 #9
0
def run(test, params, env):
    """
    Commit a qcow2 snapshot to a raw backing image.

    1. create an external qcow2v2/qcow2v3 snapshot
       based on a raw image
    2. boot the guest from the snapshot
    3. create a file in the snapshot disk, calculate its md5sum
    4. shut the guest down
    5. commit the snapshot to the raw backing image with various cache mode,
        and check whether the snapshot file emptied
    6. boot the guest from the raw image and check whether the
        file's md5sum stays same
    7. check the snapshot

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _get_img_obj_and_params(tag):
        """Get an QemuImg object and its params based on the tag."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), tag)
        return img, img_param

    def _get_compat_version():
        """Get snapshot compat version."""
        if params.get("image_extra_params") is None:
            # default compat version for now is 1.1
            return "1.1"
        return params.get("image_extra_params").split("=")[1]

    def _verify_qemu_img_info(output, b_fmt, b_name):
        """Verify qemu-img info output for this case."""
        logging.info("Verify snapshot's backing file information.")
        res = json.loads(output)
        if (res["backing-filename-format"] != b_fmt
                or res["backing-filename"] != b_name):
            test.fail("Backing file information is not correct,"
                      " got %s." % b_name)
        compat = res["format-specific"]["data"]["compat"]
        expected = _get_compat_version()
        if (compat != expected):
            test.fail("Snapshot's compat mode is not correct,"
                      " got %s, expected %s." % (compat, expected))

    file = params["guest_file_name"]
    gen = generate_base_snapshot_pair(params["image_chain"])
    base, snapshot = next(gen)
    base_img, _ = _get_img_obj_and_params(base)
    sn_img, sn_img_params = _get_img_obj_and_params(snapshot)

    logging.info("Create a snapshot %s based on %s.", snapshot, base)
    # workaround to assign system disk's image_name to image_name_image1
    params["image_name_image1"] = params["image_name"]
    sn_qit = QemuImgTest(test, params, env, snapshot)
    sn_qit.create_snapshot()
    _verify_qemu_img_info(sn_img.info(output="json"), base_img.image_format,
                          base_img.image_filename)

    logging.info(
        "Boot a guest up from snapshot image: %s, and create a"
        " file %s on the disk.", snapshot, file)
    sn_qit.start_vm()
    md5 = sn_qit.save_file(file)
    logging.info("Got %s's md5 %s from the snapshot image disk.", file, md5)
    sn_qit.destroy_vm()

    cache_mode = params.get("cache_mode")
    if cache_mode:
        logging.info("Commit snapshot image %s back to %s with cache mode %s.",
                     snapshot, base, cache_mode)
    else:
        logging.info("Commit snapshot image %s back to %s.", snapshot, base)

    org_size = json.loads(sn_img.info(output="json"))["actual-size"]
    sn_img.commit(cache_mode=cache_mode)
    remain_size = json.loads(sn_img.info(output="json"))["actual-size"]
    """Verify the snapshot file whether emptied after committing"""
    logging.info("Verify the snapshot file whether emptied after committing")
    commit_size = org_size - remain_size
    dd_size = eval(params["dd_total_size"])
    if commit_size >= dd_size:
        logging.info("The snapshot file was emptied!")
    else:
        test.fail("The snapshot file was not emptied, check pls!")

    base_qit = QemuImgTest(test, params, env, base)
    base_qit.start_vm()
    if not base_qit.check_file(file, md5):
        test.fail("The file %s's md5 on base image and"
                  " snapshot file are different." % file)
    base_qit.destroy_vm()

    logging.info("Check image %s.", snapshot)
    sn_img.check_image(sn_img_params, data_dir.get_data_dir())

    for qit in (base_qit, sn_qit):
        qit.clean()
예제 #10
0
def run(test, params, env):
    """
    'qemu-img' lock tests.

    Verify it rejects to get information due to image lock.
    Including two tests:
    1. Create a base qcow2 image.
       Create an external snapshot.
       Boot vm using the base.
       'qemu-info' the snapshot with option "--backing-chain".
       'qemu-info' the snapshot with option "--backing-chain" and "-U".

    2. Create a base qcow2 image.
       Boot vm using the base.
       'qemu-info' the base.
       'qemu-info' the base with option "-U".

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _boot_vm(boot_img):
        error_context.context("Boot vm with %s." % boot_img, logging.info)
        vm.params["images"] = boot_img
        vm.create()
        vm.verify_alive()

    def _qemu_img_info(info_img, force_share=False):
        error_context.context("Check qemu-img info with %s." % info_img,
                              logging.info)
        img_param = params.object_params(info_img)
        img = QemuImg(img_param, data_dir.get_data_dir(), info_img)
        img.info(force_share)

    def _verify_write_lock_err_msg(e, img_tag):
        error_context.context("Verify qemu-img write lock err msg.",
                              logging.info)
        img_param = params.object_params(img_tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), img_tag)
        msgs = [
            '"write" lock', 'Is another process using the image',
            img.image_filename
        ]
        if not all(msg in e.result.stderr.decode() for msg in msgs):
            test.fail("Image lock information is not as expected.")

    def _qemu_img_info_to_verify_image_lock(boot_img, info_img, img_tag):
        _boot_vm(boot_img)
        try:
            _qemu_img_info(info_img)
        except process.CmdError as e:
            _verify_write_lock_err_msg(e, img_tag)
        else:
            test.fail("The image %s is not locked." % img_tag)
        try:
            _qemu_img_info(info_img, True)
        except process.CmdError:
            test.fail("qemu-img info %s failed." % info_img)

    vm = env.get_vm(params["main_vm"])
    if params.get("create_snapshot", "no") == "yes":
        gen = generate_base_snapshot_pair(params["image_chain"])
        base, snapshot = next(gen)
        # workaround to assign system disk's image_name to image_name_image1
        params["image_name_image1"] = params["image_name"]
        qit = QemuImgTest(test, params, env, snapshot)
        qit.create_snapshot()

        _qemu_img_info_to_verify_image_lock(base, snapshot, base)
    else:
        _qemu_img_info_to_verify_image_lock("image1", "image1", "image1")
def run(test, params, env):
    """
    Commit a qcow2 snapshot to a raw backing image.

    1. create an external qcow2v2/qcow2v3 snapshot
       based on a raw image
    2. boot the guest from the snapshot
    3. create a file in the snapshot disk, calculate its md5sum
    4. shut the guest down
    5. commit the snapshot to the raw backing image with various cache mode
    6. boot the guest from the raw image and check whether the
        file's md5sum stays same
    7. check the snapshot

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _get_img_obj_and_params(tag):
        """Get an QemuImg object and its params based on the tag."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), tag)
        return img, img_param

    def _get_compat_version():
        """Get snapshot compat version."""
        if params.get("image_extra_params") is None:
            # default compat version for now is 1.1
            return "1.1"
        return params.get("image_extra_params").split("=")[1]

    def _verify_qemu_img_info(output, b_fmt, b_name):
        """Verify qemu-img info output for this case."""
        logging.info("Verify snapshot's backing file information.")
        res = json.loads(output)
        if (res["backing-filename-format"] != b_fmt or
                res["backing-filename"] != b_name):
            test.fail("Backing file information is not correct,"
                      " got %s." % b_name)
        compat = res["format-specific"]["data"]["compat"]
        expected = _get_compat_version()
        if (compat != expected):
            test.fail("Snapshot's compat mode is not correct,"
                      " got %s, expected %s." % (compat, expected))

    file = params["guest_file_name"]
    gen = generate_base_snapshot_pair(params["image_chain"])
    base, snapshot = next(gen)
    base_img, _ = _get_img_obj_and_params(base)
    sn_img, sn_img_params = _get_img_obj_and_params(snapshot)

    logging.info("Create a snapshot %s based on %s.", snapshot, base)
    # workaround to assign system disk's image_name to image_name_image1
    params["image_name_image1"] = params["image_name"]
    sn_qit = QemuImgTest(test, params, env, snapshot)
    sn_qit.create_snapshot()
    _verify_qemu_img_info(sn_img.info(output="json"),
                          base_img.image_format, base_img.image_filename)

    logging.info("Boot a guest up from snapshot image: %s, and create a"
                 " file %s on the disk.", snapshot, file)
    sn_qit.start_vm()
    md5 = sn_qit.save_file(file)
    logging.info("Got %s's md5 %s from the snapshot image disk.", file, md5)
    sn_qit.destroy_vm()

    cache_mode = params.get("cache_mode")
    if cache_mode:
        logging.info("Commit snapshot image %s back to %s with cache mode %s.",
                     snapshot, base, cache_mode)
    else:
        logging.info("Commit snapshot image %s back to %s.", snapshot, base)
    sn_img.commit(cache_mode=cache_mode)

    base_qit = QemuImgTest(test, params, env, base)
    base_qit.start_vm()
    if not base_qit.check_file(file, md5):
        test.fail("The file %s's md5 on base image and"
                  " snapshot file are different." % file)
    base_qit.destroy_vm()

    logging.info("Check image %s.", snapshot)
    sn_img.check_image(sn_img_params, data_dir.get_data_dir())

    for qit in (base_qit, sn_qit):
        qit.clean()
예제 #12
0
def run(test, params, env):
    """
    Rebase a qcow2 snapshot onto no backing file.

    1. create an external qcow2v2/qcow2v3 snapshot
       based on a raw image
    2. boot the guest from the base
    3. create a file in the base disk, calculate its md5sum
    4. shut the guest down
    5. rebase the snapshot to ""(empty string) onto no backing file
    6. check the snapshot
    7. boot the guest from the snapshot and check whether the
        file's md5sum stays same

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _get_img_obj_and_params(tag):
        """Get an QemuImg object and its params based on the tag."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), tag)
        return img, img_param

    def _get_compat_version():
        """Get snapshot compat version."""
        if params.get("image_extra_params") is None:
            # default compat version for now is 1.1
            return "1.1"
        return params.get("image_extra_params").split("=")[1]

    def _verify_qemu_img_info(output, b_fmt, b_name):
        """Verify qemu-img info output for this case."""
        logging.info("Verify snapshot's backing file information.")
        res = json.loads(output)
        if (res["backing-filename-format"] != b_fmt
                or res["backing-filename"] != b_name):
            test.fail("Backing file information is not correct,"
                      " got %s." % b_name)
        compat = res["format-specific"]["data"]["compat"]
        expected = _get_compat_version()
        if compat != expected:
            test.fail("Snapshot's compat mode is not correct,"
                      " got %s, expected %s." % (compat, expected))

    def _verify_no_backing_file(output):
        """Verify snapshot has no backing file for this case."""
        logging.info("Verify snapshot has no backing file after rebase.")
        for key in json.loads(output):
            if "backing" in key:
                test.fail("The snapshot has backing file after rebase.")

    file = params["guest_file_name"]
    gen = generate_base_snapshot_pair(params["image_chain"])
    base, snapshot = next(gen)
    base_img, _ = _get_img_obj_and_params(base)
    sn_img, sn_img_params = _get_img_obj_and_params(snapshot)

    logging.info("Create a snapshot %s based on %s.", snapshot, base)
    # workaround to assign system disk's image_name to image_name_image1
    params["image_name_image1"] = params["image_name"]
    sn_qit = QemuImgTest(test, params, env, snapshot)
    sn_qit.create_snapshot()
    _verify_qemu_img_info(sn_img.info(output="json"), base_img.image_format,
                          base_img.image_filename)

    logging.info(
        "Boot a guest up from base image: %s, and create a"
        " file %s on the disk.", base, file)
    base_qit = QemuImgTest(test, params, env, base)
    base_qit.start_vm()
    md5 = base_qit.save_file(file)
    logging.info("Got %s's md5 %s from the base image disk.", file, md5)
    base_qit.destroy_vm()

    sn_img.base_tag, sn_img.base_image_filename = ("null", "null")
    sn_img.rebase(sn_img_params)
    _verify_no_backing_file(sn_img.info(output="json"))
    sn_img.check_image(sn_img_params, data_dir.get_data_dir())

    sn_qit = QemuImgTest(test, params, env, snapshot)
    sn_qit.start_vm()
    if not sn_qit.check_file(file, md5):
        test.fail("The file %s's md5 on base image and"
                  " snapshot file are different." % file)
    sn_qit.destroy_vm()

    for qit in (base_qit, sn_qit):
        qit.clean()
예제 #13
0
def run(test, params, env):
    """
    Verify it can successfully convert a enlarged snapshot.

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _compare_images(img1, img2):
        """Compare two qemu images are identical or not."""
        logging.info("Compare two images are identical.")
        cmd = [
            img1.image_cmd, "compare", "-f", img1.image_format, "-F",
            img2.image_format, img1.image_filename, img2.image_filename
        ]
        output = process.system_output(" ".join(cmd)).decode()
        if "Images are identical" not in output:
            test.fail("%s and %s are not identical." %
                      (img1.image_filename, img2.image_filename))

    def _create_external_snapshot(tag):
        """Create an external snapshot based on tag."""
        logging.info("Create external snapshot %s." % tag)
        qit = QemuImgTest(test, params, env, tag)
        qit.create_snapshot()

    def _verify_backing_file(output, backing_tag):
        """Verify backing file is as expected."""
        if backing_tag is None:
            return
        backing_param = params.object_params(backing_tag)
        backing = QemuImg(backing_param, img_root_dir, backing_tag)
        if backing.image_filename not in json.loads(
                output)["backing-filename"]:
            test.fail("Backing file is not correct.")

    def _qemu_img_info(tag, backing_tag=None):
        """Run qemu info to given image."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, img_root_dir, tag)
        output = img.info(output="json")
        _verify_backing_file(output, backing_tag)
        return img

    def _verify_resize(img):
        """Verify the image size is as expected after resize."""
        img_size = json.loads(img.info(output="json"))["virtual-size"]
        sign = (-1 if '-' in params["sn1_size_change"] else 1)
        expected_size = (
            int(utils_numeric.normalize_data_size(params["image_size"], "B")) +
            int(
                utils_numeric.normalize_data_size(params["sn1_size_change"],
                                                  "B"))) * sign
        logging.info("Verify the size of  %s is %s." %
                     (img.image_filename, expected_size))
        if img_size != expected_size:
            test.fail("Got image virtual size: %s, should be: %s." %
                      (img_size, expected_size))

    gen = generate_base_snapshot_pair(params["image_chain"])
    img_root_dir = data_dir.get_data_dir()

    base, sn1 = next(gen)
    _create_external_snapshot(sn1)
    img_sn1 = _qemu_img_info(sn1, base)
    img_sn1.resize(params["sn1_size_change"])
    _verify_resize(img_sn1)

    sn1, sn2 = next(gen)
    _create_external_snapshot(sn2)
    img_sn2 = _qemu_img_info(sn2, sn1)
    img_sn2.convert(params.object_params(sn2), img_root_dir)

    converted = {
        "image_name_converted": params["convert_name_%s" % sn2],
        "image_format_converted": params["convert_format_%s" % sn2]
    }
    params.update(converted)
    img_converted = _qemu_img_info("converted")
    _compare_images(img_sn2, img_converted)
def run(test, params, env):
    """
    Verify it can successfully convert a enlarged snapshot.

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _compare_images(img1, img2):
        """Compare two qemu images are identical or not."""
        logging.info("Compare two images are identical.")
        cmd = [img1.image_cmd, "compare", "-f", img1.image_format,
               "-F", img2.image_format,
               img1.image_filename, img2.image_filename]
        output = process.system_output(" ".join(cmd)).decode()
        if "Images are identical" not in output:
            test.fail("%s and %s are not identical." %
                      (img1.image_filename, img2.image_filename))

    def _create_external_snapshot(tag):
        """Create an external snapshot based on tag."""
        logging.info("Create external snapshot %s." % tag)
        qit = QemuImgTest(test, params, env, tag)
        qit.create_snapshot()

    def _verify_backing_file(output, backing_tag):
        """Verify backing file is as expected."""
        if backing_tag is None:
            return
        backing_param = params.object_params(backing_tag)
        backing = QemuImg(backing_param, img_root_dir, backing_tag)
        if backing.image_filename not in json.loads(
           output)["backing-filename"]:
            test.fail("Backing file is not correct.")

    def _qemu_img_info(tag, backing_tag=None):
        """Run qemu info to given image."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, img_root_dir, tag)
        output = img.info(output="json")
        _verify_backing_file(output, backing_tag)
        return img

    def _verify_resize(img):
        """Verify the image size is as expected after resize."""
        img_size = json.loads(img.info(output="json"))["virtual-size"]
        sign = (-1 if '-' in params["sn1_size_change"] else 1)
        expected_size = (int(utils_numeric.normalize_data_size(
            params["image_size"], "B")) +
            int(utils_numeric.normalize_data_size(
                params["sn1_size_change"], "B"))) * sign
        logging.info("Verify the size of  %s is %s." %
                     (img.image_filename, expected_size))
        if img_size != expected_size:
            test.fail("Got image virtual size: %s, should be: %s." %
                      (img_size, expected_size))

    gen = generate_base_snapshot_pair(params["image_chain"])
    img_root_dir = data_dir.get_data_dir()

    base, sn1 = next(gen)
    _create_external_snapshot(sn1)
    img_sn1 = _qemu_img_info(sn1, base)
    img_sn1.resize(params["sn1_size_change"])
    _verify_resize(img_sn1)

    sn1, sn2 = next(gen)
    _create_external_snapshot(sn2)
    img_sn2 = _qemu_img_info(sn2, sn1)
    img_sn2.convert(params.object_params(sn2), img_root_dir)

    converted = {"image_name_converted": params["convert_name_%s" % sn2],
                 "image_format_converted": params["convert_format_%s" % sn2]}
    params.update(converted)
    img_converted = _qemu_img_info("converted")
    _compare_images(img_sn2, img_converted)
def run(test, params, env):
    """
    Unsafe rebase a qcow2 snapshot to a none existing the raw backing file.

    1. create a qcow2 snapshot based on a raw image with compat mode 0.10/1.1
    2. rebase the snapshot to a none exist the raw backing file
    3. check the snapshot

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _get_img_obj_and_params(tag):
        """Get an QemuImg object and its params based on the tag."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), tag)
        return img, img_param

    def _get_compat_version():
        """Get snapshot compat version."""
        if params.get("image_extra_params") is None:
            # default compat version for now is 1.1
            return "1.1"
        return params.get("image_extra_params").split("=")[1]

    def _verify_qemu_img_info(output, b_fmt, b_name):
        """Verify qemu-img info output for this case."""
        logging.info("Verify snapshot's backing file information.")
        res = json.loads(output)
        if (res["backing-filename-format"] != b_fmt or
                res["backing-filename"] != b_name):
            test.fail("Backing file information is not correct,"
                      " got %s." % b_name)
        compat = res["format-specific"]["data"]["compat"]
        expected = _get_compat_version()
        if (compat != expected):
            test.fail("Snapshot's compat mode is not correct,"
                      " got %s, expected %s." % (compat, expected))

    def _verify_unsafe_rebase(img):
        """Verify qemu-img check output for this case."""
        logging.info("Verify snapshot's unsafe check information.")
        res = process.run("%s check %s" % (img.image_cmd, img.image_filename),
                          ignore_status=True)
        expected = ["Could not open backing file", img.base_image_filename,
                    "No such file or directory"]
        for msg in expected:
            if msg not in res.stderr_text:
                test.fail("The %s should not exist." % img.base_image_filename)

    gen = generate_base_snapshot_pair(params["image_chain"])
    base, snapshot = next(gen)
    base_img, _ = _get_img_obj_and_params(base)
    sn_img, sn_img_params = _get_img_obj_and_params(snapshot)

    logging.info("Create a snapshot %s based on %s." % (snapshot, base))
    # workaround to assign system disk's image_name to image_name_image1
    params["image_name_image1"] = params["image_name"]
    QemuImgTest(test, params, env, snapshot).create_snapshot()
    _verify_qemu_img_info(sn_img.info(output="json"),
                          base_img.image_format, base_img.image_filename)

    sn_img.base_image_filename = params["none_existing_image_name"]
    sn_img.base_format = sn_img.base_image_filename.split('.')[-1]
    sn_img.rebase(sn_img_params)
    _verify_qemu_img_info(sn_img.info(output="json"),
                          sn_img.base_format, sn_img.base_image_filename)

    _verify_unsafe_rebase(sn_img)
def run(test, params, env):
    """
    Rebase a second qcow2 snapshot to a raw base file.

    1. create a qcow2 snapshot base -> sn1
    2. boot the guest from the sn1
    3. create a file in the snapshot disk,  calculate its md5sum
    4. shut the guest down
    5. create a qcow2 snapshot sn1 -> sn2
    6. rebase the sn2 to the base
    7. remove the sn1, optional
    8. boot the guest from the sn2 and check whether the
       file's md5sum stays same

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _get_img_obj_and_params(tag):
        """Get an QemuImg object and its params based on the tag."""
        img_param = params.object_params(tag)
        img = QemuImg(img_param, data_dir.get_data_dir(), tag)
        return img, img_param

    def _get_compat_version():
        """Get snapshot compat version."""
        if params.get("image_extra_params") is None:
            # default compat version for now is 1.1
            return "1.1"
        return params.get("image_extra_params").split("=")[1]

    def _verify_qemu_img_info_backing_chain(output, b_fmt, b_name):
        """Verify qemu-img info output for this case."""
        logging.info("Verify snapshot's backing file information.")
        res = json.loads(output)[:-1]
        for idx, backing in enumerate(res):
            if (backing["backing-filename-format"] != b_fmt[idx] or
                    backing["backing-filename"] != b_name[idx]):
                test.fail("Backing file information is not correct,"
                          " got %s." % b_name[idx])
            compat = backing["format-specific"]["data"]["compat"]
            expected = _get_compat_version()
            if (compat != expected):
                test.fail("Snapshot's compat mode is not correct,"
                          " got %s, expected %s." % (compat, expected))

    file = params["guest_file_name"]
    gen = generate_base_snapshot_pair(params["image_chain"])
    base, sn1 = next(gen)
    base_img, _ = _get_img_obj_and_params(base)
    sn1_img, _ = _get_img_obj_and_params(sn1)

    logging.info("Create a snapshot %s based on %s." % (sn1, base))
    # workaround to assign system disk's image_name to image_name_image1
    params["image_name_image1"] = params["image_name"]
    sn1_qit = QemuImgTest(test, params, env, sn1)
    sn1_qit.create_snapshot()
    _verify_qemu_img_info_backing_chain(sn1_img.info(output="json"),
                                        [base_img.image_format],
                                        [base_img.image_filename])
    sn1_qit.start_vm()
    md5 = sn1_qit.save_file(file)
    logging.info("Got %s's md5 %s from the initial image disk." % (file, md5))
    sn1_qit.destroy_vm()

    sn1, sn2 = next(gen)
    sn2_img, sn2_img_params = _get_img_obj_and_params(sn2)
    logging.info("Create a snapshot %s based on %s." % (sn2, sn1))
    sn2_qit = QemuImgTest(test, params, env, sn2)
    sn2_qit.create_snapshot()
    _verify_qemu_img_info_backing_chain(
        sn2_img.info(output="json"),
        [sn1_img.image_format, base_img.image_format],
        [sn1_img.image_filename, base_img.image_filename])

    cache_mode = params.get("cache_mode")
    if cache_mode:
        logging.info("Rebase the snapshot %s to %s with cache %s." %
                     (sn2, base, params["cache_mode"]))
    else:
        logging.info("Rebase the snapshot %s to %s." % (sn2, base))
    sn2_img.base_image_filename = base_img.image_filename
    sn2_img.base_format = base_img.image_format
    sn2_img.rebase(sn2_img_params, cache_mode)
    _verify_qemu_img_info_backing_chain(sn2_img.info(output="json"),
                                        [base_img.image_format],
                                        [base_img.image_filename])

    if params.get("remove_sn1", "no") == "yes":
        logging.info("Remove the snapshot %s." % sn1)
        os.unlink(sn1_img.image_filename)

    sn2_qit.start_vm()
    if not sn2_qit.check_file(file, md5):
        test.fail("The file %s's md5 on initial image and"
                  " target file are different." % file)
    sn2_qit.destroy_vm()