Esempio n. 1
0
def run_nic_promisc(test, params, env):
    """
    Test nic driver in promisc mode:

    1) Boot up a VM.
    2) Repeatedly enable/disable promiscuous mode in guest.
    3) Transfer file from host to guest, and from guest to host in the same time

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    ethname = utils_test.get_linux_ifname(session_serial,
                                          vm.get_mac_address(0))

    try:
        transfer_thread = utils.InterruptedThread(utils_test.run_file_transfer,
                                                  (test, params, env))
        transfer_thread.start()
        while transfer_thread.isAlive():
            session_serial.cmd("ip link set %s promisc on" % ethname)
            session_serial.cmd("ip link set %s promisc off" % ethname)
    except Exception:
        transfer_thread.join(suppress_exception=True)
        raise
    else:
        transfer_thread.join()
Esempio n. 2
0
def run_nic_promisc(test, params, env):
    """
    Test nic driver in promisc mode:

    1) Boot up a VM.
    2) Repeatedly enable/disable promiscuous mode in guest.
    3) Transfer file from host to guest, and from guest to host in the same time

    @param test: QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    ethname = utils_test.get_linux_ifname(session_serial,
                                              vm.get_mac_address(0))

    try:
        transfer_thread = utils.InterruptedThread(
                                               utils_test.run_file_transfer,
                                               (test, params, env))
        transfer_thread.start()
        while transfer_thread.isAlive():
            session_serial.cmd("ip link set %s promisc on" % ethname)
            session_serial.cmd("ip link set %s promisc off" % ethname)
    except Exception:
        transfer_thread.join(suppress_exception=True)
        raise
    else:
        transfer_thread.join()
Esempio n. 3
0
def run_nicdriver_unload(test, params, env):
    """
    Test nic driver.

    1) Boot a VM.
    2) Get the NIC driver name.
    3) Repeatedly unload/load NIC driver.
    4) Multi-session TCP transfer on test interface.
    5) Check whether the test interface should still work.

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    ethname = utils_test.get_linux_ifname(session_serial,
                                          vm.get_mac_address(0))

    # get ethernet driver from '/sys' directory.
    # ethtool can do the same thing and doesn't care about os type.
    # if we make sure all guests have ethtool, we can make a change here.
    sys_path = params.get("sys_path") % (ethname)

    # readlink in RHEL4.8 doesn't have '-e' param, should use '-f' in RHEL4.8.
    readlink_cmd = params.get("readlink_command", "readlink -e")
    driver = os.path.basename(
        session_serial.cmd("%s %s" % (readlink_cmd, sys_path)).strip())

    logging.info("driver is %s", driver)

    try:
        threads = []
        for _ in range(int(params.get("sessions_num", "10"))):
            thread = utils.InterruptedThread(utils_test.run_file_transfer,
                                             (test, params, env))
            thread.start()
            threads.append(thread)

        time.sleep(10)
        while threads[0].isAlive():
            session_serial.cmd("sleep 10")
            session_serial.cmd("ifconfig %s down" % ethname)
            session_serial.cmd("modprobe -r %s" % driver)
            session_serial.cmd("modprobe %s" % driver)
            session_serial.cmd("ifconfig %s up" % ethname)
    except Exception:
        for thread in threads:
            thread.join(suppress_exception=True)
            raise
    else:
        for thread in threads:
            thread.join()
Esempio n. 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: KVM 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
    logging.info("The initial MAC address is %s", old_mac)
    interface = utils_test.get_linux_ifname(session_serial, old_mac)
    # Start change MAC address
    logging.info("Changing MAC address to %s", new_mac)
    change_cmd = ("ifconfig %s down && ifconfig %s hw ether %s && "
                  "ifconfig %s up" %
                  (interface, interface, new_mac, interface))
    session_serial.cmd(change_cmd)

    # Verify whether MAC address was changed to the new one
    logging.info("Verifying the new mac address")
    session_serial.cmd("ifconfig | grep -i %s" % new_mac)

    # Restart `dhclient' to regain IP for new mac address
    logging.info("Restart the network to gain new IP")
    dhclient_cmd = "dhclient -r && dhclient %s" % interface
    session_serial.sendline(dhclient_cmd)

    # 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
    logging.info("Re-log into the guest")
    session = vm.wait_for_login(timeout=timeout)
    if not session.is_responsive():
        raise error.TestFail("The new session is not responsive.")

    session.close()
Esempio n. 5
0
def run_nicdriver_unload(test, params, env):
    """
    Test nic driver.

    1) Boot a VM.
    2) Get the NIC driver name.
    3) Repeatedly unload/load NIC driver.
    4) Multi-session TCP transfer on test interface.
    5) Check whether the test interface should still work.

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    ethname = utils_test.get_linux_ifname(session_serial,
                                               vm.get_mac_address(0))

    # get ethernet driver from '/sys' directory.
    # ethtool can do the same thing and doesn't care about os type.
    # if we make sure all guests have ethtool, we can make a change here.
    sys_path = params.get("sys_path") % (ethname)

    # readlink in RHEL4.8 doesn't have '-e' param, should use '-f' in RHEL4.8.
    readlink_cmd = params.get("readlink_command", "readlink -e")
    driver = os.path.basename(session_serial.cmd("%s %s" % (readlink_cmd,
                                                 sys_path)).strip())

    logging.info("driver is %s", driver)

    try:
        threads = []
        for _ in range(int(params.get("sessions_num", "10"))):
            thread = utils.InterruptedThread(utils_test.run_file_transfer,
                                             (test, params, env))
            thread.start()
            threads.append(thread)

        time.sleep(10)
        while threads[0].isAlive():
            session_serial.cmd("sleep 10")
            session_serial.cmd("ifconfig %s down" % ethname)
            session_serial.cmd("modprobe -r %s" % driver)
            session_serial.cmd("modprobe %s" % driver)
            session_serial.cmd("ifconfig %s up" % ethname)
    except Exception:
        for thread in threads:
            thread.join(suppress_exception=True)
            raise
    else:
        for thread in threads:
            thread.join()
Esempio n. 6
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
    logging.info("The initial MAC address is %s", old_mac)
    interface = utils_test.get_linux_ifname(session_serial, old_mac)
    # Start change MAC address
    logging.info("Changing MAC address to %s", new_mac)
    change_cmd = ("ifconfig %s down && ifconfig %s hw ether %s && "
                  "ifconfig %s up" % (interface, interface, new_mac, interface))
    session_serial.cmd(change_cmd)

    # Verify whether MAC address was changed to the new one
    logging.info("Verifying the new mac address")
    session_serial.cmd("ifconfig | grep -i %s" % new_mac)

    # Restart `dhclient' to regain IP for new mac address
    logging.info("Restart the network to gain new IP")
    dhclient_cmd = "dhclient -r && dhclient %s" % interface
    session_serial.sendline(dhclient_cmd)

    # 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
    logging.info("Re-log into the guest")
    session = vm.wait_for_login(timeout=timeout)
    if not session.is_responsive():
        raise error.TestFail("The new session is not responsive.")

    session.close()
Esempio n. 7
0
def run_vlan(test, params, env):
    """
    Test 802.1Q vlan of NIC, config it by vconfig command.

    1) Create two VMs.
    2) Setup guests in 10 different vlans by vconfig and using hard-coded
       ip address.
    3) Test by ping between same and different vlans of two VMs.
    4) Test by TCP data transfer, floop ping between same vlan of two VMs.
    5) Test maximal plumb/unplumb vlans.
    6) Recover the vlan config.

    @param test: QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    vm = []
    session = []
    ifname = []
    vm_ip = []
    digest_origin = []
    vlan_ip = ['', '']
    ip_unit = ['1', '2']
    subnet = params.get("subnet")
    vlan_num = int(params.get("vlan_num"))
    maximal = int(params.get("maximal"))
    file_size = params.get("file_size")

    vm.append(env.get_vm(params["main_vm"]))
    vm.append(env.get_vm("vm2"))
    for vm_ in vm:
        vm_.verify_alive()

    def add_vlan(session, v_id, iface="eth0"):
        session.cmd("vconfig add %s %s" % (iface, v_id))

    def set_ip_vlan(session, v_id, ip, iface="eth0"):
        iface = "%s.%s" % (iface, v_id)
        session.cmd("ifconfig %s %s" % (iface, ip))

    def set_arp_ignore(session, iface="eth0"):
        ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore"
        session.cmd(ignore_cmd)

    def rem_vlan(session, v_id, iface="eth0"):
        rem_vlan_cmd = "if [[ -e /proc/net/vlan/%s ]];then vconfig rem %s;fi"
        iface = "%s.%s" % (iface, v_id)
        return session.cmd_status(rem_vlan_cmd % (iface, iface))

    def nc_transfer(src, dst):
        nc_port = utils_misc.find_free_port(1025, 5334, vm_ip[dst])
        listen_cmd = params.get("listen_cmd")
        send_cmd = params.get("send_cmd")

        #listen in dst
        listen_cmd = listen_cmd % (nc_port, "receive")
        session[dst].sendline(listen_cmd)
        time.sleep(2)
        #send file from src to dst
        send_cmd = send_cmd % (vlan_ip[dst], str(nc_port), "file")
        session[src].cmd(send_cmd, timeout=60)
        try:
            session[dst].read_up_to_prompt(timeout=60)
        except aexpect.ExpectError:
            raise error.TestFail ("Fail to receive file"
                                    " from vm%s to vm%s" % (src+1, dst+1))
        #check MD5 message digest of receive file in dst
        output = session[dst].cmd_output("md5sum receive").strip()
        digest_receive = re.findall(r'(\w+)', output)[0]
        if digest_receive == digest_origin[src]:
            logging.info("file succeed received in vm %s", vlan_ip[dst])
        else:
            logging.info("digest_origin is  %s", digest_origin[src])
            logging.info("digest_receive is %s", digest_receive)
            raise error.TestFail("File transfered differ from origin")
        session[dst].cmd_output("rm -f receive")

    for i in range(2):
        session.append(vm[i].wait_for_login(
            timeout=int(params.get("login_timeout", 360))))
        if not session[i] :
            raise error.TestError("Could not log into guest(vm%d)" % i)
        logging.info("Logged in")

        ifname.append(utils_test.get_linux_ifname(session[i],
                      vm[i].get_mac_address()))
        #get guest ip
        vm_ip.append(vm[i].get_address())

        #produce sized file in vm
        dd_cmd = "dd if=/dev/urandom of=file bs=1024k count=%s"
        session[i].cmd(dd_cmd % file_size)
        #record MD5 message digest of file
        output = session[i].cmd("md5sum file", timeout=60)
        digest_origin.append(re.findall(r'(\w+)', output)[0])

        #stop firewall in vm
        session[i].cmd_output("/etc/init.d/iptables stop")

        #load 8021q module for vconfig
        session[i].cmd("modprobe 8021q")

    try:
        for i in range(2):
            for vlan_i in range(1, vlan_num+1):
                add_vlan(session[i], vlan_i, ifname[i])
                set_ip_vlan(session[i], vlan_i, "%s.%s.%s" %
                            (subnet, vlan_i, ip_unit[i]), ifname[i])
            set_arp_ignore(session[i], ifname[i])

        for vlan in range(1, vlan_num+1):
            logging.info("Test for vlan %s", vlan)

            logging.info("Ping between vlans")
            interface = ifname[0] + '.' + str(vlan)
            for vlan2 in range(1, vlan_num+1):
                for i in range(2):
                    interface = ifname[i] + '.' + str(vlan)
                    dest = subnet +'.'+ str(vlan2)+ '.' + ip_unit[(i+1)%2]
                    s, _ = utils_test.ping(dest, count=2,
                                              interface=interface,
                                              session=session[i], timeout=30)
                    if ((vlan == vlan2) ^ (s == 0)):
                        raise error.TestFail ("%s ping %s unexpected" %
                                                    (interface, dest))

            vlan_ip[0] = subnet + '.' + str(vlan) + '.' + ip_unit[0]
            vlan_ip[1] = subnet + '.' + str(vlan) + '.' + ip_unit[1]

            logging.info("Flood ping")
            def flood_ping(src, dst):
                # we must use a dedicated session becuase the aexpect
                # does not have the other method to interrupt the process in
                # the guest rather than close the session.
                session_flood = vm[src].wait_for_login(timeout=60)
                utils_test.ping(vlan_ip[dst], flood=True,
                                   interface=ifname[src],
                                   session=session_flood, timeout=10)
                session_flood.close()

            flood_ping(0, 1)
            flood_ping(1, 0)

            logging.info("Transfering data through nc")
            nc_transfer(0, 1)
            nc_transfer(1, 0)

    finally:
        for vlan in range(1, vlan_num+1):
            rem_vlan(session[0], vlan, ifname[0])
            rem_vlan(session[1], vlan, ifname[1])
            logging.info("rem vlan: %s", vlan)

    # Plumb/unplumb maximal number of vlan interfaces
    i = 1
    s = 0
    try:
        logging.info("Testing the plumb of vlan interface")
        for i in range (1, maximal+1):
            add_vlan(session[0], i, ifname[0])
    finally:
        for j in range (1, i+1):
            s = s or rem_vlan(session[0], j, ifname[0])
        if s == 0:
            logging.info("maximal interface plumb test done")
        else:
            logging.error("maximal interface plumb test failed")

    session[0].close()
    session[1].close()
Esempio n. 8
0
            return False
        return True


    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))

    # Let's just error the test if we identify that there's no ethtool installed
    session.cmd("ethtool -h")
    session2 = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
    mtu = 1514
    feature_status = {}
    filename = "/tmp/ethtool.dd"
    guest_ip = vm.get_address()
    ethname = utils_test.get_linux_ifname(session, vm.get_mac_address(0))

    supported_features = params.get("supported_features")
    if supported_features:
        supported_features = supported_features.split()
    else:
        raise error.TestError("No supported features set on the parameters")

    test_matrix = {
        # type:(callback,    (dependence), (exclude)
        "tx":  (tx_callback, (), ()),
        "rx":  (rx_callback, (), ()),
        "sg":  (tx_callback, ("tx",), ()),
        "tso": (so_callback, ("tx", "sg",), ("gso",)),
        "gso": (so_callback, (), ("tso",)),
        "gro": (ro_callback, ("rx",), ("lro",)),
Esempio n. 9
0
def run_nic_hotplug(test, params, env):
    """
    Test hotplug of NIC devices

    1) Boot up guest with one nic
    2) Add a host network device through monitor cmd and check if it's added
    3) Add nic device through monitor cmd and check if it's added
    4) Check if new interface gets ip address
    5) Disable primary link of guest
    6) Ping guest new ip from host
    7) Delete nic device and netdev
    8) Re-enable primary link of guest

    BEWARE OF THE NETWORK BRIDGE DEVICE USED FOR THIS TEST ("nettype=bridge"
    and "netdst=<bridgename>" param).  The KVM autotest default bridge virbr0,
    leveraging libvirt, works fine for the purpose of this test. When using
    other bridges, the timeouts which usually happen when the bridge
    topology changes (that is, devices get added and removed) may cause random
    failures.

    @param test:   QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """
    vm = utils_test.get_living_vm(env, params.get("main_vm"))
    login_timeout = int(params.get("login_timeout", 360))
    pci_model = params.get("pci_model", "rtl8139")
    run_dhclient = params.get("run_dhclient", "no")

    nettype = params.get("nettype", "bridge")
    netdst = params.get("netdst", "virbr0")
    guest_is_not_windows = "Win" not in params.get("guest_name", "")

    session = utils_test.wait_for_login(vm, timeout=login_timeout)

    udev_rules_path = "/etc/udev/rules.d/70-persistent-net.rules"
    udev_rules_bkp_path = "/tmp/70-persistent-net.rules"

    def guest_path_isfile(path):
        try:
            session.cmd("test -f %s" % path)
        except aexpect.ShellError:
            return False
        return True

    if guest_is_not_windows:
        if guest_path_isfile(udev_rules_path):
            session.cmd("mv -f %s %s" % (udev_rules_path, udev_rules_bkp_path))

        # Modprobe the module if specified in config file
        module = params.get("modprobe_module")
        if module:
            session.get_command_output("modprobe %s" % module)

    # hot-add the nic
    nic_name = 'hotadded'
    nic_info = vm.hotplug_nic(nic_model=pci_model, nic_name=nic_name,
                              netdst=netdst, nettype=nettype)

    # Only run dhclient if explicitly set and guest is not running Windows.
    # Most modern Linux guests run NetworkManager, and thus do not need this.
    if run_dhclient == "yes" and guest_is_not_windows:
        session_serial = vm.wait_for_serial_login(timeout=login_timeout)
        ifname = utils_test.get_linux_ifname(session, nic_info['mac'])
        session_serial.cmd("dhclient %s &" % ifname)

    logging.info("Shutting down the primary link(s)")
    for nic in vm.virtnet:
        if not (nic.nic_name == nic_name):
            vm.set_link(nic.device_id, up=False)

    try:
        logging.info("Waiting for new nic's ip address acquisition...")
        try:
            ip = vm.wait_for_get_address(nic_name)
        except virt_vm.VMIPAddressMissingError:
            raise error.TestFail("Could not get or verify ip address of nic")
        logging.info("Got the ip address of new nic: %s", ip)

        logging.info("Ping test the new nic ...")
        s, o = utils_test.ping(ip, 100)
        if s != 0:
            logging.error(o)
            raise error.TestFail("New nic failed ping test")

        logging.info("Detaching the previously attached nic from vm")
        vm.hotunplug_nic(nic_name)

    finally:
        logging.info("Re-enabling the primary link(s)")
        for nic in vm.virtnet:
            if not (nic.nic_name == nic_name):
                vm.set_link(nic.device_id, up=True)

    # Attempt to put back udev network naming rules, even if the command to
    # disable the rules failed. We may be undoing what was done in a previous
    # (failed) test that never reached this point.
    if guest_is_not_windows:
        if guest_path_isfile(udev_rules_bkp_path):
            session.cmd("mv -f %s %s" % (udev_rules_bkp_path, udev_rules_path))
Esempio n. 10
0
def run_nic_hotplug(test, params, env):
    """
    Test hotplug of NIC devices

    1) Boot up guest with one nic
    2) Add a host network device through monitor cmd and check if it's added
    3) Add nic device through monitor cmd and check if it's added
    4) Check if new interface gets ip address
    5) Disable primary link of guest
    6) Ping guest new ip from host
    7) Delete nic device and netdev
    8) Re-enable primary link of guest

    BEWARE OF THE NETWORK BRIDGE DEVICE USED FOR THIS TEST ("nettype=bridge"
    and "netdst=<bridgename>" param).  The KVM autotest default bridge virbr0,
    leveraging libvirt, works fine for the purpose of this test. When using
    other bridges, the timeouts which usually happen when the bridge
    topology changes (that is, devices get added and removed) may cause random
    failures.

    @param test:   KVM test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """
    vm = utils_test.get_living_vm(env, params.get("main_vm"))
    login_timeout = int(params.get("login_timeout", 360))
    pci_model = params.get("pci_model", "rtl8139")
    run_dhclient = params.get("run_dhclient", "no")

    nettype = params.get("nettype", "bridge")
    netdst = params.get("netdst", "virbr0")
    guest_is_not_windows = "Win" not in params.get("guest_name", "")

    session = utils_test.wait_for_login(vm, timeout=login_timeout)

    udev_rules_path = "/etc/udev/rules.d/70-persistent-net.rules"
    udev_rules_bkp_path = "/tmp/70-persistent-net.rules"

    def guest_path_isfile(path):
        try:
            session.cmd("test -f %s" % path)
        except aexpect.ShellError:
            return False
        return True

    if guest_is_not_windows:
        if guest_path_isfile(udev_rules_path):
            session.cmd("mv -f %s %s" % (udev_rules_path, udev_rules_bkp_path))

        # Modprobe the module if specified in config file
        module = params.get("modprobe_module")
        if module:
            session.get_command_output("modprobe %s" % module)

    # hot-add the nic
    nic_name = 'hotadded'
    nic_info = vm.hotplug_nic(nic_model=pci_model, nic_name=nic_name,
                              netdst=netdst, nettype=nettype)

    # Only run dhclient if explicitly set and guest is not running Windows.
    # Most modern Linux guests run NetworkManager, and thus do not need this.
    if run_dhclient == "yes" and guest_is_not_windows:
        session_serial = vm.wait_for_serial_login(timeout=login_timeout)
        ifname = utils_test.get_linux_ifname(session, nic_info['mac'])
        session_serial.cmd("dhclient %s &" % ifname)

    logging.info("Shutting down the primary link(s)")
    for nic in vm.virtnet:
        if nic.nic_name == nic_name:
            continue
        else:
            vm.monitor.cmd("set_link %s off" % nic.device_id)

    try:
        logging.info("Waiting for new nic's ip address acquisition...")
        try:
            ip = vm.wait_for_get_address(nic_name)
        except virt_vm.VMIPAddressMissingError:
            raise error.TestFail("Could not get or verify ip address of nic")
        logging.info("Got the ip address of new nic: %s", ip)

        logging.info("Ping test the new nic ...")
        s, o = utils_test.ping(ip, 100)
        if s != 0:
            logging.error(o)
            raise error.TestFail("New nic failed ping test")

        logging.info("Detaching the previously attached nic from vm")
        vm.hotunplug_nic(nic_name)

    finally:
        logging.info("Re-enabling the primary link(s)")
        for nic in vm.virtnet:
            if nic.nic_name == nic_name:
                continue
            else:
                vm.monitor.cmd("set_link %s on" % nic.device_id)

    # Attempt to put back udev network naming rules, even if the command to
    # disable the rules failed. We may be undoing what was done in a previous
    # (failed) test that never reached this point.
    if guest_is_not_windows:
        if guest_path_isfile(udev_rules_bkp_path):
            session.cmd("mv -f %s %s" % (udev_rules_bkp_path, udev_rules_path))
Esempio n. 11
0
def run_nic_bonding(test, params, env):
    """
    Nic bonding test in guest.

    1) Start guest with four nic models.
    2) Setup bond0 in guest by script nic_bonding_guest.py.
    3) Execute file transfer test between guest and host.
    4) Repeatedly put down/up interfaces by set_link
    5) Execute file transfer test between guest and host.

    @param test: Kvm test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 1200))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    # get params of bonding
    modprobe_cmd = "modprobe bonding"
    bonding_params = params.get("bonding_params")
    if bonding_params:
        modprobe_cmd += " %s" % bonding_params
    session_serial.cmd(modprobe_cmd)

    session_serial.cmd("ifconfig bond0 up")
    ifnames = [utils_test.get_linux_ifname(session_serial,
                                               vm.get_mac_address(vlan))
               for vlan, nic in enumerate(vm.virtnet)]
    setup_cmd = "ifenslave bond0 " + " ".join(ifnames)
    session_serial.cmd(setup_cmd)
    #do a pgrep to check if dhclient has already been running
    pgrep_cmd = "pgrep dhclient"
    try:
        session_serial.cmd(pgrep_cmd)
    #if dhclient is there, killl it
    except aexpect.ShellCmdError:
        logging.info("it's safe to run dhclient now")
    else:
        logging.info("dhclient already is running,kill it")
        session_serial.cmd("killall -9 dhclient")
        time.sleep(1)
    session_serial.cmd("dhclient bond0")

    try:
        logging.info("Test file transfering:")
        utils_test.run_file_transfer(test, params, env)

        logging.info("Failover test with file transfer")
        transfer_thread = utils.InterruptedThread(
                                              utils_test.run_file_transfer,
                                               (test, params, env))
        try:
            transfer_thread.start()
            while transfer_thread.isAlive():
                for vlan, nic in enumerate(vm.virtnet):
                    device_id = vm.get_peer(vm.netdev_id[vlan])
                    if not device_id:
                        raise error.TestError("Could not find peer device for"
                                              " nic device %s" % nic)
                    vm.set_link(device_id, up=False)
                    time.sleep(1)
                    vm.set_link(device_id, up=True)
        except Exception:
            transfer_thread.join(suppress_exception=True)
            raise
        else:
            transfer_thread.join()
    finally:
        session_serial.sendline("ifenslave -d bond0 " + " ".join(ifnames))
        session_serial.sendline("kill -9 `pgrep dhclient`")
Esempio n. 12
0
def run_nic_bonding(test, params, env):
    """
    Nic bonding test in guest.

    1) Start guest with four nic models.
    2) Setup bond0 in guest by script nic_bonding_guest.py.
    3) Execute file transfer test between guest and host.
    4) Repeatedly put down/up interfaces by set_link
    5) Execute file transfer test between guest and host.

    @param test: Kvm test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 1200))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    # get params of bonding
    modprobe_cmd = "modprobe bonding"
    bonding_params = params.get("bonding_params")
    if bonding_params:
        modprobe_cmd += " %s" % bonding_params
    session_serial.cmd(modprobe_cmd)

    session_serial.cmd("ifconfig bond0 up")
    ifnames = [
        utils_test.get_linux_ifname(session_serial, vm.get_mac_address(vlan))
        for vlan, nic in enumerate(vm.virtnet)
    ]
    setup_cmd = "ifenslave bond0 " + " ".join(ifnames)
    session_serial.cmd(setup_cmd)
    #do a pgrep to check if dhclient has already been running
    pgrep_cmd = "pgrep dhclient"
    try:
        session_serial.cmd(pgrep_cmd)
    #if dhclient is there, killl it
    except aexpect.ShellCmdError:
        logging.info("it's safe to run dhclient now")
    else:
        logging.info("dhclient already is running,kill it")
        session_serial.cmd("killall -9 dhclient")
        time.sleep(1)
    session_serial.cmd("dhclient bond0")

    try:
        logging.info("Test file transfering:")
        utils_test.run_file_transfer(test, params, env)

        logging.info("Failover test with file transfer")
        transfer_thread = utils.InterruptedThread(utils_test.run_file_transfer,
                                                  (test, params, env))
        try:
            transfer_thread.start()
            while transfer_thread.isAlive():
                for vlan, nic in enumerate(vm.virtnet):
                    device_id = vm.get_peer(vm.netdev_id[vlan])
                    if not device_id:
                        raise error.TestError("Could not find peer device for"
                                              " nic device %s" % nic)
                    vm.set_link(device_id, up=False)
                    time.sleep(1)
                    vm.set_link(device_id, up=True)
        except Exception:
            transfer_thread.join(suppress_exception=True)
            raise
        else:
            transfer_thread.join()
    finally:
        session_serial.sendline("ifenslave -d bond0 " + " ".join(ifnames))
        session_serial.sendline("kill -9 `pgrep dhclient`")
Esempio n. 13
0
def run_vlan(test, params, env):
    """
    Test 802.1Q vlan of NIC, config it by vconfig command.

    1) Create two VMs.
    2) Setup guests in 10 different vlans by vconfig and using hard-coded
       ip address.
    3) Test by ping between same and different vlans of two VMs.
    4) Test by TCP data transfer, floop ping between same vlan of two VMs.
    5) Test maximal plumb/unplumb vlans.
    6) Recover the vlan config.

    @param test: KVM test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    vm = []
    session = []
    ifname = []
    vm_ip = []
    digest_origin = []
    vlan_ip = ['', '']
    ip_unit = ['1', '2']
    subnet = params.get("subnet")
    vlan_num = int(params.get("vlan_num"))
    maximal = int(params.get("maximal"))
    file_size = params.get("file_size")

    vm.append(env.get_vm(params["main_vm"]))
    vm.append(env.get_vm("vm2"))
    for vm_ in vm:
        vm_.verify_alive()

    def add_vlan(session, v_id, iface="eth0"):
        session.cmd("vconfig add %s %s" % (iface, v_id))

    def set_ip_vlan(session, v_id, ip, iface="eth0"):
        iface = "%s.%s" % (iface, v_id)
        session.cmd("ifconfig %s %s" % (iface, ip))

    def set_arp_ignore(session, iface="eth0"):
        ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore"
        session.cmd(ignore_cmd)

    def rem_vlan(session, v_id, iface="eth0"):
        rem_vlan_cmd = "if [[ -e /proc/net/vlan/%s ]];then vconfig rem %s;fi"
        iface = "%s.%s" % (iface, v_id)
        return session.cmd_status(rem_vlan_cmd % (iface, iface))

    def nc_transfer(src, dst):
        nc_port = utils_misc.find_free_port(1025, 5334, vm_ip[dst])
        listen_cmd = params.get("listen_cmd")
        send_cmd = params.get("send_cmd")

        #listen in dst
        listen_cmd = listen_cmd % (nc_port, "receive")
        session[dst].sendline(listen_cmd)
        time.sleep(2)
        #send file from src to dst
        send_cmd = send_cmd % (vlan_ip[dst], str(nc_port), "file")
        session[src].cmd(send_cmd, timeout=60)
        try:
            session[dst].read_up_to_prompt(timeout=60)
        except aexpect.ExpectError:
            raise error.TestFail ("Fail to receive file"
                                    " from vm%s to vm%s" % (src+1, dst+1))
        #check MD5 message digest of receive file in dst
        output = session[dst].cmd_output("md5sum receive").strip()
        digest_receive = re.findall(r'(\w+)', output)[0]
        if digest_receive == digest_origin[src]:
            logging.info("file succeed received in vm %s", vlan_ip[dst])
        else:
            logging.info("digest_origin is  %s", digest_origin[src])
            logging.info("digest_receive is %s", digest_receive)
            raise error.TestFail("File transfered differ from origin")
        session[dst].cmd_output("rm -f receive")

    for i in range(2):
        session.append(vm[i].wait_for_login(
            timeout=int(params.get("login_timeout", 360))))
        if not session[i] :
            raise error.TestError("Could not log into guest(vm%d)" % i)
        logging.info("Logged in")

        ifname.append(utils_test.get_linux_ifname(session[i],
                      vm[i].get_mac_address()))
        #get guest ip
        vm_ip.append(vm[i].get_address())

        #produce sized file in vm
        dd_cmd = "dd if=/dev/urandom of=file bs=1024k count=%s"
        session[i].cmd(dd_cmd % file_size)
        #record MD5 message digest of file
        output = session[i].cmd("md5sum file", timeout=60)
        digest_origin.append(re.findall(r'(\w+)', output)[0])

        #stop firewall in vm
        session[i].cmd_output("/etc/init.d/iptables stop")

        #load 8021q module for vconfig
        session[i].cmd("modprobe 8021q")

    try:
        for i in range(2):
            for vlan_i in range(1, vlan_num+1):
                add_vlan(session[i], vlan_i, ifname[i])
                set_ip_vlan(session[i], vlan_i, "%s.%s.%s" %
                            (subnet, vlan_i, ip_unit[i]), ifname[i])
            set_arp_ignore(session[i], ifname[i])

        for vlan in range(1, vlan_num+1):
            logging.info("Test for vlan %s", vlan)

            logging.info("Ping between vlans")
            interface = ifname[0] + '.' + str(vlan)
            for vlan2 in range(1, vlan_num+1):
                for i in range(2):
                    interface = ifname[i] + '.' + str(vlan)
                    dest = subnet +'.'+ str(vlan2)+ '.' + ip_unit[(i+1)%2]
                    s, _ = utils_test.ping(dest, count=2,
                                              interface=interface,
                                              session=session[i], timeout=30)
                    if ((vlan == vlan2) ^ (s == 0)):
                        raise error.TestFail ("%s ping %s unexpected" %
                                                    (interface, dest))

            vlan_ip[0] = subnet + '.' + str(vlan) + '.' + ip_unit[0]
            vlan_ip[1] = subnet + '.' + str(vlan) + '.' + ip_unit[1]

            logging.info("Flood ping")
            def flood_ping(src, dst):
                # we must use a dedicated session becuase the aexpect
                # does not have the other method to interrupt the process in
                # the guest rather than close the session.
                session_flood = vm[src].wait_for_login(timeout=60)
                utils_test.ping(vlan_ip[dst], flood=True,
                                   interface=ifname[src],
                                   session=session_flood, timeout=10)
                session_flood.close()

            flood_ping(0, 1)
            flood_ping(1, 0)

            logging.info("Transfering data through nc")
            nc_transfer(0, 1)
            nc_transfer(1, 0)

    finally:
        for vlan in range(1, vlan_num+1):
            rem_vlan(session[0], vlan, ifname[0])
            rem_vlan(session[1], vlan, ifname[1])
            logging.info("rem vlan: %s", vlan)

    # Plumb/unplumb maximal number of vlan interfaces
    i = 1
    s = 0
    try:
        logging.info("Testing the plumb of vlan interface")
        for i in range (1, maximal+1):
            add_vlan(session[0], i, ifname[0])
    finally:
        for j in range (1, i+1):
            s = s or rem_vlan(session[0], j, ifname[0])
        if s == 0:
            logging.info("maximal interface plumb test done")
        else:
            logging.error("maximal interface plumb test failed")

    session[0].close()
    session[1].close()
Esempio n. 14
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")

    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_test.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")
            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":
            utils_net.restart_windows_guest_network(session_serial,
                                                    connection_id)

        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))
Esempio n. 15
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")

    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_test.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")
            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":
            utils_net.restart_windows_guest_network(session_serial,
                                                    connection_id)

        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_migration_after_nichotplug(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration. If it does, proceed with
       the test.
    3) Hotplug a nic.
    4) Disable the primary link of guest.
    5) Check if new interface gets ip address.
    6) Ping guest's new ip from host.
    7) Re-enabling the primary link.
    8) Send a migration command to the source VM and wait until it's finished.
    9) Disable the primary link again.
    10) Ping guest's new ip from host.
    11) Re-enabling the primary link.

    @param test: kvm test object.
    @param params: Dictionary with test parameters.
    @param env: Dictionary with the test environment.
    """


    def set_link(nic_name, up=False):
        for nic in vm.virtnet:
            if nic.nic_name != nic_name:
                vm.set_link(nic.device_id, up=up)

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)

    guest_is_not_windows = (params.get("os_type") != 'windows')
    run_dhclient = params.get("run_dhclient", "no")
    mig_timeout = float(params.get("mig_timeout", "3600"))
    nettype = params.get("nettype", "bridge")
    netdst = params.get("netdst", "virbr0")
    mig_protocol = params.get("migration_protocol", "tcp")
    mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2
    pci_model = params.get("pci_model")

    # Modprobe the module if specified in config file
    module = params.get("modprobe_module")
    if guest_is_not_windows and module:
        session.cmd_output("modprobe %s" % module)
    if session:
        session.close()

    error.context("Add network devices through monitor cmd", logging.info)
    nic_name = 'hotadded'
    nic_info = vm.hotplug_nic(nic_model=pci_model, nic_name=nic_name,
                              netdst=netdst, nettype=nettype)
    nic_mac = nic_info['mac']
    vm.params['nics'] += " %s" % nic_name
    vm.params['nic_model_%s' % nic_name] = nic_info['nic_model']

    # Only run dhclient if explicitly set and guest is not running Windows.
    # Most modern Linux guests run NetworkManager, and thus do not need this.
    if run_dhclient == "yes" and guest_is_not_windows:
        session_serial = vm.wait_for_serial_login(timeout=timeout)
        ifname = utils_test.get_linux_ifname(session, nic_mac)
        utils_test.restart_guest_network(session_serial, ifname)
        # Guest need to take quite a long time to set the ip addr, sleep a
        # while to wait for guest done.
        time.sleep(60)

    error.context("Disable the primary link of guest", logging.info)
    set_link(nic_name, up=False)

    error.context("Check if new interface gets ip address", logging.info)
    try:
        ip = vm.wait_for_get_address(nic_name)
    except virt_vm.VMIPAddressMissingError:
        raise error.TestFail("Could not get or verify ip address of nic")
    logging.info("Got the ip address of new nic: %s", ip)

    error.context("Ping guest's new ip from host", logging.info)
    s, o = utils_test.ping(ip, 10, timeout=15)
    if s != 0:
        raise error.TestFail("New nic failed ping test with output:\n %s" % o)

    error.context("Re-enabling the primary link", logging.info)
    set_link(nic_name, up=True)

    error.context("Migrate from source VM to Destination VM", logging.info)
    vm.migrate(mig_timeout, mig_protocol, mig_cancel_delay)

    error.context("Disable the primary link", logging.info)
    set_link(nic_name, up=False)

    error.context("Ping guest's new ip from host", logging.info)
    s, o = utils_test.ping(ip, 10, timeout=15)
    if s != 0:
        raise error.TestFail("New nic failed ping test with output:\n %s" % o)

    error.context("Re-enabling the primary link", logging.info)
    set_link(nic_name, up=True)