Example #1
0
    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)
Example #3
0
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)
Example #4
0
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()
Example #5
0
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)
Example #6
0
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")
Example #7
0
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()
Example #8
0
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()
Example #9
0
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()
Example #10
0
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))
Example #11
0
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()
Example #12
0
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)
Example #13
0
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()