def get_MSIs_and_queues_windows(): """ Get msi&queues infomation of currentwindows guest. First start a traceview session, then restart the nic interface to trigger logging. By analyzing the dumped output, the msi& queue info is acquired. :return: a tuple of (msis, queues) """ session_serial = vm.wait_for_serial_login(login_timeout) # start traceview error_context.context("Start trace view with pdb file", logging.info) log_path = "c:\\logfile.etl" clean_cmd = "del %s" % log_path session_serial.cmd(clean_cmd) traceview_local_path = "c:\\traceview.exe" pdb_local_path = "c:\\netkvm.pdb" start_traceview_cmd = "%s -start test_session -pdb %s -level 5 -flag 0x1fff -f %s" start_traceview_cmd %= (traceview_local_path, pdb_local_path, log_path) session_serial.cmd(start_traceview_cmd) # restart nic error_context.context("Restart guest nic", logging.info) mac = vm.get_mac_address(0) connection_id = utils_net.get_windows_nic_attribute( session_serial, "macaddress", mac, "netconnectionid") utils_net.restart_windows_guest_network(session_serial, connection_id) # stop traceview error_context.context("Stop traceview", logging.info) stop_traceview_cmd = "%s -stop test_session" % traceview_local_path session_serial.cmd(stop_traceview_cmd) # checkout traceview output error_context.context("Check etl file generated by traceview", logging.info) dump_file = "c:\\trace.txt" _remove_file(session_serial, dump_file) dump_cmd = "%s -process %s -pdb %s -o %s" dump_cmd %= (traceview_local_path, log_path, pdb_local_path, dump_file) status, output = session_serial.cmd_status_output(dump_cmd) if status: test.error("Cann't dump log file %s: %s" % (log_path, output)) time.sleep(100) status, output = session_serial.cmd_status_output( "taskkill /im traceview.exe && type %s" % dump_file) if status: test.error("Cann't read dumped file %s: %s" % (dump_file, output)) return get_MSI_queue_from_traceview_output(output)
def get_MSIs_and_queues_windows(): """ Get msi&queues infomation of currentwindows guest. First start a traceview session, then restart the nic interface to trigger logging. By analyzing the dumped output, the msi& queue info is acquired. :return: a tuple of (msis, queues) """ session_serial = vm.wait_for_serial_login(login_timeout) # start traceview error_context.context("Start trace view with pdb file", logging.info) log_path = "c:\\logfile.etl" clean_cmd = "del %s" % log_path session_serial.cmd(clean_cmd) traceview_local_path = "c:\\traceview.exe" pdb_local_path = "c:\\netkvm.pdb" start_traceview_cmd = "%s -start test_session -pdb %s -level 5 -flag 0x1fff -f %s" start_traceview_cmd %= (traceview_local_path, pdb_local_path, log_path) session_serial.cmd(start_traceview_cmd) # restart nic error_context.context("Restart guest nic", logging.info) mac = vm.get_mac_address(0) connection_id = utils_net.get_windows_nic_attribute(session_serial, "macaddress", mac, "netconnectionid") utils_net.restart_windows_guest_network(session_serial, connection_id) # stop traceview error_context.context("Stop traceview", logging.info) stop_traceview_cmd = "%s -stop test_session" % traceview_local_path session_serial.cmd(stop_traceview_cmd) # checkout traceview output error_context.context("Check etl file generated by traceview", logging.info) dump_file = "c:\\trace.txt" _remove_file(session_serial, dump_file) dump_cmd = "%s -process %s -pdb %s -o %s" dump_cmd %= (traceview_local_path, log_path, pdb_local_path, dump_file) status, output = session_serial.cmd_status_output(dump_cmd) if status: test.error("Cann't dump log file %s: %s" % (log_path, output)) time.sleep(100) status, output = session_serial.cmd_status_output("taskkill /im traceview.exe && type %s" % dump_file) if status: test.error("Cann't read dumped file %s: %s" % (dump_file, output)) return get_MSI_queue_from_traceview_output(output)
def run(test, params, env): """ Test the RX jumbo frame function of vnics: 1) Boot the VM. 2) Change the MTU of guest nics and host taps depending on the NIC model. 3) Add the static ARP entry for guest NIC. 4) Wait for the MTU ok. 5) Verify the path MTU using ping. 6) Ping the guest with large frames. 7) Increment size ping. 8) Flood ping the guest with large frames. 9) Verify the path MTU. 10) Recover the MTU. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_ovs_ports(ovs): ''' get the ovs bridge all Interface list. :param ovs: Ovs bridge name ''' cmd = "ovs-vsctl list-ports %s" % ovs return process.getoutput(cmd, shell=True) netdst = params.get("netdst", "switch") host_bridges = utils_net.find_bridge_manager(netdst) if not isinstance(host_bridges, utils_net.Bridge): ovs = host_bridges host_hw_interface = get_ovs_ports(netdst) tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}", host_hw_interface) if tmp_ports: for p in tmp_ports: process.system_output("ovs-vsctl del-port %s %s" % (netdst, p)) params["start_vm"] = "yes" env_process.preprocess_vm(test, params, env, params["main_vm"]) timeout = int(params.get("login_timeout", 360)) mtu_default = 1500 mtu = params.get("mtu", "1500") def_max_icmp_size = int(mtu) - 28 max_icmp_pkt_size = int(params.get("max_icmp_pkt_size", def_max_icmp_size)) flood_time = params.get("flood_time", "300") os_type = params.get("os_type") os_variant = params.get("os_variant") vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) session_serial = vm.wait_for_serial_login(timeout=timeout) ifname = vm.get_ifname(0) guest_ip = vm.get_address(0) if guest_ip is None: test.error("Could not get the guest ip address") host_mtu_cmd = "ifconfig %s mtu %s" if not isinstance(host_bridges, utils_net.Bridge): target_ifaces = set(get_ovs_ports(netdst).splitlines()) else: br_in_use = host_bridges.list_br() ifaces_in_use = host_bridges.list_iface() target_ifaces = set(ifaces_in_use) - set(br_in_use) 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), shell=True) try: error_context.context("Changing the MTU of guest", logging.info) # Environment preparation mac = vm.get_mac_address(0) if os_type == "linux": ethname = utils_net.get_linux_ifname(session, mac) guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname, mtu) else: connection_id = utils_net.get_windows_nic_attribute( session, "macaddress", mac, "netconnectionid") index = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "pnpdeviceid") cd_num = utils_misc.get_winutils_vol(session) copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_num session.cmd(copy_cmd) reg_set_mtu_pattern = params.get("reg_mtu_cmd") mtu_key_word = params.get("mtu_key", "MTU") reg_set_mtu = reg_set_mtu_pattern % (int(index), mtu_key_word, int(mtu)) guest_mtu_cmd = "%s " % reg_set_mtu session.cmd(guest_mtu_cmd) if os_type == "windows": mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) error_context.context("Chaning the MTU of host tap ...", logging.info) host_mtu_cmd = "ifconfig %s mtu %s" # Before change macvtap mtu, must set the base interface mtu if params.get("nettype") == "macvtap": base_if = utils_net.get_macvtap_base_iface(params.get("netdst")) process.run(host_mtu_cmd % (base_if, mtu), shell=True) process.run(host_mtu_cmd % (ifname, mtu), shell=True) error_context.context("Add a temporary static ARP entry ...", logging.info) arp_add_cmd = "arp -s %s %s -i %s" % (guest_ip, mac, ifname) process.run(arp_add_cmd, shell=True) def is_mtu_ok(): status, _ = utils_test.ping(guest_ip, 1, packetsize=max_icmp_pkt_size, hint="do", timeout=2) return status == 0 def verify_mtu(): logging.info("Verify the path MTU") status, output = utils_test.ping(guest_ip, 10, packetsize=max_icmp_pkt_size, hint="do", timeout=15) if status != 0: logging.error(output) test.fail("Path MTU is not as expected") if utils_test.get_loss_ratio(output) != 0: logging.error(output) test.fail("Packet loss ratio during MTU " "verification is not zero") def flood_ping(): logging.info("Flood with large frames") utils_test.ping(guest_ip, packetsize=max_icmp_pkt_size, flood=True, timeout=float(flood_time)) def large_frame_ping(count=100): logging.info("Large frame ping") _, output = utils_test.ping(guest_ip, count, packetsize=max_icmp_pkt_size, timeout=float(count) * 2) ratio = utils_test.get_loss_ratio(output) if ratio != 0: test.fail("Loss ratio of large frame ping is %s" % ratio) def size_increase_ping(step=random.randrange(90, 110)): logging.info("Size increase ping") for size in range(0, max_icmp_pkt_size + 1, step): logging.info("Ping %s with size %s", guest_ip, size) status, output = utils_test.ping(guest_ip, 1, packetsize=size, hint="do", timeout=1) if status != 0: status, output = utils_test.ping(guest_ip, 10, packetsize=size, adaptive=True, hint="do", timeout=20) fail_ratio = int(params.get("fail_ratio", 50)) if utils_test.get_loss_ratio(output) > fail_ratio: test.fail("Ping loss ratio is greater " "than 50% for size %s" % size) logging.info("Waiting for the MTU to be OK") wait_mtu_ok = 10 if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1): logging.debug( process.getoutput("ifconfig -a", verbose=False, ignore_status=True, shell=True)) test.error("MTU is not as expected even after %s " "seconds" % wait_mtu_ok) # Functional Test error_context.context("Checking whether MTU change is ok", logging.info) verify_mtu() large_frame_ping() size_increase_ping() # Stress test flood_ping() verify_mtu() finally: # Environment clean if session: session.close() grep_cmd = "grep '%s.*%s' /proc/net/arp" % (guest_ip, ifname) if process.system(grep_cmd, shell=True) == '0': process.run("arp -d %s -i %s" % (guest_ip, ifname), shell=True) logging.info("Removing the temporary ARP entry successfully") logging.info("Change back Bridge NICs MTU to %s", mtu_default) for iface in target_ifaces: process.run(host_mtu_cmd % (iface, mtu_default), shell=True)
def run_mac_change(test, params, env): """ Change MAC address of guest. 1) Get a new mac from pool, and the old mac addr of guest. 2) Set new mac in guest and regain new IP. 3) Re-log into guest with new MAC. @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) # This session will be used to assess whether the IP change worked session = vm.wait_for_login(timeout=timeout) old_mac = vm.get_mac_address(0) while True: vm.virtnet.free_mac_address(0) new_mac = vm.virtnet.generate_mac_address(0) if old_mac != new_mac: break os_type = params.get("os_type") os_variant = params.get("os_variant") change_cmd_pattern = params.get("change_cmd") logging.info("The initial MAC address is %s", old_mac) if os_type == "linux": interface = utils_net.get_linux_ifname(session_serial, old_mac) if params.get("shutdown_int", "yes") == "yes": int_shutdown_cmd = params.get("int_shutdown_cmd", "ifconfig %s down") session_serial.cmd(int_shutdown_cmd % interface) else: connection_id = utils_net.get_windows_nic_attribute( session, "macaddress", old_mac, "netconnectionid") nic_index = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "pnpdeviceid") cd_drive = utils_misc.get_winutils_vol(session) copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_drive session.cmd(copy_cmd) # Start change MAC address error.context("Changing MAC address to %s" % new_mac, logging.info) if os_type == "linux": change_cmd = change_cmd_pattern % (interface, new_mac) else: change_cmd = change_cmd_pattern % (int(nic_index), "".join( new_mac.split(":"))) try: session_serial.cmd(change_cmd) # Verify whether MAC address was changed to the new one error.context("Verify the new mac address, and restart the network", logging.info) if os_type == "linux": if params.get("shutdown_int", "yes") == "yes": int_activate_cmd = params.get("int_activate_cmd", "ifconfig %s up") session_serial.cmd(int_activate_cmd % interface) session_serial.cmd("ifconfig | grep -i %s" % new_mac) logging.info("Mac address change successfully, net restart...") dhclient_cmd = "dhclient -r && dhclient %s" % interface session_serial.sendline(dhclient_cmd) else: mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) o = session_serial.cmd("ipconfig /all") if not re.findall("%s" % "-".join(new_mac.split(":")), o, re.I): raise error.TestFail("Guest mac change failed") logging.info("Guest mac have been modified successfully") # Re-log into the guest after changing mac address if utils_misc.wait_for(session.is_responsive, 120, 20, 3): # Just warning when failed to see the session become dead, # because there is a little chance the ip does not change. logging.warn("The session is still responsive, settings may fail.") session.close() # Re-log into guest and check if session is responsive error.context("Re-log into the guest", logging.info) session = vm.wait_for_login(timeout=timeout) if not session.is_responsive(): raise error.TestFail("The new session is not responsive.") finally: if os_type == "windows": clean_cmd_pattern = params.get("clean_cmd") clean_cmd = clean_cmd_pattern % int(nic_index) session_serial.cmd(clean_cmd) utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) nic = vm.virtnet[0] nic.mac = old_mac vm.virtnet.update_db() session.close()
def run(test, params, env): """ Test the RX jumbo frame function of vnics: 1) Boot the VM. 2) Change the MTU of guest nics and host taps depending on the NIC model. 3) Add the static ARP entry for guest NIC. 4) Wait for the MTU ok. 5) Verify the path MTU using ping. 6) Ping the guest with large frames. 7) Increment size ping. 8) Flood ping the guest with large frames. 9) Verify the path MTU. 10) Recover the MTU. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def get_ovs_ports(ovs): ''' get the ovs bridge all Interface list. :param ovs: Ovs bridge name ''' cmd = "ovs-vsctl list-ports %s" % ovs return process.getoutput(cmd, shell=True) netdst = params.get("netdst", "switch") host_bridges = utils_net.find_bridge_manager(netdst) if not isinstance(host_bridges, utils_net.Bridge): ovs = host_bridges host_hw_interface = get_ovs_ports(netdst) tmp_ports = re.findall(r"t[0-9]{1,}-[a-zA-Z0-9]{6}", host_hw_interface) if tmp_ports: for p in tmp_ports: process.system_output("ovs-vsctl del-port %s %s" % (netdst, p)) params["start_vm"] = "yes" env_process.preprocess_vm(test, params, env, params["main_vm"]) timeout = int(params.get("login_timeout", 360)) mtu_default = 1500 mtu = params.get("mtu", "1500") def_max_icmp_size = int(mtu) - 28 max_icmp_pkt_size = int(params.get("max_icmp_pkt_size", def_max_icmp_size)) flood_time = params.get("flood_time", "300") os_type = params.get("os_type") os_variant = params.get("os_variant") vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) session_serial = vm.wait_for_serial_login(timeout=timeout) ifname = vm.get_ifname(0) guest_ip = vm.get_address(0) if guest_ip is None: test.error("Could not get the guest ip address") host_mtu_cmd = "ifconfig %s mtu %s" if not isinstance(host_bridges, utils_net.Bridge): target_ifaces = set(get_ovs_ports(netdst).splitlines()) else: br_in_use = host_bridges.list_br() ifaces_in_use = host_bridges.list_iface() target_ifaces = set(ifaces_in_use) - set(br_in_use) 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), shell=True) try: error_context.context("Changing the MTU of guest", logging.info) # Environment preparation mac = vm.get_mac_address(0) if os_type == "linux": ethname = utils_net.get_linux_ifname(session, mac) guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname, mtu) else: connection_id = utils_net.get_windows_nic_attribute( session, "macaddress", mac, "netconnectionid") index = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "pnpdeviceid") cd_num = utils_misc.get_winutils_vol(session) copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_num session.cmd(copy_cmd) reg_set_mtu_pattern = params.get("reg_mtu_cmd") mtu_key_word = params.get("mtu_key", "MTU") reg_set_mtu = reg_set_mtu_pattern % (int(index), mtu_key_word, int(mtu)) guest_mtu_cmd = "%s " % reg_set_mtu session.cmd(guest_mtu_cmd) if os_type == "windows": mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) error_context.context("Chaning the MTU of host tap ...", logging.info) host_mtu_cmd = "ifconfig %s mtu %s" # Before change macvtap mtu, must set the base interface mtu if params.get("nettype") == "macvtap": base_if = utils_net.get_macvtap_base_iface(params.get("netdst")) process.run(host_mtu_cmd % (base_if, mtu), shell=True) process.run(host_mtu_cmd % (ifname, mtu), shell=True) error_context.context("Add a temporary static ARP entry ...", logging.info) arp_add_cmd = "arp -s %s %s -i %s" % (guest_ip, mac, ifname) process.run(arp_add_cmd, shell=True) def is_mtu_ok(): status, _ = utils_test.ping(guest_ip, 1, packetsize=max_icmp_pkt_size, hint="do", timeout=2) return status == 0 def verify_mtu(): logging.info("Verify the path MTU") status, output = utils_test.ping(guest_ip, 10, packetsize=max_icmp_pkt_size, hint="do", timeout=15) if status != 0: logging.error(output) test.fail("Path MTU is not as expected") if utils_test.get_loss_ratio(output) != 0: logging.error(output) test.fail("Packet loss ratio during MTU " "verification is not zero") def flood_ping(): logging.info("Flood with large frames") utils_test.ping(guest_ip, packetsize=max_icmp_pkt_size, flood=True, timeout=float(flood_time)) def large_frame_ping(count=100): logging.info("Large frame ping") _, output = utils_test.ping(guest_ip, count, packetsize=max_icmp_pkt_size, timeout=float(count) * 2) ratio = utils_test.get_loss_ratio(output) if ratio != 0: test.fail("Loss ratio of large frame ping is %s" % ratio) def size_increase_ping(step=random.randrange(90, 110)): logging.info("Size increase ping") for size in range(0, max_icmp_pkt_size + 1, step): logging.info("Ping %s with size %s", guest_ip, size) status, output = utils_test.ping(guest_ip, 1, packetsize=size, hint="do", timeout=1) if status != 0: status, output = utils_test.ping(guest_ip, 10, packetsize=size, adaptive=True, hint="do", timeout=20) fail_ratio = int(params.get("fail_ratio", 50)) if utils_test.get_loss_ratio(output) > fail_ratio: test.fail("Ping loss ratio is greater " "than 50% for size %s" % size) logging.info("Waiting for the MTU to be OK") wait_mtu_ok = 10 if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1): logging.debug(process.getoutput("ifconfig -a", verbose=False, ignore_status=True, shell=True)) test.error("MTU is not as expected even after %s " "seconds" % wait_mtu_ok) # Functional Test error_context.context("Checking whether MTU change is ok", logging.info) verify_mtu() large_frame_ping() size_increase_ping() # Stress test flood_ping() verify_mtu() finally: # Environment clean if session: session.close() grep_cmd = "grep '%s.*%s' /proc/net/arp" % (guest_ip, ifname) if process.system(grep_cmd, shell=True) == '0': process.run("arp -d %s -i %s" % (guest_ip, ifname), shell=True) logging.info("Removing the temporary ARP entry successfully") logging.info("Change back Bridge NICs MTU to %s" % mtu_default) for iface in target_ifaces: process.run(host_mtu_cmd % (iface, mtu_default), shell=True)
def run_jumbo(test, params, env): """ Test the RX jumbo frame function of vnics: 1) Boot the VM. 2) Change the MTU of guest nics and host taps depending on the NIC model. 3) Add the static ARP entry for guest NIC. 4) Wait for the MTU ok. 5) Verify the path MTU using ping. 6) Ping the guest with large frames. 7) Increment size ping. 8) Flood ping the guest with large frames. 9) Verify the path MTU. 10) Recover the MTU. :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)) mtu = params.get("mtu", "1500") max_icmp_pkt_size = int(mtu) - 28 flood_time = params.get("flood_time", "300") os_type = params.get("os_type") os_variant = params.get("os_variant") vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) session_serial = vm.wait_for_serial_login(timeout=timeout) ifname = vm.get_ifname(0) ip = vm.get_address(0) if ip is None: raise error.TestError("Could not get the IP address") try: error.context("Changing the MTU of guest", logging.info) # Environment preparation mac = vm.get_mac_address(0) if os_type == "linux": ethname = utils_net.get_linux_ifname(session, mac) guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname, mtu) else: connection_id = utils_net.get_windows_nic_attribute( session, "macaddress", mac, "netconnectionid") index = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "pnpdeviceid") cd_num = utils_misc.get_winutils_vol(session) copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_num session.cmd(copy_cmd) reg_set_mtu_pattern = params.get("reg_mtu_cmd") mtu_key_word = params.get("mtu_key", "MTU") reg_set_mtu = reg_set_mtu_pattern % (int(index), mtu_key_word, int(mtu)) guest_mtu_cmd = "%s " % reg_set_mtu session.cmd(guest_mtu_cmd) if os_type == "windows": mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) error.context("Chaning the MTU of host tap ...", logging.info) host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu) utils.run(host_mtu_cmd) error.context("Add a temporary static ARP entry ...", logging.info) arp_add_cmd = "arp -s %s %s -i %s" % (ip, mac, ifname) utils.run(arp_add_cmd) def is_mtu_ok(): s, _ = utils_test.ping(ip, 1, interface=ifname, packetsize=max_icmp_pkt_size, hint="do", timeout=2) return s == 0 def verify_mtu(): logging.info("Verify the path MTU") s, o = utils_test.ping(ip, 10, interface=ifname, packetsize=max_icmp_pkt_size, hint="do", timeout=15) if s != 0: logging.error(o) raise error.TestFail("Path MTU is not as expected") if utils_test.get_loss_ratio(o) != 0: logging.error(o) raise error.TestFail("Packet loss ratio during MTU " "verification is not zero") def flood_ping(): logging.info("Flood with large frames") utils_test.ping(ip, interface=ifname, packetsize=max_icmp_pkt_size, flood=True, timeout=float(flood_time)) def large_frame_ping(count=100): logging.info("Large frame ping") _, o = utils_test.ping(ip, count, interface=ifname, packetsize=max_icmp_pkt_size, timeout=float(count) * 2) ratio = utils_test.get_loss_ratio(o) if ratio != 0: raise error.TestFail("Loss ratio of large frame ping is %s" % ratio) def size_increase_ping(step=random.randrange(90, 110)): logging.info("Size increase ping") for size in range(0, max_icmp_pkt_size + 1, step): logging.info("Ping %s with size %s", ip, size) s, o = utils_test.ping(ip, 1, interface=ifname, packetsize=size, hint="do", timeout=1) if s != 0: s, o = utils_test.ping(ip, 10, interface=ifname, packetsize=size, adaptive=True, hint="do", timeout=20) if utils_test.get_loss_ratio(o) > int( params.get("fail_ratio", 50)): raise error.TestFail("Ping loss ratio is greater " "than 50% for size %s" % size) logging.info("Waiting for the MTU to be OK") wait_mtu_ok = 10 if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1): logging.debug(commands.getoutput("ifconfig -a")) raise error.TestError("MTU is not as expected even after %s " "seconds" % wait_mtu_ok) # Functional Test error.context("Checking whether MTU change is ok", logging.info) verify_mtu() large_frame_ping() size_increase_ping() # Stress test flood_ping() verify_mtu() finally: # Environment clean if session: session.close() if utils.system("grep '%s.*%s' /proc/net/arp" % (ip, ifname)) == '0': utils.run("arp -d %s -i %s" % (ip, ifname)) logging.info("Removing the temporary ARP entry successfully")
def run(test, params, env): """ Test 802.1Q vlan of NIC. For Linux guest: 1) Create two VMs. 2) load 8021q module in guest. 3) Setup vlans by 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. For Windows guest: 1) Create two VMs. 2) Set vlan tag in every guest and guest will get subnet ip(169.254) automatically. 3) Test by ping between same vlan of two VMs. :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def add_vlan(test, 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' """ vlan_if = '%s.%s' % (iface, v_id) txt = "Create vlan interface '%s' on %s" % (vlan_if, iface) error_context.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" test.error(err_msg) session.cmd(cmd) def set_ip_vlan(session, v_id, vlan_ip, iface="eth0"): """ Set ip address of vlan interface """ iface = "%s.%s" % (iface, v_id) txt = "Assign IP '%s' to vlan interface '%s'" % (vlan_ip, iface) error_context.context(txt, logging.info) session.cmd("ifconfig %s %s" % (iface, vlan_ip)) def set_arp_ignore(session): """ Enable arp_ignore for all ipv4 device in guest """ error_context.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(test, 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" test.error(err_msg) error_context.context("Remove vlan interface '%s'." % v_iface, logging.info) return session.cmd_status(rem_vlan_cmd) def nc_transfer(test, src, dst): """ Transfer file by netcat """ 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") sessions[dst].sendline(listen_cmd) time.sleep(2) # send file from src to dst send_cmd = send_cmd % (vlan_ip[dst], str(nc_port), "file") sessions[src].cmd(send_cmd, timeout=60) try: sessions[dst].read_up_to_prompt(timeout=60) except aexpect.ExpectError: # kill server session_ctl[dst].cmd_output_safe("killall -9 nc") test.fail("Fail to receive file" " from vm%s to vm%s" % (src + 1, dst + 1)) # check MD5 message digest of receive file in dst output = sessions[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) test.fail("File transferred differ from origin") sessions[dst].cmd("rm -f receive") def flood_ping(src, dst): """ Flood ping test # we must use a dedicated session because the aexpect # does not have the other method to interrupt the process in # the guest rather than close the session. """ txt = "Flood ping from %s interface %s to %s" % ( vms[src].name, ifname[src], vlan_ip[dst]) error_context.context(txt, logging.info) session_flood = vms[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() def get_netkvmco_path(session): """ Get the proper netkvmco.dll path from iso. :param session: a session to send cmd :return: the proper netkvmco.dll path """ viowin_ltr = virtio_win.drive_letter_iso(session) if not viowin_ltr: err = "Could not find virtio-win drive in guest" test.error(err) guest_name = virtio_win.product_dirname_iso(session) if not guest_name: err = "Could not get product dirname of the vm" test.error(err) guest_arch = virtio_win.arch_dirname_iso(session) if not guest_arch: err = "Could not get architecture dirname of the vm" test.error(err) middle_path = "%s\\%s" % (guest_name, guest_arch) find_cmd = 'dir /b /s %s\\netkvmco.dll | findstr "\\%s\\\\"' find_cmd %= (viowin_ltr, middle_path) netkvmco_path = session.cmd(find_cmd).strip() logging.info("Found netkvmco.dll file at %s", netkvmco_path) return netkvmco_path vms = [] sessions = [] session_ctl = [] 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", 4094)) file_size = params.get("file_size", 4096) cmd_type = params.get("cmd_type", "ip") login_timeout = int(params.get("login_timeout", 360)) prepare_netkvmco_cmd = params.get("prepare_netkvmco_cmd") set_vlan_cmd = params.get("set_vlan_cmd") vms.append(env.get_vm(params["main_vm"])) vms.append(env.get_vm("vm2")) for vm_ in vms: vm_.verify_alive() for vm_index, vm in enumerate(vms): if params["os_type"] == "windows": session = vm.wait_for_login(timeout=login_timeout) session = utils_test.qemu.windrv_check_running_verifier( session, vm, test, "netkvm") netkvmco_path = get_netkvmco_path(session) session.cmd(prepare_netkvmco_cmd % netkvmco_path, timeout=240) session.close() session = vm.wait_for_serial_login(timeout=login_timeout) session.cmd(set_vlan_cmd) dev_mac = vm.virtnet[0].mac connection_id = utils_net.get_windows_nic_attribute( session, "macaddress", dev_mac, "netconnectionid") utils_net.restart_windows_guest_network(session, connection_id) time.sleep(10) nicid = utils_net.get_windows_nic_attribute( session=session, key="netenabled", value=True, target="netconnectionID") ifname.append(nicid) vm_ip.append( utils_net.get_guest_ip_addr(session, dev_mac, os_type="windows", linklocal=True)) logging.debug("IP address is %s in %s", vm_ip, vm.name) session_ctl.append(session) continue error_context.base_context("Prepare test env on %s" % vm.name) session = vm.wait_for_login(timeout=login_timeout) if not session: err_msg = "Could not log into guest %s" % vm.name test.error(err_msg) sessions.append(session) logging.info("Logged in %s successful", vm.name) session_ctl.append(vm.wait_for_login(timeout=login_timeout)) ifname.append(utils_net.get_linux_ifname(session, vm.get_mac_address())) # get guest ip vm_ip.append(vm.get_address()) logging.debug("IP address is %s in %s", vm_ip, vm.name) # produce sized file in vm dd_cmd = "dd if=/dev/urandom of=file bs=1M count=%s" session.cmd(dd_cmd % file_size) # record MD5 message digest of file md5sum_output = session.cmd("md5sum file", timeout=60) digest_origin.append(re.findall(r'(\w+)', md5sum_output)[0]) # stop firewall in vm stop_firewall_cmd = "systemctl stop firewalld||service firewalld stop" session.cmd_output_safe(stop_firewall_cmd) error_context.context("Load 8021q module in guest %s" % vm.name, logging.info) session.cmd_output_safe("modprobe 8021q") error_context.context("Setup vlan environment in guest %s" % vm.name, logging.info) for vlan_i in range(1, vlan_num + 1): add_vlan(test, session, vlan_i, ifname[vm_index], cmd_type) v_ip = "%s.%s.%s" % (subnet, vlan_i, ip_unit[vm_index]) set_ip_vlan(session, vlan_i, v_ip, ifname[vm_index]) set_arp_ignore(session) if params["os_type"] == "windows": for vm_index, vm in enumerate(vms): status, output = utils_test.ping(dest=vm_ip[(vm_index + 1) % 2], count=10, session=session_ctl[vm_index], timeout=30) loss = utils_test.get_loss_ratio(output) if not loss and ("TTL=" in output): pass # window get loss=0 when ping fail sometimes, need further check else: test.fail( "Guests ping test hit unexpected loss, error info: %s" % output) for sess in session_ctl: if sess: sess.close() return try: for vlan in range(1, vlan_num + 1): error_context.base_context("Test for vlan %s" % vlan, logging.info) error_context.context("Ping test between vlans", logging.info) interface = ifname[0] + '.' + str(vlan) for vm_index, vm in enumerate(vms): for vlan2 in range(1, vlan_num + 1): interface = ifname[vm_index] + '.' + str(vlan) dest = ".".join( (subnet, str(vlan2), ip_unit[(vm_index + 1) % 2])) status, output = utils_test.ping( dest, count=2, interface=interface, session=sessions[vm_index], timeout=30) if ((vlan == vlan2) ^ (status == 0)): err_msg = "%s ping %s unexpected, " % (interface, dest) err_msg += "error info: %s" % output test.fail(err_msg) error_context.context("Flood ping between vlans", logging.info) vlan_ip[0] = ".".join((subnet, str(vlan), ip_unit[0])) vlan_ip[1] = ".".join((subnet, str(vlan), ip_unit[1])) flood_ping(0, 1) flood_ping(1, 0) error_context.context("Transferring data between vlans by nc", logging.info) nc_transfer(test, 0, 1) nc_transfer(test, 1, 0) finally: # If client can not connect the nc server, need kill the server. for session in session_ctl: session.cmd_output_safe("killall -9 nc") error_context.base_context("Remove vlan") for vm_index, vm in enumerate(vms): for vlan in range(1, vlan_num + 1): status = rem_vlan(test, sessions[vm_index], vlan, ifname[vm_index], cmd_type) if status: logging.error("Remove vlan %s failed", vlan) # Plumb/unplumb maximal number of vlan interfaces if params.get("do_maximal_test", "no") == "yes": bound = maximal + 1 try: error_context.base_context("Vlan scalability test") error_context.context("Testing the plumb of vlan interface", logging.info) for vlan_index in range(1, bound): add_vlan(test, sessions[0], vlan_index, ifname[0], cmd_type) vlan_added = vlan_index if vlan_added != maximal: test.fail("Maximal interface plumb test failed") finally: for vlan_index in range(1, vlan_added + 1): if rem_vlan(test, sessions[0], vlan_index, ifname[0], cmd_type): logging.error("Remove vlan %s failed", vlan_index) error_context.base_context("Vlan negative test") error_context.context("Create vlan with ID %s in guest" % bound, logging.info) try: add_vlan(test, sessions[0], bound, ifname[0], cmd_type) test.fail("Maximal ID allow to vlan is %s" % maximal) except aexpect.ShellCmdError as detail: pattern = params["msg_pattern"] if not re.search(pattern, detail.output, re.M | re.I): raise sessions.extend(session_ctl) for sess in sessions: if sess: sess.close()
def run_mac_change(test, params, env): """ Change MAC address of guest. 1) Get a new mac from pool, and the old mac addr of guest. 2) Set new mac in guest and regain new IP. 3) Re-log into guest with new MAC. @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) # This session will be used to assess whether the IP change worked session = vm.wait_for_login(timeout=timeout) old_mac = vm.get_mac_address(0) while True: vm.virtnet.free_mac_address(0) new_mac = vm.virtnet.generate_mac_address(0) if old_mac != new_mac: break os_type = params.get("os_type") change_cmd_pattern = params.get("change_cmd") logging.info("The initial MAC address is %s", old_mac) if os_type == "linux": interface = utils_net.get_linux_ifname(session_serial, old_mac) else: connection_id = utils_net.get_windows_nic_attribute(session, "macaddress", old_mac, "netconnectionid") nic_index = utils_net.get_windows_nic_attribute(session, "netconnectionid", connection_id, "index") # Start change MAC address error.context("Changing MAC address to %s" % new_mac, logging.info) if os_type == "linux": change_cmd = change_cmd_pattern % (interface, interface, new_mac, interface) else: change_cmd = change_cmd_pattern % (int(nic_index), "".join(new_mac.split(":"))) try: session_serial.cmd(change_cmd) # Verify whether MAC address was changed to the new one error.context("Verify the new mac address, and restart the network", logging.info) if os_type == "linux": session_serial.cmd("ifconfig | grep -i %s" % new_mac) logging.info("Mac address change successfully, net restart...") dhclient_cmd = "dhclient -r && dhclient %s" % interface session_serial.sendline(dhclient_cmd) else: utils_net.restart_windows_guest_network(session_serial, connection_id) o = session_serial.cmd("ipconfig /all") if not re.findall("%s" % "-".join(new_mac.split(":")), o, re.I): raise error.TestFail("Guest mac change failed") logging.info("Guest mac have been modified successfully") # Re-log into the guest after changing mac address if utils_misc.wait_for(session.is_responsive, 120, 20, 3): # Just warning when failed to see the session become dead, # because there is a little chance the ip does not change. logging.warn("The session is still responsive, settings may fail.") session.close() # Re-log into guest and check if session is responsive error.context("Re-log into the guest", logging.info) session = vm.wait_for_login(timeout=timeout) if not session.is_responsive(): raise error.TestFail("The new session is not responsive.") finally: if os_type == "windows": clean_cmd_pattern = params.get("clean_cmd") clean_cmd = clean_cmd_pattern % int(nic_index) session_serial.cmd(clean_cmd) utils_net.restart_windows_guest_network(session_serial, connection_id) nic = vm.virtnet[0] nic.mac = old_mac vm.virtnet.update_db() session.close()
def run(test, params, env): """ Change MAC address of guest. 1) Get a new mac from pool, and the old mac addr of guest. 2) Check guest mac by qmp command. 3) Set new mac in guest and regain new IP. 4) Check guest new mac by qmp command. 5) Re-log into guest with new MAC. (nettype != macvtap) 6) Reboot guest and check the the mac address by monitor(optional). 7) File transfer between host and guest. optional :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) # This session will be used to assess whether the IP change worked if params.get("nettype") != "macvtap": session = vm.wait_for_login(timeout=timeout) old_mac = vm.get_mac_address(0) while True: vm.virtnet.free_mac_address(0) new_mac = vm.virtnet.generate_mac_address(0) if old_mac != new_mac: break os_type = params.get("os_type") os_variant = params.get("os_variant") change_cmd_pattern = params.get("change_cmd") logging.info("The initial MAC address is %s", old_mac) check_guest_mac(old_mac, vm) if os_type == "linux": interface = utils_net.get_linux_ifname(session_serial, old_mac) if params.get("shutdown_int", "yes") == "yes": int_shutdown_cmd = params.get("int_shutdown_cmd", "ifconfig %s down") session_serial.cmd(int_shutdown_cmd % interface) else: connection_id = utils_net.get_windows_nic_attribute(session_serial, "macaddress", old_mac, "netconnectionid") nic_index = utils_net.get_windows_nic_attribute(session_serial, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute(session, "netconnectionid", connection_id, "pnpdeviceid") cd_drive = utils_misc.get_winutils_vol(session) copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_drive session.cmd(copy_cmd) # Start change MAC address error.context("Changing MAC address to %s" % new_mac, logging.info) if os_type == "linux": change_cmd = change_cmd_pattern % (interface, new_mac) else: change_cmd = change_cmd_pattern % (int(nic_index), "".join(new_mac.split(":"))) try: session_serial.cmd(change_cmd) # Verify whether MAC address was changed to the new one error.context("Verify the new mac address, and restart the network", logging.info) if os_type == "linux": if params.get("shutdown_int", "yes") == "yes": int_activate_cmd = params.get("int_activate_cmd", "ifconfig %s up") session_serial.cmd(int_activate_cmd % interface) session_serial.cmd("ifconfig | grep -i %s" % new_mac) logging.info("Mac address change successfully, net restart...") dhclient_cmd = "dhclient -r && dhclient %s" % interface session_serial.sendline(dhclient_cmd) else: mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) o = session_serial.cmd("ipconfig /all") if not re.findall("%s" % "-".join(new_mac.split(":")), o, re.I): raise error.TestFail("Guest mac change failed") logging.info("Guest mac have been modified successfully") if params.get("nettype") != "macvtap": # Re-log into the guest after changing mac address if utils_misc.wait_for(session.is_responsive, 120, 20, 3): # Just warning when failed to see the session become dead, # because there is a little chance the ip does not change. msg = "The session is still responsive, settings may fail." logging.warn(msg) session.close() # Re-log into guest and check if session is responsive error.context("Re-log into the guest", logging.info) session = vm.wait_for_login(timeout=timeout) if not session.is_responsive(): raise error.TestFail("The new session is not responsive.") if params.get("reboot_vm_after_mac_changed") == "yes": error.context("Reboot guest and check the the mac address by " "monitor", logging.info) mac_check = new_mac if os_type == "linux": nic = vm.virtnet[0] nic.mac = old_mac vm.virtnet.update_db() mac_check = old_mac session_serial = vm.reboot(session_serial, serial=True) check_guest_mac(mac_check, vm) if params.get("file_transfer", "no") == "yes": error.context("File transfer between host and guest.", logging.info) utils_test.run_file_transfer(test, params, env) else: check_guest_mac(new_mac, vm) finally: if os_type == "windows": clean_cmd_pattern = params.get("clean_cmd") clean_cmd = clean_cmd_pattern % int(nic_index) session_serial.cmd(clean_cmd) utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) nic = vm.virtnet[0] nic.mac = old_mac vm.virtnet.update_db()
def run_jumbo(test, params, env): """ Test the RX jumbo frame function of vnics: 1) Boot the VM. 2) Change the MTU of guest nics and host taps depending on the NIC model. 3) Add the static ARP entry for guest NIC. 4) Wait for the MTU ok. 5) Verify the path MTU using ping. 6) Ping the guest with large frames. 7) Increment size ping. 8) Flood ping the guest with large frames. 9) Verify the path MTU. 10) Recover the MTU. @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ def get_drive_num(session, path): """ return file path drive """ cmd = "wmic datafile where \"path='%s'\" get drive" % path info = session.cmd_output(cmd, timeout=360).strip() drive_num = re.search(r"(\w):", info, re.M) if not drive_num: raise error.TestError("No path %s in your guest" % path) return drive_num.group() timeout = int(params.get("login_timeout", 360)) mtu = params.get("mtu", "1500") max_icmp_pkt_size = int(mtu) - 28 flood_time = params.get("flood_time", "300") os_type = params.get("os_type") os_variant = params.get("os_variant") vm = env.get_vm(params["main_vm"]) vm.verify_alive() session = vm.wait_for_login(timeout=timeout) session_serial = vm.wait_for_serial_login(timeout=timeout) ifname = vm.get_ifname(0) ip = vm.get_address(0) if ip is None: raise error.TestError("Could not get the IP address") try: error.context("Changing the MTU of guest", logging.info) # Environment preparation mac = vm.get_mac_address(0) if os_type == "linux": ethname = utils_net.get_linux_ifname(session, mac) guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname, mtu) else: connection_id = utils_net.get_windows_nic_attribute(session, "macaddress", mac, "netconnectionid") index = utils_net.get_windows_nic_attribute(session, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "pnpdeviceid" ) devcon_path = r"\\devcon\\wxp_x86\\" cd_num = get_drive_num(session, devcon_path) copy_cmd = r"xcopy %s\devcon\wxp_x86\devcon.exe c:\ " % cd_num session.cmd(copy_cmd) reg_set_mtu_pattern = params.get("reg_mtu_cmd") mtu_key_word = params.get("mtu_key", "MTU") reg_set_mtu = reg_set_mtu_pattern % (int(index), mtu_key_word, int(mtu)) guest_mtu_cmd = "%s " % reg_set_mtu session.cmd(guest_mtu_cmd) if os_type == "windows": mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) error.context("Chaning the MTU of host tap ...", logging.info) host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu) utils.run(host_mtu_cmd) error.context("Add a temporary static ARP entry ...", logging.info) arp_add_cmd = "arp -s %s %s -i %s" % (ip, mac, ifname) utils.run(arp_add_cmd) def is_mtu_ok(): s, _ = utils_test.ping(ip, 1, interface=ifname, packetsize=max_icmp_pkt_size, hint="do", timeout=2) return s == 0 def verify_mtu(): logging.info("Verify the path MTU") s, o = utils_test.ping(ip, 10, interface=ifname, packetsize=max_icmp_pkt_size, hint="do", timeout=15) if s != 0: logging.error(o) raise error.TestFail("Path MTU is not as expected") if utils_test.get_loss_ratio(o) != 0: logging.error(o) raise error.TestFail("Packet loss ratio during MTU " "verification is not zero") def flood_ping(): logging.info("Flood with large frames") utils_test.ping(ip, interface=ifname, packetsize=max_icmp_pkt_size, flood=True, timeout=float(flood_time)) def large_frame_ping(count=100): logging.info("Large frame ping") _, o = utils_test.ping(ip, count, interface=ifname, packetsize=max_icmp_pkt_size, timeout=float(count) * 2) ratio = utils_test.get_loss_ratio(o) if ratio != 0: raise error.TestFail("Loss ratio of large frame ping is %s" % ratio) def size_increase_ping(step=random.randrange(90, 110)): logging.info("Size increase ping") for size in range(0, max_icmp_pkt_size + 1, step): logging.info("Ping %s with size %s", ip, size) s, o = utils_test.ping(ip, 1, interface=ifname, packetsize=size, hint="do", timeout=1) if s != 0: s, o = utils_test.ping( ip, 10, interface=ifname, packetsize=size, adaptive=True, hint="do", timeout=20 ) if utils_test.get_loss_ratio(o) > int(params.get("fail_ratio", 50)): raise error.TestFail("Ping loss ratio is greater " "than 50% for size %s" % size) logging.info("Waiting for the MTU to be OK") wait_mtu_ok = 10 if not utils_misc.wait_for(is_mtu_ok, wait_mtu_ok, 0, 1): logging.debug(commands.getoutput("ifconfig -a")) raise error.TestError("MTU is not as expected even after %s " "seconds" % wait_mtu_ok) # Functional Test error.context("Checking whether MTU change is ok", logging.info) verify_mtu() large_frame_ping() size_increase_ping() # Stress test flood_ping() verify_mtu() finally: # Environment clean if session: session.close() logging.info("Removing the temporary ARP entry") utils.run("arp -d %s -i %s" % (ip, ifname))
def run_mac_change(test, params, env): """ Change MAC address of guest. 1) Get a new mac from pool, and the old mac addr of guest. 2) Set new mac in guest and regain new IP. 3) Re-log into guest with new MAC. @param test: QEMU test object. @param params: Dictionary with the test parameters. @param env: Dictionary with test environment. """ def get_drive_num(session, path): """ return file path drive """ cmd = "wmic datafile where \"path='%s'\" get drive" % path info = session.cmd_output(cmd, timeout=360).strip() drive_num = re.search(r'(\w):', info, re.M) if not drive_num: raise error.TestError("No path %s in your guest" % path) return drive_num.group() 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) # This session will be used to assess whether the IP change worked session = vm.wait_for_login(timeout=timeout) old_mac = vm.get_mac_address(0) while True: vm.virtnet.free_mac_address(0) new_mac = vm.virtnet.generate_mac_address(0) if old_mac != new_mac: break os_type = params.get("os_type") os_variant = params.get("os_variant") change_cmd_pattern = params.get("change_cmd") logging.info("The initial MAC address is %s", old_mac) if os_type == "linux": interface = utils_net.get_linux_ifname(session_serial, old_mac) else: connection_id = utils_net.get_windows_nic_attribute(session, "macaddress", old_mac, "netconnectionid") nic_index = utils_net.get_windows_nic_attribute(session, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute(session, "netconnectionid", connection_id, "pnpdeviceid") devcon_path = r"\\devcon\\wxp_x86\\" cd_drive = get_drive_num(session, devcon_path) copy_cmd = r"xcopy %s\devcon\wxp_x86\devcon.exe c:\ " % cd_drive session.cmd(copy_cmd) # Start change MAC address error.context("Changing MAC address to %s" % new_mac, logging.info) if os_type == "linux": change_cmd = change_cmd_pattern % (interface, interface, new_mac, interface) else: change_cmd = change_cmd_pattern % (int(nic_index), "".join(new_mac.split(":"))) try: session_serial.cmd(change_cmd) # Verify whether MAC address was changed to the new one error.context("Verify the new mac address, and restart the network", logging.info) if os_type == "linux": session_serial.cmd("ifconfig | grep -i %s" % new_mac) logging.info("Mac address change successfully, net restart...") dhclient_cmd = "dhclient -r && dhclient %s" % interface session_serial.sendline(dhclient_cmd) else: mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) o = session_serial.cmd("ipconfig /all") if not re.findall("%s" % "-".join(new_mac.split(":")), o, re.I): raise error.TestFail("Guest mac change failed") logging.info("Guest mac have been modified successfully") # Re-log into the guest after changing mac address if utils_misc.wait_for(session.is_responsive, 120, 20, 3): # Just warning when failed to see the session become dead, # because there is a little chance the ip does not change. logging.warn("The session is still responsive, settings may fail.") session.close() # Re-log into guest and check if session is responsive error.context("Re-log into the guest", logging.info) session = vm.wait_for_login(timeout=timeout) if not session.is_responsive(): raise error.TestFail("The new session is not responsive.") finally: if os_type == "windows": clean_cmd_pattern = params.get("clean_cmd") clean_cmd = clean_cmd_pattern % int(nic_index) session_serial.cmd(clean_cmd) utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) nic = vm.virtnet[0] nic.mac = old_mac vm.virtnet.update_db() session.close()
def run(test, params, env): """ Run ctrl_vlan check test. 1) Boot vm with ctrl_vlan=on/off 2) Verify if netkvm.sys is enabled in guest(only windows) 3) Check vlan table in rx-filter information 4) If ctrl_vlan=on, do step 5-6 5) Set vlan in guest 6) Check vlan table in rx-filter information again :param test: QEMU test object. :param params: Dictionary with the test parameters. :param env: Dictionary with test environment. """ def verify_vlan_table(expect_vlan=None): error_context.context("Check vlan table in rx-filter", logging.info) query_cmd = "query-rx-filter name=%s" % vm.virtnet[0].device_id vlan_table = vm.monitor.send_args_cmd(query_cmd)[0].get("vlan-table") if not expect_vlan: vlan_table.sort() if (len(set(vlan_table)) == 4095 and vlan_table[0] == 0 and vlan_table[-1] == 4094): pass else: test.fail("Guest vlan table is not correct, expect: %s," " actual: %s" % (expect_vlan, vlan_table)) elif vlan_table and vlan_table[0] != int(expect_vlan): test.fail( "Guest vlan table is not correct, expect: %s, actual: %s" % (expect_vlan, vlan_table[0])) def get_netkvmco_path(session): """ Get the proper netkvmco.dll path from iso. :param session: a session to send cmd :return: the proper netkvmco.dll path """ viowin_ltr = virtio_win.drive_letter_iso(session) if not viowin_ltr: err = "Could not find virtio-win drive in guest" test.error(err) guest_name = virtio_win.product_dirname_iso(session) if not guest_name: err = "Could not get product dirname of the vm" test.error(err) guest_arch = virtio_win.arch_dirname_iso(session) if not guest_arch: err = "Could not get architecture dirname of the vm" test.error(err) middle_path = "%s\\%s" % (guest_name, guest_arch) find_cmd = 'dir /b /s %s\\netkvmco.dll | findstr "\\%s\\\\"' find_cmd %= (viowin_ltr, middle_path) netkvmco_path = session.cmd(find_cmd).strip() logging.info("Found netkvmco.dll file at %s", netkvmco_path) return netkvmco_path login_timeout = float(params.get("login_timeout", 360)) error_context.context("Init the VM, and try to login", logging.info) vm = env.get_vm(params["main_vm"]) vm.verify_alive() if ("ctrl_vlan=on" in params["nic_extra_params"] and params["os_type"] == "linux"): expect_vlan = vm.virtnet[0].vlan else: expect_vlan = None if "ctrl_vlan=on" in params["nic_extra_params"]: error_context.context("Add vlan tag for guest network", logging.info) vlan_set_cmd = params["vlan_set_cmd"] vlan_id = params["vlan_id"] try: if params["os_type"] == "linux": session = vm.wait_for_serial_login(timeout=login_timeout) verify_vlan_table(expect_vlan) ifname = utils_net.get_linux_ifname(session, vm.virtnet[0].mac) vlan_set_cmd = vlan_set_cmd % (ifname, ifname, ifname, ifname) status, output = session.cmd_status_output(vlan_set_cmd) if status: test.error( "Error occured when set vlan tag for network interface: %s, " "err info: %s " % (ifname, output)) else: driver_verifier = params["driver_verifier"] session = vm.wait_for_login(timeout=login_timeout) error_context.context( "Verify if netkvm.sys is enabled in guest", logging.info) session = utils_test.qemu.windrv_check_running_verifier( session, vm, test, driver_verifier, timeout=120) verify_vlan_table(expect_vlan) ifname = utils_net.get_windows_nic_attribute( session=session, key="netenabled", value=True, target="netconnectionID") netkvmco_path = get_netkvmco_path(session) prepare_netkvmco_cmd = params.get("prepare_netkvmco_cmd") session.cmd(prepare_netkvmco_cmd % netkvmco_path, timeout=240) session.close() session = vm.wait_for_serial_login(timeout=login_timeout) status, output = session.cmd_status_output(vlan_set_cmd) if status: test.error("Error occured when set vlan tag for " "network interface: %s, err info: %s " % (ifname, output)) # restart nic for windows guest dev_mac = vm.virtnet[0].mac connection_id = utils_net.get_windows_nic_attribute( session, "macaddress", dev_mac, "netconnectionid") utils_net.restart_windows_guest_network(session, connection_id) time.sleep(10) finally: if session: session.close() verify_vlan_table(vlan_id)
def run(test, params, env): """ Change MAC address of guest. 1) Get a new mac from pool, and the old mac addr of guest. 2) Check guest mac by qmp command. 3) Set new mac in guest and regain new IP. 4) Check guest new mac by qmp command. 5) Re-log into guest with new MAC. (nettype != macvtap) 6) Reboot guest and check the the mac address by monitor(optional). 7) File transfer between host and guest. optional :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) # This session will be used to assess whether the IP change worked if params.get("nettype") != "macvtap": session = vm.wait_for_login(timeout=timeout) old_mac = vm.get_mac_address(0) while True: vm.virtnet.free_mac_address(0) new_mac = vm.virtnet.generate_mac_address(0) if old_mac != new_mac: break os_type = params.get("os_type") os_variant = params.get("os_variant") change_cmd_pattern = params.get("change_cmd") logging.info("The initial MAC address is %s", old_mac) check_guest_mac(test, old_mac, vm) if os_type == "linux": interface = utils_net.get_linux_ifname(session_serial, old_mac) if params.get("shutdown_int", "yes") == "yes": int_shutdown_cmd = params.get("int_shutdown_cmd", "ifconfig %s down") session_serial.cmd_output_safe(int_shutdown_cmd % interface) else: connection_id = utils_net.get_windows_nic_attribute( session_serial, "macaddress", old_mac, "netconnectionid") nic_index = utils_net.get_windows_nic_attribute( session_serial, "netconnectionid", connection_id, "index") if os_variant == "winxp": pnpdevice_id = utils_net.get_windows_nic_attribute( session, "netconnectionid", connection_id, "pnpdeviceid") cd_drive = utils_misc.get_winutils_vol(session) copy_cmd = r"xcopy %s:\devcon\wxp_x86\devcon.exe c:\ " % cd_drive session.cmd(copy_cmd) # Start change MAC address error_context.context("Changing MAC address to %s" % new_mac, logging.info) if os_type == "linux": change_cmd = change_cmd_pattern % (interface, new_mac) else: change_cmd = change_cmd_pattern % (int(nic_index), "".join( new_mac.split(":"))) try: session_serial.cmd_output_safe(change_cmd) # Verify whether MAC address was changed to the new one error_context.context( "Verify the new mac address, and restart the network", logging.info) if os_type == "linux": if params.get("shutdown_int", "yes") == "yes": int_activate_cmd = params.get("int_activate_cmd", "ifconfig %s up") session_serial.cmd_output_safe(int_activate_cmd % interface) session_serial.cmd_output_safe("ifconfig | grep -i %s" % new_mac) logging.info("Mac address change successfully, net restart...") dhclient_cmd = "dhclient -r && dhclient %s" % interface session_serial.sendline(dhclient_cmd) else: mode = "netsh" if os_variant == "winxp": connection_id = pnpdevice_id.split("&")[-1] mode = "devcon" utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) o = session_serial.cmd_output_safe("ipconfig /all") if params.get("ctrl_mac_addr") == "off": mac_check = old_mac else: mac_check = new_mac if not re.findall("%s" % "-".join(mac_check.split(":")), o, re.I): test.fail("Guest mac change failed") logging.info("Guest mac have been modified successfully") if params.get("nettype") != "macvtap": # Re-log into the guest after changing mac address if utils_misc.wait_for(session.is_responsive, 120, 20, 3): # Just warning when failed to see the session become dead, # because there is a little chance the ip does not change. msg = "The session is still responsive, settings may fail." logging.warn(msg) session.close() # In the following case, mac address should not change, # so set the old_mac back to virtnet cache # Or the vm will not able to be logined(no ip for the virtnet[0].mac) if os_type == "windows" and params.get("ctrl_mac_addr") == "off": nic = vm.virtnet[0] nic.mac = old_mac vm.virtnet.update_db() # Re-log into guest and check if session is responsive error_context.context("Re-log into the guest", logging.info) session = vm.wait_for_login(timeout=timeout) if not session.is_responsive(): test.error("The new session is not responsive.") if params.get("reboot_vm_after_mac_changed") == "yes": error_context.context( "Reboot guest and check the the mac address by " "monitor", logging.info) mac_check = new_mac if os_type == "linux": nic = vm.virtnet[0] nic.mac = old_mac vm.virtnet.update_db() mac_check = old_mac else: if params.get("ctrl_mac_addr") == "off": mac_check = old_mac session_serial = vm.reboot(session_serial, serial=True) check_guest_mac(test, mac_check, vm) if params.get("file_transfer", "no") == "yes": error_context.context("File transfer between host and guest.", logging.info) utils_test.run_file_transfer(test, params, env) else: if params.get("ctrl_mac_addr") == "off": check_guest_mac(test, old_mac, vm) else: check_guest_mac(test, new_mac, vm) finally: if os_type == "windows": clean_cmd_pattern = params.get("clean_cmd") clean_cmd = clean_cmd_pattern % int(nic_index) session_serial.cmd_output_safe(clean_cmd) utils_net.restart_windows_guest_network(session_serial, connection_id, mode=mode) nic = vm.virtnet[0] nic.mac = old_mac vm.virtnet.update_db()