diff mbox

KVM-test: Add subtest cdrom v2

Message ID 1311317060-2296-1-git-send-email-lmr@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lucas Meneghel Rodrigues July 22, 2011, 6:44 a.m. UTC
From: Amos Kong <akong@redhat.com>

Test cdrom about mount/format/copy/md5sum, change iso file by
monitor command, create iso files by pre_command, clean temporary
file by post_command.

Changes from v1:
 * Used more current autotest API, that allowed for substantial
   simplification in the test code
 * Files are compared by MD5 sum instead of diff
 * Loops are made using range() rather than decrementing an
   intermediate variable
 * Removed pre/post commands, handling everything in test and
   making it possible to not hardcode cdrom paths. Now the test
   works with cdrom directories other than /tmp/kvm_autotest_root/isos
 * Test now works with a QMP monitor

Signed-off-by: Amos Kong <akong@redhat.com>
Signed-off-by: Lucas Meneghel Rodrigues <lmr@redhat.com>
---
 client/tests/kvm/tests/cdrom.py        |  190 ++++++++++++++++++++++++++++++++
 client/tests/kvm/tests_base.cfg.sample |    7 +
 2 files changed, 197 insertions(+), 0 deletions(-)
 create mode 100644 client/tests/kvm/tests/cdrom.py
diff mbox

Patch

diff --git a/client/tests/kvm/tests/cdrom.py b/client/tests/kvm/tests/cdrom.py
new file mode 100644
index 0000000..ebd3e8c
--- /dev/null
+++ b/client/tests/kvm/tests/cdrom.py
@@ -0,0 +1,190 @@ 
+import logging, re, time, os
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.bin import utils
+from autotest_lib.client.virt import virt_utils, aexpect, kvm_monitor
+
+
+@error.context_aware
+def run_cdrom(test, params, env):
+    """
+    KVM cdrom test:
+
+    1) Boot up a VM with one iso.
+    2) Check if VM identifies correctly the iso file.
+    3) Eject cdrom and change with another iso several times.
+    4) Try to format cdrom and check the return string.
+    5) Mount cdrom device.
+    6) Copy file from cdrom and compare files using diff.
+    7) Umount and mount several times.
+
+    @param test: kvm test object
+    @param params: Dictionary with the test parameters
+    @param env: Dictionary with test environment.
+    """
+    def master_cdroms(params):
+        error.context("creating test cdrom")
+        os.chdir(test.tmpdir)
+        cdrom_cd1 = params.get("cdrom_cd1")
+        cdrom_dir = os.path.dirname(cdrom_cd1)
+        utils.run("dd if=/dev/urandom of=orig bs=10M count=1")
+        utils.run("dd if=/dev/urandom of=new bs=10M count=1")
+        utils.run("mkisofs -o %s/orig.iso orig" % cdrom_dir)
+        utils.run("mkisofs -o %s/new.iso new" % cdrom_dir)
+        return "%s/new.iso" % cdrom_dir
+
+
+    def cleanup_cdroms(cdrom_dir):
+        error.context("cleaning up temp cdrom images")
+        os.remove("%s/orig.iso" % cdrom_dir)
+        os.remove("%s/new.iso" % cdrom_dir)
+
+
+    def get_cdrom_info():
+        blocks = vm.monitor.info("block")
+        (device, file) = (None, None)
+        if isinstance(blocks, str):
+            try:
+                device = re.findall("(ide\d+-cd\d+): .*", blocks)[0]
+            except IndexError:
+                device = None
+            try:
+                file = re.findall("ide\d+-cd\d+: .*file=(\S*) ", blocks)[0]
+            except IndexError:
+                file = None
+        else:
+            for block in blocks:
+                d = block['device']
+                try:
+                    device = re.findall("(ide\d+-cd\d+)", d)[0]
+                except IndexError:
+                    device = None
+                    continue
+                try:
+                    file = block['inserted']['file']
+                except KeyError:
+                    file = None
+                break
+        logging.debug("Device name: %s, ISO: %s" % (device, file))
+        return (device, file)
+
+
+    def check_cdrom_locked(cdrom):
+        blocks = vm.monitor.info("block")
+        if isinstance(blocks, str):
+            lock_str = "locked=1"
+            for block in blocks.splitlines():
+                if cdrom in block and lock_str in block:
+                    return True
+        else:
+            for block in blocks:
+                if ('inserted' in block.keys() and
+                    block['inserted']['file'] == cdrom):
+                    return block['locked']
+        return False
+
+
+    def eject_cdrom(device, monitor):
+        if isinstance(monitor, kvm_monitor.HumanMonitor):
+            monitor.cmd("eject %s" % device)
+        elif isinstance(monitor, kvm_monitor.QMPMonitor):
+            monitor.cmd("eject", args={'device': device})
+
+
+    def change_cdrom(device, target, monitor):
+        if isinstance(monitor, kvm_monitor.HumanMonitor):
+            monitor.cmd("change %s %s" % (device, target))
+        elif isinstance(monitor, kvm_monitor.QMPMonitor):
+            monitor.cmd("change", args={'device': device, 'target': target})
+
+
+    cdrom_new = master_cdroms(params)
+    cdrom_dir = os.path.dirname(cdrom_new)
+    vm = env.get_vm(params["main_vm"])
+    vm.create()
+
+    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
+    cdrom_orig = params.get("cdrom_cd1")
+    cdrom = cdrom_orig
+    output = session.get_command_output("ls /dev/cdrom*")
+    cdrom_dev_list = re.findall("/dev/cdrom-\w+|/dev/cdrom\d*", output)
+    logging.debug("cdrom_dev_list: %s" % cdrom_dev_list)
+
+    cdrom_dev = ""
+    test_cmd = "dd if=%s of=/dev/null bs=1 count=1"
+    for d in cdrom_dev_list:
+        try:
+            output = session.cmd(test_cmd % d)
+            cdrom_dev = d
+            break
+        except aexpect.ShellError:
+            logging.error(output)
+    if not cdrom_dev:
+        raise error.TestFail("Could not find a valid cdrom device")
+
+    error.context("Detecting the existence of a cdrom")
+    (device, file) = get_cdrom_info()
+    if file != cdrom:
+        raise error.TestError("Could not find a valid cdrom device")
+
+    session.get_command_output("umount %s" % cdrom_dev)
+    if not virt_utils.wait_for(lambda: not check_cdrom_locked(file), 300):
+        raise error.TestError("Device %s could not be unlocked" % device)
+
+    max_times = int(params.get("max_times", 100))
+    error.context("Eject the cdrom for %s times" % max_times)
+    for i in range(1, max_times):
+        eject_cdrom(device, vm.monitor)
+        (device, file) = get_cdrom_info()
+        if file is not None:
+            raise error.TestFail("Device %s was not ejected" % cdrom)
+
+        cdrom = cdrom_new
+        # On even attempts, try to change the cdrom
+        if i % 2 == 0:
+            cdrom = cdrom_orig
+        change_cdrom(device, cdrom, vm.monitor)
+        time.sleep(10)
+        (device, file) = get_cdrom_info()
+        if file != cdrom:
+            raise error.TestError("It wasn't possible to change cdrom %s" %
+                                  cdrom)
+
+    error.context("Check whether the cdrom is read-only")
+    try:
+        output = session.cmd("echo y | mkfs %s" % cdrom_dev)
+        raise error.TestFail("Attempt to format cdrom %s succeeded" % cdrom_dev)
+    except aexpect.ShellError:
+        pass
+
+    error.context("Mounting the cdrom under /mnt")
+    session.cmd("mount %s %s" % (cdrom_dev, "/mnt"), timeout=30)
+
+    filename = "new"
+
+    error.context("File copying test")
+    session.cmd("rm -f /tmp/%s" % filename)
+    session.cmd("cp -f /mnt/%s /tmp/" % filename)
+
+    error.context("Compare file on disk and on cdrom")
+    f1_hash = session.cmd("md5sum /mnt/%s" % filename).split()[0].strip()
+    f2_hash = session.cmd("md5sum /tmp/%s" % filename).split()[0].strip()
+    if f1_hash != f2_hash:
+        raise error.TestFail("On disk and on cdrom files are different, "
+                             "md5 mismatch")
+
+    error.context("Mount/Unmount cdrom for %s times" % max_times)
+    for i in range(1, max_times):
+        try:
+            session.cmd("umount %s" % cdrom_dev)
+            session.cmd("mount %s /mnt" % cdrom_dev)
+        except aexpect.ShellError:
+            logging.debug(session.cmd("cat /etc/mtab"))
+            raise
+
+    session.cmd("umount %s" % cdrom_dev)
+    (device, file) = get_cdrom_info()
+    if device is not None:
+        eject_cdrom(device, vm.monitor)
+
+    session.close()
+    cleanup_cdroms(cdrom_dir)
diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample
index 65880d8..e970141 100644
--- a/client/tests/kvm/tests_base.cfg.sample
+++ b/client/tests/kvm/tests_base.cfg.sample
@@ -1101,6 +1101,13 @@  variants:
         kill_vm_gracefully = no
     # Do not define test variants below shutdown
 
+    - cdrom_test: install setup image_copy unattended_install.cdrom
+        only Linux
+        start_vm = no
+        type = cdrom
+        cdrom_cd1 = orig.iso
+        max_times = 20
+
 
 # NICs
 variants: