From: Amos Kong <akong@xxxxxxxxxx> 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@xxxxxxxxxx> Signed-off-by: Lucas Meneghel Rodrigues <lmr@xxxxxxxxxx> --- 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 --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: -- 1.7.6 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html