Пример #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 = kvm_test_utils.get_linux_ifname(session_serial,
                                              vm.get_mac_address(0))

    try:
        transfer_thread = kvm_utils.Thread(file_transfer.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:
        transfer_thread.join(suppress_exception=True)
        raise
    else:
        transfer_thread.join()
Пример #2
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 = [
        kvm_test_utils.get_linux_ifname(session_serial,
                                        vm.get_mac_address(vlan))
        for vlan, nic in enumerate(params.get("nics").split())
    ]
    setup_cmd = "ifenslave bond0 " + " ".join(ifnames)
    session_serial.cmd(setup_cmd)
    session_serial.cmd("dhclient bond0")

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

        logging.info("Failover test with file transfer")
        transfer_thread = kvm_utils.Thread(file_transfer.run_file_transfer,
                                           (test, params, env))
        try:
            transfer_thread.start()
            while transfer_thread.isAlive():
                for vlan, nic in enumerate(params.get("nics").split()):
                    device_id = vm.get_peer(vm.netdev_id[vlan])
                    vm.monitor.cmd("set_link %s down" % device_id)
                    time.sleep(1)
                    vm.monitor.cmd("set_link %s up" % device_id)
        except:
            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`")
Пример #3
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 = [kvm_test_utils.get_linux_ifname(session_serial,
                                               vm.get_mac_address(vlan))
               for vlan, nic in enumerate(params.get("nics").split())]
    setup_cmd = "ifenslave bond0 " + " ".join(ifnames)
    session_serial.cmd(setup_cmd)
    session_serial.cmd("dhclient bond0")

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

        logging.info("Failover test with file transfer")
        transfer_thread = kvm_utils.Thread(file_transfer.run_file_transfer,
                                           (test, params, env))
        try:
            transfer_thread.start()
            while transfer_thread.isAlive():
                for vlan, nic in enumerate(params.get("nics").split()):
                    device_id = vm.get_peer(vm.netdev_id[vlan])
                    vm.monitor.cmd("set_link %s down" % device_id)
                    time.sleep(1)
                    vm.monitor.cmd("set_link %s up" % device_id)
        except:
            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`")
Пример #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.
    """
    timeout = int(params.get("login_timeout", 360))
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session_serial = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2,
                                                   serial=True)
    # This session will be used to assess whether the IP change worked
    session = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2)
    old_mac = vm.get_mac_address(0)
    while True:
        vm.free_mac_address(0)
        new_mac = kvm_utils.generate_mac_address(vm.instance, 0)
        if old_mac != new_mac:
            break
    logging.info("The initial MAC address is %s", old_mac)
    interface = kvm_test_utils.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 kvm_utils.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 = kvm_test_utils.wait_for_login(vm,
              timeout=int(params.get("login_timeout", 360)))
    if not session.is_responsive():
        raise error.TestFail("The new session is not responsive.")

    session.close()
Пример #5
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.free_mac_address(0)
        new_mac = kvm_utils.generate_mac_address(vm.instance, 0)
        if old_mac != new_mac:
            break
    logging.info("The initial MAC address is %s", old_mac)
    interface = kvm_test_utils.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 kvm_utils.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()
Пример #6
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 = kvm_test_utils.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 t in range(int(params.get("sessions_num", "10"))):
            thread = kvm_utils.Thread(file_transfer.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:
        for thread in threads:
            thread.join(suppress_exception=True)
            raise
    else:
        for thread in threads:
            thread.join()
Пример #7
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 = kvm_test_utils.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 t in range(int(params.get("sessions_num", "10"))):
            thread = kvm_utils.Thread(file_transfer.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:
        for thread in threads:
            thread.join(suppress_exception=True)
            raise
    else:
        for thread in threads:
            thread.join()
Пример #8
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) TCP data transmission from host to guest, and from guest to host,
       with 1/1460/65000/100000000 bytes payloads.
    4) Clean temporary files.
    5) Stop enable/disable promiscuous mode change.

    @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 = vm.wait_for_login(timeout=timeout)
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    def compare(filename):
        md5_host = utils.hash_file(filename, method="md5")
        md5_guest = session.cmd("md5sum %s" % filename)
        md5_guest = md5_guest.split()[0]
        if md5_host != md5_guest:
            logging.error("MD5 hash mismatch between file %s "
                          "present on guest and on host", filename)
            logging.error("MD5 hash for file on guest: %s,"
                          "MD5 hash for file on host: %s", md5_host, md5_guest)
            return False
        return True

    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))

    class ThreadPromiscCmd(threading.Thread):
        def __init__(self, session, termination_event):
            self.session = session
            self.termination_event = termination_event
            super(ThreadPromiscCmd, self).__init__()


        def run(self):
            set_promisc_cmd = ("ip link set %s promisc on; sleep 0.01;"
                               "ip link set %s promisc off; sleep 0.01" %
                               (ethname, ethname))
            while True:
                self.session.cmd_output(set_promisc_cmd)
                if self.termination_event.isSet():
                    break


    logging.info("Started thread to change promisc mode in guest")
    termination_event = threading.Event()
    promisc_thread = ThreadPromiscCmd(session_serial, termination_event)
    promisc_thread.start()

    dd_cmd = "dd if=/dev/urandom of=%s bs=%d count=1"
    filename = "/tmp/nic_promisc_file"
    file_size = params.get("file_size", "1, 1460, 65000, 100000000").split(",")
    success_counter = 0
    try:
        for size in file_size:
            logging.info("Create %s bytes file on host", size)
            utils.run(dd_cmd % (filename, int(size)))

            logging.info("Transfer file from host to guest")
            try:
                vm.copy_files_to(filename, filename)
            except kvm_utils.SCPError, e:
                logging.error("File transfer failed (%s)", e)
                continue
            if not compare(filename):
                logging.error("Compare file failed")
                continue
            else:
                success_counter += 1

            logging.info("Create %s bytes file on guest", size)
            session.cmd(dd_cmd % (filename, int(size)), timeout=100)

            logging.info("Transfer file from guest to host")
            try:
                vm.copy_files_from(filename, filename)
            except kvm_utils.SCPError, e:
                logging.error("File transfer failed (%s)", e)
                continue
            if not compare(filename):
                logging.error("Compare file failed")
                continue
            else:
                success_counter += 1

            logging.info("Clean temporary files")
            cmd = "rm -f %s" % filename
            utils.run(cmd)
            session.cmd_output(cmd)
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 = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
    session_serial = kvm_test_utils.wait_for_login(vm, 0, timeout, 0, 2,
                                                   serial=True)

    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))
    sys_path = "/sys/class/net/%s/device/driver" % (ethname)
    o = session.cmd("readlink -e %s" % sys_path)
    driver = os.path.basename(o.strip())
    logging.info("driver is %s", driver)

    class ThreadScp(threading.Thread):
        def run(self):
            remote_file = '/tmp/' + self.getName()
            file_list.append(remote_file)
            ret = vm.copy_files_to(file_name, remote_file, timeout=scp_timeout)
            if ret:
                logging.debug("File %s was transfered successfuly", remote_file)
            else:
                logging.debug("Failed to transfer file %s", remote_file)

    def compare(origin_file, receive_file):
        check_sum1 = utils.hash_file(origin_file, method="md5")
        output2 = session.cmd("md5sum %s" % receive_file)
        check_sum2 = output2.strip().split()[0]
        logging.debug("original file md5: %s, received file md5: %s",
                      check_sum1, check_sum2)
        if check_sum1 != check_sum2:
            logging.error("MD5 hash of origin and received files doesn't match")
            return False
        return True

    #produce sized file in host
    file_size = params.get("file_size")
    file_name = "/tmp/nicdriver_unload_file"
    cmd = "dd if=/dev/urandom of=%s bs=%sM count=1"
    utils.system(cmd % (file_name, file_size))

    file_list = []
    connect_time = params.get("connect_time")
    scp_timeout = int(params.get("scp_timeout"))
    thread_num = int(params.get("thread_num"))
    unload_load_cmd = ("sleep %s && ifconfig %s down && modprobe -r %s && "
                       "sleep 1 && modprobe %s && sleep 4 && ifconfig %s up" %
                       (connect_time, ethname, driver, driver, ethname))
    pid = os.fork()
    if pid != 0:
        logging.info("Unload/load NIC driver repeatedly in guest...")
        while True:
            logging.debug("Try to unload/load nic drive once")
            try:
                session_serial.cmd(unload_load_cmd, timeout=120)
            except:
                session.cmd_output("rm -rf /tmp/Thread-*")
                raise
            pid, s = os.waitpid(pid, os.WNOHANG)
            status = os.WEXITSTATUS(s)
            if (pid, status) != (0, 0):
                logging.debug("Child process ending")
                break
    else:
        logging.info("Multi-session TCP data transfer")
        threads = []
        for i in range(thread_num):
            t = ThreadScp()
            t.start()
            threads.append(t)
        for t in threads:
            t.join(timeout = scp_timeout)
        os._exit(0)


    try:
        logging.info("Check MD5 hash for received files in multi-session")
        for f in file_list:
            if not compare(file_name, f):
                raise error.TestFail("Fail to compare (guest) file %s" % f)

        logging.info("Test nic function after load/unload")
        if not vm.copy_files_to(file_name, file_name):
            raise error.TestFail("Fail to copy file from host to guest")
        if not compare(file_name, file_name):
            raise error.TestFail("Test nic function after load/unload fail")

    finally:
        session.cmd_output("rm -rf /tmp/Thread-*")
        session.close()
Пример #10
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 = kvm_utils.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 kvm_subprocess.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(kvm_test_utils.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, o = kvm_test_utils.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 kvm_subprocess
                # 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)
                kvm_test_utils.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()
Пример #11
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

    @param test:   KVM test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    guest_delay = int(params.get("guest_delay", 20))
    session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
    romfile = params.get("romfile")

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

    def netdev_add(vm):
        netdev_id = kvm_utils.generate_random_id()
        attach_cmd = ("netdev_add tap,id=%s" % netdev_id)
        nic_script = params.get("nic_script")
        if nic_script:
            attach_cmd += ",script=%s" % kvm_utils.get_path(
                vm.root_dir, nic_script)
        netdev_extra_params = params.get("netdev_extra_params")
        if netdev_extra_params:
            attach_cmd += ",%s" % netdev_extra_params
        logging.info("Adding netdev through %s", attach_cmd)
        vm.monitor.cmd(attach_cmd)

        network = vm.monitor.info("network")
        if netdev_id not in network:
            logging.error(network)
            raise error.TestError("Fail to add netdev: %s" % netdev_id)
        else:
            return netdev_id

    def netdev_del(vm, n_id):
        vm.monitor.cmd("netdev_del %s" % n_id)

        network = vm.monitor.info("network")
        if n_id in network:
            logging.error(network)
            raise error.TestError("Fail to remove netdev %s" % n_id)

    def nic_add(vm, model, netdev_id, mac, rom=None):
        """
        Add a nic to virtual machine

        @vm: VM object
        @model: nic model
        @netdev_id: id of netdev
        @mac: Mac address of new nic
        @rom: Rom file
        """
        nic_id = kvm_utils.generate_random_id()
        if model == "virtio":
            model = "virtio-net-pci"
        device_add_cmd = "device_add %s,netdev=%s,mac=%s,id=%s" % (
            model, netdev_id, mac, nic_id)
        if rom:
            device_add_cmd += ",romfile=%s" % rom
        logging.info("Adding nic through %s", device_add_cmd)
        vm.monitor.cmd(device_add_cmd)

        qdev = vm.monitor.info("qtree")
        if not nic_id in qdev:
            logging.error(qdev)
            raise error.TestFail("Device %s was not plugged into qdev"
                                 "tree" % nic_id)
        else:
            return nic_id

    def nic_del(vm, nic_id, wait=True):
        """
        Remove the nic from pci tree.

        @vm: VM object
        @id: the nic id
        @wait: Whether need to wait for the guest to unplug the device
        """
        nic_del_cmd = "device_del %s" % nic_id
        vm.monitor.cmd(nic_del_cmd)
        if wait:
            logging.info("waiting for the guest to finish the unplug")
            if not kvm_utils.wait_for(
                    lambda: nic_id not in vm.monitor.info("qtree"),
                    guest_delay, 5, 1):
                logging.error(vm.monitor.info("qtree"))
                raise error.TestError("Device is not unplugged by "
                                      "guest, please check whether the "
                                      "hotplug module was loaded in guest")

    logging.info("Attach a virtio nic to vm")
    mac = kvm_utils.generate_mac_address(vm.instance, 1)
    if not mac:
        mac = "00:00:02:00:00:02"
    netdev_id = netdev_add(vm)
    device_id = nic_add(vm, "virtio", netdev_id, mac, romfile)

    if "Win" not in params.get("guest_name", ""):
        session.sendline("dhclient %s &" %
                         kvm_test_utils.get_linux_ifname(session, mac))

    logging.info("Shutting down the primary link")
    vm.monitor.cmd("set_link %s down" % vm.netdev_id[0])

    try:
        logging.info("Waiting for new nic's ip address acquisition...")
        if not kvm_utils.wait_for(
                lambda: (vm.address_cache.get(mac) is not None), 10, 1):
            raise error.TestFail("Could not get ip address of new nic")
        ip = vm.address_cache.get(mac)
        if not kvm_utils.verify_ip_address_ownership(ip, mac):
            raise error.TestFail("Could not verify the ip address of new nic")
        else:
            logging.info("Got the ip address of new nic: %s", ip)

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

        logging.info("Detaching a virtio nic from vm")
        nic_del(vm, device_id)
        netdev_del(vm, netdev_id)

    finally:
        vm.free_mac_address(1)
        logging.info("Re-enabling the primary link")
        vm.monitor.cmd("set_link %s up" % vm.netdev_id[0])
Пример #12
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

    @param test:   KVM test object.
    @param params: Dictionary with the test parameters.
    @param env:    Dictionary with test environment.
    """
    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    timeout = int(params.get("login_timeout", 360))
    guest_delay = int(params.get("guest_delay", 20))
    session_serial = kvm_test_utils.wait_for_login(vm, timeout=timeout,
                                                   serial=True)

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

    def netdev_add(vm):
        netdev_id = kvm_utils.generate_random_id()
        attach_cmd = ("netdev_add tap,id=%s,script=%s" %
                      (netdev_id, kvm_utils.get_path(vm.root_dir,
                                                     params.get("nic_script"))))
        netdev_extra_params = params.get("netdev_extra_params")
        if netdev_extra_params:
            attach_cmd += ",%s" % netdev_extra_params
        logging.info("Adding netdev through %s", attach_cmd)
        vm.monitor.cmd(attach_cmd)

        network = vm.monitor.info("network")
        if netdev_id not in network:
            logging.error(network)
            raise error.TestError("Fail to add netdev: %s" % netdev_id)
        else:
            return netdev_id

    def netdev_del(vm, n_id):
        vm.monitor.cmd("netdev_del %s" % n_id)

        network = vm.monitor.info("network")
        if n_id in network:
            logging.error(network)
            raise error.TestError("Fail to remove netdev %s" % n_id)

    def nic_add(vm, model, netdev_id, mac):
        """
        Add a nic to virtual machine

        @vm: VM object
        @model: nic model
        @netdev_id: id of netdev
        @mac: Mac address of new nic
        """
        nic_id = kvm_utils.generate_random_id()
        if model == "virtio":
            model = "virtio-net-pci"
        device_add_cmd = "device_add %s,netdev=%s,mac=%s,id=%s" % (model,
                                                                   netdev_id,
                                                                   mac, nic_id)
        logging.info("Adding nic through %s", device_add_cmd)
        vm.monitor.cmd(device_add_cmd)

        qdev = vm.monitor.info("qtree")
        if id not in qdev:
            logging.error(qdev)
            raise error.TestFail("Device %s was not plugged into qdev"
                                 "tree" % nic_id)
        else:
            return nic_id

    def nic_del(vm, nic_id, wait=True):
        """
        Remove the nic from pci tree.

        @vm: VM object
        @id: the nic id
        @wait: Whether need to wait for the guest to unplug the device
        """
        nic_del_cmd = "device_del %s" % nic_id
        vm.monitor.cmd(nic_del_cmd)
        if wait:
            logging.info("waiting for the guest to finish the unplug")
            if not kvm_utils.wait_for(lambda: nic_id not in
                                      vm.monitor.info("qtree"),
                                      guest_delay, 5 ,1):
                logging.error(vm.monitor.info("qtree"))
                raise error.TestError("Device is not unplugged by "
                                      "guest, please check whether the "
                                      "hotplug module was loaded in guest")

    logging.info("Attach a virtio nic to vm")
    mac = kvm_utils.generate_mac_address(vm.instance, 1)
    if not mac:
        mac = "00:00:02:00:00:02"
    netdev_id = netdev_add(vm)
    device_id = nic_add(vm, "virtio", netdev_id, mac)

    if "Win" not in params.get("guest_name", ""):
        session_serial.sendline("dhclient %s &" %
                         kvm_test_utils.get_linux_ifname(session_serial, mac))

    logging.info("Shutting down the primary link")
    vm.monitor.cmd("set_link %s down" % vm.netdev_id[0])

    try:
        logging.info("Waiting for new nic's ip address acquisition...")
        if not kvm_utils.wait_for(lambda: (vm.address_cache.get(mac) is
                                           not None), 10, 1):
            raise error.TestFail("Could not get ip address of new nic")
        ip = vm.address_cache.get(mac)
        if not kvm_utils.verify_ip_address_ownership(ip, mac):
            raise error.TestFail("Could not verify the ip address of new nic")
        else:
            logging.info("Got the ip address of new nic: %s", ip)

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

        logging.info("Detaching a virtio nic from vm")
        nic_del(vm, device_id)
        netdev_del(vm, netdev_id)

    finally:
        vm.free_mac_address(1)
        logging.info("Re-enabling the primary link")
        vm.monitor.cmd("set_link %s up" % vm.netdev_id[0])
Пример #13
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: 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()
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
    mtu = params.get("mtu", "1500")
    flood_time = params.get("flood_time", "300")
    max_icmp_pkt_size = int(mtu) - 28

    ifname = vm.get_ifname(0)
    ip = vm.get_address(0)
    if ip is None:
        raise error.TestError("Could not get the IP address")

    try:
        # Environment preparation
        ethname = kvm_test_utils.get_linux_ifname(session,
                                                  vm.get_mac_address(0))

        logging.info("Changing the MTU of guest ...")
        guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname, mtu)
        session.cmd(guest_mtu_cmd)

        logging.info("Chaning the MTU of host tap ...")
        host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu)
        utils.run(host_mtu_cmd)

        logging.info("Add a temporary static ARP entry ...")
        arp_add_cmd = "arp -s %s %s -i %s" % (ip, vm.get_mac_address(0),
                                              ifname)
        utils.run(arp_add_cmd)

        def is_mtu_ok():
            s, o = kvm_test_utils.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 = kvm_test_utils.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 kvm_test_utils.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")
            kvm_test_utils.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")
            s, o = kvm_test_utils.ping(ip,
                                       count,
                                       interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       timeout=float(count) * 2)
            ratio = kvm_test_utils.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 = kvm_test_utils.ping(ip,
                                           1,
                                           interface=ifname,
                                           packetsize=size,
                                           hint="do",
                                           timeout=1)
                if s != 0:
                    s, o = kvm_test_utils.ping(ip,
                                               10,
                                               interface=ifname,
                                               packetsize=size,
                                               adaptive=True,
                                               hint="do",
                                               timeout=20)

                    if kvm_test_utils.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 kvm_utils.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
        verify_mtu()
        large_frame_ping()
        size_increase_ping()

        # Stress test
        flood_ping()
        verify_mtu()

    finally:
        # Environment clean
        session.close()
        logging.info("Removing the temporary ARP entry")
        utils.run("arp -d %s -i %s" % (ip, ifname))
Пример #14
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) TCP data transmission from host to guest, and from guest to host,
       with 1/1460/65000/100000000 bytes payloads.
    4) Clean temporary files.
    5) Stop enable/disable promiscuous mode change.

    @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 = vm.wait_for_login(timeout=timeout)
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    def compare(filename):
        md5_host = utils.hash_file(filename, method="md5")
        md5_guest = session.cmd("md5sum %s" % filename)
        md5_guest = md5_guest.split()[0]
        if md5_host != md5_guest:
            logging.error(
                "MD5 hash mismatch between file %s "
                "present on guest and on host", filename)
            logging.error(
                "MD5 hash for file on guest: %s,"
                "MD5 hash for file on host: %s", md5_host, md5_guest)
            return False
        return True

    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))

    class ThreadPromiscCmd(threading.Thread):
        def __init__(self, session, termination_event):
            self.session = session
            self.termination_event = termination_event
            super(ThreadPromiscCmd, self).__init__()

        def run(self):
            set_promisc_cmd = ("ip link set %s promisc on; sleep 0.01;"
                               "ip link set %s promisc off; sleep 0.01" %
                               (ethname, ethname))
            while True:
                self.session.cmd_output(set_promisc_cmd)
                if self.termination_event.isSet():
                    break

    logging.info("Started thread to change promisc mode in guest")
    termination_event = threading.Event()
    promisc_thread = ThreadPromiscCmd(session_serial, termination_event)
    promisc_thread.start()

    dd_cmd = "dd if=/dev/urandom of=%s bs=%d count=1"
    filename = "/tmp/nic_promisc_file"
    file_size = params.get("file_size", "1, 1460, 65000, 100000000").split(",")
    success_counter = 0
    try:
        for size in file_size:
            logging.info("Create %s bytes file on host", size)
            utils.run(dd_cmd % (filename, int(size)))

            logging.info("Transfer file from host to guest")
            try:
                vm.copy_files_to(filename, filename)
            except kvm_utils.SCPError, e:
                logging.error("File transfer failed (%s)", e)
                continue
            if not compare(filename):
                logging.error("Compare file failed")
                continue
            else:
                success_counter += 1

            logging.info("Create %s bytes file on guest", size)
            session.cmd(dd_cmd % (filename, int(size)), timeout=100)

            logging.info("Transfer file from guest to host")
            try:
                vm.copy_files_from(filename, filename)
            except kvm_utils.SCPError, e:
                logging.error("File transfer failed (%s)", e)
                continue
            if not compare(filename):
                logging.error("Compare file failed")
                continue
            else:
                success_counter += 1

            logging.info("Clean temporary files")
            cmd = "rm -f %s" % filename
            utils.run(cmd)
            session.cmd_output(cmd)
Пример #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: 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()
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
    mtu = params.get("mtu", "1500")
    flood_time = params.get("flood_time", "300")
    max_icmp_pkt_size = int(mtu) - 28

    ifname = vm.get_ifname(0)
    ip = vm.get_address(0)
    if ip is None:
        raise error.TestError("Could not get the IP address")

    try:
        # Environment preparation
        ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))

        logging.info("Changing the MTU of guest ...")
        guest_mtu_cmd = "ifconfig %s mtu %s" % (ethname , mtu)
        session.cmd(guest_mtu_cmd)

        logging.info("Chaning the MTU of host tap ...")
        host_mtu_cmd = "ifconfig %s mtu %s" % (ifname, mtu)
        utils.run(host_mtu_cmd)

        logging.info("Add a temporary static ARP entry ...")
        arp_add_cmd = "arp -s %s %s -i %s" % (ip, vm.get_mac_address(0), ifname)
        utils.run(arp_add_cmd)

        def is_mtu_ok():
            s, o = kvm_test_utils.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 = kvm_test_utils.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 kvm_test_utils.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")
            kvm_test_utils.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")
            s, o = kvm_test_utils.ping(ip, count, interface=ifname,
                                       packetsize=max_icmp_pkt_size,
                                       timeout=float(count) * 2)
            ratio = kvm_test_utils.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 = kvm_test_utils.ping(ip, 1, interface=ifname,
                                           packetsize=size,
                                           hint="do", timeout=1)
                if s != 0:
                    s, o = kvm_test_utils.ping(ip, 10, interface=ifname,
                                               packetsize=size,
                                               adaptive=True, hint="do",
                                               timeout=20)

                    if kvm_test_utils.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 kvm_utils.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
        verify_mtu()
        large_frame_ping()
        size_increase_ping()

        # Stress test
        flood_ping()
        verify_mtu()

    finally:
        # Environment clean
        session.close()
        logging.info("Removing the temporary ARP entry")
        utils.run("arp -d %s -i %s" % (ip, ifname))
Пример #16
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 = kvm_utils.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 kvm_subprocess.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(
            kvm_test_utils.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, o = kvm_test_utils.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 kvm_subprocess
                # 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)
                kvm_test_utils.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()
Пример #17
0
def run_ethtool(test, params, env):
    """
    Test offload functions of ethernet device by ethtool

    1) Log into a guest.
    2) Initialize the callback of sub functions.
    3) Enable/disable sub function of NIC.
    4) Execute callback function.
    5) Check the return value.
    6) Restore original configuration.

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

    @todo: Not all guests have ethtool installed, so
        find a way to get it installed using yum/apt-get/
        whatever
    """
    def ethtool_get(type):
        feature_pattern = {
            'tx':  'tx.*checksumming',
            'rx':  'rx.*checksumming',
            'sg':  'scatter.*gather',
            'tso': 'tcp.*segmentation.*offload',
            'gso': 'generic.*segmentation.*offload',
            'gro': 'generic.*receive.*offload',
            'lro': 'large.*receive.*offload',
            }
        o = session.cmd("ethtool -k %s" % ethname)
        try:
            return re.findall("%s: (.*)" % feature_pattern.get(type), o)[0]
        except IndexError:
            logging.debug("Could not get %s status" % type)


    def ethtool_set(type, status):
        """
        Set ethernet device offload status

        @param type: Offload type name
        @param status: New status will be changed to
        """
        logging.info("Try to set %s %s" % (type, status))
        if status not in ["off", "on"]:
            return False
        cmd = "ethtool -K %s %s %s" % (ethname, type, status)
        if ethtool_get(type) != status:
            try:
                session.cmd(cmd)
                return True
            except:
                return False
        if ethtool_get(type) != status:
            logging.error("Fail to set %s %s" % (type, status))
            return False
        return True


    def ethtool_save_params():
        logging.info("Save ethtool configuration")
        for i in supported_features:
            feature_status[i] = ethtool_get(i)


    def ethtool_restore_params():
        logging.info("Restore ethtool configuration")
        for i in supported_features:
            ethtool_set(i, feature_status[i])


    def compare_md5sum(name):
        logging.info("Compare md5sum of the files on guest and host")
        host_result = utils.hash_file(name, method="md5")
        try:
            o = session.cmd_output("md5sum %s" % name)
            guest_result = re.findall("\w+", o)[0]
        except IndexError:
            logging.error("Could not get file md5sum in guest")
            return False
        logging.debug("md5sum: guest(%s), host(%s)" %
                      (guest_result, host_result))
        return guest_result == host_result


    def transfer_file(src="guest"):
        """
        Transfer file by scp, use tcpdump to capture packets, then check the
        return string.

        @param src: Source host of transfer file
        @return: Tuple (status, error msg/tcpdump result)
        """
        session2.cmd_output("rm -rf %s" % filename)
        dd_cmd = ("dd if=/dev/urandom of=%s bs=1M count=%s" %
                  (filename, params.get("filesize")))
        logging.info("Creat file in source host, cmd: %s" % dd_cmd)
        tcpdump_cmd = "tcpdump -lep -s 0 tcp -vv port ssh"
        if src == "guest":
            session.cmd_output(dd_cmd, timeout=360)
            tcpdump_cmd += " and src %s" % guest_ip
            copy_files_fun = vm.copy_files_from
        else:
            s, o = commands.getstatusoutput(dd_cmd)
            tcpdump_cmd += " and dst %s" % guest_ip
            copy_files_fun = vm.copy_files_to
        if s != 0:
            return (False, "Fail to create file by dd, cmd: %s" % dd_cmd)

        # only capture the new tcp port after offload setup
        original_tcp_ports = re.findall("tcp.*:(\d+).*%s" % guest_ip,
                                      utils.system_output("/bin/netstat -nap"))
        for i in original_tcp_ports:
            tcpdump_cmd += " and not port %s" % i
        logging.debug("Listen by command: %s" % tcpdump_cmd)
        session2.sendline(tcpdump_cmd)
        if not kvm_utils.wait_for(
                           lambda:session.cmd_status("pgrep tcpdump") == 0, 30):
            return (False, "Tcpdump process wasn't launched")

        logging.info("Start to transfer file")
        if not copy_files_fun(filename, filename):
            return (False, "Child process transfer file failed")
        logging.info("Transfer file completed")
        session.cmd("killall tcpdump")
        try:
            tcpdump_string = session2.read_up_to_prompt(timeout=60)
        except kvm_subprocess.ExpectError:
            return (False, "Fail to read tcpdump's output")

        if not compare_md5sum(filename):
            return (False, "Files' md5sum mismatched")
        return (True, tcpdump_string)


    def tx_callback(status="on"):
        s, o = transfer_file(src="guest")
        if not s:
            logging.error(o)
            return False
        return True


    def rx_callback(status="on"):
        s, o = transfer_file(src="host")
        if not s:
            logging.error(o)
            return False
        return True


    def so_callback(status="on"):
        s, o = transfer_file(src="guest")
        if not s:
            logging.error(o)
            return False
        logging.info("Check if contained large frame")
        # MTU: default IPv4 MTU is 1500 Bytes, ethernet header is 14 Bytes
        return (status == "on") ^ (len([i for i in re.findall(
                                   "length (\d*):", o) if int(i) > mtu]) == 0)


    def ro_callback(status="on"):
        s, o = transfer_file(src="host")
        if not s:
            logging.error(o)
            return False
        return True


    vm = kvm_test_utils.get_living_vm(env, params.get("main_vm"))
    session = kvm_test_utils.wait_for_login(vm,
                  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 = kvm_test_utils.wait_for_login(vm,
                  timeout=int(params.get("login_timeout", 360)))
    mtu = 1514
    feature_status = {}
    filename = "/tmp/ethtool.dd"
    guest_ip = vm.get_address()
    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))
    supported_features = params.get("supported_features").split()
    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",)),
        "lro": (rx_callback, (), ("gro",)),
        }
    ethtool_save_params()
    success = True
    try:
        for type in supported_features:
            callback = test_matrix[type][0]
            for i in test_matrix[type][2]:
                if not ethtool_set(i, "off"):
                    logging.error("Fail to disable %s" % i)
                    success = False
            for i in [f for f in test_matrix[type][1]] + [type]:
                if not ethtool_set(i, "on"):
                    logging.error("Fail to enable %s" % i)
                    success = False
            if not callback():
                raise error.TestFail("Test failed, %s: on" % type)

            if not ethtool_set(type, "off"):
                logging.error("Fail to disable %s" % type)
                success = False
            if not callback(status="off"):
                raise error.TestFail("Test failed, %s: off" % type)
        if not success:
            raise error.TestError("Enable/disable offload function fail")
    finally:
        ethtool_restore_params()
        session.close()
        session2.close()
Пример #18
0
        if not s:
            logging.error(o)
            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 = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))
    supported_features = params.get("supported_features").split()
    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", )),
        "lro": (rx_callback, (), ("gro", )),
    }
    ethtool_save_params()
Пример #19
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 = vm.wait_for_login(timeout=timeout)
    session_serial = vm.wait_for_serial_login(timeout=timeout)

    ethname = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))
    sys_path = "/sys/class/net/%s/device/driver" % (ethname)
    o = session.cmd("readlink -e %s" % sys_path)
    driver = os.path.basename(o.strip())
    logging.info("driver is %s", driver)

    class ThreadScp(threading.Thread):
        def run(self):
            remote_file = '/tmp/' + self.getName()
            file_list.append(remote_file)
            vm.copy_files_to(file_name, remote_file, timeout=scp_timeout)
            logging.debug("File %s was transfered successfuly", remote_file)

    def compare(origin_file, receive_file):
        check_sum1 = utils.hash_file(origin_file, method="md5")
        output2 = session.cmd("md5sum %s" % receive_file)
        check_sum2 = output2.strip().split()[0]
        logging.debug("original file md5: %s, received file md5: %s",
                      check_sum1, check_sum2)
        if check_sum1 != check_sum2:
            logging.error(
                "MD5 hash of origin and received files doesn't match")
            return False
        return True

    #produce sized file in host
    file_size = params.get("file_size")
    file_name = "/tmp/nicdriver_unload_file"
    cmd = "dd if=/dev/urandom of=%s bs=%sM count=1"
    utils.system(cmd % (file_name, file_size))

    file_list = []
    connect_time = params.get("connect_time")
    scp_timeout = int(params.get("scp_timeout"))
    thread_num = int(params.get("thread_num"))
    unload_load_cmd = ("sleep %s && ifconfig %s down && modprobe -r %s && "
                       "sleep 1 && modprobe %s && sleep 4 && ifconfig %s up" %
                       (connect_time, ethname, driver, driver, ethname))
    pid = os.fork()
    if pid != 0:
        logging.info("Unload/load NIC driver repeatedly in guest...")
        while True:
            logging.debug("Try to unload/load nic drive once")
            try:
                session_serial.cmd(unload_load_cmd, timeout=120)
            except:
                session.cmd_output("rm -rf /tmp/Thread-*")
                raise
            pid, s = os.waitpid(pid, os.WNOHANG)
            status = os.WEXITSTATUS(s)
            if (pid, status) != (0, 0):
                logging.debug("Child process ending")
                break
    else:
        logging.info("Multi-session TCP data transfer")
        threads = []
        for i in range(thread_num):
            t = ThreadScp()
            t.start()
            threads.append(t)
        for t in threads:
            t.join(timeout=scp_timeout)
        os._exit(0)

    try:
        logging.info("Check MD5 hash for received files in multi-session")
        for f in file_list:
            if not compare(file_name, f):
                raise error.TestFail("Fail to compare (guest) file %s" % f)

        logging.info("Test nic function after load/unload")
        vm.copy_files_to(file_name, file_name)
        if not compare(file_name, file_name):
            raise error.TestFail("Test nic function after load/unload fail")

    finally:
        session.cmd_output("rm -rf /tmp/Thread-*")
        session.close()
Пример #20
0
            logging.error(o)
            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 = kvm_test_utils.get_linux_ifname(session, vm.get_mac_address(0))
    supported_features = params.get("supported_features")
    if supported_features:
        supported_features = supported_features.split()
    else:
        supported_features = []
    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",)),
        "lro": (rx_callback, (), ("gro",)),
        }