Beispiel #1
0
def run(test, params, env):
    """
    Test interface xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac=None):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        if mac:
            iface.mac_address = mac
        if iface_rom:
            iface.rom = eval(iface_rom)
        logging.debug("Create new interface xml: %s", iface)
        return iface

    def get_all_mac_in_vm():
        """
        get the mac address list of all the interfaces from a running vm os

        return: a list of the mac addresses
        """
        mac_list = []
        interface_list = vm.get_interfaces()
        for iface_ in interface_list:
            mac_ = vm.get_interface_mac(iface_)
            mac_list.append(mac_)
        return mac_list

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source", "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    iface_rom = params.get("iface_rom")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd", "no")
    start_vm = "yes" == params.get("start_vm", "yes")
    options_test = "yes" == params.get("options_test", "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))
    err_msgs1 = params.get("err_msgs1")
    err_msgs2 = params.get("err_msgs2")
    err_msg_rom = params.get("err_msg_rom")
    del_pci = "yes" == params.get("del_pci", "no")
    del_mac = "yes" == params.get("del_mac", "no")
    del_alias = "yes" == params.get("del_alias", "no")
    set_pci = "yes" == params.get("set_pci", "no")
    set_mac = "yes" == params.get("set_mac", "no")
    set_alias = "yes" == params.get("set_alias", "no")
    status_error = "yes" == params.get("status_error", "no")
    pci_addr = params.get("pci")
    check_mac = "yes" == params.get("check_mac", "no")
    vnet_mac = params.get("vnet_mac", None)
    customer_alias = "yes" == params.get("customer_alias", "no")
    detach_error = params.get("detach_error", None)

    libvirt_version.is_libvirt_feature_supported(params)
    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    sep_options = attach_option.split()
    logging.debug("sep_options: %s" % sep_options)
    for sep_option in sep_options:
        if attach_device and sep_option:
            check_cmds.append(('attach-device', sep_option))
        if attach_iface and sep_option:
            check_cmds.append(('attach-interface', sep_option))
        if (detach_device or stress_test_detach_device) and sep_option:
            check_cmds.append(('detach-device', sep_option))
        if stress_test_detach_interface and sep_option:
            check_cmds.append(('detach-device', sep_option))

    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if not start_vm:
                virsh.destroy(vm_name)
            for i in range(int(iface_num)):
                if attach_device:
                    logging.info("Try to attach device loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                        iface_xml_obj = create_iface_xml(mac)
                    elif check_mac:
                        iface_xml_obj = create_iface_xml()
                    else:
                        mac = utils_net.generate_mac_address_simple()
                        iface_xml_obj = create_iface_xml(mac)
                    if customer_alias:
                        random_id = process.run(
                            "uuidgen", ignore_status=True,
                            shell=True).stdout_text.strip()
                        alias_str = "ua-" + random_id
                        iface_xml_obj.alias = {"name": alias_str}
                        logging.debug("Update number %s interface xml: %s", i,
                                      iface_xml_obj)
                    iface_xml_obj.xmltreefile.write()
                    if check_mac:
                        mac_bef = get_all_mac_in_vm()
                    ret = virsh.attach_device(vm_name,
                                              iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True,
                                              debug=True)
                elif attach_iface:
                    logging.info("Try to attach interface loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name,
                                                 options,
                                                 ignore_status=True)
                if ret.exit_status:
                    if any([msg in ret.stderr for msg in err_msgs]):
                        logging.debug(
                            "No more pci slots, can't attach more devices")
                        break
                    elif ret.stderr.count("doesn't support option %s" %
                                          attach_option):
                        test.cancel(ret.stderr)
                    elif err_msgs1 in ret.stderr:
                        logging.debug(
                            "option %s is not supported when domain running is %s"
                            % (attach_option, vm.is_alive()))
                        if start_vm or ("--live" not in sep_options
                                        and attach_option):
                            test.fail(
                                "return not supported, but it is unexpected")
                    elif err_msgs2 in ret.stderr:
                        logging.debug("options %s are mutually exclusive" %
                                      attach_option)
                        if not ("--current" in sep_options
                                and len(sep_options) > 1):
                            test.fail(
                                "return mutualy exclusive, but it is unexpected"
                            )
                    elif err_msg_rom and err_msg_rom in ret.stderr:
                        logging.debug("Attach failed with expect err msg: %s" %
                                      err_msg_rom)
                    else:
                        test.fail("Failed to attach-interface: %s" %
                                  ret.stderr.strip())
                elif stress_test:
                    if attach_device:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name,
                                                  iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                    elif attach_iface:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                    libvirt.check_exit_status(ret)
                else:
                    if attach_device:
                        if check_mac:
                            mac_aft = get_all_mac_in_vm()
                            add_mac = list(
                                set(mac_aft).difference(set(mac_bef)))
                            try:
                                mac = add_mac[0]
                                logging.debug(
                                    "The mac address of the attached interface is %s"
                                    % mac)
                            except IndexError:
                                test.fail(
                                    "Can not find the new added interface in the guest os!"
                                )
                        iface_list.append({
                            'mac': mac,
                            'iface_xml': iface_xml_obj
                        })
                    elif attach_iface:
                        iface_list.append({'mac': mac})
            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                # After restart libvirtd, the old console was invalidated,
                # so we need create a new serial console
                vm.cleanup_serial_console()
                vm.create_serial_console()
            # in options test, check if the interface is attached
            # in current state when attach return true

            def check_iface_exist():
                try:
                    session = vm.wait_for_serial_login(username=username,
                                                       password=password)
                    if utils_net.get_linux_ifname(session, iface['mac']):
                        return True
                    else:
                        logging.debug("can not find interface in vm")
                except Exception:
                    return False

            if options_test:
                for iface in iface_list:
                    if 'mac' in iface:
                        # Check interface in dumpxml output
                        if_attr = vm_xml.VMXML.get_iface_by_mac(
                            vm_name, iface['mac'])
                        if vm.is_alive() and attach_option == "--config":
                            if if_attr:
                                test.fail("interface should not exists "
                                          "in current live vm while "
                                          "attached by --config")
                        else:
                            if if_attr:
                                logging.debug("interface %s found current "
                                              "state in xml" % if_attr['mac'])
                            else:
                                test.fail("no interface found in "
                                          "current state in xml")

                        if if_attr:
                            if if_attr['type'] != iface_type or \
                                    if_attr['source'] != \
                                    iface_source['network']:
                                test.fail("Interface attribute doesn't "
                                          "match attachment options")
                        # check interface in vm only when vm is active
                        if vm.is_alive():
                            logging.debug("check interface in current state "
                                          "in vm")

                            if not utils_misc.wait_for(check_iface_exist,
                                                       timeout=20):
                                if not attach_option == "--config":
                                    test.fail("Can't see interface "
                                              "in current state in vm")
                                else:
                                    logging.debug("find interface in "
                                                  "current state in vm")
                            else:
                                logging.debug("find interface in "
                                              "current state in vm")
                            # in options test, if the attach is performed
                            # when the vm is running
                            # need to destroy and start to check again
                            vm.destroy()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # check if interface is attached
            for iface in iface_list:
                if 'mac' in iface:
                    logging.debug("check interface in xml")
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(
                        vm_name, iface['mac'])
                    logging.debug(if_attr)
                    if if_attr:
                        logging.debug("interface {} is found in xml".format(
                            if_attr['mac']))
                        if (if_attr['type'] != iface_type or
                                if_attr['source'] != iface_source['network']):
                            test.fail("Interface attribute doesn't "
                                      "match attachment options")
                        if options_test and start_vm and attach_option \
                                in ("--current", "--live", ""):
                            test.fail("interface should not exists when "
                                      "restart vm in options_test")
                    else:
                        logging.debug("no interface found in xml")
                        if options_test and start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("interface not exists next state "
                                          "in xml with %s" % attach_option)
                        else:
                            test.fail("Can't see interface in dumpxml")

                    # Check interface on guest
                    if not utils_misc.wait_for(check_iface_exist, timeout=20):
                        logging.debug("can't see interface next state in vm")
                        if start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("it is expected")
                        else:
                            test.fail("should find interface "
                                      "but no seen in next state in vm")
                    if vnet_mac:
                        # get the name of the backend tap device
                        iface_params = vm_xml.VMXML.get_iface_by_mac(
                            vm_name, mac)
                        target_name = iface_params['target']['dev']
                        # check the tap device mac on host
                        tap_info = process.run("ip l show %s" % target_name,
                                               shell=True,
                                               ignore_status=True).stdout_text
                        logging.debug("vnet_mac should be %s" % vnet_mac)
                        logging.debug(
                            "check on host for the details of tap device %s: %s"
                            % (target_name, tap_info))
                        if vnet_mac not in tap_info:
                            test.fail(
                                "The mac address of the tap device do not match!"
                            )
            # Detach hot/cold-plugged interface at last
            if detach_device:
                logging.debug("detach interface here:")
                if attach_device:
                    vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
                    iface_xml_ls = vmxml.get_devices("interface")
                    iface_xml_ls_det = iface_xml_ls[1:]
                    for iface_xml_det in iface_xml_ls_det:
                        if del_mac:
                            iface_xml_det.del_mac_address()
                        if del_pci:
                            iface_xml_det.del_address()
                        if del_alias:
                            iface_xml_det.del_alias()
                        if set_mac:
                            mac = utils_net.generate_mac_address_simple()
                            iface_xml_det.set_mac_address(mac)
                        if set_pci:
                            pci_dict = ast.literal_eval(pci_addr)
                            addr = iface_xml_det.new_iface_address(
                                **{"attrs": pci_dict})
                            iface_xml_det.set_address(addr)
                        if set_alias:
                            random_id = process.run(
                                "uuidgen", ignore_status=True,
                                shell=True).stdout_text.strip()
                            alias_str = "ua-" + random_id
                            iface_xml_det.set_alias({"name": alias_str})
                        ori_pid_libvirtd = process.getoutput("pidof libvirtd")
                        logging.debug(
                            "The xml of the interface to detach is %s",
                            iface_xml_det)
                        ret = virsh.detach_device(vm_name,
                                                  iface_xml_det.xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret, status_error)
                        if detach_device and status_error and detach_error:
                            if not ret.stderr.count(detach_error):
                                test.error(
                                    "Detach fail as expected, but the error msg %s can not match!"
                                    % ret.stderr)
                        aft_pid_libvirtd = process.getoutput("pidof libvirtd")
                        if not utils_libvirtd.Libvirtd.is_running or ori_pid_libvirtd != aft_pid_libvirtd:
                            test.fail(
                                "Libvirtd crash after detach non-exists interface"
                            )
                else:
                    for iface in iface_list:
                        options = ("%s --mac %s" % (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                if not status_error:
                    for iface in iface_list:
                        if 'mac' in iface:
                            polltime = time.time() + poll_timeout
                            while True:
                                # Check interface in dumpxml output
                                if not vm_xml.VMXML.get_iface_by_mac(
                                        vm_name, iface['mac']):
                                    break
                                else:
                                    time.sleep(2)
                                    if time.time() > polltime:
                                        test.fail("Interface still "
                                                  "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            test.fail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
Beispiel #2
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        iface.mac_address = mac
        logging.debug("Create new interface xml: %s", iface)
        return iface

    status_error = "yes" == params.get("status_error", "no")

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source",
                                   "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd",
                                           "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))

    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    if not status_error:
        if attach_device and attach_option:
            check_cmds.append(('attach-device', attach_option))
        if attach_iface and attach_option:
            check_cmds.append(('attach-interface', attach_option))
        if (detach_device or stress_test_detach_device) and detach_option:
            check_cmds.append(('detach-device', detach_option))
        if stress_test_detach_interface and detach_option:
            check_cmds.append(('detach-device', detach_option))
    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if attach_device:
                for i in range(int(iface_num)):
                    logging.info("Try to attach interface loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    iface_xml_obj = create_iface_xml(mac)
                    iface_xml_obj.xmltreefile.write()
                    ret = virsh.attach_device(vm_name, iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True)
                    if ret.exit_status:
                        if any([msg in ret.stderr for msg in err_msgs]):
                            logging.debug("No more pci slots, can't"
                                          " attach more devices")
                            break
                        elif (ret.stderr.count("doesn't support option %s"
                                               % attach_option)):
                            raise error.TestNAError(ret.stderr)
                        elif status_error:
                            continue
                        else:
                            logging.error("Command output %s" %
                                          ret.stdout.strip())
                            raise error.TestFail("Failed to attach-device")
                    elif stress_test:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name, iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        iface_list.append({'mac': mac,
                                           'iface_xml': iface_xml_obj})
                # Need sleep here for attachment take effect
                time.sleep(5)
            elif attach_iface:
                for i in range(int(iface_num)):
                    logging.info("Try to attach interface loop %s" % i)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name, options,
                                                 ignore_status=True)
                    if ret.exit_status:
                        if any([msg in ret.stderr for msg in err_msgs]):
                            logging.debug("No more pci slots, can't"
                                          " attach more devices")
                            break
                        elif (ret.stderr.count("doesn't support option %s"
                                               % attach_option)):
                            raise error.TestNAError(ret.stderr)
                        elif status_error:
                            continue
                        else:
                            logging.error("Command output %s" %
                                          ret.stdout.strip())
                            raise error.TestFail("Failed to attach-interface")
                    elif stress_test:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        iface_list.append({'mac': mac})
                # Need sleep here for attachment take effect
                time.sleep(5)

            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                vm.cleanup_serial_console()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # Check if interface was attached
            for iface in iface_list:
                if iface.has_key('mac'):
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                            iface['mac'])
                    if not if_attr:
                        raise error.TestFail("Can't see interface "
                                             " in dumpxml")
                    if (if_attr['type'] != iface_type or
                            if_attr['source'] != iface_source['network']):
                        raise error.TestFail("Interface attribute doesn't"
                                             " match attachment opitons")
                    # Check interface on guest
                    if not utils_net.get_linux_ifname(session,
                                                      iface['mac']):
                        raise error.TestFail("Can't see interface"
                                             " on guest")

            # Detach hot/cold-plugged interface at last
            if detach_device:
                for iface in iface_list:
                    if iface.has_key('iface_xml'):
                        ret = virsh.detach_device(vm_name,
                                                  iface['iface_xml'].xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        options = ("%s --mac %s" %
                                   (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                for iface in iface_list:
                    if iface.has_key('mac'):
                        polltime = time.time() + poll_timeout
                        while True:
                            # Check interface in dumpxml output
                            if not vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                                 iface['mac']):
                                break
                            else:
                                time.sleep(2)
                                if time.time() > polltime:
                                    test.fail("Interface still "
                                              "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            raise error.TestFail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
Beispiel #3
0
def run(test, params, env):
    """
    Test command: virsh change-media.

    The command changes the media used by CD or floppy drives.

    Test steps:
    1. Prepare test environment.
    2. Perform virsh change-media operation.
    3. Recover test environment.
    4. Confirm the test result.
    """
    @error_context.context_aware
    def env_pre(old_iso, new_iso):
        """
        Prepare ISO image for test

        :param old_iso: sourse file for insert
        :param new_iso: sourse file for update
        """
        error_context.context("Preparing ISO images")
        process.run("dd if=/dev/urandom of=%s/old bs=1M count=1" % iso_dir,
                    shell=True)
        process.run("dd if=/dev/urandom of=%s/new bs=1M count=1" % iso_dir,
                    shell=True)
        process.run("mkisofs -o %s %s/old" % (old_iso, iso_dir), shell=True)
        process.run("mkisofs -o %s %s/new" % (new_iso, iso_dir), shell=True)

    @error_context.context_aware
    def check_media(session, target_file, action, rw_test=False):
        """
        Check guest cdrom/floppy files

        :param session: guest session
        :param target_file: the expected files
        :param action: test case action
        """
        if target_device == "hdc" or target_device == "sdc":
            drive_name = session.cmd(
                "cat /proc/sys/dev/cdrom/info | grep -i 'drive name'",
                ignore_all_errors=True).split()[2]
        if action != "--eject ":
            error_context.context("Checking guest %s files" % target_device)
            if target_device == "hdc" or target_device == "sdc":
                mount_cmd = "mount /dev/%s /media" % drive_name
            else:
                if session.cmd_status("ls /dev/fd0"):
                    session.cmd("mknod /dev/fd0 b 2 0")
                mount_cmd = "mount /dev/fd0 /media"
            session.cmd(mount_cmd)
            if rw_test:
                target_file = "/media/rw_test.txt"
                session.cmd("touch %s" % target_file)
                session.cmd("echo 'Hello World'> %s" % target_file)
                output = session.get_command_output("cat %s" % target_file)
                logging.debug("cat %s output: %s", target_file, output)
            else:
                session.cmd("test -f /media/%s" % target_file)
            session.cmd("umount /media")

        else:
            error_context.context("Ejecting guest cdrom files")
            if target_device == "hdc" or target_device == "sdc":
                if session.cmd_status("mount /dev/%s /media -o loop" %
                                      drive_name) == 32:
                    logging.info("Eject succeeded")
            else:
                if session.cmd_status("ls /dev/fd0"):
                    session.cmd("mknod /dev/fd0 b 2 0")
                if session.cmd_status("mount /dev/fd0 /media -o loop") == 32:
                    logging.info("Eject succeeded")

    def add_device(vm_name, init_source="''"):
        """
        Add device for test vm

        :param vm_name: guest name
        :param init_source: source file
        """
        if vm.is_alive():
            virsh.destroy(vm_name)

        device_target_bus = params.get("device_target_bus", "ide")
        virsh.attach_disk(
            vm_name,
            init_source,
            target_device,
            "--type %s --sourcetype file --targetbus %s --config" %
            (device_type, device_target_bus),
            debug=True)

    def update_device(vm_name, init_iso, options, start_vm):
        """
        Update device iso file for test case

        :param vm_name: guest name
        :param init_iso: source file
        :param options: update-device option
        :param start_vm: guest start flag
        """
        if 'disk_alias' not in locals() or disk_alias is None:
            disk_alias_update = ""
        else:
            disk_alias_update = disk_alias
        device_target_bus = params.get("device_target_bus", "ide")
        snippet = """
<disk type='file' device='%s'>
<driver name='qemu' type='raw'/>
<source file='%s'/>
<target dev='%s' bus='%s'/>
<readonly/>
<alias name='%s'/>
</disk>
""" % (device_type, init_iso, target_device, device_target_bus,
        disk_alias_update)
        logging.info("Update xml is %s", snippet)
        with open(update_iso_xml, "w") as update_iso_file:
            update_iso_file.write(snippet)

        cmd_options = "--force "
        if options == "--config" or start_vm == "no":
            cmd_options += " --config"

        # Give domain the ISO image file
        return virsh.update_device(domainarg=vm_name,
                                   filearg=update_iso_xml,
                                   flagstr=cmd_options,
                                   debug=True)

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vm_ref = params.get("change_media_vm_ref")
    action = params.get("change_media_action")
    start_vm = params.get("start_vm")
    options = params.get("change_media_options")
    device_type = params.get("change_media_device_type", "cdrom")
    target_device = params.get("change_media_target_device", "hdc")
    source_name = params.get("change_media_source")
    status_error = "yes" == params.get("status_error", "no")
    check_file = params.get("change_media_check_file")
    update_iso_xml_name = params.get("change_media_update_iso_xml")
    init_iso_name = params.get("change_media_init_iso")
    old_iso_name = params.get("change_media_old_iso")
    new_iso_name = params.get("change_media_new_iso")
    source_path = params.get("change_media_source_path", "yes")

    if device_type not in ['cdrom', 'floppy']:
        test.cancel("Got a invalid device type:/n%s" % device_type)

    try:
        utils_path.find_command("mkisofs")
    except utils_path.CmdNotFoundError:
        test.cancel("Command 'mkisofs' is missing. You must "
                    "install it (try 'genisoimage' package.")

    # Check virsh command option
    if options and not status_error:
        libvirt.virsh_cmd_has_option('change-media', options)

    # Backup for recovery.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    try:
        iso_dir = os.path.join(data_dir.get_tmp_dir(), "tmp")
        old_iso = os.path.join(iso_dir, old_iso_name)
        new_iso = os.path.join(iso_dir, new_iso_name)
        update_iso_xml = os.path.join(iso_dir, update_iso_xml_name)
        if not os.path.exists(iso_dir):
            os.mkdir(iso_dir)
        if not init_iso_name:
            init_iso = ""
        else:
            init_iso = os.path.join(iso_dir, init_iso_name)

        if vm_ref == "name":
            vm_ref = vm_name

        env_pre(old_iso, new_iso)
        # Check domain's disk device
        disk_blk = vm_xml.VMXML.get_disk_blk(vm_name)
        logging.info("disk_blk %s", disk_blk)
        if target_device not in disk_blk:
            logging.info("Adding device")
            add_device(vm_name)

        if vm.is_alive() and start_vm == "no":
            logging.info("Destroying guest...")
            vm.destroy()

        elif vm.is_dead() and start_vm == "yes":
            logging.info("Starting guest...")
            vm.start()

        disk_alias = libvirt.get_disk_alias(vm)
        logging.debug("disk_alias is %s", disk_alias)
        # If test target is floppy, you need to set selinux to Permissive mode.
        result = update_device(vm_name, init_iso, options, start_vm)

        # If the selinux is set to enforcing, if we FAIL, then just SKIP
        force_SKIP = False
        if result.exit_status == 1 and utils_misc.selinux_enforcing() and \
           result.stderr.count("unable to execute QEMU command 'change':"):
            force_SKIP = True

        # Libvirt will ignore --source when action is eject
        if action == "--eject ":
            source = ""
        else:
            source = os.path.join(iso_dir, source_name)
            if source_path == "no":
                source = source_name

        # For read&write floppy test, the iso media need a writeable fs
        rw_floppy_test = "yes" == params.get("rw_floppy_test", "no")
        if rw_floppy_test:
            process.run("mkfs.ext3 -F %s" % source, shell=True)

        all_options = action + options + " " + source
        result = virsh.change_media(vm_ref,
                                    target_device,
                                    all_options,
                                    ignore_status=True,
                                    debug=True)
        if status_error:
            if start_vm == "no" and vm.is_dead():
                try:
                    vm.start()
                except virt_vm.VMStartError as detail:
                    result.exit_status = 1
                    result.stderr = str(detail)
            if start_vm == "yes" and vm.is_alive():
                vm.destroy(gracefully=False)
                try:
                    vm.start()
                except virt_vm.VMStartError as detail:
                    result.exit_status = 1
                    result.stderr = str(detail)

        status = result.exit_status

        if not status_error:
            if 'print-xml' in options:
                vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name)
                if source in vmxml_new:
                    test.fail("Run command with 'print-xml'"
                              " option, unexpected device was"
                              " found in domain xml")
            else:
                if options == "--config" and vm.is_alive():
                    vm.destroy()
                if vm.is_dead():
                    vm.start()
                if 'block' in options and 'eject' not in action:
                    vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name)
                    logging.debug("vmxml: %s", vmxml_new)
                    if not vm_xml.VMXML.check_disk_type(
                            vm_name, source, "block"):
                        test.fail("Disk isn't a 'block' device")
                session = vm.wait_for_login()
                check_media(session, check_file, action, rw_floppy_test)
                session.close()
        # Negative testing
        if status_error:
            if status:
                logging.info("Expected error (negative testing). Output: %s",
                             result.stderr.strip())
            else:
                test.fail("Unexpected return code %d "
                          "(negative testing)" % status)

        # Positive testing
        else:
            if status:
                if force_SKIP:
                    test.cancel("SELinux is set to enforcing and has "
                                "resulted in this test failing to open "
                                "the iso file for a floppy.")
                test.fail("Unexpected error (positive testing). "
                          "Output: %s" % result.stderr.strip())
            else:
                logging.info("Expected success. Output: %s",
                             result.stdout.strip())
    finally:
        # Clean the iso dir  and clean the device
        update_device(vm_name, "", options, start_vm)
        vm.destroy(gracefully=False)
        # Recover xml of vm.
        vmxml_backup.sync()
        utils_misc.safe_rmdir(iso_dir)
Beispiel #4
0
def run(test, params, env):
    """
    Step 1: Get the virsh domiflist value.
    Step 2: Check for interface in xml file.
    Step 3: Check for type in xml file.
    Step 4: Check for model inside the guest and xml file.
    Step 5: Check for mac id inside the guest and xml file
    """

    def parse_interface_details(output):
        """
        To parse the interface details from virsh command output
        """
        iface_cmd = {}
        ifaces_cmd = []
        for line in output.split('\n'):
            match_obj = rg.search(line)
            # Due to the extra space in the list
            if match_obj is not None:
                iface_cmd['interface'] = match_obj.group(1)
                iface_cmd['type'] = match_obj.group(2)
                iface_cmd['source'] = match_obj.group(3)
                iface_cmd['model'] = match_obj.group(4)
                iface_cmd['mac'] = match_obj.group(5)
                ifaces_cmd.append(iface_cmd)
                iface_cmd = {}
        return ifaces_cmd

    def check_output(ifaces_actual, vm, login_nic_index=0):
        """
        1. Get the interface details of the command output
        2. Get the interface details from xml file
        3. Check command output against xml and guest output
        """
        vm_name = vm.name

        try:
            session = vm.wait_for_login(nic_index=login_nic_index)
        except Exception as detail:
            test.fail("Unable to login to VM:%s" % detail)
        iface_xml = {}
        error_count = 0
        # Check for the interface values
        for item in ifaces_actual:
            # Check for mac and model
            model = item['model']
            iname = utils_net.get_linux_ifname(session, item['mac'])
            if iname is not None:
                cmd = 'ethtool -i %s | grep driver | awk \'{print $2}\'' % iname
                drive = session.cmd_output(cmd).strip()
                if driver_dict[model] != drive:
                    error_count += 1
                    logging.error("Mismatch in the model for the interface %s\n"
                                  "Expected Model:%s\nActual Model:%s",
                                  item['interface'], driver_dict[model],
                                  item['model'])
            else:
                error_count += 1
                logging.error("Mismatch in the mac for the interface %s\n",
                              item['interface'])
            iface_xml = vm_xml.VMXML.get_iface_by_mac(vm_name, item['mac'])
            if iface_xml is not None:
                if iface_xml['type'] != item['type']:
                    error_count += 1
                    logging.error("Mismatch in the network type for the "
                                  "interface %s \n Type in command output: %s\n"
                                  "Type in xml file: %s",
                                  item['interface'],
                                  item['type'],
                                  iface_xml['type'])
                if iface_xml['source'] != item['source']:
                    error_count += 1
                    logging.error("Mismatch in the network source for the"
                                  " interface %s \n Source in command output:"
                                  "%s\nSource in xml file: %s",
                                  item['interface'],
                                  item['source'],
                                  iface_xml['source'])

            else:
                error_count += 1
                logging.error("There is no interface in the xml file "
                              "with the below specified mac address\n"
                              "Mac:%s", item['mac'])
            iface_xml = {}
        if error_count > 0:
            test.fail("The test failed, consult previous error logs")

    def add_iface(vm, at_option=""):
        """
        Attach interface for the vm
        """
        if vm.is_alive() and "--inactive" not in additional_options:
            vm.destroy(gracefully=False)
        iface_source = params.get("iface_source", "default")
        iface_type = params.get("iface_type", "network")
        iface_model = params.get("iface_model", "virtio")
        iface_mac = utils_net.generate_mac_address_simple()
        at_options = (" --type %s --source %s --model %s --mac %s --config %s"
                      % (iface_type, iface_source, iface_model,
                         iface_mac, at_option))
        ret = virsh.attach_interface(vm.name, at_options, ignore_status=True)
        libvirt.check_exit_status(ret)
        nic_params = {'mac': iface_mac, 'nettype': 'bridge'}
        vm.add_nic(**nic_params)
        if not vm.is_alive():
            vm.start()
        # Return the new attached interface index
        return vm.get_nic_index_by_mac(iface_mac)

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    domid = vm.get_id()
    domuuid = vm.get_uuid()
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    additional_options = params.get("domiflist_extra_options", "")
    vm_backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    login_nic_index = 0
    new_nic_index = 0
    status_error = "yes" == params.get("status_error", "no")

    # Check virsh command option
    if attach_iface and attach_option and not status_error:
        libvirt.virsh_cmd_has_option('attach-interface', attach_option)

    try:
        # Get the virsh domiflist
        options = params.get("domiflist_domname_options", "id")

        if options == "id":
            options = domid
        elif options == "uuid":
            options = domuuid
        elif options == "name":
            options = vm_name

        result = virsh.domiflist(vm_name, "", ignore_status=True)
        libvirt.check_exit_status(result)
        old_iflist = parse_interface_details(result.stdout.strip())
        logging.debug("Old interface list: %s", old_iflist)
        # Attach interface for testing.
        if attach_iface:
            new_nic_index = add_iface(vm, attach_option)
            # Basically, after VM started, the new attached interface will get
            # IP address, so we should use this interface to login
            if '--inactive' not in additional_options:
                if new_nic_index > 0:
                    login_nic_index = new_nic_index

        vm.verify_alive()
        result = virsh.domiflist(options, additional_options, ignore_status=True)
        new_iflist = parse_interface_details(result.stdout.strip())
        logging.debug("New interface list: %s", new_iflist)

        if status_error:
            if result.exit_status == 0:
                test.fail("Run passed for incorrect command \nCommand: "
                          "virsh domiflist %s\nOutput Status:%s\n"
                          % (options, result.exit_status))
        else:
            if 'print-xml' in attach_option:
                if len(old_iflist) != len(new_iflist):
                    test.fail("Interface attached with"
                              " '--print-xml' option")
            else:
                check_output(new_iflist, vm, login_nic_index)

    finally:
        # Delete the new attached interface
        if new_nic_index > 0:
            vm.del_nic(new_nic_index)
        # Destroy vm after test.
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vm_backup_xml.sync()
Beispiel #5
0
def run(test, params, env):
    """
    Step 1: Get the virsh domiflist value.
    Step 2: Check for interface in xml file.
    Step 3: Check for type in xml file.
    Step 4: Check for model inside the guest and xml file.
    Step 5: Check for mac id inside the guest and xml file
    """
    def parse_interface_details(output):
        """
        To parse the interface details from virsh command output
        """
        iface_cmd = {}
        ifaces_cmd = []
        for line in output.split('\n'):
            match_obj = rg.search(line)
            # Due to the extra space in the list
            if match_obj is not None:
                iface_cmd['interface'] = match_obj.group(1)
                iface_cmd['type'] = match_obj.group(2)
                iface_cmd['source'] = match_obj.group(3)
                iface_cmd['model'] = match_obj.group(4)
                iface_cmd['mac'] = match_obj.group(5)
                ifaces_cmd.append(iface_cmd)
                iface_cmd = {}
        return ifaces_cmd

    def check_output(ifaces_actual, vm, login_nic_index=0):
        """
        1. Get the interface details of the command output
        2. Get the interface details from xml file
        3. Check command output against xml and guest output
        """
        vm_name = vm.name

        try:
            session = vm.wait_for_login(nic_index=login_nic_index)
        except Exception as detail:
            test.fail("Unable to login to VM:%s" % detail)
        iface_xml = {}
        error_count = 0
        # Check for the interface values
        for item in ifaces_actual:
            # Check for mac and model
            model = item['model']
            iname = utils_net.get_linux_ifname(session, item['mac'])
            if iname is not None:
                cmd = 'ethtool -i %s | grep driver | awk \'{print $2}\'' % iname
                drive = session.cmd_output(cmd).strip()
                if driver_dict[model] != drive:
                    error_count += 1
                    logging.error(
                        "Mismatch in the model for the interface %s\n"
                        "Expected Model:%s\nActual Model:%s",
                        item['interface'], driver_dict[model], item['model'])
            else:
                error_count += 1
                logging.error("Mismatch in the mac for the interface %s\n",
                              item['interface'])
            iface_xml = vm_xml.VMXML.get_iface_by_mac(vm_name, item['mac'])
            if iface_xml is not None:
                if iface_xml['type'] != item['type']:
                    error_count += 1
                    logging.error(
                        "Mismatch in the network type for the "
                        "interface %s \n Type in command output: %s\n"
                        "Type in xml file: %s", item['interface'],
                        item['type'], iface_xml['type'])
                if iface_xml['source'] != item['source']:
                    error_count += 1
                    logging.error(
                        "Mismatch in the network source for the"
                        " interface %s \n Source in command output:"
                        "%s\nSource in xml file: %s", item['interface'],
                        item['source'], iface_xml['source'])

            else:
                error_count += 1
                logging.error(
                    "There is no interface in the xml file "
                    "with the below specified mac address\n"
                    "Mac:%s", item['mac'])
            iface_xml = {}
        if error_count > 0:
            test.fail("The test failed, consult previous error logs")

    def add_iface(vm, at_option=""):
        """
        Attach interface for the vm
        """
        if vm.is_alive() and "--inactive" not in additional_options:
            vm.destroy(gracefully=False)
        iface_source = params.get("iface_source", "default")
        iface_type = params.get("iface_type", "network")
        iface_model = params.get("iface_model", "virtio")
        iface_mac = utils_net.generate_mac_address_simple()
        at_options = (
            " --type %s --source %s --model %s --mac %s --config %s" %
            (iface_type, iface_source, iface_model, iface_mac, at_option))
        ret = virsh.attach_interface(vm.name, at_options, ignore_status=True)
        libvirt.check_exit_status(ret)
        nic_params = {'mac': iface_mac, 'nettype': 'bridge'}
        vm.add_nic(**nic_params)
        if not vm.is_alive():
            vm.start()
        # Return the new attached interface index
        return vm.get_nic_index_by_mac(iface_mac)

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    domid = vm.get_id()
    domuuid = vm.get_uuid()
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    additional_options = params.get("domiflist_extra_options", "")
    vm_backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    login_nic_index = 0
    new_nic_index = 0
    status_error = "yes" == params.get("status_error", "no")

    # Check virsh command option
    if attach_iface and attach_option and not status_error:
        libvirt.virsh_cmd_has_option('attach-interface', attach_option)

    try:
        # Get the virsh domiflist
        options = params.get("domiflist_domname_options", "id")

        if options == "id":
            options = domid
        elif options == "uuid":
            options = domuuid
        elif options == "name":
            options = vm_name

        result = virsh.domiflist(vm_name, "", ignore_status=True)
        libvirt.check_exit_status(result)
        old_iflist = parse_interface_details(result.stdout.strip())
        logging.debug("Old interface list: %s", old_iflist)
        # Attach interface for testing.
        if attach_iface:
            new_nic_index = add_iface(vm, attach_option)
            # Basically, after VM started, the new attached interface will get
            # IP address, so we should use this interface to login
            if '--inactive' not in additional_options:
                if new_nic_index > 0:
                    login_nic_index = new_nic_index

        vm.verify_alive()
        result = virsh.domiflist(options,
                                 additional_options,
                                 ignore_status=True)
        new_iflist = parse_interface_details(result.stdout.strip())
        logging.debug("New interface list: %s", new_iflist)

        if status_error:
            if result.exit_status == 0:
                test.fail("Run passed for incorrect command \nCommand: "
                          "virsh domiflist %s\nOutput Status:%s\n" %
                          (options, result.exit_status))
        else:
            if 'print-xml' in attach_option:
                if len(old_iflist) != len(new_iflist):
                    test.fail("Interface attached with"
                              " '--print-xml' option")
            else:
                check_output(new_iflist, vm, login_nic_index)

    finally:
        # Delete the new attached interface
        if new_nic_index > 0:
            vm.del_nic(new_nic_index)
        # Destroy vm after test.
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vm_backup_xml.sync()
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    domid = vm.get_id()
    domuuid = vm.get_uuid()
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    additional_options = params.get("domiflist_extra_options", "")
    vm_backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    login_nic_index = 0
    new_nic_index = 0
    status_error = "yes" == params.get("status_error", "no")

    # Check virsh command option
    if attach_iface and attach_option and not status_error:
        libvirt.virsh_cmd_has_option('attach-interface', attach_option)

    try:
        # Get the virsh domiflist
        options = params.get("domiflist_domname_options", "id")

        if options == "id":
            options = domid
        elif options == "uuid":
            options = domuuid
        elif options == "name":
            options = vm_name

        result = virsh.domiflist(vm_name, "", ignore_status=True)
        libvirt.check_exit_status(result)
        old_iflist = parse_interface_details(result.stdout)
Beispiel #7
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        iface.mac_address = mac
        if iface_rom:
            iface.rom = eval(iface_rom)
        logging.debug("Create new interface xml: %s", iface)
        return iface

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source",
                                   "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    iface_rom = params.get("iface_rom")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd",
                                           "no")
    start_vm = "yes" == params.get("start_vm", "yes")
    options_test = "yes" == params.get("options_test", "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))
    err_msgs1 = params.get("err_msgs1")
    err_msgs2 = params.get("err_msgs2")
    err_msg_rom = params.get("err_msg_rom")

    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    sep_options = attach_option.split()
    logging.debug("sep_options: %s" % sep_options)
    for sep_option in sep_options:
        if attach_device and sep_option:
            check_cmds.append(('attach-device', sep_option))
        if attach_iface and sep_option:
            check_cmds.append(('attach-interface', sep_option))
        if (detach_device or stress_test_detach_device) and sep_option:
            check_cmds.append(('detach-device', sep_option))
        if stress_test_detach_interface and sep_option:
            check_cmds.append(('detach-device', sep_option))

    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if not start_vm:
                virsh.destroy(vm_name)
            for i in range(int(iface_num)):
                if attach_device:
                    logging.info("Try to attach device loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    iface_xml_obj = create_iface_xml(mac)
                    iface_xml_obj.xmltreefile.write()
                    ret = virsh.attach_device(vm_name, iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True,
                                              debug=True)
                elif attach_iface:
                    logging.info("Try to attach interface loop %s" % i)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name, options,
                                                 ignore_status=True)
                if ret.exit_status:
                    if any([msg in ret.stderr for msg in err_msgs]):
                        logging.debug("No more pci slots, can't attach more devices")
                        break
                    elif (ret.stderr.count("doesn't support option %s" % attach_option)):
                        test.cancel(ret.stderr)
                    elif err_msgs1 in ret.stderr:
                        logging.debug("option %s is not supported when domain running is %s" % (attach_option, vm.is_alive()))
                        if start_vm or ("--live" not in sep_options and attach_option):
                            test.fail("return not supported, but it is unexpected")
                    elif err_msgs2 in ret.stderr:
                        logging.debug("options %s are mutually exclusive" % attach_option)
                        if not ("--current" in sep_options and len(sep_options) > 1):
                            test.fail("return mutualy exclusive, but it is unexpected")
                    elif err_msg_rom in ret.stderr:
                        logging.debug("Attach failed with expect err msg: %s" % err_msg_rom)
                    else:
                        test.fail("Failed to attach-interface: %s" % ret.stderr.strip())
                elif stress_test:
                    if attach_device:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name, iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                    elif attach_iface:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                    libvirt.check_exit_status(ret)
                else:
                    if attach_device:
                        iface_list.append({'mac': mac,
                                           'iface_xml': iface_xml_obj})
                    elif attach_iface:
                        iface_list.append({'mac': mac})
            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                # After restart libvirtd, the old console was invalidated,
                # so we need create a new serial console
                vm.cleanup_serial_console()
                vm.create_serial_console()
            # in options test, check if the interface is attached
            # in current state when attach return true

            def check_iface_exist():
                try:
                    session = vm.wait_for_serial_login(username=username,
                                                       password=password)
                    if utils_net.get_linux_ifname(session, iface['mac']):
                        return True
                    else:
                        logging.debug("can not find interface in vm")
                except Exception:
                    return False
            if options_test:
                for iface in iface_list:
                    if 'mac' in iface:
                        # Check interface in dumpxml output
                        if_attr = vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                                iface['mac'])
                        if vm.is_alive() and attach_option == "--config":
                            if if_attr:
                                test.fail("interface should not exists "
                                          "in current live vm while "
                                          "attached by --config")
                        else:
                            if if_attr:
                                logging.debug("interface %s found current "
                                              "state in xml" % if_attr['mac'])
                            else:
                                test.fail("no interface found in "
                                          "current state in xml")

                        if if_attr:
                            if if_attr['type'] != iface_type or \
                                    if_attr['source'] != \
                                    iface_source['network']:
                                test.fail("Interface attribute doesn't "
                                          "match attachment options")
                        # check interface in vm only when vm is active
                        if vm.is_alive():
                            logging.debug("check interface in current state "
                                          "in vm")

                            if not utils_misc.wait_for(check_iface_exist, timeout=20):
                                if not attach_option == "--config":
                                    test.fail("Can't see interface "
                                              "in current state in vm")
                                else:
                                    logging.debug("find interface in "
                                                  "current state in vm")
                            else:
                                logging.debug("find interface in "
                                              "current state in vm")
                            # in options test, if the attach is performed
                            # when the vm is running
                            # need to destroy and start to check again
                            vm.destroy()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # check if interface is attached
            for iface in iface_list:
                if 'mac' in iface:
                    logging.debug("check interface in xml")
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                            iface['mac'])
                    logging.debug(if_attr)
                    if if_attr:
                        logging.debug("interface {} is found in xml".
                                      format(if_attr['mac']))
                        if (if_attr['type'] != iface_type or
                                if_attr['source'] != iface_source['network']):
                            test.fail("Interface attribute doesn't "
                                      "match attachment options")
                        if options_test and start_vm and attach_option \
                                in ("--current", "--live", ""):
                            test.fail("interface should not exists when "
                                      "restart vm in options_test")
                    else:
                        logging.debug("no interface found in xml")
                        if options_test and start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("interface not exists next state "
                                          "in xml with %s" % attach_option)
                        else:
                            test.fail("Can't see interface in dumpxml")

                    # Check interface on guest
                    if not utils_misc.wait_for(check_iface_exist, timeout=20):
                        logging.debug("can't see interface next state in vm")
                        if start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("it is expected")
                        else:
                            test.fail("should find interface "
                                      "but no seen in next state in vm")

            # Detach hot/cold-plugged interface at last
            if detach_device:
                for iface in iface_list:
                    if 'iface_xml' in iface:
                        ret = virsh.detach_device(vm_name,
                                                  iface['iface_xml'].xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        options = ("%s --mac %s" %
                                   (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name, options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                for iface in iface_list:
                    if 'mac' in iface:
                        polltime = time.time() + poll_timeout
                        while True:
                            # Check interface in dumpxml output
                            if not vm_xml.VMXML.get_iface_by_mac(vm_name,
                                                                 iface['mac']):
                                break
                            else:
                                time.sleep(2)
                                if time.time() > polltime:
                                    test.fail("Interface still "
                                              "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            test.fail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
def run(test, params, env):
    """
    Test command: virsh change-media.

    The command changes the media used by CD or floppy drives.

    Test steps:
    1. Prepare test environment.
    2. Perform virsh change-media operation.
    3. Recover test environment.
    4. Confirm the test result.
    """
    @error_context.context_aware
    def env_pre(old_iso, new_iso):
        """
        Prepare ISO image for test

        :param old_iso: sourse file for insert
        :param new_iso: sourse file for update
        """
        error_context.context("Preparing ISO images")
        process.run("dd if=/dev/urandom of=%s/old bs=1M count=1" % iso_dir, shell=True)
        process.run("dd if=/dev/urandom of=%s/new bs=1M count=1" % iso_dir, shell=True)
        process.run("mkisofs -o %s %s/old" % (old_iso, iso_dir), shell=True)
        process.run("mkisofs -o %s %s/new" % (new_iso, iso_dir), shell=True)

    @error_context.context_aware
    def check_media(session, target_file, action, rw_test=False):
        """
        Check guest cdrom/floppy files

        :param session: guest session
        :param target_file: the expected files
        :param action: test case action
        """
        if target_device == "hdc" or target_device == "sdc":
            drive_name = session.cmd("cat /proc/sys/dev/cdrom/info | grep -i 'drive name'", ignore_all_errors=True).split()[2]
        if action != "--eject ":
            error_context.context("Checking guest %s files" % target_device)
            if target_device == "hdc" or target_device == "sdc":
                mount_cmd = "mount /dev/%s /media" % drive_name
            else:
                if session.cmd_status("ls /dev/fd0"):
                    session.cmd("mknod /dev/fd0 b 2 0")
                mount_cmd = "mount /dev/fd0 /media"
            session.cmd(mount_cmd)
            if rw_test:
                target_file = "/media/rw_test.txt"
                session.cmd("touch %s" % target_file)
                session.cmd("echo 'Hello World'> %s" % target_file)
                output = session.get_command_output("cat %s" % target_file)
                logging.debug("cat %s output: %s", target_file, output)
            else:
                session.cmd("test -f /media/%s" % target_file)
            session.cmd("umount /media")

        else:
            error_context.context("Ejecting guest cdrom files")
            if target_device == "hdc" or target_device == "sdc":
                if session.cmd_status("mount /dev/%s /media -o loop" % drive_name) == 32:
                    logging.info("Eject succeeded")
            else:
                if session.cmd_status("ls /dev/fd0"):
                    session.cmd("mknod /dev/fd0 b 2 0")
                if session.cmd_status("mount /dev/fd0 /media -o loop") == 32:
                    logging.info("Eject succeeded")

    def add_device(vm_name, init_source="''"):
        """
        Add device for test vm

        :param vm_name: guest name
        :param init_source: source file
        """
        if vm.is_alive():
            virsh.destroy(vm_name)

        device_target_bus = params.get("device_target_bus", "ide")
        virsh.attach_disk(vm_name, init_source,
                          target_device,
                          "--type %s --sourcetype file --targetbus %s --config" % (device_type, device_target_bus),
                          debug=True)

    def update_device(vm_name, init_iso, options, start_vm):
        """
        Update device iso file for test case

        :param vm_name: guest name
        :param init_iso: source file
        :param options: update-device option
        :param start_vm: guest start flag
        """
        if 'disk_alias' not in locals() or disk_alias is None:
            disk_alias_update = ""
        else:
            disk_alias_update = disk_alias
        device_target_bus = params.get("device_target_bus", "ide")
        snippet = """
<disk type='file' device='%s'>
<driver name='qemu' type='raw'/>
<source file='%s'/>
<target dev='%s' bus='%s'/>
<readonly/>
<alias name='%s'/>
</disk>
""" % (device_type, init_iso, target_device, device_target_bus, disk_alias_update)
        logging.info("Update xml is %s", snippet)
        with open(update_iso_xml, "w") as update_iso_file:
            update_iso_file.write(snippet)

        cmd_options = "--force "
        if options == "--config" or start_vm == "no":
            cmd_options += " --config"

        # Give domain the ISO image file
        return virsh.update_device(domainarg=vm_name,
                                   filearg=update_iso_xml, flagstr=cmd_options,
                                   debug=True)

    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    vm_ref = params.get("change_media_vm_ref")
    action = params.get("change_media_action")
    start_vm = params.get("start_vm")
    options = params.get("change_media_options")
    device_type = params.get("change_media_device_type", "cdrom")
    target_device = params.get("change_media_target_device", "hdc")
    source_name = params.get("change_media_source")
    status_error = "yes" == params.get("status_error", "no")
    check_file = params.get("change_media_check_file")
    update_iso_xml_name = params.get("change_media_update_iso_xml")
    init_iso_name = params.get("change_media_init_iso")
    old_iso_name = params.get("change_media_old_iso")
    new_iso_name = params.get("change_media_new_iso")
    source_path = params.get("change_media_source_path", "yes")

    if device_type not in ['cdrom', 'floppy']:
        test.cancel("Got a invalid device type:/n%s" % device_type)

    try:
        utils_path.find_command("mkisofs")
    except utils_path.CmdNotFoundError:
        test.cancel("Command 'mkisofs' is missing. You must "
                    "install it (try 'genisoimage' package.")

    # Check virsh command option
    if options and not status_error:
        libvirt.virsh_cmd_has_option('change-media', options)

    # Backup for recovery.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    try:
        iso_dir = os.path.join(data_dir.get_tmp_dir(), "tmp")
        old_iso = os.path.join(iso_dir, old_iso_name)
        new_iso = os.path.join(iso_dir, new_iso_name)
        update_iso_xml = os.path.join(iso_dir, update_iso_xml_name)
        if not os.path.exists(iso_dir):
            os.mkdir(iso_dir)
        if not init_iso_name:
            init_iso = ""
        else:
            init_iso = os.path.join(iso_dir, init_iso_name)

        if vm_ref == "name":
            vm_ref = vm_name

        env_pre(old_iso, new_iso)
        # Check domain's disk device
        disk_blk = vm_xml.VMXML.get_disk_blk(vm_name)
        logging.info("disk_blk %s", disk_blk)
        if target_device not in disk_blk:
            logging.info("Adding device")
            add_device(vm_name)

        if vm.is_alive() and start_vm == "no":
            logging.info("Destroying guest...")
            vm.destroy()

        elif vm.is_dead() and start_vm == "yes":
            logging.info("Starting guest...")
            vm.start()

        disk_alias = libvirt.get_disk_alias(vm)
        logging.debug("disk_alias is %s", disk_alias)
        # If test target is floppy, you need to set selinux to Permissive mode.
        result = update_device(vm_name, init_iso, options, start_vm)

        # If the selinux is set to enforcing, if we FAIL, then just SKIP
        force_SKIP = False
        if result.exit_status == 1 and utils_misc.selinux_enforcing() and \
           result.stderr.count("unable to execute QEMU command 'change':"):
            force_SKIP = True

        # Libvirt will ignore --source when action is eject
        if action == "--eject ":
            source = ""
        else:
            source = os.path.join(iso_dir, source_name)
            if source_path == "no":
                source = source_name

        # For read&write floppy test, the iso media need a writeable fs
        rw_floppy_test = "yes" == params.get("rw_floppy_test", "no")
        if rw_floppy_test:
            process.run("mkfs.ext3 -F %s" % source, shell=True)

        all_options = action + options + " " + source
        result = virsh.change_media(vm_ref, target_device,
                                    all_options, ignore_status=True, debug=True)
        if status_error:
            if start_vm == "no" and vm.is_dead():
                try:
                    vm.start()
                except virt_vm.VMStartError as detail:
                    result.exit_status = 1
                    result.stderr = str(detail)
            if start_vm == "yes" and vm.is_alive():
                vm.destroy(gracefully=False)
                try:
                    vm.start()
                except virt_vm.VMStartError as detail:
                    result.exit_status = 1
                    result.stderr = str(detail)

        status = result.exit_status

        if not status_error:
            if 'print-xml' in options:
                vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name)
                if source in vmxml_new:
                    test.fail("Run command with 'print-xml'"
                              " option, unexpected device was"
                              " found in domain xml")
            else:
                if options == "--config" and vm.is_alive():
                    vm.destroy()
                if vm.is_dead():
                    vm.start()
                if 'block' in options and 'eject' not in action:
                    vmxml_new = vm_xml.VMXML.new_from_dumpxml(vm_name)
                    logging.debug("vmxml: %s", vmxml_new)
                    if not vm_xml.VMXML.check_disk_type(vm_name, source, "block"):
                        test.fail("Disk isn't a 'block' device")
                session = vm.wait_for_login()
                check_media(session, check_file, action, rw_floppy_test)
                session.close()
        # Negative testing
        if status_error:
            if status:
                logging.info("Expected error (negative testing). Output: %s",
                             result.stderr.strip())
            else:
                test.fail("Unexpected return code %d "
                          "(negative testing)" % status)

        # Positive testing
        else:
            if status:
                if force_SKIP:
                    test.cancel("SELinux is set to enforcing and has "
                                "resulted in this test failing to open "
                                "the iso file for a floppy.")
                test.fail("Unexpected error (positive testing). "
                          "Output: %s" % result.stderr.strip())
            else:
                logging.info("Expected success. Output: %s", result.stdout.strip())
    finally:
        # Clean the iso dir  and clean the device
        update_device(vm_name, "", options, start_vm)
        vm.destroy(gracefully=False)
        # Recover xml of vm.
        vmxml_backup.sync()
        utils_misc.safe_rmdir(iso_dir)
Beispiel #9
0
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    domid = vm.get_id()
    domuuid = vm.get_uuid()
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    additional_options = params.get("domiflist_extra_options", "")
    vm_backup_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    login_nic_index = 0
    new_nic_index = 0
    status_error = "yes" == params.get("status_error", "no")

    # Check virsh command option
    if attach_iface and attach_option and not status_error:
        libvirt.virsh_cmd_has_option('attach-interface', attach_option)

    try:
        # Get the virsh domiflist
        options = params.get("domiflist_domname_options", "id")

        if options == "id":
            options = domid
        elif options == "uuid":
            options = domuuid
        elif options == "name":
            options = vm_name

        result = virsh.domiflist(vm_name, "", ignore_status=True)
        libvirt.check_exit_status(result)
        old_iflist = parse_interface_details(result.stdout)
Beispiel #10
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    if vm.is_alive():
        vm.wait_for_login()

    def create_iface_xml(mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        iface.source = iface_source
        iface.model = iface_model if iface_model else "virtio"
        if iface_target:
            iface.target = {'dev': iface_target}
        iface.mac_address = mac
        logging.debug("Create new interface xml: %s", iface)
        return iface

    # Interface specific attributes.
    iface_num = params.get("iface_num", '1')
    iface_type = params.get("iface_type", "network")
    iface_source = eval(params.get("iface_source", "{'network':'default'}"))
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_mac = params.get("iface_mac")
    attach_device = "yes" == params.get("attach_device", "no")
    attach_iface = "yes" == params.get("attach_iface", "no")
    attach_option = params.get("attach_option", "")
    detach_device = "yes" == params.get("detach_device")
    stress_test = "yes" == params.get("stress_test")
    restart_libvirtd = "yes" == params.get("restart_libvirtd", "no")
    start_vm = "yes" == params.get("start_vm", "yes")
    options_test = "yes" == params.get("options_test", "no")
    username = params.get("username")
    password = params.get("password")
    poll_timeout = int(params.get("poll_timeout", 10))
    err_msgs1 = params.get("err_msgs1")
    err_msgs2 = params.get("err_msgs2")

    # stree_test require detach operation
    stress_test_detach_device = False
    stress_test_detach_interface = False
    if stress_test:
        if attach_device:
            stress_test_detach_device = True
        if attach_iface:
            stress_test_detach_interface = True

    # The following detach-device step also using attach option
    detach_option = attach_option

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    #iface_mac = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    libvirtd = utils_libvirtd.Libvirtd()

    # Check virsh command option
    check_cmds = []
    sep_options = attach_option.split()
    logging.debug("sep_options: %s" % sep_options)
    for sep_option in sep_options:
        if attach_device and sep_option:
            check_cmds.append(('attach-device', sep_option))
        if attach_iface and sep_option:
            check_cmds.append(('attach-interface', sep_option))
        if (detach_device or stress_test_detach_device) and sep_option:
            check_cmds.append(('detach-device', sep_option))
        if stress_test_detach_interface and sep_option:
            check_cmds.append(('detach-device', sep_option))

    for cmd, option in check_cmds:
        libvirt.virsh_cmd_has_option(cmd, option)

    try:
        try:
            # Attach an interface when vm is running
            iface_list = []
            err_msgs = ("No more available PCI slots",
                        "No more available PCI addresses")
            if not start_vm:
                virsh.destroy(vm_name)
            for i in range(int(iface_num)):
                if attach_device:
                    logging.info("Try to attach device loop %s" % i)
                    if iface_mac:
                        mac = iface_mac
                    else:
                        mac = utils_net.generate_mac_address_simple()
                    iface_xml_obj = create_iface_xml(mac)
                    iface_xml_obj.xmltreefile.write()
                    ret = virsh.attach_device(vm_name,
                                              iface_xml_obj.xml,
                                              flagstr=attach_option,
                                              ignore_status=True)
                elif attach_iface:
                    logging.info("Try to attach interface loop %s" % i)
                    mac = utils_net.generate_mac_address_simple()
                    options = ("%s %s --model %s --mac %s %s" %
                               (iface_type, iface_source['network'],
                                iface_model, mac, attach_option))
                    ret = virsh.attach_interface(vm_name,
                                                 options,
                                                 ignore_status=True)
                if ret.exit_status:
                    if any([msg in ret.stderr for msg in err_msgs]):
                        logging.debug(
                            "No more pci slots, can't attach more devices")
                        break
                    elif (ret.stderr.count("doesn't support option %s" %
                                           attach_option)):
                        test.cancel(ret.stderr)
                    elif err_msgs1 in ret.stderr:
                        logging.debug(
                            "option %s is not supported when domain running is %s"
                            % (attach_option, vm.is_alive()))
                        if start_vm or ("--live" not in sep_options
                                        and attach_option):
                            test.fail(
                                "return not supported, but it is unexpected")
                    elif err_msgs2 in ret.stderr:
                        logging.debug("options %s are mutually exclusive" %
                                      attach_option)
                        if not ("--current" in sep_options
                                and len(sep_options) > 1):
                            test.fail(
                                "return mutualy exclusive, but it is unexpected"
                            )
                    else:
                        logging.error("Command output %s" % ret.stdout.strip())
                        test.fail("Failed to attach-interface")
                elif stress_test:
                    if attach_device:
                        # Detach the device immediately for stress test
                        ret = virsh.detach_device(vm_name,
                                                  iface_xml_obj.xml,
                                                  flagstr=detach_option,
                                                  ignore_status=True)
                    elif attach_iface:
                        # Detach the device immediately for stress test
                        options = ("--type %s --mac %s %s" %
                                   (iface_type, mac, detach_option))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                    libvirt.check_exit_status(ret)
                else:
                    if attach_device:
                        iface_list.append({
                            'mac': mac,
                            'iface_xml': iface_xml_obj
                        })
                    elif attach_iface:
                        iface_list.append({'mac': mac})
            # Restart libvirtd service
            if restart_libvirtd:
                libvirtd.restart()
                # After restart libvirtd, the old console was invalidated,
                # so we need create a new serial console
                vm.cleanup_serial_console()
                vm.create_serial_console()
            # in options test, check if the interface is attached
            # in current state when attach return true

            def check_iface_exist():
                try:
                    session = vm.wait_for_serial_login(username=username,
                                                       password=password)
                    if utils_net.get_linux_ifname(session, iface['mac']):
                        return True
                    else:
                        logging.debug("can not find interface in vm")
                except Exception:
                    return False

            if options_test:
                for iface in iface_list:
                    if 'mac' in iface:
                        # Check interface in dumpxml output
                        if_attr = vm_xml.VMXML.get_iface_by_mac(
                            vm_name, iface['mac'])
                        if vm.is_alive() and attach_option == "--config":
                            if if_attr:
                                test.fail("interface should not exists "
                                          "in current live vm while "
                                          "attached by --config")
                        else:
                            if if_attr:
                                logging.debug("interface %s found current "
                                              "state in xml" % if_attr['mac'])
                            else:
                                test.fail("no interface found in "
                                          "current state in xml")

                        if if_attr:
                            if if_attr['type'] != iface_type or \
                                    if_attr['source'] != \
                                    iface_source['network']:
                                test.fail("Interface attribute doesn't "
                                          "match attachment options")
                        # check interface in vm only when vm is active
                        if vm.is_alive():
                            logging.debug("check interface in current state "
                                          "in vm")

                            if not utils_misc.wait_for(check_iface_exist,
                                                       timeout=20):
                                if not attach_option == "--config":
                                    test.fail("Can't see interface "
                                              "in current state in vm")
                                else:
                                    logging.debug("find interface in "
                                                  "current state in vm")
                            else:
                                logging.debug("find interface in "
                                              "current state in vm")
                            # in options test, if the attach is performed
                            # when the vm is running
                            # need to destroy and start to check again
                            vm.destroy()

            # Start the domain if needed
            if vm.is_dead():
                vm.start()
            session = vm.wait_for_serial_login(username=username,
                                               password=password)

            # check if interface is attached
            for iface in iface_list:
                if 'mac' in iface:
                    logging.debug("check interface in xml")
                    # Check interface in dumpxml output
                    if_attr = vm_xml.VMXML.get_iface_by_mac(
                        vm_name, iface['mac'])
                    logging.debug(if_attr)
                    if if_attr:
                        logging.debug("interface {} is found in xml".format(
                            if_attr['mac']))
                        if (if_attr['type'] != iface_type or
                                if_attr['source'] != iface_source['network']):
                            test.fail("Interface attribute doesn't "
                                      "match attachment options")
                        if options_test and start_vm and attach_option \
                                in ("--current", "--live", ""):
                            test.fail("interface should not exists when "
                                      "restart vm in options_test")
                    else:
                        logging.debug("no interface found in xml")
                        if options_test and start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("interface not exists next state "
                                          "in xml with %s" % attach_option)
                        else:
                            test.fail("Can't see interface in dumpxml")

                    # Check interface on guest
                    if not utils_misc.wait_for(check_iface_exist, timeout=20):
                        logging.debug("can't see interface next state in vm")
                        if start_vm and attach_option in \
                                ("--current", "--live", ""):
                            logging.debug("it is expected")
                        else:
                            test.fail("should find interface "
                                      "but no seen in next state in vm")

            # Detach hot/cold-plugged interface at last
            if detach_device:
                for iface in iface_list:
                    if 'iface_xml' in iface:
                        ret = virsh.detach_device(vm_name,
                                                  iface['iface_xml'].xml,
                                                  flagstr="",
                                                  ignore_status=True)
                        libvirt.check_exit_status(ret)
                    else:
                        options = ("%s --mac %s" % (iface_type, iface['mac']))
                        ret = virsh.detach_interface(vm_name,
                                                     options,
                                                     ignore_status=True)
                        libvirt.check_exit_status(ret)

                # Check if interface was detached
                for iface in iface_list:
                    if 'mac' in iface:
                        polltime = time.time() + poll_timeout
                        while True:
                            # Check interface in dumpxml output
                            if not vm_xml.VMXML.get_iface_by_mac(
                                    vm_name, iface['mac']):
                                break
                            else:
                                time.sleep(2)
                                if time.time() > polltime:
                                    test.fail("Interface still "
                                              "exists after detachment")
            session.close()
        except virt_vm.VMStartError as e:
            logging.info(str(e))
            test.fail('VM failed to start:\n%s' % e)

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()