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()
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()
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)
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()
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)
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)
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)
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()