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
Example #2
0
 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 run(test, params, env):
    """
    qemu-img map an unaligned image.

    1.create a raw file using truncate
    2.write data into the raw file
    3.verify the dumped mete-data using qemu-img map

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _generate_random_string(max_len=19):
        """Generate random alphabets string in the range of [1, max_len+1]."""
        random_str = ''.join(random.choice(
            string.ascii_lowercase) for _ in range(random.randint(1, max_len)))
        return random_str, len(random_str)

    def _verify_qemu_img_map(output, str_len):
        """Verify qemu-img map's output."""
        logging.info("Verify the dumped mete-data of the unaligned image.")
        qemu_path = utils_misc.get_qemu_binary(params)
        qemu_version = env_process._get_qemu_version(qemu_path)
        match = re.search(r'[0-9]+\.[0-9]+\.[0-9]+(\-[0-9]+)?', qemu_version)
        host_qemu = match.group(0)
        if host_qemu in VersionInterval('[6.1.0,)'):
            expected = [
                {"start": 0, "length": str_len, "depth": 0, "present": True,
                 "zero": False, "data": True, "offset": 0},
                {"start": str_len, "length": 512 - (str_len % 512), "depth": 0,
                 "present": True, "zero": True, "data": False,
                 "offset": str_len}]
        else:
            expected = [{"start": 0, "length": str_len, "depth": 0,
                         "zero": False, "data": True, "offset": 0},
                        {"start": str_len, "length": 512 - (str_len % 512),
                         "depth": 0, "zero": True, "data": False,
                         "offset": str_len}]
        res = json.loads(output)
        if res != expected:
            test.fail("The dumped mete-data of the unaligned "
                      "image '%s' is not correct." % img.image_filename)

    img_param = params.object_params("test")
    img = QemuImg(img_param, data_dir.get_data_dir(), "test")

    logging.info("Create a new file %s using truncate.", img.image_filename)
    process.run("rm -f %s" % img.image_filename)
    process.run("truncate -s 1G %s " % img.image_filename)

    random_str, str_len = _generate_random_string()
    logging.info("Write '%s' into the file %s.", random_str, img.image_filename)
    process.run("echo -n '%s' > %s" % (random_str, img.image_filename),
                shell=True)
    res = img.map(output="json")
    if res.exit_status != 0:
        test.fail("qemu-img map error: %s." % res.stderr_text)
    _verify_qemu_img_map(res.stdout_text, str_len)
 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 run(test, params, env):
    """
    qemu-img supports 'discard' for raw block target images.

    1. Create source image via dd with all zero.
    2. Modprobe a 1G scsi_debug disk with writesame_16 mode.
    3. Trace the system calls while converting the zero image to the
       scsi_debug block device, then check whether 'fallocate' system call
       results work in the log.
    :param test: Qemu test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def _check_output(strace_event, strace_output, match_str):
        """Check whether the value is good in the output file."""
        logging.debug("Check the output file '%s'.", strace_output)
        with open(strace_output) as fd:
            m = re.findall(match_str + r', \d+, \d+', fd.read())
            if not m:
                test.fail("The result of system call '%s' is not right, "
                          "check '%s' for more details." %
                          (strace_event, strace_output))
            last_lst = m[-1].split(',')
            sum_size = int(last_lst[-1]) + int(last_lst[-2])
            # get the source image size in byte unit
            byte_image_size = int(
                utils_numeric.normalize_data_size(image_size, "B"))
            if sum_size != byte_image_size:
                test.fail(
                    "The target allocated size '%s' is different from the source image size, "
                    "check '%s' for more details." %
                    (str(sum_size), strace_output))

    src_image = params["images"]
    image_size = params["image_size_test"]
    root_dir = data_dir.get_data_dir()
    source = QemuImg(params.object_params(src_image), root_dir, src_image)
    strace_event = params["strace_event"]
    strace_events = strace_event.split()
    strace_output_file = os.path.join(test.debugdir, "convert_to_block.log")

    source.create(source.params)
    # Generate the target scsi block file.
    tgt_disk = process.system_output("lsscsi | grep '%s' | awk '{print $NF}'" %
                                     params["scsi_mod"],
                                     shell=True).decode()
    params["image_name_target"] = tgt_disk

    logging.debug(
        "Convert from %s to %s with cache mode none, strace log: %s.",
        source.image_filename, tgt_disk, strace_output_file)
    with strace(source, strace_events, strace_output_file, trace_child=True):
        fail_on((process.CmdError, ))(source.convert)(
            params.object_params(src_image), root_dir, cache_mode="none")

    _check_output(strace_event, strace_output_file, "FALLOC_FL_PUNCH_HOLE")
Example #6
0
def run(test, params, env):
    """
    A 'qemu-img' resize test.

    1.create a raw image
    2.change the raw image size * n
    3.verify resize * n

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _sum_size_changes(size_changes):
        """
        Sum the list of size changes.

        :param size_changes: list of size changes
        """
        res = []
        for change in size_changes:
            s = int(utils_numeric.normalize_data_size(
                change, "B")) * (-1 if '-' in change else 1)
            res.append(s)
        return sum(res)

    def _verify_resize(img_size, expected_size):
        """Verify the image size is as expected after resize."""
        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))

    def _resize(size_changes):
        """Resize the image and verify its size."""
        for idx, size in enumerate(size_changes):
            logging.info("Resize the raw image %s %s." %
                         (img.image_filename, size))
            shrink = True if "-" in size else False
            img.resize(size, shrink=shrink)

            img_size = json.loads(img.info(output="json"))["virtual-size"]
            expected_size = (int(
                utils_numeric.normalize_data_size(params["image_size_test"],
                                                  "B")) +
                             _sum_size_changes(size_changes[:idx + 1]))
            _verify_resize(img_size, expected_size)

    img_param = params.object_params('test')
    img = QemuImg(img_param, data_dir.get_data_dir(), 'test')
    size_changes = params["size_changes"].split()

    logging.info("Create a raw image %s." % img.image_filename)
    img.create(img_param)

    _resize(size_changes)
Example #7
0
def run(test, params, env):
    """
    A 'qemu-img' resize test.

    1.create a raw image
    2.change the raw image size * n
    3.verify resize * n

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _sum_size_changes(size_changes):
        """
        Sum the list of size changes.

        :param size_changes: list of size changes
        """
        res = []
        for change in size_changes:
            s = int(utils_numeric.normalize_data_size(change, "B")
                    ) * (-1 if '-' in change else 1)
            res.append(s)
        return sum(res)

    def _verify_resize(img_size, expected_size):
        """Verify the image size is as expected after resize."""
        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))

    def _resize(size_changes):
        """Resize the image and verify its size."""
        for idx, size in enumerate(size_changes):
            logging.info("Resize the raw image %s %s." % (img.image_filename,
                                                          size))
            shrink = True if "-" in size else False
            img.resize(size, shrink=shrink)

            img_size = json.loads(img.info(output="json"))["virtual-size"]
            expected_size = (int(utils_numeric.normalize_data_size(
                params["image_size_test"], "B")) +
                _sum_size_changes(size_changes[:idx + 1]))
            _verify_resize(img_size, expected_size)

    img_param = params.object_params('test')
    img = QemuImg(img_param, data_dir.get_data_dir(), 'test')
    size_changes = params["size_changes"].split()

    logging.info("Create a raw image %s." % img.image_filename)
    img.create(img_param)

    _resize(size_changes)
Example #8
0
def run(test, params, env):
    """
    Negative test.
    Verify that qemu-img supports to check the options used for
    creating external snapshot, and raise accurate error when
    specifying a wrong option.
    1. It should be failed to create the snapshot when specifying
       a wrong format for backing file.
    2. It should be failed to create the snapshot when specifying
       a non-existing backing file.
    3. It should be failed to create the snapshot when specifying
       an empty string for backing file.

    :param test: Qemu test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def _check_command(cmds):
        """run the command and check the output"""
        cmds = cmds.split(";")
        for qemu_img_cmd in cmds:
            if qemu_img_cmd_agrs:
                qemu_img_cmd %= qemu_img_cmd_agrs
            cmd_result = process.run(qemu_img_cmd,
                                     ignore_status=True,
                                     shell=True)
            if not re.search(err_info, cmd_result.stderr.decode(),
                             re.I | re.M):
                test.fail("Failed to get error information. The actual error "
                          "information is %s." % cmd_result.stderr.decode())

    def run_cmd_with_incorrect_format():
        cmds = params.get("cmd_with_incorrect_format")
        _check_command(cmds)

    def run_cmd_with_non_existing_backing_file():
        cmds = params.get("cmd_with_non_existing_backing_file")
        _check_command(cmds)

    def run_cmd_with_empty_string_for_backing_file():
        cmds = params.get("cmd_with_empty_string_for_backing_file")
        _check_command(cmds)

    qemu_img_cmd_agrs = ""
    image_stg = params["images"]
    if image_stg == "stg":
        root_dir = data_dir.get_data_dir()
        stg = QemuImg(params.object_params(image_stg), root_dir, image_stg)
        stg.create(stg.params)
        qemu_img_cmd_agrs = stg.image_filename
    err_info = params["err_info"]
    test_scenario = params["test_scenario"]
    locals()[test_scenario]()
Example #9
0
    def create_image(self):
        """
        Create a image.
        """
        image_name = self.params.get("image_name")
        self.params['image_name_snapshot'] = image_name + "-snap"
        snapshot_params = self.params.object_params("snapshot")
        base_dir = self.params.get("images_base_dir", data_dir.get_data_dir())

        image_io = QemuImg(snapshot_params, base_dir, image_name)
        image_name, _ = image_io.create(snapshot_params)
        return image_name
Example #10
0
    def create_image(self):
        """
        Create a image.
        """
        image_name = self.params.get("image_name")
        self.params['image_name_snapshot'] = image_name + "-snap"
        snapshot_params = self.params.object_params("snapshot")
        base_dir = self.params.get("images_base_dir", data_dir.get_data_dir())

        image_io = QemuImg(snapshot_params, base_dir, image_name)
        image_name, _ = image_io.create(snapshot_params)
        return image_name
Example #11
0
 def _create_tmpfs_data_disk():
     """
     Create a tmpfs data disk
     """
     logging.info("Create tmpfs data disk")
     disk_name_key = params["disk_name_key"]
     tmp_dir = data_dir.get_tmp_dir()
     tmpfs_dir = os.path.join(tmp_dir, "tmpfs")
     if not os.path.isdir(tmpfs_dir):
         os.makedirs(tmpfs_dir)
     params[disk_name_key] = os.path.join(tmpfs_dir, "data")
     tmpfs_image_name = params["tmpfs_image_name"]
     img_param = params.object_params(tmpfs_image_name)
     img = QemuImg(img_param, data_dir.get_data_dir(), tmpfs_image_name)
     img.create(img_param)
Example #12
0
def run(test, params, env):
    """
    qemu-img supports convert images with unaligned size.

    1. create source image via truncate, and  write 10k "1" into
       the source image via qemu-io
    2. convert the source image to target, check whether there is error

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _qemu_io(img, cmd):
        """Run qemu-io cmd to a given img."""
        logging.info("Run qemu-io %s", img.image_filename)
        try:
            QemuIOSystem(test, params, img.image_filename).cmd_output(cmd, 120)
        except process.CmdError:
            test.fail("qemu-io to '%s' failed." % img.image_filename)

    src_image = params["images"]
    tgt_image = params["convert_target"]
    img_dir = data_dir.get_data_dir()

    source = QemuImg(params.object_params(src_image), img_dir, src_image)
    with open(source.image_filename, mode='wb') as fd:
        fd.truncate(int(params["truncate_size"]))
    _qemu_io(source, 'write -P 1 0 %s' % params["write_size"])

    fail_on((process.CmdError, ))(source.convert)(source.params,
                                                  img_dir,
                                                  cache_mode="none",
                                                  source_cache_mode="none")

    params["images"] += " " + tgt_image
def run(test, params, env):
    """
    qemu-img map an unaligned image.

    1.create a raw file using truncate
    2.write data into the raw file
    3.verify the dumped mete-data using qemu-img map

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """
    def _generate_random_string(max_len=19):
        """Generate random alphabets string in the range of [1, max_len+1]."""
        random_str = ''.join(random.choice(
            string.ascii_lowercase) for _ in range(random.randint(1, max_len)))
        return random_str, len(random_str)

    def _verify_qemu_img_map(output, str_len):
        """Verify qemu-img map's output."""
        logging.info("Verify the dumped mete-data of the unaligned image.")
        expected = [{"start": 0, "length": str_len, "depth": 0,
                    "zero": False, "data": True, "offset": 0},
                    {"start": str_len, "length": 512 - (str_len % 512),
                     "depth": 0, "zero": True, "data": False,
                     "offset": str_len}]
        res = json.loads(output)
        if res != expected:
            test.fail("The dumped mete-data of the unaligned "
                      "image '%s' is not correct." % img.image_filename)

    img_param = params.object_params("test")
    img = QemuImg(img_param, data_dir.get_data_dir(), "test")

    logging.info("Create a new file %s using truncate." % img.image_filename)
    process.run("rm -f %s" % img.image_filename)
    process.run("truncate -s 1G %s " % img.image_filename)

    random_str, str_len = _generate_random_string()
    logging.info("Write '%s' into the file %s." % (random_str,
                                                   img.image_filename))
    process.run("echo -n '%s' > %s" % (random_str, img.image_filename),
                shell=True)
    res = img.map(output="json")
    if res.exit_status != 0:
        test.fail("qemu-img map error: %s." % res.stderr_text)
    _verify_qemu_img_map(res.stdout_text, str_len)
def run(test, params, env):
    """
    qemu-img supports 'discard' for raw block target images.

    1. Create source image via dd with all zero.
    2. Modprobe a 1G scsi_debug disk with writesame_16 mode.
    3. Trace the system calls while converting the zero image to the
       scsi_debug block device, then check whether 'fallocate' system call
       works in the log.
    :param test: Qemu test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def check_output(strace_event, strace_output, match_str):
        """Check whether the value is good in the output file."""
        logging.debug("Check the output file '%s'.", strace_output)
        with open(strace_output) as fd:
            if match_str not in fd.read():
                test.fail("The system call of '%s' is not right, "
                          "check '%s' for more details." %
                          (strace_event, strace_output))

    src_image = params["images"]
    root_dir = data_dir.get_data_dir()
    source = QemuImg(params.object_params(src_image), root_dir, src_image)
    strace_event = params["strace_event"]
    strace_events = strace_event.split()
    strace_output_file = os.path.join(test.debugdir, "convert_to_block.log")

    source.create(source.params)
    # Generate the target scsi block file.
    tgt_disk = process.system_output("lsscsi | grep '%s' | awk '{print $NF}'" %
                                     params["scsi_mod"],
                                     shell=True).decode()
    params["image_name_target"] = tgt_disk

    logging.debug(
        "Convert from %s to %s with cache mode none, strace log: %s.",
        source.image_filename, tgt_disk, strace_output_file)
    with strace(source, strace_events, strace_output_file, trace_child=True):
        fail_on((process.CmdError, ))(source.convert)(
            params.object_params(src_image), root_dir, cache_mode="none")

    check_output(strace_event, strace_output_file,
                 "FALLOC_FL_PUNCH_HOLE, 0, 1073741824")
Example #15
0
 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 get_node_name(image_tag):
     """ Get the node name. """
     img_params = params.object_params(image_tag)
     root_dir = data_dir.get_data_dir()
     img = QemuImg(img_params, root_dir, image_tag)
     filename = img.image_filename
     if img.image_format == 'luks':
         filename = get_image_json(image_tag, img_params, root_dir)
     return vm.get_block({"filename": filename})
Example #17
0
 def commit(self, t_params=None):
     """
     commit snapshot to backing file;
     """
     error_context.context("commit snapshot to backingfile", logging.info)
     params = self.params.object_params(self.tag)
     if t_params:
         params.update(t_params)
     cache_mode = params.get("cache_mode")
     return QemuImg.commit(self, params, cache_mode)
Example #18
0
def run(test, params, env):
    """
    Check the data after resizing short overlay over longer backing files.
    1. Create a qcow2 base image.
    2. Create a middle snapshot file with smaller size.
    3. Create a top snapshot with the size as the same as the one of base.
    4. Write '1' to the base image file.
    5. Check the data of the top image file.
    6. Commit top image file.
    7. Check the data in the middle image file.
    :param test: VT test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def _qemu_io(img, cmd):
        """Run qemu-io cmd to a given img."""
        logging.info("Run qemu-io %s" % img.image_filename)
        try:
            QemuIOSystem(test, params, img.image_filename).cmd_output(cmd, 120)
        except process.CmdError as err:
            test.fail("qemu-io to '%s' failed: %s." %
                      (img.image_filename, err))

    images = params["image_chain"].split()
    root_dir = data_dir.get_data_dir()
    base = QemuImg(params.object_params(images[0]), root_dir, images[0])
    mid = QemuImg(params.object_params(images[1]), root_dir, images[1])
    top = QemuImg(params.object_params(images[-1]), root_dir, images[-1])

    logging.info("Create base and snapshot files")
    for image in (base, mid, top):
        image.create(image.params)

    _qemu_io(base, params["base_cmd"])

    top_cmd = params["top_cmd"]
    _qemu_io(top, top_cmd)

    logging.info("Commit %s image file." % top.image_filename)
    fail_on((process.CmdError, ))(top.commit)()

    _qemu_io(mid, top_cmd)
Example #19
0
def run(test, params, env):
    """
    Creating a raw image with large size on different file systems.
    1. Create a raw image with large size on XFS and check the output info.
    2. Setup EXT4 filesystem.
    3. Create a raw image with large size on the EXT4 file system and
    check the output info.

    :param test: VT test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    large_img = params["images"]
    root_dir = data_dir.get_data_dir()
    loop_img = os.path.join(root_dir, "loop.img")
    loop_size = int(params["loop_file_size"])
    file_sys = params["file_sys"]
    err_info = params["err_info"].split(";")

    mnt_dir = os.path.join(root_dir, "tmp")
    large = QemuImg(params.object_params(large_img), mnt_dir, large_img)

    # Setup file system env
    part = p.Partition(loop_img, loop_size=loop_size, mountpoint=mnt_dir)
    part.mkfs(file_sys)
    part.mount()

    logging.info("Test creating an image with large size over %s.", file_sys)
    try:
        large.create(large.params)
    except TestError as err:
        for info in err_info:
            if info in six.text_type(err):
                break
        else:
            test.fail("CML failed with unexpected output: %s" % err)
    else:
        test.fail("There is no error when creating an image with large size.")
    finally:
        part.unmount()
        os.rmdir(mnt_dir)
        os.remove(loop_img)
Example #20
0
 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 run(test, params, env):
    """
    qemu-img supports to create a raw image file.
    1. Create test image, and  write 1M "1" into
       the test image via qemu-io.
    2. Check the image virtual and actual size info.
    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _qemu_io(img, cmd):
        """Run qemu-io cmd to a given img."""
        logging.info("Run qemu-io %s" % img.image_filename)
        try:
            QemuIOSystem(test, params, img.image_filename).cmd_output(cmd, 120)
        except process.CmdError as err:
            test.fail("qemu-io to '%s' failed: %s." %
                      (img.image_filename, err))

    def _check_img_size(img_info, defined_sizes, size_keys):
        """Check the size info of the image"""
        for defined_size, size_key in zip(defined_sizes, size_keys):
            logging.info("Check the '%s' size info of %s" %
                         (size_key, source.image_filename))
            defined_size = normalize_data_size(defined_size, "B")
            get_size = img_info[size_key]
            if int(defined_size) != int(get_size):
                test.fail("Got unexpected size '%s', expected size is '%s'" %
                          (get_size, defined_size))

    src_image = params["images"]
    img_dir = data_dir.get_data_dir()
    write_size = params["write_size"]

    source = QemuImg(params.object_params(src_image), img_dir, src_image)
    source.create(source.params)
    _qemu_io(source, 'write -P 1 0 %s' % write_size)

    src_info = json.loads(source.info(output="json"))
    _check_img_size(src_info, [write_size, params["image_size_test"]],
                    ["actual-size", "virtual-size"])
Example #22
0
def run(test, params, env):
    """
    qemu-img supports convert with copy-offloading.

    1. create source image, and  write "1" into
       the half of source image via qemu-io
    2. trace the system calls for qemu-img convert
       with copy-offloading and inspect whether
       there is copy_file_range
    3. compare the sourc and target images

    :param test: Qemu test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def _qemu_io(img, cmd):
        """Run qemu-io cmd to a given img."""
        logging.info("Run qemu-io %s", img.image_filename)
        QemuIOSystem(test, params, img.image_filename).cmd_output(cmd, 120)

    def _convert_with_copy_offloading_and_verify(src, tgt):
        """Verify whether copy_offloading works."""
        logging.info("Verify whether copy_offloading works for commit.")
        cmd = ("strace -e trace=copy_file_range -f qemu-img convert -C -f "
               "%s %s -O %s %s " % (src.image_format, src.image_filename,
                                    tgt.image_format, tgt.image_filename))
        sts, text = process.getstatusoutput(cmd, verbose=True)
        if sts != 0:
            test.fail("Convert with copy_offloading failed: %s." % text)

    src_image = params["src_image"]
    tgt_image = params["tgt_image"]
    img_dir = data_dir.get_data_dir()

    source = QemuImg(params.object_params(src_image), img_dir, src_image)
    source.create(source.params)
    _qemu_io(source, 'write -P 1 0 %s' % params["write_size"])

    target = QemuImg(params.object_params(tgt_image), img_dir, tgt_image)
    _convert_with_copy_offloading_and_verify(source, target)
def run(test, params, env):
    """
    Convert a image to a virtual block device.
    1. Create source and middle images.
    2. Setup loop device with the middle image.
    3. Convert the source image to the loop device.
    :param test: Qemu test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def setup_loop_dev(image_path):
        """
        Setup a loop device with a file image.
        :param image_path: The path to the image used to setup loop device
        :return: The loop device under /dev
        """
        cmd_result = process.run("losetup -f %s --show" % image_path)
        return cmd_result.stdout_text.strip()

    def free_loop_dev(loop_dev):
        """
        Free a loop device.
        :param loop_dev: The loop device will be free
        """
        process.run("losetup -d %s" % loop_dev)

    src_img = params["images"].split()[0]
    mid_img = params["images"].split()[-1]
    root_dir = data_dir.get_data_dir()
    source = QemuImg(params.object_params(src_img), root_dir, src_img)
    middle = QemuImg(params.object_params(mid_img), root_dir, mid_img)
    mid_filename = middle.image_filename

    logging.info("Create the test image files.")
    source.create(source.params)
    middle.create(middle.params)

    logging.info("Setup target loop device via 'losetup'.")
    target = setup_loop_dev(mid_filename)
    params["image_name_target"] = target

    logging.debug("Convert from %s to %s with cache mode none.",
                  source.image_filename, mid_filename)
    try:
        fail_on((process.CmdError,))(source.convert)(
            params.object_params(src_img), root_dir, cache_mode="none")
    finally:
        logging.info("Clean the loop device.")
        free_loop_dev(target)
def run(test, params, env):
    """
    Creating image with large size.
    1. Create a qcow2 image with large size and check the output info.
    2. Create a qcow2 with a normal size.
    3. Increase a large size to the qcow2 image and check the output info.

    :param test: VT test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    large_img, small_img = params["images"].split()
    root_dir = data_dir.get_data_dir()
    large = QemuImg(params.object_params(large_img), root_dir, large_img)
    small = QemuImg(params.object_params(small_img), root_dir, small_img)
    large_filename = large.image_filename
    size_increases = params["size_changes"]
    create_err_info = params["create_err_info"]
    resize_err_info = params["resize_err_info"]

    logging.info("Test creating an image with large size.")
    try:
        large.create(large.params)
    except exceptions.TestError as err:
        if create_err_info not in str(err) or large_filename not in str(err):
            test.fail("CML failed with unexpected output: %s" % err)
    else:
        test.fail("There is no error when creating an image with large size.")

    logging.info("Test resizing an image with large size.")
    small.create(small.params)
    result = small.resize(size_increases)
    status, output = result.exit_status, result.stderr_text
    if status == 0:
        test.fail("There is no error when resizing an image with large size.")
    elif resize_err_info not in output:
        test.fail("CML failed with unexpected output: %s" % output)
Example #25
0
def run(test, params, env):
    """
    qemu-img uses larger output buffer for "none" cache mode.
    1. Create 100M source image with random data via 'dd'.
    2. Trace the system calls while converting the source image to the
       a qcow2 target image, and check the maxim result of pwrite/pwrite64
       should be 2M.
    :param test: Qemu test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    src_image = params["images"]
    tgt_image = params["convert_target"]
    root_dir = data_dir.get_data_dir()
    source = QemuImg(params.object_params(src_image), root_dir, src_image)
    strace_event = params["strace_event"]
    strace_events = strace_event.split()
    strace_output_file = os.path.join(test.debugdir, "convert_with_none.log")
    src_filename = source.image_filename
    process.run("dd if=/dev/urandom of=%s bs=1M count=100" % src_filename)
    logging.debug(
        "Convert from %s to %s with cache mode none, strace log: "
        "%s.", src_filename, tgt_image, strace_output_file)
    with strace(source, strace_events, strace_output_file, trace_child=True):
        fail_on((process.CmdError, ))(source.convert)(
            params.object_params(src_image), root_dir, cache_mode="none")

    logging.debug("Check whether the max size of %s syscall is 2M in %s.",
                  strace_event, strace_output_file)
    with open(strace_output_file) as fd:
        for line in fd.readlines():
            if int(line.split()[-1]) == 2097152:
                break
        else:
            test.fail("The max size of '%s' is not 2M, check '%s' please.",
                      strace_event, strace_output_file)

    params["images"] += " " + tgt_image
Example #26
0
def run(test, params, env):
    """
    Image creation locking should be properly released.
    1. Create raw image and close it after 0.5 sec.
    2. Check there is no lock error of the CML.
    :param test: Qemu test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    lock_test = params["images"]
    root_dir = data_dir.get_data_dir()
    test_image = QemuImg(params.object_params(lock_test), root_dir, lock_test)
    test_filename = test_image.image_filename
    lock_err_info = 'Failed to get "consistent read" lock'
    try:
        process.run("qemu-img create -f raw -o preallocation=full %s 1G & "
                    "sleep 0.5;qemu-io -c info -c close -r %s" %
                    (test_filename, test_filename),
                    shell=True)
    except process.CmdError as err:
        if lock_err_info in err.result.stderr.decode():
            test.fail("Image lock not released: %s" % err)
        else:
            test.error("Command line failed: %s" % err)
def run(test, params, env):
    """
    'qemu-img check' should report the end offset of the image.
    1. Create a test qcow2 image.
    2. Check there is image end offset and the value with both "humam"
        and "json" output.
    :param test: Qemu test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def _check_result(key, offset, output):
        """Check the keywords and the value from the output."""
        if key not in output or int(offset) != int(output[key]):
            test.fail("The keyword/value is no correct. Check please.")

    report = params["images"]
    root_dir = data_dir.get_data_dir()
    report = QemuImg(params.object_params(report), root_dir, report)
    offset = params["image_end_offset"]
    human_key = params["human_key"]
    json_key = params["json_key"]

    logging.info("Create the test image file.")
    report.create(report.params)

    # 'qemu-img check' the image and check the output info.
    check_result = report.check(report.params, root_dir,
                                output="human").stdout.decode()
    if not check_result:
        test.error("There is no output of check command, check please.")
    logging.debug("The check output with human output format: %s",
                  check_result)
    result_dict = dict(re.findall(r'(.+):\s(.+)', check_result))
    _check_result(human_key, offset, result_dict)

    check_result = report.check(report.params, root_dir,
                                output="json").stdout.decode()
    if not check_result:
        test.error("There is no output of check command, check please.")
    logging.debug("The check output with json output format: %s", check_result)
    _check_result(json_key, offset, json.loads(check_result))
Example #28
0
def run(test, params, env):
    """
    Run qcow2 performance tests:
    1. Create image with given parameters
    2. Write to the image to prepare a certain size image
    3. Do one operations to the image and measure the time
    4. Record the results

    :param test:   QEMU test object
    :param params: Dictionary with the test parameters
    :param env:    Dictionary with test environment.
    """
    image_chain = params.get("image_chain")
    test_image = int(params.get("test_image", "0"))
    interval_size = params.get("interval_szie", "64k")
    write_round = int(params.get("write_round", "16384"))
    op_type = params.get("op_type")
    new_base = params.get("new_base")
    writecmd = params.get("writecmd")
    iocmd = params.get("iocmd")
    opcmd = params.get("opcmd")
    io_options = params.get("io_options", "n")
    cache_mode = params.get("cache_mode")
    image_dir = data_dir.get_data_dir()

    if not re.match("\d+", interval_size[-1]):
        write_unit = interval_size[-1]
        interval_size = int(interval_size[:-1])
    else:
        interval_size = int(interval_size)
        write_unit = ""

    error.context("Init images for testing", logging.info)
    sn_list = []
    for img in re.split("\s+", image_chain.strip()):
        image_params = params.object_params(img)
        sn_tmp = QemuImg(image_params, image_dir, img)
        sn_tmp.create(image_params)
        sn_list.append((sn_tmp, image_params))

    # Write to the test image
    error.context("Prepare the image with write a certain size block",
                  logging.info)
    dropcache = 'echo 3 > /proc/sys/vm/drop_caches && sleep 5'
    snapshot_file = sn_list[test_image][0].image_filename

    if op_type != "writeoffset1":
        offset = 0
        writecmd0 = writecmd % (write_round, offset, interval_size, write_unit,
                                interval_size, write_unit)
        iocmd0 = iocmd % (writecmd0, io_options, snapshot_file)
        logging.info("writecmd-offset-0: %s", writecmd0)
        utils.run(dropcache)
        output = utils.run(iocmd0)
    else:
        offset = 1
        writecmd1 = writecmd % (write_round, offset, interval_size, write_unit,
                                interval_size, write_unit)
        iocmd1 = iocmd % (writecmd1, io_options, snapshot_file)
        logging.info("writecmd-offset-1: %s", writecmd1)
        utils.run(dropcache)
        output = utils.run(iocmd1)

    error.context("Do one operations to the image and measure the time",
                  logging.info)

    if op_type == "read":
        readcmd = opcmd % (io_options, snapshot_file)
        logging.info("read: %s", readcmd)
        utils.run(dropcache)
        output = utils.run(readcmd)
    elif op_type == "commit":
        commitcmd = opcmd % (cache_mode, snapshot_file)
        logging.info("commit: %s", commitcmd)
        utils.run(dropcache)
        output = utils.run(commitcmd)
    elif op_type == "rebase":
        new_base_img = QemuImg(params.object_params(new_base), image_dir,
                               new_base)
        new_base_img.create(params.object_params(new_base))
        rebasecmd = opcmd % (new_base_img.image_filename, cache_mode,
                             snapshot_file)
        logging.info("rebase: %s", rebasecmd)
        utils.run(dropcache)
        output = utils.run(rebasecmd)
    elif op_type == "convert":
        convertname = sn_list[test_image][0].image_filename + "_convert"
        convertcmd = opcmd % (snapshot_file, cache_mode, convertname)
        logging.info("convert: %s", convertcmd)
        utils.run(dropcache)
        output = utils.run(convertcmd)

    error.context("Result recording", logging.info)
    result_file = open(
        "%s/%s_%s_results" % (test.resultsdir, "qcow2perf", op_type), 'w')
    result_file.write("%s:%s\n" % (op_type, output))
    logging.info("%s takes %s" % (op_type, output))
    result_file.close()
Example #29
0
 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
Example #30
0
def run_qemu_io_blkdebug(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 perror by error number set in config file
    5. Compare the error message

    @param test:   kvm test object
    @param params: Dictionary with the test parameters
    @param env:    Dictionary with test environment.
    """
    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())
    re_std_msg = params["re_std_msg"]
    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")

    error.context("Create image", logging.info)
    image_io = QemuImg(params.object_params(image), test.bindir, 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("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)

        output = session.cmd_output(err_command, timeout=test_timeout)
        error.context("Get error message from command perror", logging.info)
        perror_cmd = "perror %s" % errn
        std_msg = utils.system_output(perror_cmd)
        std_msg = re.findall(re_std_msg, std_msg)
        if std_msg:
            std_msg = std_msg[0]
        else:
            std_msg = ""
            logging.warning("Can not find error message from perror")

        session.close()
        error.context("Compare the error message", logging.info)
        if std_msg:
            if std_msg in output:
                logging.info("Error message is correct in qemu-io")
            else:
                fail_log = "The error message is mismatch:"
                fail_log += "qemu-io reports: '%s'," % output
                fail_log += "perror reports: '%s'" % std_msg
                raise error.TestFail(fail_log)
        else:
            logging.warning("Can not find error message from perror."
                            " The output from qemu-io is %s" % output)
Example #31
0
def run(test, params, env):
    """
    change a removable media:
    1) Boot VM with QMP/human monitor enabled.
    2) Connect to QMP/human monitor server.
    3) Eject original cdrom.
    4) Eject original cdrom for second time.
    5) Insert new image to cdrom.
    6) Eject device after add new image by change command.
    7) Insert original cdrom to cdrom.
    8) Try to eject non-removable device w/o force option.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment
    """

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
    logging.info("Wait until device is ready")
    time.sleep(10)

    def check_block(block):
        return True if block in str(vm.monitor.info("block")) else False

    orig_img_name = params.get("cdrom_cd1")
    p_dict = {"file": orig_img_name}
    device_name = vm.get_block(p_dict)
    if device_name is None:
        msg = "Fail to get device using image %s" % orig_img_name
        test.fail(msg)

    eject_check = QMPEventCheckCDEject(vm, device_name)
    change_check = QMPEventCheckCDChange(vm, device_name)

    # eject first time
    error_context.context("Eject original device.", logging.info)
    with eject_check:
        vm.eject_cdrom(device_name)
    if check_block(orig_img_name):
        test.fail("Fail to eject cdrom %s. " % orig_img_name)

    # eject second time
    error_context.context("Eject original device for second time",
                          logging.info)
    with eject_check:
        vm.eject_cdrom(device_name)

    # change media
    new_img_name = params.get("new_img_name")
    error_context.context("Insert new image to device.", logging.info)
    with change_check:
        vm.change_media(device_name, new_img_name)
    if not check_block(new_img_name):
        test.fail("Fail to change cdrom to %s." % new_img_name)

    # eject after change
    error_context.context("Eject device after add new image by change command",
                          logging.info)
    with eject_check:
        vm.eject_cdrom(device_name)
    if check_block(new_img_name):
        test.fail("Fail to eject cdrom %s." % orig_img_name)

    # change back to orig_img_name
    error_context.context(
        "Insert %s to device %s" % (orig_img_name, device_name), logging.info)
    with change_check:
        vm.change_media(device_name, orig_img_name)
    if not check_block(orig_img_name):
        test.fail("Fail to change cdrom to %s." % orig_img_name)

    # change again
    error_context.context(
        "Insert %s to device %s" % (new_img_name, device_name), logging.info)
    with change_check:
        vm.change_media(device_name, new_img_name)
    if not check_block(new_img_name):
        test.fail("Fail to change cdrom to %s." % new_img_name)

    # eject non-removable
    error_context.context("Try to eject non-removable device", logging.info)
    p_dict = {"removable": False}
    device_name = vm.get_block(p_dict)
    if vm.check_capability(Flags.BLOCKDEV):
        sys_image = QemuImg(params, data_dir.get_data_dir(),
                            params['images'].split()[0])
        device_name = vm.get_block({"filename": sys_image.image_filename})
    if device_name is None:
        test.error("Could not find non-removable device")
    try:
        if params.get("force_eject", "no") == "yes":
            vm.eject_cdrom(device_name, force=True)
        else:
            vm.eject_cdrom(device_name)
    except Exception as e:
        if "is not removable" not in str(e):
            test.fail(e)
        logging.debug("Catch exception message: %s" % e)
    if not check_block(device_name):
        test.fail("Could remove non-removable device!")

    session.close()
Example #32
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(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)
Example #33
0
 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)
Example #34
0
def run(test, params, env):
    """
    KVM block resize test:

    1) Start guest with data disk or system disk.
    2) Do format disk in guest if needed.
    3) Record md5 of test file on the data disk.
       Enlarge the data disk image from qemu monitor.
    4) Extend data disk partition/file-system in guest.
    5) Verify the data disk size match expected size.
    6) Reboot the guest.
    7) Do iozone test, compare the md5 of test file.
    8) Shrink data disk partition/file-system in guest.
    9) Shrink data disk image from qemu monitor.
    10) Verify the data disk size match expected size.
    11) Reboot the guest.
    12) Do iozone test, compare the md5 of test file.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def verify_disk_size(session, os_type, disk):
        """
        Verify the current block size match with the expected size.
        """
        global current_size
        current_size = utils_disk.get_disk_size(session, os_type, disk)
        accept_ratio = float(params.get("accept_ratio", 0))
        if (current_size <= block_size
                and current_size >= block_size * (1 - accept_ratio)):
            logging.info(
                "Block Resizing Finished !!! \n"
                "Current size %s is same as the expected %s", current_size,
                block_size)
            return True

    def create_md5_file(filename):
        """
        Create the file to verify md5 value.
        """
        logging.debug("create md5 file %s" % filename)
        if os_type == 'windows':
            vm.copy_files_to(params["tmp_md5_file"], filename)
        else:
            session.cmd(params["dd_cmd"] % filename)

    def get_md5_of_file(filename):
        """
        Get the md5 value of filename.
        """
        ex_args = (mpoint, filename) if os_type == 'windows' else filename
        return session.cmd(md5_cmd % ex_args).split()[0]

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    driver_name = params.get("driver_name")
    os_type = params["os_type"]
    fstype = params.get("fstype")
    labeltype = params.get("labeltype", "msdos")
    img_size = params.get("image_size_stg", "10G")
    mpoint = params.get("disk_letter", "C")
    disk = params.get("disk_index", 0)
    md5_cmd = params.get("md5_cmd", "md5sum %s")
    md5_file = params.get("md5_file", "md5.dat")
    data_image = params.get("images").split()[-1]
    data_image_params = params.object_params(data_image)
    data_image_filename = storage.get_image_filename(data_image_params,
                                                     data_dir.get_data_dir())
    data_image_dev = vm.get_block({'file': data_image_filename})
    img = QemuImg(data_image_params, data_dir.get_data_dir(), data_image)
    block_virtual_size = json.loads(img.info(force_share=True,
                                             output="json"))["virtual-size"]

    session = vm.wait_for_login(timeout=timeout)

    if os_type == 'windows' and driver_name:
        session = utils_test.qemu.windrv_check_running_verifier(
            session, vm, test, driver_name, timeout)

    if params.get("format_disk") == "yes":
        if os_type == 'linux':
            disk = sorted(utils_disk.get_linux_disks(session).keys())[0]
        else:
            disk = utils_disk.get_windows_disks_index(session, img_size)[0]
            utils_disk.update_windows_disk_attributes(session, disk)
        error_context.context("Formatting disk", logging.info)
        mpoint = utils_disk.configure_empty_disk(session,
                                                 disk,
                                                 img_size,
                                                 os_type,
                                                 fstype=fstype,
                                                 labeltype=labeltype)[0]
        partition = mpoint.replace('mnt', 'dev') if 'mnt' in mpoint else None

    for ratio in params.objects("disk_change_ratio"):
        block_size = int(int(block_virtual_size) * float(ratio))

        # Record md5
        if params.get('md5_test') == 'yes':
            junction = ":\\" if os_type == 'windows' else "/"
            md5_filename = mpoint + junction + md5_file
            create_md5_file(md5_filename)
            md5 = get_md5_of_file(md5_filename)
            logging.debug("Got md5 %s ratio:%s on %s" % (md5, ratio, disk))

        # We need shrink the disk in guest first, than in monitor
        if float(ratio) < 1.0:
            error_context.context(
                "Shrink disk size to %s in guest" % block_size, logging.info)
            if os_type == 'windows':
                shr_size = utils_numeric.normalize_data_size(
                    str(
                        utils_disk.get_disk_size(session, os_type, disk) -
                        block_size), 'M').split(".")[0]
                drive.shrink_volume(session, mpoint, shr_size)
            else:
                utils_disk.resize_filesystem_linux(session, partition,
                                                   str(block_size))
                utils_disk.resize_partition_linux(session, partition,
                                                  str(block_size))

        error_context.context("Change disk size to %s in monitor" % block_size,
                              logging.info)
        if vm.check_capability(Flags.BLOCKDEV):
            args = (None, block_size, data_image_dev)
        else:
            args = (data_image_dev, block_size)
        vm.monitor.block_resize(*args)

        if params.get("guest_prepare_cmd", ""):
            session.cmd(params.get("guest_prepare_cmd"))
        # Update GPT due to size changed
        if os_type == "linux" and labeltype == "gpt":
            session.cmd("sgdisk -e /dev/%s" % disk)
        if params.get("need_reboot") == "yes":
            session = vm.reboot(session=session)
        if params.get("need_rescan") == "yes":
            drive.rescan_disks(session)

        # We need extend disk in monitor first than extend it in guest
        if float(ratio) > 1.0:
            error_context.context("Extend disk to %s in guest" % block_size,
                                  logging.info)
            if os_type == 'windows':
                drive.extend_volume(session, mpoint)
            else:
                utils_disk.resize_partition_linux(session, partition,
                                                  str(block_size))
                utils_disk.resize_filesystem_linux(session, partition,
                                                   utils_disk.SIZE_AVAILABLE)
        global current_size
        current_size = 0
        if not wait.wait_for(lambda: verify_disk_size(session, os_type, disk),
                             20, 0, 1, "Block Resizing"):
            test.fail("Block size get from guest is not same as expected.\n"
                      "Reported: %s\nExpect: %s\n" %
                      (current_size, block_size))
        session = vm.reboot(session=session)

        if os_type == 'linux':
            if not utils_disk.is_mount(
                    partition, dst=mpoint, fstype=fstype, session=session):
                utils_disk.mount(partition,
                                 mpoint,
                                 fstype=fstype,
                                 session=session)

        if params.get('iozone_test') == 'yes':
            iozone_timeout = float(params.get("iozone_timeout", 1800))
            iozone_cmd_options = params.get("iozone_option") % mpoint
            io_test = generate_instance(params, vm, 'iozone')
            try:
                io_test.run(iozone_cmd_options, iozone_timeout)
            finally:
                io_test.clean()

        # Verify md5
        if params.get('md5_test') == 'yes':
            new_md5 = get_md5_of_file(md5_filename)
            test.assertTrue(new_md5 == md5, "Unmatched md5: %s" % new_md5)

    session.close()
Example #35
0
def run(test, params, env):
    """
    Check the dump info of snapshot files over nbd.
    1. Create a base image with 4 clusters of 64k.
    3. Create a top snapshot based on the base image.
    4. Write data to the first/second/third cluster of the base image file.
    5. Write data to the second/third cluster of the top image.
    6. Export the snapshot image over NBD.
    7. Check the dump info of the snapshot over NBD.
    :param test: VT test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def _qemu_io(img, cmd):
        """Run qemu-io cmd to a given img."""
        try:
            QemuIOSystem(test, params, img.image_filename).cmd_output(cmd, 120)
        except process.CmdError as err:
            test.fail("qemu-io to '%s' failed: %s." %
                      (img.image_filename, str(err)))

    images = params["image_chain"].split()
    base_img = images[0]
    top_img = images[1]
    root_dir = data_dir.get_data_dir()
    base = QemuImg(params.object_params(base_img), root_dir, base_img)
    top = QemuImg(params.object_params(top_img), root_dir, top_img)

    # write data to the base image
    _qemu_io(base, params["base_io_cmd_01"])
    _qemu_io(base, params["base_io_cmd_02"])
    _qemu_io(base, params["base_io_cmd_03"])

    # write data to the top image
    _qemu_io(top, params["top_io_cmd_01"])
    _qemu_io(top, params["top_io_cmd_02"])

    # export the top image over nbd
    nbd_export = QemuNBDExportImage(params, top_img)
    nbd_export.export_image()

    nbd_image_tag = params['nbd_image_tag']
    nbd_image_params = params.object_params(nbd_image_tag)
    localhost = socket.gethostname()
    nbd_image_params['nbd_server'] = localhost if localhost else 'localhost'
    qemu_img = qemu_storage.QemuImg(nbd_image_params, None, nbd_image_tag)
    nbd_image = qemu_img.image_filename
    map_cmd = params["map_cmd"]
    check_msg = params["check_msg"]

    logging.info("Dump the info of '%s'", nbd_image)
    try:
        result = process.run(map_cmd + " " + nbd_image,
                             ignore_status=True,
                             shell=True)
        if result.exit_status != 0:
            test.fail('Failed to execute the map command, error message: %s' %
                      result.stderr.decode())
        elif check_msg not in result.stdout.decode().strip():
            test.fail("Message '%s' mismatched with '%s'" %
                      (check_msg, result.stdout.decode()))
    finally:
        nbd_export.stop_export()
Example #36
0
def run_qemu_io_blkdebug(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 perror by error number set in config file
    5. Compare the error message

    @param test:   kvm test object
    @param params: Dictionary with the test parameters
    @param env:    Dictionary with test environment.
    """
    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())
    re_std_msg = params["re_std_msg"]
    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")

    error.context("Create image", logging.info)
    image_io = QemuImg(params.object_params(image), test.bindir, 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("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)

        output = session.cmd_output(err_command, timeout=test_timeout)
        error.context("Get error message from command perror", logging.info)
        perror_cmd = "perror %s" % errn
        std_msg = utils.system_output(perror_cmd)
        std_msg = re.findall(re_std_msg, std_msg)
        if std_msg:
            std_msg = std_msg[0]
        else:
            std_msg = ""
            logging.warning("Can not find error message from perror")

        session.close()
        error.context("Compare the error message", logging.info)
        if std_msg:
            if std_msg in output:
                logging.info("Error message is correct in qemu-io")
            else:
                fail_log = "The error message is mismatch:"
                fail_log += "qemu-io reports: '%s'," % output
                fail_log += "perror reports: '%s'" % std_msg
                raise error.TestFail(fail_log)
        else:
            logging.warning("Can not find error message from perror."
                            " The output from qemu-io is %s" % output)
Example #37
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)
Example #38
0
def run(test, params, env):
    """
    Run qcow2 performance tests:
    1. Create image with given parameters
    2. Write to the image to prepare a certain size image
    3. Do one operations to the image and measure the time
    4. Record the results

    :param test:   QEMU test object
    :param params: Dictionary with the test parameters
    :param env:    Dictionary with test environment.
    """
    image_chain = params.get("image_chain")
    test_image = int(params.get("test_image", "0"))
    interval_size = params.get("interval_szie", "64k")
    write_round = int(params.get("write_round", "16384"))
    op_type = params.get("op_type")
    new_base = params.get("new_base")
    writecmd = params.get("writecmd")
    iocmd = params.get("iocmd")
    opcmd = params.get("opcmd")
    io_options = params.get("io_options", "n")
    cache_mode = params.get("cache_mode")
    image_dir = data_dir.get_data_dir()

    if not re.match("\d+", interval_size[-1]):
        write_unit = interval_size[-1]
        interval_size = int(interval_size[:-1])
    else:
        interval_size = int(interval_size)
        write_unit = ""

    error.context("Init images for testing", logging.info)
    sn_list = []
    for img in re.split("\s+", image_chain.strip()):
        image_params = params.object_params(img)
        sn_tmp = QemuImg(image_params, image_dir, img)
        sn_tmp.create(image_params)
        sn_list.append((sn_tmp, image_params))

    # Write to the test image
    error.context("Prepare the image with write a certain size block",
                  logging.info)
    dropcache = 'echo 3 > /proc/sys/vm/drop_caches && sleep 5'
    snapshot_file = sn_list[test_image][0].image_filename

    if op_type != "writeoffset1":
        offset = 0
        writecmd0 = writecmd % (write_round, offset, interval_size,
                                write_unit, interval_size, write_unit)
        iocmd0 = iocmd % (writecmd0, io_options, snapshot_file)
        logging.info("writecmd-offset-0: %s", writecmd0)
        utils.run(dropcache)
        output = utils.run(iocmd0)
    else:
        offset = 1
        writecmd1 = writecmd % (write_round, offset, interval_size,
                                write_unit, interval_size, write_unit)
        iocmd1 = iocmd % (writecmd1, io_options, snapshot_file)
        logging.info("writecmd-offset-1: %s", writecmd1)
        utils.run(dropcache)
        output = utils.run(iocmd1)

    error.context("Do one operations to the image and measure the time",
                  logging.info)

    if op_type == "read":
        readcmd = opcmd % (io_options, snapshot_file)
        logging.info("read: %s", readcmd)
        utils.run(dropcache)
        output = utils.run(readcmd)
    elif op_type == "commit":
        commitcmd = opcmd % (cache_mode, snapshot_file)
        logging.info("commit: %s", commitcmd)
        utils.run(dropcache)
        output = utils.run(commitcmd)
    elif op_type == "rebase":
        new_base_img = QemuImg(params.object_params(new_base), image_dir,
                               new_base)
        new_base_img.create(params.object_params(new_base))
        rebasecmd = opcmd % (new_base_img.image_filename,
                             cache_mode, snapshot_file)
        logging.info("rebase: %s", rebasecmd)
        utils.run(dropcache)
        output = utils.run(rebasecmd)
    elif op_type == "convert":
        convertname = sn_list[test_image][0].image_filename + "_convert"
        convertcmd = opcmd % (snapshot_file, cache_mode, convertname)
        logging.info("convert: %s", convertcmd)
        utils.run(dropcache)
        output = utils.run(convertcmd)

    error.context("Result recording", logging.info)
    result_file = open("%s/%s_%s_results" %
                       (test.resultsdir, "qcow2perf", op_type), 'w')
    result_file.write("%s:%s\n" % (op_type, output))
    logging.info("%s takes %s" % (op_type, output))
    result_file.close()
Example #39
0
        logging.info("Enable virt NFS SELinux boolean on target host.")
        seLinuxBool = SELinuxBoolean(params)
        seLinuxBool.setup()

        subdriver = utils_test.get_image_info(shared_storage)['format']
        extra_attach = ("--config --driver qemu --subdriver %s --cache %s"
                        % (subdriver, disk_cache))

        # Attach a scsi device for special testcases
        if attach_scsi_disk:
            shared_dir = os.path.dirname(shared_storage)
            # This is a workaround. It does not take effect to specify
            # this parameter in config file
            params["image_name"] = "scsi_test"
            scsi_qemuImg = QemuImg(params, shared_dir, '')
            scsi_disk, _ = scsi_qemuImg.create(params)
            s_attach = virsh.attach_disk(vm_name, scsi_disk, "sdb",
                                         extra_attach, debug=True)
            if s_attach.exit_status != 0:
                logging.error("Attach another scsi disk failed.")

        # Get vcpu and memory info of guest for numa related tests
        if enable_numa:
            numa_dict_list = []
            vmxml = vm_xml.VMXML.new_from_dumpxml(vm.name)
            vcpu = vmxml.vcpu
            max_mem = vmxml.max_mem
            max_mem_unit = vmxml.max_mem_unit
            if vcpu < 1:
                raise error.TestError("%s not having even 1 vcpu"