This patch adds the check for tray status and fixes some bugs. Also it changes the VM handling. The VM restart is now necessarily only when the test fails. * tray-open status subtest * change vm handling * absolute paths of cdrom locations * workaround locked cdrom * workaround eject time Signed-off-by: Lukas Doktor <ldoktor@xxxxxxxxxx> --- client/tests/kvm/tests/cdrom.py | 128 +++++++++++++++++++++++++++++++-------- client/virt/subtests.cfg.sample | 5 +- 2 files changed, 106 insertions(+), 27 deletions(-) diff --git a/client/tests/kvm/tests/cdrom.py b/client/tests/kvm/tests/cdrom.py index ebd3e8c..941e81c 100644 --- a/client/tests/kvm/tests/cdrom.py +++ b/client/tests/kvm/tests/cdrom.py @@ -1,3 +1,10 @@ +""" +KVM cdrom test +@author: Amos Kong <akong@xxxxxxxxxx> +@author: Lucas Meneghel Rodrigues <lmr@xxxxxxxxxx> +@author: Lukas Doktor <ldoktor@xxxxxxxxxx> +@copyright: 2011 Red Hat, Inc. +""" import logging, re, time, os from autotest_lib.client.common_lib import error from autotest_lib.client.bin import utils @@ -11,21 +18,23 @@ def run_cdrom(test, params, env): 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. + 3) Eject cdrom using monitor and change with another iso several times. + 4) Eject cdrom in guest and check tray status reporting. + 5) Try to format cdrom and check the return string. + 6) Mount cdrom device. + 7) Copy file from cdrom and compare files using diff. + 8) 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): + """ Creates 'new' cdrom with one file on it """ error.context("creating test cdrom") os.chdir(test.tmpdir) cdrom_cd1 = params.get("cdrom_cd1") - cdrom_dir = os.path.dirname(cdrom_cd1) + cdrom_dir = os.path.realpath(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) @@ -34,41 +43,45 @@ def run_cdrom(test, params, env): def cleanup_cdroms(cdrom_dir): + """ Removes created cdrom """ 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(): + """ Gets device string and file from kvm-monitor """ blocks = vm.monitor.info("block") (device, file) = (None, None) if isinstance(blocks, str): try: - device = re.findall("(ide\d+-cd\d+): .*", blocks)[0] + device = re.findall("(\w+\d+-cd\d+): .*", blocks)[0] except IndexError: device = None try: - file = re.findall("ide\d+-cd\d+: .*file=(\S*) ", blocks)[0] + file = re.findall("\w+\d+-cd\d+: .*file=(\S*) ", blocks)[0] + file = os.path.realpath(file) except IndexError: file = None else: for block in blocks: d = block['device'] try: - device = re.findall("(ide\d+-cd\d+)", d)[0] + device = re.findall("(\w+\d+-cd\d+)", d)[0] except IndexError: device = None continue try: file = block['inserted']['file'] + file = os.path.realpath(file) except KeyError: file = None break - logging.debug("Device name: %s, ISO: %s" % (device, file)) + logging.debug("Device name: %s, ISO: %s", device, file) return (device, file) def check_cdrom_locked(cdrom): + """ Checks whether the cdrom is locked """ blocks = vm.monitor.info("block") if isinstance(blocks, str): lock_str = "locked=1" @@ -83,14 +96,37 @@ def run_cdrom(test, params, env): return False + def check_cdrom_tray(cdrom): + """ Checks whether the tray is opend """ + blocks = vm.monitor.info("block") + if isinstance(blocks, str): + for block in blocks.splitlines(): + if cdrom in block: + if "tray-open=1" in block: + return True + elif "tray-open=0" in block: + return False + else: + for block in blocks: + if block['device'] == cdrom and 'tray_open' in block.keys(): + return block['tray_open'] + raise error.TestNAError('cdrom tray reporting not supported') + + def eject_cdrom(device, monitor): + """ Ejects the cdrom using kvm-monitor """ if isinstance(monitor, kvm_monitor.HumanMonitor): monitor.cmd("eject %s" % device) elif isinstance(monitor, kvm_monitor.QMPMonitor): - monitor.cmd("eject", args={'device': device}) + try: + monitor.cmd("eject", args={'device': device}) + except kvm_monitor.QMPCmdError, details: + if workaround_locked_cdrom == 1: # no workaround, raise err + raise details def change_cdrom(device, target, monitor): + """ Changes the medium using kvm-monitor """ if isinstance(monitor, kvm_monitor.HumanMonitor): monitor.cmd("change %s %s" % (device, target)) elif isinstance(monitor, kvm_monitor.QMPMonitor): @@ -100,10 +136,19 @@ def run_cdrom(test, params, env): cdrom_new = master_cdroms(params) cdrom_dir = os.path.dirname(cdrom_new) vm = env.get_vm(params["main_vm"]) - vm.create() + if vm.is_dead() or vm.needs_restart(): + vm.create() + + # Some versions of qemu won't unlock CDROM + if params.get('workaround_locked_cdrom', 'no') == 'yes': + workaround_locked_cdrom = 20 + else: + workaround_locked_cdrom = 1 + # Some versions of qemu are unable to eject CDROM directly after insert + workaround_eject_time = float(params.get('workaround_eject_time', 0)) session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) - cdrom_orig = params.get("cdrom_cd1") + cdrom_orig = os.path.realpath(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) @@ -124,30 +169,45 @@ def run_cdrom(test, params, env): 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") + raise error.TestFail("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) + if workaround_locked_cdrom is not 1: + error.context("Trying to unlock the cdrom") + if not virt_utils.wait_for(lambda: not check_cdrom_locked(file), 300): + raise error.TestFail("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) + error.context("Eject the cdrom in monitor %s times" % max_times) for i in range(1, max_times): - eject_cdrom(device, vm.monitor) - (device, file) = get_cdrom_info() + for _ in range(workaround_locked_cdrom): + eject_cdrom(device, vm.monitor) + (device, file) = get_cdrom_info() + if file is None: + break + time.sleep(1) if file is not None: - raise error.TestFail("Device %s was not ejected" % cdrom) + raise error.TestFail("Device %s was not ejected (%s)" % (cdrom, i)) 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) + raise error.TestFail("It wasn't possible to change cdrom %s (%s)" + % (cdrom, i)) + + error.context('Eject the cdrom in guest %s times' % max_times) + for i in range(1, max_times): + session.cmd('eject %s' % cdrom_dev) + if not check_cdrom_tray(device): + raise error.TestFail("Monitor reports closed tray (%s)" % i) + session.cmd('dd if=%s of=/dev/null count=1' % cdrom_dev) + if check_cdrom_tray(device): + raise error.TestFail("Monitor reports opened tray (%s)" % i) + time.sleep(workaround_eject_time) error.context("Check whether the cdrom is read-only") try: @@ -182,9 +242,25 @@ def run_cdrom(test, params, env): raise session.cmd("umount %s" % cdrom_dev) + + error.context("Cleanup") + # Return the cdrom_orig (device, file) = get_cdrom_info() - if device is not None: - eject_cdrom(device, vm.monitor) + if file != cdrom_orig: + for _ in range(workaround_locked_cdrom): + eject_cdrom(device, vm.monitor) + (device, file) = get_cdrom_info() + if file is None: + break + time.sleep(1) + if file is not None: + raise error.TestFail("Device %s was not ejected (%s)" % (cdrom, i)) + + change_cdrom(device, cdrom_orig, vm.monitor) + (device, file) = get_cdrom_info() + if file != cdrom_orig: + raise error.TestFail("It wasn't possible to change cdrom %s (%s)" + % (cdrom, i)) session.close() cleanup_cdroms(cdrom_dir) diff --git a/client/virt/subtests.cfg.sample b/client/virt/subtests.cfg.sample index bcbb2b5..9a161a0 100644 --- a/client/virt/subtests.cfg.sample +++ b/client/virt/subtests.cfg.sample @@ -1631,10 +1631,13 @@ variants: - cdrom_test: install setup image_copy unattended_install.cdrom only Linux - start_vm = no type = cdrom cdrom_cd1 = orig.iso + start_vm = no + kill_vm_on_error = yes max_times = 20 + workaround_locked_cdrom = yes + workaround_eject_time = 2 - floppy_test: install setup image_copy unattended_install.cdrom only Linux -- 1.7.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