From patchwork Thu Apr 15 07:00:20 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Meneghel Rodrigues X-Patchwork-Id: 92687 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o3F70fcx024591 for ; Thu, 15 Apr 2010 07:00:41 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752751Ab0DOHA3 (ORCPT ); Thu, 15 Apr 2010 03:00:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:27780 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752722Ab0DOHA1 (ORCPT ); Thu, 15 Apr 2010 03:00:27 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o3F70Phm024042 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 15 Apr 2010 03:00:25 -0400 Received: from localhost.localdomain (vpn-8-103.rdu.redhat.com [10.11.8.103]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o3F70MqW018859; Thu, 15 Apr 2010 03:00:23 -0400 From: Lucas Meneghel Rodrigues To: autotest@test.kernel.org Cc: kvm@vger.kernel.org, Lucas Meneghel Rodrigues Subject: [PATCH] KVM-test: Add a subtest 'qemu_img' v3 Date: Thu, 15 Apr 2010 04:00:20 -0300 Message-Id: <1271314820-3600-1-git-send-email-lmr@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 15 Apr 2010 07:00:41 +0000 (UTC) diff --git a/client/tests/kvm/tests/qemu_img.py b/client/tests/kvm/tests/qemu_img.py new file mode 100644 index 0000000..d3f7ff1 --- /dev/null +++ b/client/tests/kvm/tests/qemu_img.py @@ -0,0 +1,325 @@ +import re, os, logging, commands +from autotest_lib.client.common_lib import utils, error +import kvm_vm, kvm_utils + + +def run_qemu_img(test, params, env): + """ + 'qemu-img' functions test: + 1) Judge what subcommand is going to be tested + 2) Run subcommand test + + @param test: kvm test object + @param params: Dictionary with the test parameters + @param env: Dictionary with test environment. + """ + cmd = kvm_utils.get_path(test.bindir, params.get("qemu_img_binary")) + if not os.path.exists(cmd): + raise error.TestError("Binary of 'qemu-img' not found") + image_format = params.get("image_format") + image_size = params.get("image_size", "10G") + image_name = kvm_vm.get_image_filename(params, test.bindir) + + + def _check(cmd, img): + """ + Simple 'qemu-img check' function implementation. + + @param cmd: qemu-img base command. + @param img: image to be checked + """ + cmd += " check %s" % img + logging.info("Checking image '%s'...", img) + try: + output = utils.system_output(cmd) + except error.CmdError, e: + if "does not support checks" in str(e): + return (True, "") + else: + return (False, str(e)) + return (True, output) + + + def check_test(cmd): + """ + Subcommand 'qemu-img check' test. + + This tests will 'dd' to create a specified size file, and check it. + Then convert it to supported image_format in each loop and check again. + + @param cmd: qemu-img base command. + """ + test_image = kvm_utils.get_path(test.bindir, + params.get("image_name_dd")) + print "test_image = %s" % test_image + create_image_cmd = params.get("create_image_cmd") + create_image_cmd = create_image_cmd % test_image + print "create_image_cmd = %s" % create_image_cmd + utils.system(create_image_cmd) + s, o = _check(cmd, test_image) + if not s: + raise error.TestFail("Check image '%s' failed with error: %s" % + (test_image, o)) + for fmt in params.get("supported_image_formats").split(): + output_image = test_image + ".%s" % fmt + _convert(cmd, fmt, test_image, output_image) + s, o = _check(cmd, output_image) + if not s: + raise error.TestFail("Check image '%s' got error: %s" % + (output_image, o)) + os.remove(output_image) + os.remove(test_image) + + + def _create(cmd, img_name, fmt, img_size=None, base_img=None, + base_img_fmt=None, encrypted="no"): + """ + Simple wrapper of 'qemu-img create' + + @param cmd: qemu-img base command. + @param img_name: name of the image file + @param fmt: image format + @param img_size: image size + @param base_img: base image if create a snapshot image + @param base_img_fmt: base image format if create a snapshot image + @param encrypted: indicates whether the created image is encrypted + """ + cmd += " create" + if encrypted == "yes": + cmd += " -e" + if base_img: + cmd += " -b %s" % base_img + if base_img_fmt: + cmd += " -F %s" % base_img_fmt + cmd += " -f %s" % fmt + cmd += " %s" % img_name + if img_size: + cmd += " %s" % img_size + utils.system(cmd) + + + def create_test(cmd): + """ + Subcommand 'qemu-img create' test. + + @param cmd: qemu-img base command. + """ + image_large = params.get("image_name_large") + img = kvm_utils.get_path(test.bindir, image_large) + img += '.' + image_format + _create(cmd, img_name=img, fmt=image_format, + img_size=params.get("image_size_large")) + os.remove(img) + + + def _convert(cmd, output_fmt, img_name, output_filename, + fmt=None, compressed="no", encrypted="no"): + """ + Simple wrapper of 'qemu-img convert' function. + + @param cmd: qemu-img base command. + @param output_fmt: the output format of converted image + @param img_name: image name that to be converted + @param output_filename: output image name that converted + @param fmt: output image format + @param compressed: whether output image is compressed + @param encrypted: whether output image is encrypted + """ + cmd += " convert" + if compressed == "yes": + cmd += " -c" + if encrypted == "yes": + cmd += " -e" + if fmt: + cmd += " -f %s" % fmt + cmd += " -O %s" % output_fmt + cmd += " %s %s" % (img_name, output_filename) + logging.info("Converting '%s' from format '%s' to '%s'", img_name, fmt, + output_fmt) + utils.system(cmd) + + + def convert_test(cmd): + """ + Subcommand 'qemu-img convert' test. + + @param cmd: qemu-img base command. + """ + dest_img_fmt = params.get("dest_image_format") + output_filename = "%s.converted_%s" % (image_name, dest_img_fmt) + + _convert(cmd, dest_img_fmt, image_name, output_filename, + image_format, params.get("compressed"), params.get("encrypted")) + + if dest_img_fmt == "qcow2": + s, o = _check(cmd, output_filename) + if s: + os.remove(output_filename) + else: + raise error.TestFail("Check image '%s' failed with error: %s" % + (output_filename, o)) + else: + os.remove(output_filename) + + + def _info(cmd, img, string=None, fmt=None): + """ + Simple wrapper of 'qemu-img info'. + + @param cmd: qemu-img base command. + @param img: image file + @param string: sub info, say 'backing file' + @param fmt: image format + """ + cmd += " info" + if fmt: + cmd += " -f %s" % fmt + cmd += " %s" % img + + try: + output = utils.system_output(cmd) + except error.CmdError, e: + logging.error("Get info of image '%s' failed: %s", img, str(e)) + return None + + if not string: + return output + + string += ": (.*)" + matches = re.findall(string, output) + if matches: + return matches[0] + return None + + + def info_test(cmd): + """ + Subcommand 'qemu-img info' test. + + @param cmd: qemu-img base command. + """ + img_info = _info(cmd, image_name) + logging.info("Info of image '%s':\n%s", image_name, img_info) + if not image_format in img_info: + raise error.TestFail("Got unexpected format of image '%s'" + " in info test" % image_name) + if not image_size in img_info: + raise error.TestFail("Got unexpected size of image '%s'" + " in info test" % image_name) + + + def snapshot_test(cmd): + """ + Subcommand 'qemu-img snapshot' test. + + @param cmd: qemu-img base command. + """ + cmd += " snapshot" + for i in range(2): + crtcmd = cmd + sn_name = "snapshot%d" % i + crtcmd += " -c %s %s" % (sn_name, image_name) + s, o = commands.getstatusoutput(crtcmd) + if s != 0: + raise error.TestFail("Create snapshot failed via command: %s;" + "Output is: %s" % (crtcmd, o)) + logging.info("Created snapshot '%s' in '%s'" % (sn_name,image_name)) + listcmd = cmd + listcmd += " -l %s" % image_name + s, o = commands.getstatusoutput(listcmd) + if not ("snapshot0" in o and "snapshot1" in o and s == 0): + raise error.TestFail("Snapshot created failed or missed;" + "snapshot list is: \n%s" % o) + for i in range(2): + sn_name = "snapshot%d" % i + delcmd = cmd + delcmd += " -d %s %s" % (sn_name, image_name) + s, o = commands.getstatusoutput(delcmd) + if s != 0: + raise error.TestFail("Delete snapshot '%s' failed: %s" % + (sn_name, o)) + + + def commit_test(cmd): + """ + Subcommand 'qemu-img commit' test. + + @param cmd: qemu-img base command. + """ + pass + + + def _rebase(cmd, img_name, base_img, backing_fmt, mode="unsafe"): + """ + Simple wrapper of 'qemu-img rebase'. + + @param cmd: qemu-img base command. + @param img_name: image name to be rebased + @param base_img: indicates the base image + @param backing_fmt: the format of base image + @param mode: rebase mode: safe mode, unsafe mode + """ + cmd += " rebase" + if mode == "unsafe": + cmd += " -u" + cmd += " -b %s -F %s %s" % (base_img, backing_fmt, img_name) + logging.info("Trying to rebase '%s' to '%s'..." % (img_name, base_img)) + s, o = commands.getstatusoutput(cmd) + if s != 0: + raise error.TestError("Failed to rebase '%s' to '%s': %s" % + (img_name, base_img, o)) + + + def rebase_test(cmd): + """ + Subcommand 'qemu-img rebase' test + + Change the backing file of a snapshot image in "unsafe mode": + Assume the previous backing file had missed and we just have to change + reference of snapshot to new one. After change the backing file of a + snapshot image in unsafe mode, the snapshot should work still. + + @param cmd: qemu-img base command. + """ + if not 'rebase' in utils.system_output(cmd + ' --help', + ignore_status=True): + raise error.TestNAError("Current kvm user space version does not" + " support 'rebase' subcommand") + sn_fmt = params.get("snapshot_format", "qcow2") + sn1 = params.get("image_name_snapshot1") + sn1 = kvm_utils.get_path(test.bindir, sn1) + ".%s" % sn_fmt + base_img = kvm_vm.get_image_filename(params, test.bindir) + _create(cmd, sn1, sn_fmt, base_img=base_img, base_img_fmt=image_format) + + # Create snapshot2 based on snapshot1 + sn2 = params.get("image_name_snapshot2") + sn2 = kvm_utils.get_path(test.bindir, sn2) + ".%s" % sn_fmt + _create(cmd, sn2, sn_fmt, base_img=sn1, base_img_fmt=sn_fmt) + + rebase_mode = params.get("rebase_mode") + if rebase_mode == "unsafe": + os.remove(sn1) + + _rebase(cmd, sn2, base_img, image_format, mode=rebase_mode) + + # Check sn2's format and backing_file + actual_base_img = _info(cmd, sn2, "backing file") + base_img_name = os.path.basename(params.get("image_name")) + if not base_img_name in actual_base_img: + raise error.TestFail("After rebase the backing_file of 'sn2' is " + "'%s' which is not expected as '%s'" + % (actual_base_img, base_img_name)) + s, o = _check(cmd, sn2) + if not s: + raise error.TestFail("Check image '%s' failed after rebase;" + "got error: %s" % (sn2, o)) + try: + os.remove(sn2) + os.remove(sn1) + except: + pass + + + # Here starts test + subcommand = params.get("subcommand") + eval("%s_test(cmd)" % subcommand) diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample index b132506..019f5c7 100644 --- a/client/tests/kvm/tests_base.cfg.sample +++ b/client/tests/kvm/tests_base.cfg.sample @@ -291,6 +291,48 @@ variants: - ksm_parallel: ksm_mode = "parallel" + - qemu_img: + type = qemu_img + vms = '' + profilers = '' + take_regular_screendumps = no + variants: + - check: + subcommand = check + image_name_dd = dd_created_image + force_create_image_dd = no + remove_image_dd = yes + create_image_cmd = "dd if=/dev/zero of=%s bs=1G count=1" + # Test the convertion from 'dd_image_name' to specified format + supported_image_formats = qcow2 raw + - create: + subcommand = create + images += " large" + force_create_image_large = yes + image_size_large = 1G + image_name_large = create_large_image + remove_image_large = yes + - convert: + subcommand = convert + variants: + - to_qcow2: + dest_image_format = qcow2 + compressed = no + encrypted = no + - to_raw: + dest_image_format = raw + - snapshot: + subcommand = snapshot + - commit: + subcommand = commit + - info: + subcommand = info + - rebase: + subcommand = rebase + rebase_mode = unsafe + image_name_snapshot1 = sn1 + image_name_snapshot2 = sn2 + # system_powerdown, system_reset and shutdown *must* be the last ones # defined (in this order), since the effect of such tests can leave # the VM on a bad state.