def enable_multi_queues(vm): sess = vm.wait_for_serial_login(timeout=login_timeout) error.context("Enable multi queues in guest.", logging.info) for nic_index, nic in enumerate(vm.virtnet): ifname = utils_net.get_linux_ifname(sess, nic.mac) queues = int(nic.queues) change_queues_number(sess, ifname, queues)
def mtu_set(mtu): """ Set server/client/host's mtu :param mtu: mtu value to be set """ server_mtu_cmd = params.get("server_mtu_cmd") client_mtu_cmd = params.get("client_mtu_cmd") host_mtu_cmd = params.get("host_mtu_cmd") error_context.context("Changing the MTU of guest", logging.info) if params.get("os_type") == "linux": ethname = utils_net.get_linux_ifname(server_ctl, mac) ssh_cmd(server_ctl, server_mtu_cmd % (ethname, mtu)) elif params.get("os_type") == "windows": connection_id = utils_net.get_windows_nic_attribute( server_ctl, "macaddress", mac, "netconnectionid") ssh_cmd(server_ctl, server_mtu_cmd % (connection_id, mtu)) error_context.context("Changing the MTU of client", logging.info) ssh_cmd(client, client_mtu_cmd % (params.get("client_physical_nic"), mtu)) netdst = params.get("netdst", "switch") host_bridges = utils_net.Bridge() br_in_use = host_bridges.list_br() if netdst in br_in_use: ifaces_in_use = host_bridges.list_iface() target_ifaces = list(ifaces_in_use + br_in_use) error_context.context("Change all Bridge NICs MTU to %s" % mtu, logging.info) for iface in target_ifaces: utils.run(host_mtu_cmd % (iface, mtu), ignore_status=False)
def get_ip_by_mac(mac_addr, timeout=120): """ Get interface IP address by given MAC address. """ if vm.serial_console is not None: vm.cleanup_serial_console() vm.create_serial_console() session = vm.wait_for_serial_login(timeout=240) def get_ip(): return utils_net.get_guest_ip_addr(session, mac_addr) try: ip_addr = "" iface_name = utils_net.get_linux_ifname(session, mac_addr) if iface_name is None: test.fail("no interface with MAC address %s found" % mac_addr) session.cmd("pkill -9 dhclient", ignore_all_errors=True) session.cmd("dhclient %s " % iface_name, ignore_all_errors=True) ip_addr = utils_misc.wait_for(get_ip, 20) logging.debug("The ip addr is %s", ip_addr) except Exception: logging.warning("Find %s with MAC address %s but no ip for it" % (iface_name, mac_addr)) finally: session.close() return ip_addr
def get_ping_dest(vm_session, mac_addr="", restart_network=False): """ Get an ip address to ping :param vm_session: The session object to the guest :param mac_addr: mac address of given interface :param restart_network: Whether to restart guest's network :return: ip address """ if restart_network: if not utils_package.package_install('dhcp-client', session=vm_session): raise exceptions.TestFail( "Failed to install dhcp-client on guest.") utils_net.restart_guest_network(vm_session) vm_iface = utils_net.get_linux_ifname(vm_session, mac_addr) if isinstance(vm_iface, list): iface_name = vm_iface[0] else: iface_name = vm_iface utils_misc.wait_for( lambda: utils_net.get_net_if_addrs(iface_name, vm_session.cmd_output). get('ipv4'), 20) cmd = ("ip route |awk -F '/' '/^[0-9]/, /dev %s/ {print $1}'" % iface_name) status, output = utils_misc.cmd_status_output(cmd, shell=True, session=vm_session) if status or not output: raise exceptions.TestError("Failed to run cmd - {}, status - {}, " "output - {}.".format(cmd, status, output)) return re.sub('\d+$', '1', output.strip().splitlines()[-1])
def run_nic_promisc(test, params, env): """ Test nic driver in promisc mode: 1) Boot up a VM. 2) Repeatedly enable/disable promiscuous mode in guest. 3) Transfer file from host to guest, and from guest to host in the same time @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session_serial = vm.wait_for_serial_login(timeout=timeout) ethname = utils_net.get_linux_ifname(session_serial, vm.get_mac_address(0)) try: transfer_thread = utils.InterruptedThread(utils_test.run_file_transfer, (test, params, env)) transfer_thread.start() while transfer_thread.isAlive(): session_serial.cmd("ip link set %s promisc on" % ethname) session_serial.cmd("ip link set %s promisc off" % ethname) except Exception: transfer_thread.join(suppress_exception=True) raise else: transfer_thread.join()
def test_ping(): """ Ping test for nic option. """ package_sizes = params.objects("ping_sizes") if params["os_type"] == "windows": ifname = utils_net.get_windows_nic_attribute( session=session, key="netenabled", value=True, target="netconnectionID") else: ifname = utils_net.get_linux_ifname(session, vm.get_mac_address()) dest = utils_net.get_host_ip_address(params) for size in package_sizes: error_context.context("Test ping from '%s' to host '%s' on guest '%s'" " with package size %s. " % (ifname, dest, vm.name, size), logging.info) status, output = utils_net.ping(dest=dest, count=10, packetsize=size, session=session, timeout=30) if status: test.fail("%s ping %s unexpected, output %s" % (vm.name, dest, output)) if params["os_type"] == "windows": # windows guest get loss=0 when ping failed sometime, # need further check loss = utils_test.get_loss_ratio(output) if loss or "TTL" in output: pass else: test.fail("Guest ping test hit unexpected loss, " "error_info: %s" % output)
def get_ip_by_mac(mac_addr, try_dhclint=False): """ Get interface IP address by given MAC addrss. If try_dhclint is True, then try to allocate IP addrss for the interface. """ session = vm.wait_for_login() def f(): return utils_net.get_guest_ip_addr(session, mac_addr) try: ip_addr = utils_misc.wait_for(f, 10) if ip_addr is None: iface_name = utils_net.get_linux_ifname(session, mac_addr) if try_dhclint: session.cmd("dhclient %s" % iface_name) ip_addr = utils_misc.wait_for(f, 10) else: # No IP for the interface, just print the interface name logging.warn("Find '%s' with MAC address '%s', " "but which has no IP address", iface_name, mac_addr) finally: session.close() return ip_addr
def get_ip_by_mac(mac_addr, try_dhclint=False, timeout=120): """ Get interface IP address by given MAC addrss. If try_dhclint is True, then try to allocate IP addrss for the interface. """ session = vm.wait_for_login(login_nic_index, timeout=timeout, serial=True) def f(): return utils_net.get_guest_ip_addr(session, mac_addr) try: ip_addr = utils_misc.wait_for(f, 10) if ip_addr is None: iface_name = utils_net.get_linux_ifname(session, mac_addr) if try_dhclint: session.cmd("dhclient %s" % iface_name) ip_addr = utils_misc.wait_for(f, 10) else: # No IP for the interface, just print the interface name logging.warn( "Find '%s' with MAC address '%s', " "but which has no IP address", iface_name, mac_addr) finally: session.close() return ip_addr
def transfer_file(src): """ Transfer file by scp, use tcpdump to capture packets, then check the return string. :param src: Source host of transfer file :return: Tuple (status, error msg/tcpdump result) """ sess = vm.wait_for_login(timeout=login_timeout) session.cmd_output("rm -rf %s" % filename) dd_cmd = ("dd if=/dev/urandom of=%s bs=1M count=%s" % (filename, params.get("filesize"))) failure = (False, "Failed to create file using dd, cmd: %s" % dd_cmd) txt = "Creating file in source host, cmd: %s" % dd_cmd error.context(txt, logging.info) ethname = utils_net.get_linux_ifname(session, vm.get_mac_address(0)) tcpdump_cmd = "tcpdump -lep -i %s -s 0 tcp -vv port ssh" % ethname if src == "guest": tcpdump_cmd += " and src %s" % guest_ip copy_files_func = vm.copy_files_from try: sess.cmd_output(dd_cmd, timeout=360) except aexpect.ShellCmdError, e: return failure
def run(test, params, env): """ When "acpi-index=N" is enabled, NIC name should always be "ethN" 1) Boot up guest with a single nic, add nic option "acpi-index=1" 2) Remove "biosdevname=0" and "net.ifname=0" from kenrel command line 3) Reboot guest 4) Check the nic name, the guest nic name enoN == acpi-index=N :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ login_timeout = int(params.get("login_timeout", 360)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_serial_login(timeout=login_timeout) ifname = utils_net.get_linux_ifname(session, vm.get_mac_address()) pattern = int(re.findall(r'\d+', ifname)[-1]) nic_name_number = params.get_numeric("nic_name_number") if pattern == nic_name_number: logging.info("nic name match") else: test.fail("nic name doesn't match") host_ip = utils_net.get_host_ip_address(params) status, output = utils_net.ping(host_ip, 10, timeout=30) if status: test.fail("%s ping %s unexpected, output %s" % (vm.name, host_ip, output)) if session: session.close()
def run_enable_mq(test, params, env): """ Enable MULTI_QUEUE feature in guest 1) Boot up VM(s) 2) Login guests one by one 3) Enable MQ for all virtio nics by ethtool -L :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ login_timeout = int(params.get("login_timeout", 360)) queues = int(params.get("queues", 1)) vms = params.get("vms").split() if queues == 1: logging.info("No need to enable MQ feature for single queue") return for vm in vms: vm = env.get_vm(vm) vm.verify_alive() session = vm.wait_for_login(timeout=login_timeout) for i, nic in enumerate(vm.virtnet): if "virtio" in nic["nic_model"]: ifname = utils_net.get_linux_ifname(session, vm.get_mac_address(0)) session.cmd_output("ethtool -L %s combined %d" % (ifname, queues)) o = session.cmd_output("ethtool -l %s" % ifname) if len(re.findall("Combined:\s+%d\s" % queues, o)) != 2: raise error.TestError("Fail to enable MQ feature of (%s)" % nic.nic_name) logging.info("MQ feature of (%s) is enabled" % nic.nic_name) session.close()
def run_nic_promisc(test, params, env): """ Test nic driver in promisc mode: 1) Boot up a VM. 2) Repeatedly enable/disable promiscuous mode in guest. 3) Transfer file from host to guest, and from guest to host in the same time @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session_serial = vm.wait_for_serial_login(timeout=timeout) ethname = utils_net.get_linux_ifname(session_serial, vm.get_mac_address(0)) try: transfer_thread = utils.InterruptedThread( utils_test.run_file_transfer, (test, params, env)) transfer_thread.start() while transfer_thread.isAlive(): session_serial.cmd("ip link set %s promisc on" % ethname) session_serial.cmd("ip link set %s promisc off" % ethname) except Exception: transfer_thread.join(suppress_exception=True) raise else: transfer_thread.join()
def chk_mq_enabled(vm, queues): """ Check whether MQ value set in qemu cmd line fits the value in guest :param vm: guest vm :param queues: queues value in qemu cmd line """ login_timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) mac = vm.get_mac_address(0) ifname = utils_net.get_linux_ifname(session, mac) queues_status_list = get_queues_status(session, ifname) session.close() if not queues_status_list[0] == queues or \ not queues_status_list[1] == min(queues, int(vm.cpuinfo.smp)): txt = "Pre-set maximums Combined should equals to queues in qemu" txt += " cmd line.\n" txt += "Current hardware settings Combined should be the min of " txt += "queues and smp.\n" txt += "Pre-set maximum Combined is: %s, " % queues_status_list[0] txt += " queues in qemu cmd line is: %s.\n" % queues txt += "Current hardware settings Combined " txt += "is: %s, " % queues_status_list[1] txt += " smp in qemu cmd line is: %s." % int(vm.cpuinfo.smp) test.fail(txt)
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 verified_nic_name(): ifname = utils_net.get_linux_ifname(session, vm.get_mac_address()) pattern = int(re.findall(r'\d+', ifname)[-1]) nic_name_number = params.get_numeric("nic_name_number") if pattern == nic_name_number: logging.info("nic name match") else: test.fail("nic name doesn't match")
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 run_nicdriver_unload(test, params, env): """ Test nic driver. 1) Boot a VM. 2) Get the NIC driver name. 3) Repeatedly unload/load NIC driver. 4) Multi-session TCP transfer on test interface. 5) Check whether the test interface should still work. @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ timeout = int(params.get("login_timeout", 360)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session_serial = vm.wait_for_serial_login(timeout=timeout) ethname = utils_net.get_linux_ifname(session_serial, vm.get_mac_address(0)) # get ethernet driver from '/sys' directory. # ethtool can do the same thing and doesn't care about os type. # if we make sure all guests have ethtool, we can make a change here. sys_path = params.get("sys_path") % (ethname) # readlink in RHEL4.8 doesn't have '-e' param, should use '-f' in RHEL4.8. readlink_cmd = params.get("readlink_command", "readlink -e") driver = os.path.basename(session_serial.cmd("%s %s" % (readlink_cmd, sys_path)).strip()) logging.info("driver is %s", driver) try: threads = [] for _ in range(int(params.get("sessions_num", "10"))): thread = utils.InterruptedThread(utils_test.run_file_transfer, (test, params, env)) thread.start() threads.append(thread) time.sleep(10) while threads[0].isAlive(): session_serial.cmd("sleep 10") session_serial.cmd("ifconfig %s down" % ethname) session_serial.cmd("modprobe -r %s" % driver) session_serial.cmd("modprobe %s" % driver) session_serial.cmd("ifconfig %s up" % ethname) except Exception: for thread in threads: thread.join(suppress_exception=True) raise else: for thread in threads: thread.join()
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
def renew_ip_address(session, mac): ifname = utils_net.get_linux_ifname(session, mac) make_conf = "nmcli connection add type ethernet con-name %s ifname " \ "%s autoconnect yes" % (ifname, ifname) arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh" session.cmd_output_safe(make_conf) session.cmd_output_safe("ip link set dev %s up" % ifname) session.cmd_output_safe("dhclient -r", timeout=240) session.cmd_output_safe("dhclient %s" % ifname, timeout=240) session.cmd_output_safe(arp_clean)
def run_nicdriver_unload(test, params, env): """ Test nic driver. 1) Boot a VM. 2) Get the NIC driver name. 3) Repeatedly unload/load NIC driver. 4) Multi-session TCP transfer on test interface. 5) Check whether the test interface should still work. @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ timeout = int(params.get("login_timeout", 360)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session_serial = vm.wait_for_serial_login(timeout=timeout) ethname = utils_net.get_linux_ifname(session_serial, vm.get_mac_address(0)) # get ethernet driver from '/sys' directory. # ethtool can do the same thing and doesn't care about os type. # if we make sure all guests have ethtool, we can make a change here. sys_path = params.get("sys_path") % (ethname) # readlink in RHEL4.8 doesn't have '-e' param, should use '-f' in RHEL4.8. readlink_cmd = params.get("readlink_command", "readlink -e") driver = os.path.basename( session_serial.cmd("%s %s" % (readlink_cmd, sys_path)).strip()) logging.info("driver is %s", driver) try: threads = [] for _ in range(int(params.get("sessions_num", "10"))): thread = utils.InterruptedThread(utils_test.run_file_transfer, (test, params, env)) thread.start() threads.append(thread) time.sleep(10) while threads[0].isAlive(): session_serial.cmd("sleep 10") session_serial.cmd("ifconfig %s down" % ethname) session_serial.cmd("modprobe -r %s" % driver) session_serial.cmd("modprobe %s" % driver) session_serial.cmd("ifconfig %s up" % ethname) except Exception: for thread in threads: thread.join(suppress_exception=True) raise else: for thread in threads: thread.join()
def run_nic_promisc(test, params, env): """ Test nic driver in promisc mode: 1) Boot up a VM. 2) Repeatedly enable/disable promiscuous mode in guest. 3) Transfer file between host and guest during nic promisc on/off @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ def set_nic_promisc_onoff(session): if os_type == "linux": session.cmd("ip link set %s promisc on" % ethname) session.cmd("ip link set %s promisc off" % ethname) else: cmd = "c:\\set_win_promisc.py" session.cmd(cmd) error.context("Boot vm and prepare test environment", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session_serial = vm.wait_for_serial_login(timeout=timeout) session = vm.wait_for_login(timeout=timeout) os_type = params.get("os_type") if os_type == "linux": ethname = utils_net.get_linux_ifname(session, vm.get_mac_address(0)) else: script_path = os.path.join(test.virtdir, "scripts/set_win_promisc.py") vm.copy_files_to(script_path, "C:\\") try: transfer_thread = utils.InterruptedThread(utils_test.run_file_transfer, (test, params, env)) error.context("Run utils_test.file_transfer ...", logging.info) transfer_thread.start() error.context("Perform file transfer while turning nic promisc on/off", logging.info) while transfer_thread.isAlive(): set_nic_promisc_onoff(session_serial) except Exception: transfer_thread.join(suppress_exception=True) raise else: transfer_thread.join() if session_serial: session_serial.close() if session: session.close()
def check_nics_num(expect_c, session): txt = "Check whether guest NICs info match with params setting." error.context(txt, logging.info) nics_list = utils_net.get_linux_ifname(session) actual_c = len(nics_list) msg = "Expected NICs count is: %d\n" % expect_c msg += "Actual NICs count is: %d\n" % actual_c if not expect_c == actual_c: msg += "Nics count mismatch!\n" return (False, msg) return (True, msg + 'Nics count match')
def enable_multi_queues(vm): session = vm.wait_for_login(timeout=login_timeout) error.context("Enable multi queues in guest.", logging.info) for nic_index, nic in enumerate(vm.virtnet): ifname = utils_net.get_linux_ifname(session, nic.mac) queues = int(nic.queues) mq_set_cmd = "ethtool -L %s combined %d" % (ifname, queues) status, output = session.cmd_status_output(mq_set_cmd) if status: msg = "Fail to enable multi queue in guest." msg += "Command %s, fail with output %s" % (mq_set_cmd, output) error.TestError(msg)
def enable_multi_queues(vm): session = vm.wait_for_login(timeout=login_timeout) error_context.context("Enable multi queues in guest.", logging.info) for nic_index, nic in enumerate(vm.virtnet): ifname = utils_net.get_linux_ifname(session, nic.mac) queues = int(nic.queues) mq_set_cmd = "ethtool -L %s combined %d" % (ifname, queues) status, output = session.cmd_status_output(mq_set_cmd) if status: msg = "Fail to enable multi queue in guest." msg += "Command %s, fail with output %s" % (mq_set_cmd, output) test.error(msg)
def run(test, params, env): """ Test nic driver in promisc mode: 1) Boot up a VM. 2) Repeatedly enable/disable promiscuous mode in guest. 3) Transfer file between host and guest during nic promisc on/off :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def set_nic_promisc_onoff(session): if os_type == "linux": session.cmd_output_safe("ip link set %s promisc on" % ethname) session.cmd_output_safe("ip link set %s promisc off" % ethname) else: cmd = "c:\\set_win_promisc.py" session.cmd(cmd) error.context("Boot vm and prepare test environment", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session_serial = vm.wait_for_serial_login(timeout=timeout) session = vm.wait_for_login(timeout=timeout) os_type = params.get("os_type") if os_type == "linux": ethname = utils_net.get_linux_ifname(session, vm.get_mac_address(0)) else: script_path = os.path.join(test.virtdir, "scripts/set_win_promisc.py") vm.copy_files_to(script_path, "C:\\") try: transfer_thread = utils_misc.InterruptedThread( utils_test.run_file_transfer, (test, params, env)) error.context("Run utils_test.file_transfer ...", logging.info) transfer_thread.start() error.context("Perform file transfer while turning nic promisc on/off", logging.info) while transfer_thread.isAlive(): set_nic_promisc_onoff(session_serial) except Exception: transfer_thread.join(suppress_exception=True) raise else: transfer_thread.join() if session: session.close()
def mtu_test(): logging.info("Set mtu value and verfied") serial_session.cmd(params["fw_stop_cmd"], ignore_all_errors=True) guest_ifname = utils_net.get_linux_ifname(serial_session, vm.get_mac_address(0)) if guest_ifname != 'eth0': test.cancel("Guest device name is not expected") serial_session.cmd(params["set_mtu_cmd"] % guest_ifname) output = serial_session.cmd_output(params["check_mtu_cmd"] % guest_ifname) match_string = "mtu %s" % params["mtu_value"] if match_string not in output: test.fail("Guest mtu is not the expected value %s" % params["mtu_value"])
def mtu_set(mtu): """ Set server/client/host's mtu :param mtu: mtu value to be set """ server_mtu_cmd = params.get("server_mtu_cmd") client_mtu_cmd = params.get("client_mtu_cmd") host_mtu_cmd = params.get("host_mtu_cmd") error_context.context("Changing the MTU of guest", logging.info) if params.get("os_type") == "linux": ethname = utils_net.get_linux_ifname(server_ctl, mac) netperf_base.ssh_cmd(server_ctl, server_mtu_cmd % (ethname, mtu)) elif params.get("os_type") == "windows": connection_id = utils_net.get_windows_nic_attribute( server_ctl, "macaddress", mac, "netconnectionid") netperf_base.ssh_cmd(server_ctl, server_mtu_cmd % (connection_id, mtu)) error_context.context("Changing the MTU of client", logging.info) netperf_base.ssh_cmd( client, client_mtu_cmd % (params.get("client_physical_nic"), mtu)) netdst = params.get("netdst", "switch") host_bridges = utils_net.Bridge() br_in_use = host_bridges.list_br() if netdst in br_in_use: ifaces_in_use = host_bridges.list_iface() target_ifaces = list(ifaces_in_use + br_in_use) if params.get("netdst_nic1") in process.system_output( "ovs-vsctl list-br", ignore_status=True, shell=True).decode(): ovs_list = "ovs-vsctl list-ports %s" % params["netdst_nic1"] ovs_port = process.system_output(ovs_list, shell=True).decode().splitlines() target_ifaces = target_ifaces + \ params.objects("netdst_nic1") + ovs_port if vm.virtnet[0].nettype == "macvtap": target_ifaces.extend([vm.virtnet[0].netdst, vm.get_ifname(0)]) error_context.context("Change all Bridge NICs MTU to %s" % mtu, logging.info) for iface in target_ifaces: try: process.run(host_mtu_cmd % (iface, mtu), ignore_status=False, shell=True) except process.CmdError as err: if "SIOCSIFMTU" in err.result.stderr.decode(): test.cancel("The ethenet device does not support jumbo," "cancel test")
def check_nic_removed(mac, session): """ Get interface IP address by given MAC addrss. If try_dhclint is True, then try to allocate IP addrss for the interface. :param mac: The mac address of plugged interface :param session: Vm session """ except_mesg = '' try: if guest_os_type == 'Windows': except_mesg = "Get nic netconnectionid failed" utils_net.restart_windows_guest_network_by_key( session, "macaddress", mac) else: except_mesg = ("Failed to determine interface" " name with mac %s" % mac) utils_net.get_linux_ifname(session, mac) except exceptions.TestError as e: if except_mesg in str(e): return True else: return False
def ping_hotplug_nic(ip, mac, session, is_linux_guest): status, output = utils_test.ping(ip, 10, timeout=30) if status != 0: if not is_linux_guest: return status, output ifname = utils_net.get_linux_ifname(session, mac) add_route_cmd = "route add %s dev %s" % (ip, ifname) del_route_cmd = "route del %s dev %s" % (ip, ifname) logging.warn("Failed to ping %s from host.") logging.info("Add route and try again") session.cmd_output_safe(add_route_cmd) status, output = utils_test.ping(hotnic_ip, 10, timeout=30) logging.info("Del the route.") status, output = session.cmd_output_safe(del_route_cmd) return status, output
def renew_ip_address(session, mac, is_linux_guest=True): if not is_linux_guest: utils_net.restart_windows_guest_network_by_key(session, "macaddress", mac) return None ifname = utils_net.get_linux_ifname(session, mac) p_cfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % ifname cfg_con = "DEVICE=%s\nBOOTPROTO=dhcp\nONBOOT=yes" % ifname make_conf = "test -f %s || echo '%s' > %s" % (p_cfg, cfg_con, p_cfg) arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh" session.cmd_output_safe(make_conf) session.cmd_output_safe("ifconfig %s up" % ifname) session.cmd_output_safe("dhclient -r", timeout=240) session.cmd_output_safe("dhclient %s" % ifname, timeout=240) session.cmd_output_safe(arp_clean) return None
def guest_config(vm, ip_addr): """ Add a new nic to guest and set a static ip address :param vm: Configured guest :param ip_addr: Set ip address """ # Attach an interface device # Use attach-device, not attach-interface, because attach-interface # doesn't support 'direct' interface_class = vm_xml.VMXML.get_device_class('interface') interface = interface_class(type_name="direct") interface.source = dict(dev=str(eth_card_no), mode=str(iface_mode)) interface.model = "virtio" interface.xmltreefile.write() if vm.is_alive(): vm.destroy(gracefully=False) virsh.attach_device(vm.name, interface.xml, flagstr="--config") os.remove(interface.xml) vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name) new_nic = vmxml.get_devices(device_type="interface")[-1] # Modify new interface's IP vm.start() session = vm.wait_for_login() eth_name = utils_net.get_linux_ifname(session, new_nic.mac_address) eth_config_detail_list = [ 'DEVICE=%s' % eth_name, 'HWADDR=%s' % new_nic.mac_address, 'ONBOOT=yes', 'BOOTPROTO=static', 'IPADDR=%s' % ip_addr ] remote_file = remote.RemoteFile(vm.get_address(), 'scp', 'root', params.get('password'), 22, eth_config_file) remote_file.truncate() remote_file.add(eth_config_detail_list) try: # Attached interface maybe already active session.cmd("ifdown %s" % eth_name) except aexpect.ShellCmdError: pass try: session.cmd("ifup %s" % eth_name) except aexpect.ShellCmdError: pass return session
def mtu_set(mtu): """ Set server/client/host's mtu :param mtu: mtu value to be set """ server_mtu_cmd = params.get("server_mtu_cmd") client_mtu_cmd = params.get("client_mtu_cmd") host_mtu_cmd = params.get("host_mtu_cmd") error_context.context("Changing the MTU of guest", logging.info) if params.get("os_type") == "linux": ethname = utils_net.get_linux_ifname(server_ctl, mac) ssh_cmd(server_ctl, server_mtu_cmd % (ethname, mtu)) elif params.get("os_type") == "windows": connection_id = utils_net.get_windows_nic_attribute( server_ctl, "macaddress", mac, "netconnectionid") ssh_cmd(server_ctl, server_mtu_cmd % (connection_id, mtu)) error_context.context("Changing the MTU of client", logging.info) ssh_cmd(client, client_mtu_cmd % (params.get("client_physical_nic"), mtu)) netdst = params.get("netdst", "switch") host_bridges = utils_net.Bridge() br_in_use = host_bridges.list_br() if netdst in br_in_use: ifaces_in_use = host_bridges.list_iface() target_ifaces = list(ifaces_in_use + br_in_use) if params.get("netdst_nic1") in process.system_output( "ovs-vsctl list-br", ignore_status=True, shell=True).decode(): ovs_list = "ovs-vsctl list-ports %s" % params["netdst_nic1"] ovs_port = process.system_output(ovs_list, shell=True).decode().splitlines() target_ifaces = target_ifaces + \ params.objects("netdst_nic1") + ovs_port if vm.virtnet[0].nettype == "macvtap": target_ifaces.extend([vm.virtnet[0].netdst, vm.get_ifname(0)]) error_context.context("Change all Bridge NICs MTU to %s" % mtu, logging.info) for iface in target_ifaces: try: process.run(host_mtu_cmd % (iface, mtu), ignore_status=False, shell=True) except process.CmdError as err: if "SIOCSIFMTU" in err.result.stderr.decode(): test.cancel("The ethenet device does not support jumbo," "cancel test")
def renew_ip_address(session, mac, guest_os_type): """ Renew ip for plugged nic :param session: Vm session :param mac: The mac address of plugged interface :param guest_os_type: Guest os type, Linux or Windows """ if guest_os_type == 'Windows': utils_net.restart_windows_guest_network_by_key( session, "macaddress", mac) ifname = utils_net.get_linux_ifname(session, mac) utils_net.create_network_script(ifname, mac, 'dhcp', '255.255.255.0') utils_net.restart_guest_network(session, mac) arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh" session.cmd_output_safe(arp_clean)
def renew_ip_address(session, mac, is_linux_guest=True): if not is_linux_guest: utils_net.restart_windows_guest_network_by_key( session, "macaddress", mac) return None ifname = utils_net.get_linux_ifname(session, mac) p_cfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % ifname cfg_con = "DEVICE=%s\nBOOTPROTO=dhcp\nONBOOT=yes" % ifname make_conf = "test -f %s || echo '%s' > %s" % (p_cfg, cfg_con, p_cfg) arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh" session.cmd_output_safe(make_conf) session.cmd_output_safe("ifconfig %s up" % ifname) session.cmd_output_safe("dhclient -r", timeout=240) session.cmd_output_safe("dhclient %s" % ifname, timeout=240) session.cmd_output_safe(arp_clean) return None
def guest_config(vm, ip_addr): """ Add a new nic to guest and set a static ip address :param vm: Configured guest :param ip_addr: Set ip address """ # Attach an interface device # Use attach-device, not attach-interface, because attach-interface # doesn't support 'direct' interface_class = vm_xml.VMXML.get_device_class('interface') interface = interface_class(type_name="direct") interface.source = dict(dev=str(eth_card_no), mode=str(iface_mode)) interface.model = "virtio" interface.xmltreefile.write() if vm.is_alive(): vm.destroy(gracefully=False) virsh.attach_device(vm.name, interface.xml, flagstr="--config") os.remove(interface.xml) vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name) new_nic = vmxml.get_devices(device_type="interface")[-1] # Modify new interface's IP vm.start() session = vm.wait_for_login() eth_name = utils_net.get_linux_ifname(session, new_nic.mac_address) eth_config_detail_list = ['DEVICE=%s' % eth_name, 'HWADDR=%s' % new_nic.mac_address, 'ONBOOT=yes', 'BOOTPROTO=static', 'IPADDR=%s' % ip_addr] remote_file = remote.RemoteFile(vm.get_address(), 'scp', 'root', params.get('password'), 22, eth_config_file) remote_file.truncate() remote_file.add(eth_config_detail_list, linesep='\n') try: # Attached interface maybe already active session.cmd("ifdown %s" % eth_name) except aexpect.ShellCmdError: raise error.TestFail("ifdown %s failed." % eth_name) try: session.cmd("ifup %s" % eth_name) except aexpect.ShellCmdError: raise error.TestFail("ifup %s failed." % eth_name) return session
def check_nics_num(expect_c, session): """ Check whether guest NICs number match with params set in cfg file :param expect_c: expected nics no. :param session: in which session the guest runs in """ txt = "Check whether guest NICs info match with params setting." error_context.context(txt, logging.info) nics_list = utils_net.get_linux_ifname(session) actual_c = len(nics_list) msg = "Expected NICs count is: %d\n" % expect_c msg += "Actual NICs count is: %d\n" % actual_c if not expect_c == actual_c: msg += "Nics count mismatch!\n" return (False, msg) return (True, msg + 'Nics count match')
def run(test, params, env): """ Test iface stat """ vm_name = params.get('main_vm') case = params.get('case', '') vm = env.get_vm(vm_name) bk_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) try: if case == 'compare': host_ifname = utils_net.get_net_if(state="UP")[0] iface_dict = { k.replace('new_iface_', ''): v for k, v in params.items() if k.startswith('new_iface_') } iface_dict['source'] = iface_dict['source'] % host_ifname logging.debug('iface_dict is %s', iface_dict) libvirt.modify_vm_iface(vm_name, 'update_iface', iface_dict) vm.start() vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface = vmxml.devices.by_device_tag("interface")[0] iface_mac = iface.mac_address iface_target_dev = iface.target['dev'] session = vm.wait_for_serial_login(timeout=60) iface_in_vm = utils_net.get_linux_ifname(session, iface_mac) session.cmd('ping www.redhat.com -4 -c 20') host_iface_stat = get_host_iface_stat(vm_name, iface_target_dev) vm_iface_stat = get_vm_iface_stat(session, iface_in_vm) session.close() if not compare_iface_stat(vm_iface_stat, host_iface_stat, bar=0.2): test.fail('Iface stat of host and vm should be close.') finally: bk_xml.sync()
def renew_ip_address(session, mac, is_linux_guest=True): if not is_linux_guest: utils_net.restart_windows_guest_network_by_key(session, "macaddress", mac) return None ifname = utils_net.get_linux_ifname(session, mac) if params.get("make_change") == "yes": p_cfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % ifname cfg_con = "DEVICE=%s\nBOOTPROTO=dhcp\nONBOOT=yes" % ifname make_conf = "test -f %s || echo '%s' > %s" % (p_cfg, cfg_con, p_cfg) else: make_conf = "nmcli connection add type ethernet con-name %s ifname" \ " %s autoconnect yes" % (ifname, ifname) arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh" session.cmd_output_safe(make_conf) session.cmd_output_safe("ip link set dev %s up" % ifname) session.cmd_output_safe("dhclient -r", timeout=240) session.cmd_output_safe("dhclient %s" % ifname, timeout=240) session.cmd_output_safe(arp_clean) return None
def run_enable_mq(test, params, env): """ Enable MULTI_QUEUE feature in guest 1) Boot up VM(s) 2) Login guests one by one 3) Enable MQ for all virtio nics by ethtool -L :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ login_timeout = int(params.get("login_timeout", 360)) queues = int(params.get("queues", 1)) vms = params.get("vms").split() if queues == 1: logging.info("No need to enable MQ feature for single queue") return for vm in vms: vm = env.get_vm(vm) vm.verify_alive() session = vm.wait_for_login(timeout=login_timeout) for i, nic in enumerate(vm.virtnet): if "virtio" in nic['nic_model']: ifname = utils_net.get_linux_ifname(session, vm.get_mac_address(0)) session.cmd_output("ethtool -L %s combined %d" % (ifname, queues)) o = session.cmd_output("ethtool -l %s" % ifname) if len(re.findall("Combined:\s+%d\s" % queues, o)) != 2: raise error.TestError("Fail to enable MQ feature of (%s)" % nic.nic_name) logging.info("MQ feature of (%s) is enabled" % nic.nic_name) session.close()
def get_speed_duplex_linux(session): """ Get the speed and duplex information on linux guests. return: a tuple of (speed, duplex), which speed is measured by mbps, and duplex is one of 'half' and 'full'. """ error_context.context("Get speed & duplex info", logging.info) mac = vm.get_mac_address(0) ethname = utils_net.get_linux_ifname(session, mac) check_speed_cmd = params["check_speed_cmd"] % ethname status, output = session.cmd_status_output(check_speed_cmd) if status: test.fail("Failed to get speed info," "status=%s, ouput=%s" % (status, output)) logging.info(output) result = re.findall(r"(?:Speed:\s+(\d+)Mb/s)|(?:Duplex:\s+(\w+))", output) if len(result) < 2: test.error("Can't get speed or duplex info") speed = int(result[0][0]) duplex = result[1][1].lower() return (speed, duplex)
def mtu_set(mtu): """ Set server/client/host's mtu :param mtu: mtu value to be set """ server_mtu_cmd = params.get("server_mtu_cmd") client_mtu_cmd = params.get("client_mtu_cmd") host_mtu_cmd = params.get("host_mtu_cmd") error_context.context("Changing the MTU of guest", logging.info) if params.get("os_type") == "linux": ethname = utils_net.get_linux_ifname(server_ctl, mac) ssh_cmd(server_ctl, server_mtu_cmd % (ethname, mtu)) elif params.get("os_type") == "windows": connection_id = utils_net.get_windows_nic_attribute( server_ctl, "macaddress", mac, "netconnectionid") ssh_cmd(server_ctl, server_mtu_cmd % (connection_id, mtu)) error_context.context("Changing the MTU of client", logging.info) ssh_cmd(client, client_mtu_cmd % (params.get("client_physical_nic"), mtu)) netdst = params.get("netdst", "switch") host_bridges = utils_net.Bridge() br_in_use = host_bridges.list_br() if netdst in br_in_use: ifaces_in_use = host_bridges.list_iface() target_ifaces = list(ifaces_in_use + br_in_use) if vm.virtnet[0].nettype == "macvtap": target_ifaces.extend([vm.virtnet[0].netdst, vm.get_ifname(0)]) error_context.context("Change all Bridge NICs MTU to %s" % mtu, logging.info) for iface in target_ifaces: process.run(host_mtu_cmd % (iface, mtu), ignore_status=False, shell=True)
def guest_config(vm, ip_addr): """ Add a new nic to guest and set a static ip address :param vm: Configured guest :param ip_addr: Set ip address """ # Attach an interface device # Use attach-device, not attach-interface, because attach-interface # doesn't support 'direct' interface_class = vm_xml.VMXML.get_device_class('interface') interface = interface_class(type_name="direct") interface.source = dict(dev=str(eth_card_no), mode=str(iface_mode)) interface.model = "virtio" interface.xmltreefile.write() if vm.is_alive(): vm.destroy(gracefully=False) virsh.attach_device(vm.name, interface.xml, flagstr="--config") os.remove(interface.xml) vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name) new_nic = vmxml.get_devices(device_type="interface")[-1] # Modify new interface's IP vm.start() session = vm.wait_for_login() eth_name = utils_net.get_linux_ifname(session, new_nic.mac_address) eth_config_detail = "DEVICE=%s\nHWADDR=%s\nONBOOT=yes\n"\ "BOOTPROTO=static\nIPADDR=%s"\ % (eth_name, new_nic.mac_address, ip_addr) add_cmd = "echo %s >> %s" % (eth_config_detail, eth_config_file) session.cmd(add_cmd) session.cmd("sync") try: session.cmd("ifup %s" % eth_name) except aexpect.ShellCmdError: pass
guest_netwok_connecting_check(guest_ip, link_up, change_queues) vm = env.get_vm(params["main_vm"]) vm.verify_alive() login_timeout = float(params.get("login_timeout", 360)) session = vm.wait_for_login(timeout=login_timeout) change_queues = False guest_ifname = "" guest_ip = vm.get_address() # Win guest '2' represent 'Connected', '7' represent 'Media disconnected' win_media_connected = params.get("win_media_connected", "2") win_media_disconnected = params.get("win_media_disconnected", "7") if params.get("os_type") == "linux": guest_ifname = utils_net.get_linux_ifname(session, vm.get_mac_address()) queues = int(params.get("queues", 1)) if queues != 1 and vm.virtnet[0].nic_model == "virtio": change_queues = True session.close() netdev_id = vm.virtnet[0].netdev_id device_id = vm.virtnet[0].device_id expect_down_status = params.get("down-status", "down") expect_up_status = params.get("up-status", "up") operstate_always_up = params.get("operstate_always_up", "no") == "yes" error.context("Disable guest netdev link '%s' by set_link" % netdev_id, logging.info) set_link_test(netdev_id, False, expect_down_status, operstate_always_up,
def run(test, params, env): """ Nic bonding test in guest. 1) Start guest with four nic models. 2) Setup bond0 in guest by script nic_bonding_guest.py. 3) Execute file transfer test between guest and host. 4) Repeatedly put down/up interfaces by set_link 5) Execute file transfer test between guest and host. :param test: Kvm test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ timeout = int(params.get("login_timeout", 1200)) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session_serial = vm.wait_for_serial_login(timeout=timeout) ifnames = [utils_net.get_linux_ifname(session_serial, vm.get_mac_address(vlan)) for vlan, nic in enumerate(vm.virtnet)] # get params of bonding nm_stop_cmd = "pidof NetworkManager && service NetworkManager stop; true" session_serial.cmd_output_safe(nm_stop_cmd) modprobe_cmd = "modprobe bonding" bonding_params = params.get("bonding_params") if bonding_params: modprobe_cmd += " %s" % bonding_params session_serial.cmd_output_safe(modprobe_cmd) session_serial.cmd_output_safe("ifconfig bond0 up") setup_cmd = "ifenslave bond0 " + " ".join(ifnames) session_serial.cmd_output_safe(setup_cmd) # do a pgrep to check if dhclient has already been running pgrep_cmd = "pgrep dhclient" try: session_serial.cmd_output_safe(pgrep_cmd) # if dhclient is there, killl it except aexpect.ShellCmdError: logging.info("it's safe to run dhclient now") else: logging.info("dhclient already is running,kill it") session_serial.cmd_output_safe("killall -9 dhclient") time.sleep(1) session_serial.cmd_output_safe("dhclient bond0") #get_bonding_nic_mac and ip try: logging.info("Test file transferring:") utils_test.run_file_transfer(test, params, env) logging.info("Failover test with file transfer") transfer_thread = utils.InterruptedThread(utils_test.run_file_transfer, (test, params, env)) transfer_thread.start() try: while transfer_thread.isAlive(): for vlan, nic in enumerate(vm.virtnet): device_id = nic.device_id if not device_id: raise error.TestError("Could not find peer device for" " nic device %s" % nic) vm.set_link(device_id, up=False) time.sleep(random.randint(1, 30)) vm.set_link(device_id, up=True) time.sleep(random.randint(1, 30)) except Exception: transfer_thread.join(suppress_exception=True) raise else: transfer_thread.join() finally: session_serial.sendline("ifenslave -d bond0 " + " ".join(ifnames)) session_serial.sendline("kill -9 `pgrep dhclient`")
def run(test, params, env): """ Test Step 1. boot up two virtual machine 2. Transfer data: host <--> guest1 <--> guest2 <-->host via ipv6 3. after data transfer, check data have no change Params: :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ timeout = int(params.get("login_timeout", '360')) client = params.get("file_transfer_client") port = params.get("file_transfer_port") password = params.get("password") username = params.get("username") tmp_dir = params.get("tmp_dir", "/tmp/") filesize = int(params.get("filesize", '4096')) dd_cmd = params.get("dd_cmd") file_trans_timeout = int(params.get("file_trans_timeout", '1200')) file_md5_check_timeout = int(params.get("file_md5_check_timeout", '600')) def get_linux_ipv6_linklocal_address(ifname, session=None): """ Get host/guest ipv6 linklocal address via ifname """ if session is not None: o = session.cmd_output("ifconfig %s" % ifname) else: o = utils.system_output("ifconfig %s" % ifname) ipv6_address_reg = re.compile(r"(fe80::[^\s|/]*)") if o: ipv6_linklocal_address = ipv6_address_reg.findall(o) if not ipv6_linklocal_address: raise error.TestError("Can't get %s linklocal address" % ifname) return ipv6_linklocal_address[0] else: return None def get_file_md5sum(file_name, session, timeout): """ Get file md5sum from guest. """ logging.info("Get md5sum of the file:'%s'" % file_name) try: o = session.cmd_output("md5sum %s" % file_name, timeout=timeout) file_md5sum = re.findall("\w+", o)[0] except IndexError: raise error.TestError("Could not get file md5sum in guest") return file_md5sum sessions = {} addresses = {} inet_name = {} vms = [] error.context("Boot vms for test", logging.info) for vm_name in params.get("vms", "vm1 vm2").split(): vms.append(env.get_vm(vm_name)) # config ipv6 address host and guest. host_ifname = params.get("netdst") for vm in vms: vm.verify_alive() sessions[vm] = vm.wait_for_login(timeout=timeout) inet_name[vm] = utils_net.get_linux_ifname(sessions[vm], vm.get_mac_address()) addresses[vm] = get_linux_ipv6_linklocal_address(inet_name[vm], sessions[vm]) # prepare test data guest_path = (tmp_dir + "src-%s" % utils_misc.generate_random_string(8)) dest_path = (tmp_dir + "dst-%s" % utils_misc.generate_random_string(8)) host_path = os.path.join(test.tmpdir, "tmp-%s" % utils_misc.generate_random_string(8)) logging.info("Test setup: Creating %dMB file on host", filesize) utils.run(dd_cmd % (host_path, filesize)) try: src_md5 = (utils.hash_file(host_path, method="md5")) # transfer data for vm in vms: error.context("Transfer data from host to %s" % vm.name, logging.info) remote.copy_files_to(addresses[vm], client, username, password, port, host_path, guest_path, timeout=file_trans_timeout, interface=host_ifname) dst_md5 = get_file_md5sum(guest_path, sessions[vm], timeout=file_md5_check_timeout) if dst_md5 != src_md5: raise error.TestFail("File changed after transfer host -> %s" % vm.name) for vm_src in addresses: for vm_dst in addresses: if vm_src != vm_dst: error.context("Transferring data from %s to %s" % (vm_src.name, vm_dst.name), logging.info) remote.scp_between_remotes(addresses[vm_src], addresses[vm_dst], port, password, password, username, username, guest_path, dest_path, timeout=file_trans_timeout, src_inter=host_ifname, dst_inter=inet_name[vm_src]) dst_md5 = get_file_md5sum(dest_path, sessions[vm_dst], timeout=file_md5_check_timeout) if dst_md5 != src_md5: raise error.TestFail("File changed transfer %s -> %s" % (vm_src.name, vm_dst.name)) for vm in vms: error.context("Transfer data from %s to host" % vm.name, logging.info) remote.copy_files_from(addresses[vm], client, username, password, port, dest_path, host_path, timeout=file_trans_timeout, interface=host_ifname) error.context("Check whether the file changed after trans", logging.info) dst_md5 = (utils.hash_file(host_path, method="md5")) if dst_md5 != src_md5: raise error.TestFail("File changed after transfer (md5sum mismatch)") utils.system_output("rm -rf %s" % host_path, timeout=timeout) finally: utils.system("rm -rf %s" % host_path, timeout=timeout, ignore_status=True) for vm in vms: sessions[vm].cmd("rm -rf %s %s || true" % (guest_path, dest_path), timeout=timeout, ignore_all_errors=True) sessions[vm].close()
def run(test, params, env): """ Test qmp event notification function: 1) Boot up guest with qmp and macvtap. 2) In guest, change network interface to promisc state. 3) Try to catch qmp event notification in qmp monitor. 4) Execute query-rx-filter in host qmp session. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environmen. """ if not utils_misc.qemu_has_option("qmp"): error.TestNAError("This test case requires a host QEMU with QMP " "monitor support") if params.get("nettype", "macvtap") != "macvtap": error.TestNAError("This test case test macvtap.") params["start_vm"] = "yes" vm_name = params.get("main_vm", "vm1") env_process.preprocess_vm(test, params, env, vm_name) vm = env.get_vm(vm_name) vm.verify_alive() event_cmd = params.get("event_cmd") event_cmd_type = params.get("event_cmd_type") event_check = params.get("event_check") timeout = int(params.get("check_timeout", 360)) pre_cmd = params.get("pre_cmd") post_cmd = params.get("post_cmd") post_cmd_type = params.get("post_cmd_type") session = vm.wait_for_serial_login(timeout=int(params.get("login_timeout", 360))) callback = {"host_cmd": utils.system_output, "guest_cmd": session.get_command_output, "qmp_cmd": vm.get_monitors_by_type("qmp")[0].send_args_cmd} def send_cmd(cmd, cmd_type): if cmd_type in callback.keys(): return callback[cmd_type](cmd) else: raise error.TestError("cmd_type is not supported") if pre_cmd: error.context("Run pre_cmd '%s'", logging.info) pre_cmd_type = params.get("pre_cmd_type", event_cmd_type) send_cmd(pre_cmd, pre_cmd_type) mac = vm.get_mac_address() interface_name = utils_net.get_linux_ifname(session, mac) error.context("In guest, change network interface to promisc state.", logging.info) event_cmd = params.get("event_cmd") % interface_name send_cmd(event_cmd, event_cmd_type) error.context("Try to get qmp events in %s seconds!" % timeout, logging.info) end_time = time.time() + timeout qmp_monitors = vm.get_monitors_by_type("qmp") qmp_num = len(qmp_monitors) while time.time() < end_time: for monitor in qmp_monitors: event = monitor.get_event(event_check) if event: txt = "Monitr %s " % monitor.name txt += "receive qmp %s event notification" % event_check logging.info(txt) qmp_num -= 1 qmp_monitors.remove(monitor) time.sleep(5) if qmp_num <= 0: break if qmp_num > 0: output = session.cmd("ip link show") err = "Monitor(s) " for monitor in qmp_monitors: err += "%s " % monitor.name err += " did not receive qmp %s event notification." % event_check err += " ip link show command output in guest: %s" % output raise error.TestFail(err) if post_cmd: for nic in vm.virtnet: post_cmd = post_cmd % nic.device_id error.context("Run post_cmd '%s'" % post_cmd, logging.info) post_cmd_type = params.get("post_cmd_type", event_cmd_type) output = send_cmd(post_cmd, post_cmd_type) post_cmd_check = params.get("post_cmd_check") if post_cmd_check: if post_cmd_check not in str(output): err = "Did not find '%s' in " % post_cmd_check err += "'%s' command's output: %s" % (post_cmd, output) raise error.TestFail(err) if session: session.close()
def run(test, params, env): """ MULTI_QUEUE chang queues number test 1) Boot up VM, and login guest 2) Check guest pci msi support and reset it as expection 3) Enable the queues in guest 4) Run bg_stress_test(pktgen, netperf or file copy) if needed 5) Change queues number repeatly during stress test running 6) Ping external host (local host, if external host not available) :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def change_queues_number(session, ifname, q_number, queues_status=None): """ Change queues number """ mq_set_cmd = "ethtool -L %s combined %d" % (ifname, q_number) if not queues_status: queues_status = get_queues_status(session, ifname) if (q_number != queues_status[1] and q_number <= queues_status[0] and q_number > 0): expect_status = 0 else: expect_status = 1 status, output = session.cmd_status_output(mq_set_cmd, safe=True) cur_queues_status = get_queues_status(session, ifname) if status != expect_status: err_msg = "Change queues number failed, " err_msg += "current queues set is %s, " % queues_status[1] err_msg += "max allow queues set is %s, " % queues_status[0] err_msg += "when run cmd: '%s', " % mq_set_cmd err_msg += "expect exit status is: %s, " % expect_status err_msg += "output: '%s'" % output raise error.TestFail(err_msg) if not status and cur_queues_status == queues_status: raise error.TestFail("params is right, but change queues failed") elif status and cur_queues_status != queues_status: raise error.TestFail("No need change queues number") return [int(_) for _ in cur_queues_status] def get_queues_status(session, ifname, timeout=240): """ Get queues status """ mq_get_cmd = "ethtool -l %s" % ifname nic_mq_info = session.cmd_output(mq_get_cmd, timeout=timeout, safe=True) queues_reg = re.compile(r"Combined:\s+(\d)", re.I) queues_info = queues_reg.findall(" ".join(nic_mq_info.splitlines())) if len(queues_info) != 2: err_msg = "Oops, get guest queues info failed, " err_msg += "make sure your guest support MQ.\n" err_msg += "Check cmd is: '%s', " % mq_get_cmd err_msg += "Command output is: '%s'." % nic_mq_info raise error.TestNAError(err_msg) return [int(x) for x in queues_info] def enable_multi_queues(vm): sess = vm.wait_for_serial_login(timeout=login_timeout) error.context("Enable multi queues in guest.", logging.info) for nic_index, nic in enumerate(vm.virtnet): ifname = utils_net.get_linux_ifname(sess, nic.mac) queues = int(nic.queues) change_queues_number(sess, ifname, queues) def ping_test(dest_ip, ping_time, lost_raito, session=None): status, output = utils_test.ping(dest=dest_ip, timeout=ping_time, session=session) packets_lost = utils_test.get_loss_ratio(output) if packets_lost > lost_raito: err = " %s%% packages lost during ping. " % packets_lost err += "Ping command log:\n %s" % "\n".join(output.splitlines()[-3:]) raise error.TestFail(err) error.context("Init guest and try to login", logging.info) login_timeout = int(params.get("login_timeout", 360)) bg_stress_test = params.get("run_bgstress") bg_stress_run_flag = params.get("bg_stress_run_flag") vm = env.get_vm(params["main_vm"]) vm.verify_alive() vm.wait_for_login(timeout=login_timeout) if params.get("pci_nomsi", "no") == "yes": error.context("Disable pci msi in guest", logging.info) utils_test.update_boot_option(vm, args_added="pci=nomsi") vm.wait_for_login(timeout=login_timeout) enable_multi_queues(vm) session_serial = vm.wait_for_serial_login(timeout=login_timeout) s_session = None bg_ping = params.get("bg_ping") b_ping_lost_ratio = int(params.get("background_ping_package_lost_ratio", 5)) f_ping_lost_ratio = int(params.get("final_ping_package_lost_ratio", 5)) guest_ip = vm.get_address() b_ping_time = int(params.get("background_ping_time", 60)) f_ping_time = int(params.get("final_ping_time", 60)) bg_test = None try: ifnames = [] for nic_index, nic in enumerate(vm.virtnet): ifname = utils_net.get_linux_ifname(session_serial, vm.virtnet[nic_index].mac) ifnames.append(ifname) if bg_stress_test: error.context("Run test %s background" % bg_stress_test, logging.info) stress_thread = "" wait_time = float(params.get("wait_bg_time", 60)) env[bg_stress_run_flag] = False stress_thread = utils.InterruptedThread( utils_test.run_virt_sub_test, (test, params, env), {"sub_type": bg_stress_test}) stress_thread.start() if bg_stress_run_flag: utils_misc.wait_for(lambda: env.get(bg_stress_run_flag), wait_time, 0, 5, "Wait %s start background" % bg_stress_test) if bg_ping == "yes": error.context("Ping guest from host", logging.info) args = (guest_ip, b_ping_time, b_ping_lost_ratio) bg_test = utils.InterruptedThread(ping_test, args) bg_test.start() error.context("Change queues number repeatly", logging.info) repeat_counts = int(params.get("repeat_counts", 10)) for nic_index, nic in enumerate(vm.virtnet): if "virtio" not in nic['nic_model']: continue queues = int(vm.virtnet[nic_index].queues) if queues == 1: logging.info("Nic with single queue, skip and continue") continue ifname = ifnames[nic_index] default_change_list = xrange(1, int(queues + 1)) change_list = params.get("change_list") if change_list: change_list = change_list.split(",") else: change_list = default_change_list for repeat_num in xrange(1, repeat_counts + 1): error.context("Change queues number -- %sth" % repeat_num, logging.info) try: queues_status = get_queues_status(session_serial, ifname) for q_number in change_list: queues_status = change_queues_number(session_serial, ifname, int(q_number), queues_status) except aexpect.ShellProcessTerminatedError: vm = env.get_vm(params["main_vm"]) session = vm.wait_for_serial_login(timeout=login_timeout) session_serial = session queues_status = get_queues_status(session_serial, ifname) for q_number in change_list: queues_status = change_queues_number(session_serial, ifname, int(q_number), queues_status) if params.get("ping_after_changing_queues", "yes") == "yes": default_host = "www.redhat.com" try: ext_host = utils_net.get_host_default_gateway() except error.CmdError: logging.warn("Can't get specified host," " Fallback to default host '%s'", default_host) ext_host = default_host if not ext_host: # Fallback to a hardcode host, eg: ext_host = default_host s_session = vm.wait_for_login(timeout=login_timeout) txt = "ping %s after changing queues in guest." error.context(txt, logging.info) ping_test(ext_host, f_ping_time, f_ping_lost_ratio, s_session) if bg_stress_test: env[bg_stress_run_flag] = False if stress_thread: error.context("wait for background test finish", logging.info) try: stress_thread.join() except Exception, err: err_msg = "Run %s test background error!\n " err_msg += "Error Info: '%s'" raise error.TestError(err_msg % (bg_stress_test, err)) finally: if bg_stress_test: env[bg_stress_run_flag] = False if session_serial: session_serial.close() if s_session: s_session.close() if bg_test: error.context("Wait for background ping test finish.", logging.info) try: bg_test.join() except Exception, err: txt = "Fail to wait background ping test finish. " txt += "Got error message %s" % err raise error.TestFail(txt)
def run(test, params, env): """ KVM migration test: 1) Get a live VM and clone it. 2) Verify that the source VM supports migration. If it does, proceed with the test. 3) Hotplug a nic. 4) Disable the primary link of guest. 5) Check if new interface gets ip address. 6) Ping guest's new ip from host. 7) Re-enabling the primary link. 8) Send a migration command to the source VM and wait until it's finished. 9) Disable the primary link again. 10) Ping guest's new ip from host. 11) Re-enabling the primary link. :param test: kvm test object. :param params: Dictionary with test parameters. :param env: Dictionary with the test environment. """ def set_link(nic_name, up=False): for nic in vm.virtnet: if nic.nic_name != nic_name: vm.set_link(nic.device_id, up=up) vm = env.get_vm(params["main_vm"]) vm.verify_alive() timeout = int(params.get("login_timeout", 360)) session = vm.wait_for_serial_login(timeout=timeout) guest_is_not_windows = (params.get("os_type") != 'windows') run_dhclient = params.get("run_dhclient", "no") mig_timeout = float(params.get("mig_timeout", "3600")) nettype = params.get("nettype", "bridge") netdst = params.get("netdst", "virbr0") mig_protocol = params.get("migration_protocol", "tcp") mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2 pci_model = params.get("pci_model") # Modprobe the module if specified in config file module = params.get("modprobe_module") if guest_is_not_windows and module: session.cmd_output("modprobe %s" % module) if session: session.close() error.context("Add network devices through monitor cmd", logging.info) nic_name = 'hotadded' enable_msix_vectors = params.get("enable_msix_vectors") nic_info = vm.hotplug_nic(nic_model=pci_model, nic_name=nic_name, netdst=netdst, nettype=nettype, queues=params.get('queues'), enable_msix_vectors=enable_msix_vectors) nic_mac = nic_info['mac'] vm.params['nics'] += " %s" % nic_name vm.params['nic_model_%s' % nic_name] = nic_info['nic_model'] # Only run dhclient if explicitly set and guest is not running Windows. # Most modern Linux guests run NetworkManager, and thus do not need this. if run_dhclient == "yes" and guest_is_not_windows: session_serial = vm.wait_for_serial_login(timeout=timeout) ifname = utils_net.get_linux_ifname(session, nic_mac) utils_net.restart_guest_network(session_serial, ifname) # Guest need to take quite a long time to set the ip addr, sleep a # while to wait for guest done. time.sleep(60) error.context("Disable the primary link of guest", logging.info) set_link(nic_name, up=False) error.context("Check if new interface gets ip address", logging.info) try: ip = vm.wait_for_get_address(nic_name) except virt_vm.VMIPAddressMissingError: raise error.TestFail("Could not get or verify ip address of nic") logging.info("Got the ip address of new nic: %s", ip) error.context("Ping guest's new ip from host", logging.info) s, o = utils_test.ping(ip, 10, timeout=15) if s != 0: raise error.TestFail("New nic failed ping test with output:\n %s" % o) error.context("Re-enabling the primary link", logging.info) set_link(nic_name, up=True) error.context("Migrate from source VM to Destination VM", logging.info) vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay, env=env) error.context("Disable the primary link", logging.info) set_link(nic_name, up=False) error.context("Ping guest's new ip from host", logging.info) s, o = utils_test.ping(ip, 10, timeout=15) if s != 0: raise error.TestFail("New nic failed ping test with output:\n %s" % o) error.context("Re-enabling the primary link", logging.info) set_link(nic_name, up=True) error.context("Reboot guest and verify new nic works", logging.info) host_ip = utils_net.get_ip_address_by_interface(netdst) session = vm.reboot(session=session) status, output = utils_test.ping(dest=host_ip, count=100, timeout=240, session=session) if status != 0: raise error.TestFail("Fail to ping host form guest")
def run_vlan(test, params, env): """ Test 802.1Q vlan of NIC, config it by vconfig/ip command. 1) Create two VMs. 2) load 8021q module in guest. 3) Setup vlans by vconfig/ip in guest and using hard-coded ip address. 4) Enable arp_ignore for all ipv4 device in guest. 5) Repeat steps 2 - 4 in every guest. 6) Test by ping between same and different vlans of two VMs. 7) Test by flood ping between same vlan of two VMs. 8) Test by TCP data transfer between same vlan of two VMs. 9) Remove the named vlan-device. 10) Test maximal plumb/unplumb vlans. @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ def add_vlan(session, v_id, iface="eth0", cmd_type="ip"): """ Creates a vlan-device on iface by cmd that assigned by cmd_type now only support 'ip' and 'vconfig' """ txt = "Create a vlan-device on interface %s with vlan id %s" % (iface, v_id) error.context(txt, logging.info) if cmd_type == "vconfig": cmd = "vconfig add %s %s" % (iface, v_id) elif cmd_type == "ip": v_name = "%s.%s" % (iface, v_id) cmd = "ip link add link %s %s type vlan id %s " % (iface, v_name, v_id) else: err_msg = "Unexpected vlan operation command: %s" % cmd_type err_msg += "only support 'ip' and 'vconfig' now" raise error.TestError(err_msg) session.cmd(cmd) def set_ip_vlan(session, v_id, ip, iface="eth0"): """ Set ip address of vlan interface """ iface = "%s.%s" % (iface, v_id) txt = "Set ip to '%s' for interface '%s'" % (iface, ip) error.context(txt, logging.info) session.cmd("ifconfig %s %s" % (iface, ip)) def set_arp_ignore(session): """ Enable arp_ignore for all ipv4 device in guest """ error.context("Enable arp_ignore for all ipv4 device in guest", logging.info) ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore" session.cmd(ignore_cmd) def rem_vlan(session, v_id, iface="eth0", cmd_type="ip"): """ Removes the named vlan interface(iface+v_id) """ v_iface = '%s.%s' % (iface, v_id) if cmd_type == "vconfig": rem_vlan_cmd = "vconfig rem %s" % v_iface elif cmd_type == "ip": rem_vlan_cmd = "ip link delete %s" % v_iface else: err_msg = "Unexpected vlan operation command: %s" % cmd_type err_msg += "only support 'ip' and 'vconfig' now" raise error.TestError(err_msg) send_cmd = "[ -e /proc/net/vlan/%s ] && %s" % (v_iface, rem_vlan_cmd) error.context("Remove the vlan-device '%s'." % v_iface, logging.info) return session.cmd_status(send_cmd) def nc_transfer(src, dst): nc_port = utils_misc.find_free_port(1025, 5334, vm_ip[dst]) listen_cmd = params.get("listen_cmd") send_cmd = params.get("send_cmd") #listen in dst listen_cmd = listen_cmd % (nc_port, "receive") session[dst].sendline(listen_cmd) time.sleep(2) #send file from src to dst send_cmd = send_cmd % (vlan_ip[dst], str(nc_port), "file") session[src].cmd(send_cmd, timeout=60) try: session[dst].read_up_to_prompt(timeout=60) except aexpect.ExpectError: raise error.TestFail ("Fail to receive file" " from vm%s to vm%s" % (src+1, dst+1)) #check MD5 message digest of receive file in dst output = session[dst].cmd_output("md5sum receive").strip() digest_receive = re.findall(r'(\w+)', output)[0] if digest_receive == digest_origin[src]: logging.info("file succeed received in vm %s", vlan_ip[dst]) else: logging.info("digest_origin is %s", digest_origin[src]) logging.info("digest_receive is %s", digest_receive) raise error.TestFail("File transfered differ from origin") session[dst].cmd("rm -f receive") def flood_ping(src, dst): # we must use a dedicated session becuase the aexpect # does not have the other method to interrupt the process in # the guest rather than close the session. error.context("Flood ping from %s interface %s to %s" % (vm[src].name, ifname[src], vlan_ip[dst]), logging.info) session_flood = vm[src].wait_for_login(timeout=60) utils_test.ping(vlan_ip[dst], flood=True, interface=ifname[src], session=session_flood, timeout=10) session_flood.close() vm = [] session = [] ifname = [] vm_ip = [] digest_origin = [] vlan_ip = ['', ''] ip_unit = ['1', '2'] subnet = params.get("subnet", "192.168") vlan_num = int(params.get("vlan_num", 5)) maximal = int(params.get("maximal")) file_size = params.get("file_size", 4094) cmd_type = params.get("cmd_type", "ip") login_timeout = int(params.get("login_timeout", 360)) vm.append(env.get_vm(params["main_vm"])) vm.append(env.get_vm("vm2")) for vm_ in vm: vm_.verify_alive() for i in range(2): session.append(vm[i].wait_for_login(timeout=login_timeout)) if not session[i] : raise error.TestError("Could not log into guest %s" % vm[i].name) logging.info("Logged in %s successfull" % vm[i].name) ifname.append(utils_net.get_linux_ifname(session[i], vm[i].get_mac_address())) #get guest ip vm_ip.append(vm[i].get_address()) #produce sized file in vm dd_cmd = "dd if=/dev/urandom of=file bs=1024k count=%s" session[i].cmd(dd_cmd % file_size) #record MD5 message digest of file output = session[i].cmd("md5sum file", timeout=60) digest_origin.append(re.findall(r'(\w+)', output)[0]) #stop firewall in vm session[i].cmd("service iptables stop; true") error.context("load 8021q module in guest %s" % vm[i].name, logging.info) session[i].cmd("modprobe 8021q") try: for i in range(2): logging.info("Setup vlan environment in guest %s" % vm[i].name) for vlan_i in range(1, vlan_num+1): add_vlan(session[i], vlan_i, ifname[i], cmd_type) v_ip = "%s.%s.%s" % (subnet, vlan_i, ip_unit[i]) set_ip_vlan(session[i], vlan_i, v_ip, ifname[i]) set_arp_ignore(session[i]) for vlan in range(1, vlan_num+1): error.context("Test for vlan %s" % vlan, logging.info) error.context("Ping test between vlans", logging.info) interface = ifname[0] + '.' + str(vlan) for vlan2 in range(1, vlan_num+1): for i in range(2): interface = ifname[i] + '.' + str(vlan) dest = subnet +'.'+ str(vlan2)+ '.' + ip_unit[(i+1)%2] s, o = utils_test.ping(dest, count=2, interface=interface, session=session[i], timeout=30) if ((vlan == vlan2) ^ (s == 0)): raise error.TestFail ("%s ping %s unexpected" % (interface, dest)) vlan_ip[0] = subnet + '.' + str(vlan) + '.' + ip_unit[0] vlan_ip[1] = subnet + '.' + str(vlan) + '.' + ip_unit[1] flood_ping(0, 1) flood_ping(1, 0) error.context("Transfering data through nc", logging.info) nc_transfer(0, 1) nc_transfer(1, 0) finally: for vlan in range(1, vlan_num+1): logging.info("rem vlan: %s", vlan) rem_vlan(session[0], vlan, ifname[0], cmd_type) rem_vlan(session[1], vlan, ifname[1], cmd_type) # Plumb/unplumb maximal number of vlan interfaces i = 1 s = 0 try: error.context("Testing the plumb of vlan interface", logging.info) for i in range (1, maximal+1): add_vlan(session[0], i, ifname[0], cmd_type) finally: for j in range (1, i+1): s = s or rem_vlan(session[0], j, ifname[0], cmd_type) if s == 0: logging.info("maximal interface plumb test done") else: logging.error("maximal interface plumb test failed") session[0].close() session[1].close()
def run(test, params, env): """ Run Pktgen test between host/guest 1) Boot the main vm, or just grab it if it's already booted. 2) Configure pktgen server(only linux) 3) Run pktgen test, finish when timeout or env["pktgen_run"] != True :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ login_timeout = float(params.get("login_timeout", 360)) error.context("Init the VM, and try to login", logging.info) external_host = params.get("external_host") if not external_host: get_host_cmd = "ip route | awk '/default/ {print $3}'" external_host = utils.system_output(get_host_cmd) vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=login_timeout) error.context("Pktgen server environment prepare", logging.info) # pktgen server only support linux, since pktgen is a linux kernel module pktgen_server = params.get("pktgen_server", "localhost") params_server = params.object_params("pktgen_server") s_shell_client = params_server.get("shell_client", "ssh") s_shell_port = params_server.get("shell_port", "22") s_username = params_server.get("username", "root") s_passwd = params_server.get("password", "123456") s_shell_prompt = params_server.get("shell_prompt") server_session = "" # pktgen server is autotest virtual guest(only linux) if pktgen_server in params.get("vms", "vm1 vm2"): vm_pktgen = env.get_vm(pktgen_server) vm_pktgen.verify_alive() server_session = vm_pktgen.wait_for_login(timeout=login_timeout) runner = server_session.cmd_output_safe pktgen_ip = vm_pktgen.get_address() pktgen_mac = vm_pktgen.get_mac_address() server_interface = utils_net.get_linux_ifname(server_session, pktgen_mac) # pktgen server is a external host assigned elif re.match(r"((\d){1,3}\.){3}(\d){1,3}", pktgen_server): pktgen_ip = pktgen_server server_session = remote.wait_for_login( s_shell_client, pktgen_ip, s_shell_port, s_username, s_passwd, s_shell_prompt ) runner = server_session.cmd_output_safe server_interface = params.get("server_interface") if not server_interface: raise error.TestNAError("Must config server interface before test") else: # using host as a pktgen server server_interface = params.get("netdst", "switch") host_nic = utils_net.Interface(server_interface) pktgen_ip = host_nic.get_ip() pktgen_mac = host_nic.get_mac() runner = utils.system # copy pktgen_test scipt to the test server. local_path = os.path.join(data_dir.get_root_dir(), "shared/scripts/pktgen.sh") remote_path = "/tmp/pktgen.sh" remote.scp_to_remote(pktgen_ip, s_shell_port, s_username, s_passwd, local_path, remote_path) error.context("Run pktgen test", logging.info) run_threads = params.get("pktgen_threads", 1) pktgen_stress_timeout = float(params.get("pktgen_test_timeout", 600)) exec_cmd = "%s %s %s %s %s" % (remote_path, vm.get_address(), vm.get_mac_address(), server_interface, run_threads) try: env["pktgen_run"] = True try: # Set a run flag in env, when other case call this case as a sub # backgroud process, can set run flag to False to stop this case. start_time = time.time() stop_time = start_time + pktgen_stress_timeout while env["pktgen_run"] and time.time() < stop_time: runner(exec_cmd, timeout=pktgen_stress_timeout) # using ping to kill the pktgen stress except aexpect.ShellTimeoutError: session.cmd("ping %s" % pktgen_ip, ignore_all_errors=True) finally: env["pktgen_run"] = False error.context("Verify Host and guest kernel no error and call trace", logging.info) vm.verify_kernel_crash() utils_misc.verify_host_dmesg() error.context("Ping external host after pktgen test", logging.info) status, output = utils_test.ping(dest=external_host, session=session, timeout=240, count=20) loss_ratio = utils_test.get_loss_ratio(output) if loss_ratio > int(params.get("packet_lost_ratio", 5)) or loss_ratio == -1: logging.debug("Ping %s output: %s" % (external_host, output)) raise error.TestFail("Guest network connction unusable," + "packet lost ratio is '%d%%'" % loss_ratio) if server_session: server_session.close() if session: session.close()
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) virsh_dargs = {'debug': True, 'ignore_status': False} def create_iface_xml(iface_mac): """ Create interface xml file """ iface = Interface(type_name=iface_type) source = ast.literal_eval(iface_source) if source: iface.source = source iface.model = iface_model if iface_model else "virtio" iface.mac_address = iface_mac driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) logging.debug("Create new interface xml: %s", iface) return iface def modify_iface_xml(update, status_error=False): """ Modify interface xml options """ vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) xml_devices = vmxml.devices iface_index = xml_devices.index( xml_devices.by_device_tag("interface")[0]) iface = xml_devices[iface_index] if iface_model: iface.model = iface_model else: del iface.model if iface_type: iface.type_name = iface_type del iface.source source = ast.literal_eval(iface_source) if source: net_ifs = utils_net.get_net_if(state="UP") # Check source device is valid or not, # if it's not in host interface list, try to set # source device to first active interface of host if (iface.type_name == "direct" and source.has_key('dev') and source['dev'] not in net_ifs): logging.warn("Source device %s is not a interface" " of host, reset to %s", source['dev'], net_ifs[0]) source['dev'] = net_ifs[0] iface.source = source backend = ast.literal_eval(iface_backend) if backend: iface.backend = backend driver_dict = {} driver_host = {} driver_guest = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) if iface_driver_host: driver_host = ast.literal_eval(iface_driver_host) if iface_driver_guest: driver_guest = ast.literal_eval(iface_driver_guest) iface.driver = iface.new_driver(driver_attr=driver_dict, driver_host=driver_host, driver_guest=driver_guest) if iface.address: del iface.address logging.debug("New interface xml file: %s", iface) if unprivileged_user: # Create disk image for unprivileged user disk_index = xml_devices.index( xml_devices.by_device_tag("disk")[0]) disk_xml = xml_devices[disk_index] logging.debug("source: %s", disk_xml.source) disk_source = disk_xml.source.attrs["file"] cmd = ("cp -fZ {0} {1} && chown {2}:{2} {1}" "".format(disk_source, dst_disk, unprivileged_user)) utils.run(cmd) disk_xml.source = disk_xml.new_disk_source( attrs={"file": dst_disk}) vmxml.devices = xml_devices # Remove all channels to avoid of permission problem channels = vmxml.get_devices(device_type="channel") for channel in channels: vmxml.del_device(channel) vmxml.xmltreefile.write() logging.debug("New VM xml: %s", vmxml) utils.run("chmod a+rw %s" % vmxml.xml) virsh.define(vmxml.xml, **virsh_dargs) # Try to modify interface xml by update-device or edit xml elif update: iface.xmltreefile.write() ret = virsh.update_device(vm_name, iface.xml, ignore_status=True) libvirt.check_exit_status(ret, status_error) else: vmxml.devices = xml_devices vmxml.xmltreefile.write() vmxml.sync() def check_offloads_option(if_name, driver_options, session=None): """ Check interface offloads by ethtool output """ offloads = {"csum": "tx-checksumming", "gso": "generic-segmentation-offload", "tso4": "tcp-segmentation-offload", "tso6": "tx-tcp6-segmentation", "ecn": "tx-tcp-ecn-segmentation", "ufo": "udp-fragmentation-offload"} if session: ret, output = session.cmd_status_output("ethtool -k %s | head" " -18" % if_name) else: out = utils.run("ethtool -k %s | head -18" % if_name) ret, output = out.exit_status, out.stdout if ret: raise error.TestFail("ethtool return error code") logging.debug("ethtool output: %s", output) for offload in driver_options.keys(): if offloads.has_key(offload): if (output.count(offloads[offload]) and not output.count("%s: %s" % ( offloads[offload], driver_options[offload]))): raise error.TestFail("offloads option %s: %s isn't" " correct in ethtool output" % (offloads[offload], driver_options[offload])) def run_xml_test(iface_mac): """ Test for interface options in vm xml """ # Get the interface object according the mac address vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name) iface_devices = vmxml.get_devices(device_type="interface") iface = None for iface_dev in iface_devices: if iface_dev.mac_address == iface_mac: iface = iface_dev if not iface: raise error.TestFail("Can't find interface with mac" " '%s' in vm xml" % iface_mac) driver_dict = {} if iface_driver: driver_dict = ast.literal_eval(iface_driver) for driver_opt in driver_dict.keys(): if not driver_dict[driver_opt] == iface.driver.driver_attr[driver_opt]: raise error.TestFail("Can't see driver option %s=%s in vm xml" % (driver_opt, driver_dict[driver_opt])) if iface_target: if (not iface.target.has_key("dev") or not iface.target["dev"].startswith(iface_target)): raise error.TestFail("Can't see device target dev in vm xml") # Check macvtap mode by ip link command if iface_target == "macvtap" and iface.source.has_key("mode"): cmd = "ip -d link show %s" % iface.target["dev"] output = utils.run(cmd).stdout logging.debug("ip link output: %s", output) mode = iface.source["mode"] if mode == "passthrough": mode = "passthru" if not output.count("macvtap mode %s" % mode): raise error.TestFail("Failed to verify macvtap mode") def run_cmdline_test(iface_mac): """ Test for qemu-kvm command line options """ cmd = ("ps -ef | grep %s | grep -v grep " % vm_name) if test_vhost_net: cmd += " | grep 'vhost=on'" ret = utils.run(cmd) if ret.exit_status: raise error.TestFail("Can't parse qemu-kvm command line") logging.debug("Command line %s", ret.stdout) if iface_model == "virtio": model_option = "device virtio-net-pci" else: model_option = "device rtl8139" iface_cmdline = re.findall(r"%s,(.+),mac=%s" % (model_option, iface_mac), ret.stdout) if not iface_cmdline: raise error.TestFail("Can't see %s with mac %s in command" " line" % (model_option, iface_mac)) cmd_opt = {} for opt in iface_cmdline[0].split(','): tmp = opt.rsplit("=") cmd_opt[tmp[0]] = tmp[1] logging.debug("Command line options %s", cmd_opt) driver_dict = {} # Test <driver> xml options. if iface_driver: iface_driver_dict = ast.literal_eval(iface_driver) for driver_opt in iface_driver_dict.keys(): if driver_opt == "name": continue elif driver_opt == "txmode": if iface_driver_dict["txmode"] == "iothread": driver_dict["tx"] = "bh" else: driver_dict["tx"] = iface_driver_dict["txmode"] elif driver_opt == "queues": driver_dict["mq"] = "on" driver_dict["vectors"] = str(int( iface_driver_dict["queues"]) * 2 + 2) else: driver_dict[driver_opt] = iface_driver_dict[driver_opt] # Test <driver><host/><driver> xml options. if iface_driver_host: driver_dict.update(ast.literal_eval(iface_driver_host)) # Test <driver><guest/><driver> xml options. if iface_driver_guest: driver_dict.update(ast.literal_eval(iface_driver_guest)) for driver_opt in driver_dict.keys(): if (not cmd_opt.has_key(driver_opt) or not cmd_opt[driver_opt] == driver_dict[driver_opt]): raise error.TestFail("Can't see option '%s=%s' in qemu-kvm " " command line" % (driver_opt, driver_dict[driver_opt])) if test_backend: guest_pid = ret.stdout.rsplit()[1] cmd = "lsof %s | grep %s" % (backend["tap"], guest_pid) if utils.system(cmd, ignore_status=True): raise error.TestFail("Guest process didn't open backend file" % backend["tap"]) cmd = "lsof %s | grep %s" % (backend["vhost"], guest_pid) if utils.system(cmd, ignore_status=True): raise error.TestFail("Guest process didn't open backend file" % backend["tap"]) def get_guest_ip(session, mac): """ Wrapper function to get guest ip address """ utils_net.restart_guest_network(session, mac) # Wait for IP address is ready utils_misc.wait_for( lambda: utils_net.get_guest_ip_addr(session, mac), 10) return utils_net.get_guest_ip_addr(session, mac) def check_user_network(session): """ Check user network ip address on guest """ vm_ips = [] vm_ips.append(get_guest_ip(session, iface_mac_old)) if attach_device: vm_ips.append(get_guest_ip(session, iface_mac)) logging.debug("IP address on guest: %s", vm_ips) if len(vm_ips) != len(set(vm_ips)): raise error.TestFail("Duplicated IP address on guest. " "Check bug: https://bugzilla.redhat." "com/show_bug.cgi?id=1147238") for vm_ip in vm_ips: if vm_ip is None or not vm_ip.startswith("10.0.2."): raise error.TestFail("Found wrong IP address" " on guest") # Check gateway address gateway = utils_net.get_net_gateway(session.cmd_output) if gateway != "10.0.2.2": raise error.TestFail("The gateway on guest is not" " right") # Check dns server address ns_list = utils_net.get_net_nameserver(session.cmd_output) if "10.0.2.3" not in ns_list: raise error.TestFail("The dns server can't be found" " on guest") def check_mcast_network(session): """ Check multicast ip address on guests """ src_addr = ast.literal_eval(iface_source)['address'] add_session = additional_vm.wait_for_serial_login() vms_sess_dict = {vm_name: session, additional_vm.name: add_session} # Check mcast address on host cmd = "netstat -g | grep %s" % src_addr if utils.run(cmd, ignore_status=True).exit_status: raise error.TestFail("Can't find multicast ip address" " on host") vms_ip_dict = {} # Get ip address on each guest for vms in vms_sess_dict.keys(): vm_mac = vm_xml.VMXML.get_first_mac_by_name(vms) vm_ip = get_guest_ip(vms_sess_dict[vms], vm_mac) if not vm_ip: raise error.TestFail("Can't get multicast ip" " address on guest") vms_ip_dict.update({vms: vm_ip}) if len(set(vms_ip_dict.values())) != len(vms_sess_dict): raise error.TestFail("Got duplicated multicast ip address") logging.debug("Found ips on guest: %s", vms_ip_dict) # Run omping server on host if not utils_misc.yum_install(["omping"]): raise error.TestError("Failed to install omping" " on host") cmd = ("iptables -F;omping -m %s %s" % (src_addr, "192.168.122.1 %s" % ' '.join(vms_ip_dict.values()))) # Run a backgroup job waiting for connection of client bgjob = utils.AsyncJob(cmd) # Run omping client on guests for vms in vms_sess_dict.keys(): # omping should be installed first if not utils_misc.yum_install(["omping"], vms_sess_dict[vms]): raise error.TestError("Failed to install omping" " on guest") cmd = ("iptables -F; omping -c 5 -T 5 -m %s %s" % (src_addr, "192.168.122.1 %s" % vms_ip_dict[vms])) ret, output = vms_sess_dict[vms].cmd_status_output(cmd) logging.debug("omping ret: %s, output: %s", ret, output) if (not output.count('multicast, xmt/rcv/%loss = 5/5/0%') or not output.count('unicast, xmt/rcv/%loss = 5/5/0%')): raise error.TestFail("omping failed on guest") # Kill the backgroup job bgjob.kill_func() status_error = "yes" == params.get("status_error", "no") start_error = "yes" == params.get("start_error", "no") unprivileged_user = params.get("unprivileged_user") # Interface specific attributes. iface_type = params.get("iface_type", "network") iface_source = params.get("iface_source", "{}") iface_driver = params.get("iface_driver") iface_model = params.get("iface_model") iface_target = params.get("iface_target") iface_backend = params.get("iface_backend", "{}") iface_driver_host = params.get("iface_driver_host") iface_driver_guest = params.get("iface_driver_guest") attach_device = params.get("attach_iface_device") change_option = "yes" == params.get("change_iface_options", "no") update_device = "yes" == params.get("update_iface_device", "no") additional_guest = "yes" == params.get("additional_guest", "no") serial_login = "******" == params.get("serial_login", "no") test_option_cmd = "yes" == params.get( "test_iface_option_cmd", "no") test_option_xml = "yes" == params.get( "test_iface_option_xml", "no") test_vhost_net = "yes" == params.get( "test_vhost_net", "no") test_option_offloads = "yes" == params.get( "test_option_offloads", "no") test_iface_user = "******" == params.get( "test_iface_user", "no") test_iface_mcast = "yes" == params.get( "test_iface_mcast", "no") test_libvirtd = "yes" == params.get("test_libvirtd", "no") test_guest_ip = "yes" == params.get("test_guest_ip", "no") test_backend = "yes" == params.get("test_backend", "no") if iface_driver_host or iface_driver_guest or test_backend: if not libvirt_version.version_compare(1, 2, 8): raise error.TestNAError("Offloading/backend options not " "supported in this libvirt version") if iface_driver and "queues" in ast.literal_eval(iface_driver): if not libvirt_version.version_compare(1, 0, 6): raise error.TestNAError("Queues options not supported" " in this libvirt version") if unprivileged_user: virsh_dargs["unprivileged_user"] = unprivileged_user # Create unprivileged user if needed cmd = ("grep {0} /etc/passwd || " "useradd {0}".format(unprivileged_user)) utils.run(cmd) # Need another disk image for unprivileged user to access dst_disk = "/tmp/%s.img" % unprivileged_user # Destroy VM first if vm.is_alive(): vm.destroy(gracefully=False) # Back up xml file. vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name) iface_mac_old = vm_xml.VMXML.get_first_mac_by_name(vm_name) # iface_mac will update if attach a new interface iface_mac = iface_mac_old # Additional vm for test additional_vm = None libvirtd = utils_libvirtd.Libvirtd() try: # Build the xml and run test. try: # Prepare interface backend files if test_backend: if not os.path.exists("/dev/vhost-net"): utils.run("modprobe vhost-net") backend = ast.literal_eval(iface_backend) backend_tap = "/dev/net/tun" backend_vhost = "/dev/vhost-net" if not backend: backend["tap"] = backend_tap backend["vhost"] = backend_vhost if not start_error: # Create backend files for normal test if not os.path.exists(backend["tap"]): os.rename(backend_tap, backend["tap"]) if not os.path.exists(backend["vhost"]): os.rename(backend_vhost, backend["vhost"]) # Edit the interface xml. if change_option: modify_iface_xml(update=False) # Check vhost driver. if test_vhost_net: if os.path.exists("/dev/vhost-net"): cmd = ("modprobe -r {0}; lsmod | " "grep {0}".format("vhost_net")) if not utils.system(cmd, ignore_status=True): raise error.TestError("Can't remove " "vhost_net driver") # Attach a interface when vm is shutoff if attach_device == 'config': iface_mac = utils_net.generate_mac_address_simple() iface_xml_obj = create_iface_xml(iface_mac) iface_xml_obj.xmltreefile.write() ret = virsh.attach_device(vm_name, iface_xml_obj.xml, flagstr="--config", ignore_status=True) libvirt.check_exit_status(ret) # Clone additional vm if additional_guest: guest_name = "%s_%s" % (vm_name, '1') # Clone additional guest timeout = params.get("clone_timeout", 360) utils_libguestfs.virt_clone_cmd(vm_name, guest_name, True, timeout=timeout) additional_vm = vm.clone(guest_name) additional_vm.start() #additional_vm.wait_for_login() # Start the VM. if unprivileged_user: virsh.start(vm_name, **virsh_dargs) cmd = ("su - %s -c 'virsh console %s'" % (unprivileged_user, vm_name)) session = aexpect.ShellSession(cmd) session.sendline() remote.handle_prompts(session, params.get("username"), params.get("password"), "[\#\$]", 30) # Get ip address on guest if not get_guest_ip(session, iface_mac): raise error.TestError("Can't get ip address on guest") else: # Will raise VMStartError exception if start fails vm.start() if serial_login: session = vm.wait_for_serial_login() else: session = vm.wait_for_login() if start_error: raise error.TestFail("VM started unexpectedly") if test_vhost_net: if utils.system("lsmod | grep vhost_net", ignore_status=True): raise error.TestFail("vhost_net module can't be" " loaded automatically") # Attach a interface when vm is running if attach_device == 'live': iface_mac = utils_net.generate_mac_address_simple() iface_xml_obj = create_iface_xml(iface_mac) iface_xml_obj.xmltreefile.write() ret = virsh.attach_device(vm_name, iface_xml_obj.xml, flagstr="--live", ignore_status=True) libvirt.check_exit_status(ret) # Need sleep here for attachment take effect time.sleep(5) # Update a interface options if update_device: modify_iface_xml(update=True, status_error=status_error) # Run tests for qemu-kvm command line options if test_option_cmd: run_cmdline_test(iface_mac) # Run tests for vm xml if test_option_xml: run_xml_test(iface_mac) # Run tests for offloads options if test_option_offloads: if iface_driver_host: ifname_guest = utils_net.get_linux_ifname( session, iface_mac) check_offloads_option( ifname_guest, ast.literal_eval( iface_driver_host), session) if iface_driver_guest: ifname_host = libvirt.get_ifname_host(vm_name, iface_mac) check_offloads_option( ifname_host, ast.literal_eval(iface_driver_guest)) if test_iface_user: # Test user type network check_user_network(session) if test_iface_mcast: # Test mcast type network check_mcast_network(session) # Check guest ip address if test_guest_ip: if not get_guest_ip(session, iface_mac): raise error.TestFail("Guest can't get a" " valid ip address") session.close() # Restart libvirtd and guest, then test again if test_libvirtd: libvirtd.restart() vm.destroy() vm.start() if test_option_xml: run_xml_test(iface_mac) # Detach hot/cold-plugged interface at last if attach_device: ret = virsh.detach_device(vm_name, iface_xml_obj.xml, flagstr="", ignore_status=True) libvirt.check_exit_status(ret) except virt_vm.VMStartError, e: logging.info(str(e)) if start_error: pass else: raise error.TestFail('VM Failed to start for some reason!') finally: # Recover VM. logging.info("Restoring vm...") # Restore interface backend files if test_backend: if not os.path.exists(backend_tap): os.rename(backend["tap"], backend_tap) if not os.path.exists(backend_vhost): os.rename(backend["vhost"], backend_vhost) if unprivileged_user: virsh.remove_domain(vm_name, "--remove-all-storage", **virsh_dargs) if additional_vm: virsh.remove_domain(additional_vm.name, "--remove-all-storage") # Kill all omping server process on host utils.system("pidof omping && killall omping", ignore_status=True) if vm.is_alive(): vm.destroy(gracefully=False) vmxml_backup.sync()
def run(test, params, env): """ Verify guest NIC numbers again whats provided in test config file. If the guest NICs info does not match whats in the params at first, try to fix these by operating the networking config file. 1. Boot guest with multi NICs. 2. Check whether guest NICs info match with params setting. 3. Create configure file for every NIC interface in guest. 4. Reboot guest. 5. Check whether guest NICs info match with params setting. :param test: QEMU test object :param params: Dictionary with the test parameters :param env: Dictionary with test environment. """ def check_nics_num(expect_c, session): txt = "Check whether guest NICs info match with params setting." error.context(txt, logging.info) nics_list = utils_net.get_linux_ifname(session) actual_c = len(nics_list) msg = "Expected NICs count is: %d\n" % expect_c msg += "Actual NICs count is: %d\n" % actual_c if not expect_c == actual_c: msg += "Nics count mismatch!\n" return (False, msg) return (True, msg + 'Nics count match') vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) # Redirect ifconfig output from guest to log file log_file = os.path.join(test.debugdir, "ifconfig") ifconfig_output = session.cmd("ifconfig") log_file_object = open(log_file, "w") log_file_object.write(ifconfig_output) # Get the ethernet cards number from params nics_num = len(params.objects("nics")) logging.info("[ %s ] NICs card specified in config file" % nics_num) # Pre-judgement for the ethernet interface logging.debug(check_nics_num(nics_num, session)[1]) txt = "Create configure file for every NIC interface in guest." error.context(txt, logging.info) ifname_list = utils_net.get_linux_ifname(session) ifcfg_path = "/etc/sysconfig/network-scripts/ifcfg-%s" for ifname in ifname_list: eth_config_path = ifcfg_path % ifname eth_config = """DEVICE=%s BOOTPROTO=dhcp ONBOOT=yes """ % ifname cmd = "echo '%s' > %s" % (eth_config, eth_config_path) s, o = session.get_command_status_output(cmd) if s != 0: err_msg = "Failed to create ether config file: %s\nReason is: %s" raise error.TestError(err_msg % (eth_config_path, o)) # Reboot and check the configurations. new_session = vm.reboot(session) s, msg = check_nics_num(nics_num, new_session) if not s: raise error.TestFail(msg) # NICs matched. logging.info(msg)