Example #1
0
 def enable_multi_queues(vm):
     sess = vm.wait_for_serial_login(timeout=login_timeout)
     error.context("Enable multi queues in guest.", logging.info)
     for nic_index, nic in enumerate(vm.virtnet):
         ifname = utils_net.get_linux_ifname(sess, nic.mac)
         queues = int(nic.queues)
         change_queues_number(sess, ifname, queues)
Example #2
0
    def mtu_set(mtu):
        """
        Set server/client/host's mtu

        :param mtu: mtu value to be set
        """

        server_mtu_cmd = params.get("server_mtu_cmd")
        client_mtu_cmd = params.get("client_mtu_cmd")
        host_mtu_cmd = params.get("host_mtu_cmd")
        error_context.context("Changing the MTU of guest", logging.info)
        if params.get("os_type") == "linux":
            ethname = utils_net.get_linux_ifname(server_ctl, mac)
            ssh_cmd(server_ctl, server_mtu_cmd % (ethname, mtu))
        elif params.get("os_type") == "windows":
            connection_id = utils_net.get_windows_nic_attribute(
                server_ctl, "macaddress", mac, "netconnectionid")
            ssh_cmd(server_ctl, server_mtu_cmd % (connection_id, mtu))

        error_context.context("Changing the MTU of client", logging.info)
        ssh_cmd(client,
                client_mtu_cmd % (params.get("client_physical_nic"), mtu))

        netdst = params.get("netdst", "switch")
        host_bridges = utils_net.Bridge()
        br_in_use = host_bridges.list_br()
        if netdst in br_in_use:
            ifaces_in_use = host_bridges.list_iface()
            target_ifaces = list(ifaces_in_use + br_in_use)
        error_context.context("Change all Bridge NICs MTU to %s" % mtu,
                              logging.info)
        for iface in target_ifaces:
            utils.run(host_mtu_cmd % (iface, mtu), ignore_status=False)
Example #3
0
    def get_ip_by_mac(mac_addr, timeout=120):
        """
        Get interface IP address by given MAC address.
        """
        if vm.serial_console is not None:
            vm.cleanup_serial_console()
        vm.create_serial_console()
        session = vm.wait_for_serial_login(timeout=240)

        def get_ip():
            return utils_net.get_guest_ip_addr(session, mac_addr)

        try:
            ip_addr = ""
            iface_name = utils_net.get_linux_ifname(session, mac_addr)
            if iface_name is None:
                test.fail("no interface with MAC address %s found" % mac_addr)
            session.cmd("pkill -9 dhclient", ignore_all_errors=True)
            session.cmd("dhclient %s " % iface_name, ignore_all_errors=True)
            ip_addr = utils_misc.wait_for(get_ip, 20)
            logging.debug("The ip addr is %s", ip_addr)
        except Exception:
            logging.warning("Find %s with MAC address %s but no ip for it" %
                            (iface_name, mac_addr))
        finally:
            session.close()
        return ip_addr
Example #4
0
def get_ping_dest(vm_session, mac_addr="", restart_network=False):
    """
    Get an ip address to ping

    :param vm_session: The session object to the guest
    :param mac_addr: mac address of given interface
    :param restart_network:  Whether to restart guest's network
    :return: ip address
    """
    if restart_network:
        if not utils_package.package_install('dhcp-client',
                                             session=vm_session):
            raise exceptions.TestFail(
                "Failed to install dhcp-client on guest.")
        utils_net.restart_guest_network(vm_session)
    vm_iface = utils_net.get_linux_ifname(vm_session, mac_addr)
    if isinstance(vm_iface, list):
        iface_name = vm_iface[0]
    else:
        iface_name = vm_iface
    utils_misc.wait_for(
        lambda: utils_net.get_net_if_addrs(iface_name, vm_session.cmd_output).
        get('ipv4'), 20)
    cmd = ("ip route |awk -F '/' '/^[0-9]/, /dev %s/ {print $1}'" % iface_name)
    status, output = utils_misc.cmd_status_output(cmd,
                                                  shell=True,
                                                  session=vm_session)
    if status or not output:
        raise exceptions.TestError("Failed to run cmd - {}, status - {}, "
                                   "output - {}.".format(cmd, status, output))
    return re.sub('\d+$', '1', output.strip().splitlines()[-1])
Example #5
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_net.get_linux_ifname(session_serial, vm.get_mac_address(0))

    try:
        transfer_thread = utils.InterruptedThread(utils_test.run_file_transfer,
                                                  (test, params, env))
        transfer_thread.start()
        while transfer_thread.isAlive():
            session_serial.cmd("ip link set %s promisc on" % ethname)
            session_serial.cmd("ip link set %s promisc off" % ethname)
    except Exception:
        transfer_thread.join(suppress_exception=True)
        raise
    else:
        transfer_thread.join()
Example #6
0
    def test_ping():
        """
        Ping test for nic option.
        """
        package_sizes = params.objects("ping_sizes")
        if params["os_type"] == "windows":
            ifname = utils_net.get_windows_nic_attribute(
                session=session,
                key="netenabled",
                value=True,
                target="netconnectionID")
        else:
            ifname = utils_net.get_linux_ifname(session,
                                                vm.get_mac_address())
        dest = utils_net.get_host_ip_address(params)

        for size in package_sizes:
            error_context.context("Test ping from '%s' to host '%s' on guest '%s'"
                                  " with package size %s. " %
                                  (ifname, dest, vm.name, size), logging.info)
            status, output = utils_net.ping(dest=dest, count=10, packetsize=size, session=session, timeout=30)
            if status:
                test.fail("%s ping %s unexpected, output %s" % (vm.name, dest,
                                                                output))
            if params["os_type"] == "windows":
                # windows guest get loss=0 when ping failed sometime,
                # need further check
                loss = utils_test.get_loss_ratio(output)
                if loss or "TTL" in output:
                    pass
                else:
                    test.fail("Guest ping test hit unexpected loss, "
                              "error_info: %s" % output)
    def get_ip_by_mac(mac_addr, try_dhclint=False):
        """
        Get interface IP address by given MAC addrss. If try_dhclint is
        True, then try to allocate IP addrss for the interface.
        """
        session = vm.wait_for_login()

        def f():
            return utils_net.get_guest_ip_addr(session, mac_addr)

        try:
            ip_addr = utils_misc.wait_for(f, 10)
            if ip_addr is None:
                iface_name = utils_net.get_linux_ifname(session, mac_addr)
                if try_dhclint:
                    session.cmd("dhclient %s" % iface_name)
                    ip_addr = utils_misc.wait_for(f, 10)
                else:
                    # No IP for the interface, just print the interface name
                    logging.warn("Find '%s' with MAC address '%s', "
                                 "but which has no IP address", iface_name,
                                 mac_addr)
        finally:
            session.close()
        return ip_addr
Example #8
0
    def get_ip_by_mac(mac_addr, try_dhclint=False, timeout=120):
        """
        Get interface IP address by given MAC addrss. If try_dhclint is
        True, then try to allocate IP addrss for the interface.
        """
        session = vm.wait_for_login(login_nic_index,
                                    timeout=timeout,
                                    serial=True)

        def f():
            return utils_net.get_guest_ip_addr(session, mac_addr)

        try:
            ip_addr = utils_misc.wait_for(f, 10)
            if ip_addr is None:
                iface_name = utils_net.get_linux_ifname(session, mac_addr)
                if try_dhclint:
                    session.cmd("dhclient %s" % iface_name)
                    ip_addr = utils_misc.wait_for(f, 10)
                else:
                    # No IP for the interface, just print the interface name
                    logging.warn(
                        "Find '%s' with MAC address '%s', "
                        "but which has no IP address", iface_name, mac_addr)
        finally:
            session.close()
        return ip_addr
Example #9
0
    def transfer_file(src):
        """
        Transfer file by scp, use tcpdump to capture packets, then check the
        return string.

        :param src: Source host of transfer file
        :return: Tuple (status, error msg/tcpdump result)
        """
        sess = vm.wait_for_login(timeout=login_timeout)
        session.cmd_output("rm -rf %s" % filename)
        dd_cmd = ("dd if=/dev/urandom of=%s bs=1M count=%s" %
                  (filename, params.get("filesize")))
        failure = (False, "Failed to create file using dd, cmd: %s" % dd_cmd)
        txt = "Creating file in source host, cmd: %s" % dd_cmd
        error.context(txt, logging.info)
        ethname = utils_net.get_linux_ifname(session,
                                             vm.get_mac_address(0))
        tcpdump_cmd = "tcpdump -lep -i %s -s 0 tcp -vv port ssh" % ethname
        if src == "guest":
            tcpdump_cmd += " and src %s" % guest_ip
            copy_files_func = vm.copy_files_from
            try:
                sess.cmd_output(dd_cmd, timeout=360)
            except aexpect.ShellCmdError, e:
                return failure
Example #10
0
def run(test, params, env):
    """
    When "acpi-index=N" is enabled, NIC name should always be "ethN"

    1) Boot up guest with a single nic, add nic option "acpi-index=1"
    2) Remove "biosdevname=0" and "net.ifname=0" from kenrel command line
    3) Reboot guest
    4) Check the nic name, the guest nic name enoN == acpi-index=N

    :param test:   QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env:    Dictionary with test environment.
    """
    login_timeout = int(params.get("login_timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_serial_login(timeout=login_timeout)
    ifname = utils_net.get_linux_ifname(session,
                                        vm.get_mac_address())
    pattern = int(re.findall(r'\d+', ifname)[-1])
    nic_name_number = params.get_numeric("nic_name_number")
    if pattern == nic_name_number:
        logging.info("nic name match")
    else:
        test.fail("nic name doesn't match")
    host_ip = utils_net.get_host_ip_address(params)
    status, output = utils_net.ping(host_ip, 10, timeout=30)
    if status:
        test.fail("%s ping %s unexpected, output %s" % (vm.name, host_ip, output))
    if session:
        session.close()
Example #11
0
    def transfer_file(src):
        """
        Transfer file by scp, use tcpdump to capture packets, then check the
        return string.

        :param src: Source host of transfer file
        :return: Tuple (status, error msg/tcpdump result)
        """
        sess = vm.wait_for_login(timeout=login_timeout)
        session.cmd_output("rm -rf %s" % filename)
        dd_cmd = ("dd if=/dev/urandom of=%s bs=1M count=%s" %
                  (filename, params.get("filesize")))
        failure = (False, "Failed to create file using dd, cmd: %s" % dd_cmd)
        txt = "Creating file in source host, cmd: %s" % dd_cmd
        error.context(txt, logging.info)
        ethname = utils_net.get_linux_ifname(session,
                                             vm.get_mac_address(0))
        tcpdump_cmd = "tcpdump -lep -i %s -s 0 tcp -vv port ssh" % ethname
        if src == "guest":
            tcpdump_cmd += " and src %s" % guest_ip
            copy_files_func = vm.copy_files_from
            try:
                sess.cmd_output(dd_cmd, timeout=360)
            except aexpect.ShellCmdError, e:
                return failure
Example #12
0
def run_enable_mq(test, params, env):
    """
    Enable MULTI_QUEUE feature in guest

    1) Boot up VM(s)
    2) Login guests one by one
    3) Enable MQ for all virtio nics by ethtool -L

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

    login_timeout = int(params.get("login_timeout", 360))
    queues = int(params.get("queues", 1))
    vms = params.get("vms").split()
    if queues == 1:
        logging.info("No need to enable MQ feature for single queue")
        return

    for vm in vms:
        vm = env.get_vm(vm)
        vm.verify_alive()
        session = vm.wait_for_login(timeout=login_timeout)
        for i, nic in enumerate(vm.virtnet):
            if "virtio" in nic["nic_model"]:
                ifname = utils_net.get_linux_ifname(session, vm.get_mac_address(0))
                session.cmd_output("ethtool -L %s combined %d" % (ifname, queues))
                o = session.cmd_output("ethtool -l %s" % ifname)
                if len(re.findall("Combined:\s+%d\s" % queues, o)) != 2:
                    raise error.TestError("Fail to enable MQ feature of (%s)" % nic.nic_name)

                logging.info("MQ feature of (%s) is enabled" % nic.nic_name)

        session.close()
Example #13
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_net.get_linux_ifname(session_serial,
                                              vm.get_mac_address(0))

    try:
        transfer_thread = utils.InterruptedThread(
                                               utils_test.run_file_transfer,
                                               (test, params, env))
        transfer_thread.start()
        while transfer_thread.isAlive():
            session_serial.cmd("ip link set %s promisc on" % ethname)
            session_serial.cmd("ip link set %s promisc off" % ethname)
    except Exception:
        transfer_thread.join(suppress_exception=True)
        raise
    else:
        transfer_thread.join()
Example #14
0
    def chk_mq_enabled(vm, queues):
        """
        Check whether MQ value set in qemu cmd line fits the value in guest

        :param vm: guest vm
        :param queues: queues value in qemu cmd line
        """
        login_timeout = int(params.get("login_timeout", 360))
        session = vm.wait_for_login(timeout=login_timeout)

        mac = vm.get_mac_address(0)
        ifname = utils_net.get_linux_ifname(session, mac)
        queues_status_list = get_queues_status(session, ifname)

        session.close()
        if not queues_status_list[0] == queues or \
                not queues_status_list[1] == min(queues, int(vm.cpuinfo.smp)):
            txt = "Pre-set maximums Combined should equals to queues in qemu"
            txt += " cmd line.\n"
            txt += "Current hardware settings Combined should be the min of "
            txt += "queues and smp.\n"
            txt += "Pre-set maximum Combined is: %s, " % queues_status_list[0]
            txt += " queues in qemu cmd line is: %s.\n" % queues
            txt += "Current hardware settings Combined "
            txt += "is: %s, " % queues_status_list[1]
            txt += " smp in qemu cmd line is: %s." % int(vm.cpuinfo.smp)
            test.fail(txt)
Example #15
0
    def get_ip_by_mac(mac_addr, timeout=120):
        """
        Get interface IP address by given MAC address.
        """
        if vm.serial_console is not None:
            vm.cleanup_serial_console()
        vm.create_serial_console()
        session = vm.wait_for_serial_login(timeout=240)

        def get_ip():
            return utils_net.get_guest_ip_addr(session, mac_addr)

        try:
            ip_addr = ""
            iface_name = utils_net.get_linux_ifname(session, mac_addr)
            if iface_name is None:
                test.fail("no interface with MAC address %s found" % mac_addr)
            session.cmd("pkill -9 dhclient", ignore_all_errors=True)
            session.cmd("dhclient %s " % iface_name, ignore_all_errors=True)
            ip_addr = utils_misc.wait_for(get_ip, 20)
            logging.debug("The ip addr is %s", ip_addr)
        except Exception:
            logging.warning("Find %s with MAC address %s but no ip for it" % (iface_name, mac_addr))
        finally:
            session.close()
        return ip_addr
Example #16
0
 def enable_multi_queues(vm):
     sess = vm.wait_for_serial_login(timeout=login_timeout)
     error.context("Enable multi queues in guest.", logging.info)
     for nic_index, nic in enumerate(vm.virtnet):
         ifname = utils_net.get_linux_ifname(sess, nic.mac)
         queues = int(nic.queues)
         change_queues_number(sess, ifname, queues)
Example #17
0
    def check_output(ifaces_actual, vm, login_nic_index=0):
        """
        1. Get the interface details of the command output
        2. Get the interface details from xml file
        3. Check command output against xml and guest output
        """
        vm_name = vm.name

        try:
            session = vm.wait_for_login(nic_index=login_nic_index)
        except Exception as detail:
            test.fail("Unable to login to VM:%s" % detail)
        iface_xml = {}
        error_count = 0
        # Check for the interface values
        for item in ifaces_actual:
            # Check for mac and model
            model = item['model']
            iname = utils_net.get_linux_ifname(session, item['mac'])
            if iname is not None:
                cmd = 'ethtool -i %s | grep driver | awk \'{print $2}\'' % iname
                drive = session.cmd_output(cmd).strip()
                if driver_dict[model] != drive:
                    error_count += 1
                    logging.error("Mismatch in the model for the interface %s\n"
                                  "Expected Model:%s\nActual Model:%s",
                                  item['interface'], driver_dict[model],
                                  item['model'])
            else:
                error_count += 1
                logging.error("Mismatch in the mac for the interface %s\n",
                              item['interface'])
            iface_xml = vm_xml.VMXML.get_iface_by_mac(vm_name, item['mac'])
            if iface_xml is not None:
                if iface_xml['type'] != item['type']:
                    error_count += 1
                    logging.error("Mismatch in the network type for the "
                                  "interface %s \n Type in command output: %s\n"
                                  "Type in xml file: %s",
                                  item['interface'],
                                  item['type'],
                                  iface_xml['type'])
                if iface_xml['source'] != item['source']:
                    error_count += 1
                    logging.error("Mismatch in the network source for the"
                                  " interface %s \n Source in command output:"
                                  "%s\nSource in xml file: %s",
                                  item['interface'],
                                  item['source'],
                                  iface_xml['source'])

            else:
                error_count += 1
                logging.error("There is no interface in the xml file "
                              "with the below specified mac address\n"
                              "Mac:%s", item['mac'])
            iface_xml = {}
        if error_count > 0:
            test.fail("The test failed, consult previous error logs")
Example #18
0
 def verified_nic_name():
     ifname = utils_net.get_linux_ifname(session, vm.get_mac_address())
     pattern = int(re.findall(r'\d+', ifname)[-1])
     nic_name_number = params.get_numeric("nic_name_number")
     if pattern == nic_name_number:
         logging.info("nic name match")
     else:
         test.fail("nic name doesn't match")
Example #19
0
    def check_output(ifaces_actual, vm, login_nic_index=0):
        """
        1. Get the interface details of the command output
        2. Get the interface details from xml file
        3. Check command output against xml and guest output
        """
        vm_name = vm.name

        try:
            session = vm.wait_for_login(nic_index=login_nic_index)
        except Exception as detail:
            test.fail("Unable to login to VM:%s" % detail)
        iface_xml = {}
        error_count = 0
        # Check for the interface values
        for item in ifaces_actual:
            # Check for mac and model
            model = item['model']
            iname = utils_net.get_linux_ifname(session, item['mac'])
            if iname is not None:
                cmd = 'ethtool -i %s | grep driver | awk \'{print $2}\'' % iname
                drive = session.cmd_output(cmd).strip()
                if driver_dict[model] != drive:
                    error_count += 1
                    logging.error(
                        "Mismatch in the model for the interface %s\n"
                        "Expected Model:%s\nActual Model:%s",
                        item['interface'], driver_dict[model], item['model'])
            else:
                error_count += 1
                logging.error("Mismatch in the mac for the interface %s\n",
                              item['interface'])
            iface_xml = vm_xml.VMXML.get_iface_by_mac(vm_name, item['mac'])
            if iface_xml is not None:
                if iface_xml['type'] != item['type']:
                    error_count += 1
                    logging.error(
                        "Mismatch in the network type for the "
                        "interface %s \n Type in command output: %s\n"
                        "Type in xml file: %s", item['interface'],
                        item['type'], iface_xml['type'])
                if iface_xml['source'] != item['source']:
                    error_count += 1
                    logging.error(
                        "Mismatch in the network source for the"
                        " interface %s \n Source in command output:"
                        "%s\nSource in xml file: %s", item['interface'],
                        item['source'], iface_xml['source'])

            else:
                error_count += 1
                logging.error(
                    "There is no interface in the xml file "
                    "with the below specified mac address\n"
                    "Mac:%s", item['mac'])
            iface_xml = {}
        if error_count > 0:
            test.fail("The test failed, consult previous error logs")
Example #20
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: QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=timeout)

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

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

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

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

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

        time.sleep(10)
        while threads[0].isAlive():
            session_serial.cmd("sleep 10")
            session_serial.cmd("ifconfig %s down" % ethname)
            session_serial.cmd("modprobe -r %s" % driver)
            session_serial.cmd("modprobe %s" % driver)
            session_serial.cmd("ifconfig %s up" % ethname)
    except Exception:
        for thread in threads:
            thread.join(suppress_exception=True)
            raise
    else:
        for thread in threads:
            thread.join()
Example #21
0
 def check_iface_exist():
     try:
         session = vm.wait_for_serial_login(username=username,
                                            password=password)
         if utils_net.get_linux_ifname(session, iface['mac']):
             return True
         else:
             logging.debug("can not find interface in vm")
     except Exception:
         return False
Example #22
0
 def check_iface_exist():
     try:
         session = vm.wait_for_serial_login(username=username,
                                            password=password)
         if utils_net.get_linux_ifname(session, iface['mac']):
             return True
         else:
             logging.debug("can not find interface in vm")
     except Exception:
         return False
Example #23
0
 def renew_ip_address(session, mac):
     ifname = utils_net.get_linux_ifname(session, mac)
     make_conf = "nmcli connection add type ethernet con-name %s ifname " \
                 "%s autoconnect yes" % (ifname, ifname)
     arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh"
     session.cmd_output_safe(make_conf)
     session.cmd_output_safe("ip link set dev %s up" % ifname)
     session.cmd_output_safe("dhclient -r", timeout=240)
     session.cmd_output_safe("dhclient %s" % ifname, timeout=240)
     session.cmd_output_safe(arp_clean)
Example #24
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: QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", 360))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=timeout)

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

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

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

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

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

        time.sleep(10)
        while threads[0].isAlive():
            session_serial.cmd("sleep 10")
            session_serial.cmd("ifconfig %s down" % ethname)
            session_serial.cmd("modprobe -r %s" % driver)
            session_serial.cmd("modprobe %s" % driver)
            session_serial.cmd("ifconfig %s up" % ethname)
    except Exception:
        for thread in threads:
            thread.join(suppress_exception=True)
            raise
    else:
        for thread in threads:
            thread.join()
Example #25
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 between host and guest during nic promisc on/off

    @param test: QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    def set_nic_promisc_onoff(session):
        if os_type == "linux":
            session.cmd("ip link set %s promisc on" % ethname)
            session.cmd("ip link set %s promisc off" % ethname)
        else:
            cmd = "c:\\set_win_promisc.py"
            session.cmd(cmd)

    error.context("Boot vm and prepare test environment", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session_serial = vm.wait_for_serial_login(timeout=timeout)
    session = vm.wait_for_login(timeout=timeout)

    os_type = params.get("os_type")
    if os_type == "linux":
        ethname = utils_net.get_linux_ifname(session, vm.get_mac_address(0))
    else:
        script_path = os.path.join(test.virtdir, "scripts/set_win_promisc.py")
        vm.copy_files_to(script_path, "C:\\")

    try:
        transfer_thread = utils.InterruptedThread(utils_test.run_file_transfer,
                                                  (test, params, env))

        error.context("Run utils_test.file_transfer ...", logging.info)
        transfer_thread.start()

        error.context("Perform file transfer while turning nic promisc on/off",
                      logging.info)
        while transfer_thread.isAlive():
            set_nic_promisc_onoff(session_serial)
    except Exception:
        transfer_thread.join(suppress_exception=True)
        raise
    else:
        transfer_thread.join()
        if session_serial:
            session_serial.close()
        if session:
            session.close()
Example #26
0
    def check_nics_num(expect_c, session):
        txt = "Check whether guest NICs info match with params setting."
        error.context(txt, logging.info)
        nics_list = utils_net.get_linux_ifname(session)
        actual_c = len(nics_list)
        msg = "Expected NICs count is: %d\n" % expect_c
        msg += "Actual NICs count is: %d\n" % actual_c

        if not expect_c == actual_c:
            msg += "Nics count mismatch!\n"
            return (False, msg)
        return (True, msg + 'Nics count match')
Example #27
0
 def enable_multi_queues(vm):
     session = vm.wait_for_login(timeout=login_timeout)
     error.context("Enable multi queues in guest.", logging.info)
     for nic_index, nic in enumerate(vm.virtnet):
         ifname = utils_net.get_linux_ifname(session, nic.mac)
         queues = int(nic.queues)
         mq_set_cmd = "ethtool -L %s combined %d" % (ifname, queues)
         status, output = session.cmd_status_output(mq_set_cmd)
         if status:
             msg = "Fail to enable multi queue in guest."
             msg += "Command %s, fail with output %s" % (mq_set_cmd, output)
             error.TestError(msg)
 def enable_multi_queues(vm):
     session = vm.wait_for_login(timeout=login_timeout)
     error_context.context("Enable multi queues in guest.", logging.info)
     for nic_index, nic in enumerate(vm.virtnet):
         ifname = utils_net.get_linux_ifname(session, nic.mac)
         queues = int(nic.queues)
         mq_set_cmd = "ethtool -L %s combined %d" % (ifname, queues)
         status, output = session.cmd_status_output(mq_set_cmd)
         if status:
             msg = "Fail to enable multi queue in guest."
             msg += "Command %s, fail with output %s" % (mq_set_cmd, output)
             test.error(msg)
Example #29
0
def run(test, params, env):
    """
    Test nic driver in promisc mode:

    1) Boot up a VM.
    2) Repeatedly enable/disable promiscuous mode in guest.
    3) Transfer file between host and guest during nic promisc on/off

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def set_nic_promisc_onoff(session):
        if os_type == "linux":
            session.cmd_output_safe("ip link set %s promisc on" % ethname)
            session.cmd_output_safe("ip link set %s promisc off" % ethname)
        else:
            cmd = "c:\\set_win_promisc.py"
            session.cmd(cmd)

    error.context("Boot vm and prepare test environment", logging.info)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session_serial = vm.wait_for_serial_login(timeout=timeout)
    session = vm.wait_for_login(timeout=timeout)

    os_type = params.get("os_type")
    if os_type == "linux":
        ethname = utils_net.get_linux_ifname(session, vm.get_mac_address(0))
    else:
        script_path = os.path.join(test.virtdir, "scripts/set_win_promisc.py")
        vm.copy_files_to(script_path, "C:\\")

    try:
        transfer_thread = utils_misc.InterruptedThread(
            utils_test.run_file_transfer, (test, params, env))

        error.context("Run utils_test.file_transfer ...", logging.info)
        transfer_thread.start()

        error.context("Perform file transfer while turning nic promisc on/off",
                      logging.info)
        while transfer_thread.isAlive():
            set_nic_promisc_onoff(session_serial)
    except Exception:
        transfer_thread.join(suppress_exception=True)
        raise
    else:
        transfer_thread.join()
        if session:
            session.close()
Example #30
0
 def mtu_test():
     logging.info("Set mtu value and verfied")
     serial_session.cmd(params["fw_stop_cmd"], ignore_all_errors=True)
     guest_ifname = utils_net.get_linux_ifname(serial_session,
                                               vm.get_mac_address(0))
     if guest_ifname != 'eth0':
         test.cancel("Guest device name is not expected")
     serial_session.cmd(params["set_mtu_cmd"] % guest_ifname)
     output = serial_session.cmd_output(params["check_mtu_cmd"] %
                                        guest_ifname)
     match_string = "mtu %s" % params["mtu_value"]
     if match_string not in output:
         test.fail("Guest mtu is not the expected value %s" %
                   params["mtu_value"])
Example #31
0
    def mtu_set(mtu):
        """
        Set server/client/host's mtu

        :param mtu: mtu value to be set
        """

        server_mtu_cmd = params.get("server_mtu_cmd")
        client_mtu_cmd = params.get("client_mtu_cmd")
        host_mtu_cmd = params.get("host_mtu_cmd")
        error_context.context("Changing the MTU of guest", logging.info)
        if params.get("os_type") == "linux":
            ethname = utils_net.get_linux_ifname(server_ctl, mac)
            netperf_base.ssh_cmd(server_ctl, server_mtu_cmd % (ethname, mtu))
        elif params.get("os_type") == "windows":
            connection_id = utils_net.get_windows_nic_attribute(
                server_ctl, "macaddress", mac, "netconnectionid")
            netperf_base.ssh_cmd(server_ctl,
                                 server_mtu_cmd % (connection_id, mtu))

        error_context.context("Changing the MTU of client", logging.info)
        netperf_base.ssh_cmd(
            client, client_mtu_cmd % (params.get("client_physical_nic"), mtu))

        netdst = params.get("netdst", "switch")
        host_bridges = utils_net.Bridge()
        br_in_use = host_bridges.list_br()
        if netdst in br_in_use:
            ifaces_in_use = host_bridges.list_iface()
            target_ifaces = list(ifaces_in_use + br_in_use)
        if params.get("netdst_nic1") in process.system_output(
                "ovs-vsctl list-br", ignore_status=True, shell=True).decode():
            ovs_list = "ovs-vsctl list-ports %s" % params["netdst_nic1"]
            ovs_port = process.system_output(ovs_list,
                                             shell=True).decode().splitlines()
            target_ifaces = target_ifaces + \
                params.objects("netdst_nic1") + ovs_port
        if vm.virtnet[0].nettype == "macvtap":
            target_ifaces.extend([vm.virtnet[0].netdst, vm.get_ifname(0)])
        error_context.context("Change all Bridge NICs MTU to %s" % mtu,
                              logging.info)
        for iface in target_ifaces:
            try:
                process.run(host_mtu_cmd % (iface, mtu),
                            ignore_status=False,
                            shell=True)
            except process.CmdError as err:
                if "SIOCSIFMTU" in err.result.stderr.decode():
                    test.cancel("The ethenet device does not support jumbo,"
                                "cancel test")
Example #32
0
    def check_nic_removed(mac, session):
        """
        Get interface IP address by given MAC addrss. If try_dhclint is
        True, then try to allocate IP addrss for the interface.

        :param mac: The mac address of plugged interface
        :param session: Vm session
        """
        except_mesg = ''
        try:
            if guest_os_type == 'Windows':
                except_mesg = "Get nic netconnectionid failed"
                utils_net.restart_windows_guest_network_by_key(
                    session, "macaddress", mac)
            else:
                except_mesg = ("Failed to determine interface"
                               " name with mac %s" % mac)
                utils_net.get_linux_ifname(session, mac)
        except exceptions.TestError as e:
            if except_mesg in str(e):
                return True
        else:
            return False
Example #33
0
 def ping_hotplug_nic(ip, mac, session, is_linux_guest):
     status, output = utils_test.ping(ip, 10, timeout=30)
     if status != 0:
         if not is_linux_guest:
             return status, output
         ifname = utils_net.get_linux_ifname(session, mac)
         add_route_cmd = "route add %s dev %s" % (ip, ifname)
         del_route_cmd = "route del %s dev %s" % (ip, ifname)
         logging.warn("Failed to ping %s from host.")
         logging.info("Add route and try again")
         session.cmd_output_safe(add_route_cmd)
         status, output = utils_test.ping(hotnic_ip, 10, timeout=30)
         logging.info("Del the route.")
         status, output = session.cmd_output_safe(del_route_cmd)
     return status, output
Example #34
0
 def renew_ip_address(session, mac, is_linux_guest=True):
     if not is_linux_guest:
         utils_net.restart_windows_guest_network_by_key(session, "macaddress", mac)
         return None
     ifname = utils_net.get_linux_ifname(session, mac)
     p_cfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % ifname
     cfg_con = "DEVICE=%s\nBOOTPROTO=dhcp\nONBOOT=yes" % ifname
     make_conf = "test -f %s || echo '%s' > %s" % (p_cfg, cfg_con, p_cfg)
     arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh"
     session.cmd_output_safe(make_conf)
     session.cmd_output_safe("ifconfig %s up" % ifname)
     session.cmd_output_safe("dhclient -r", timeout=240)
     session.cmd_output_safe("dhclient %s" % ifname, timeout=240)
     session.cmd_output_safe(arp_clean)
     return None
Example #35
0
    def guest_config(vm, ip_addr):
        """
        Add a new nic to guest and set a static ip address

        :param vm: Configured guest
        :param ip_addr: Set ip address
        """
        # Attach an interface device
        # Use attach-device, not attach-interface, because attach-interface
        # doesn't support 'direct'
        interface_class = vm_xml.VMXML.get_device_class('interface')
        interface = interface_class(type_name="direct")
        interface.source = dict(dev=str(eth_card_no), mode=str(iface_mode))
        interface.model = "virtio"
        interface.xmltreefile.write()
        if vm.is_alive():
            vm.destroy(gracefully=False)
        virsh.attach_device(vm.name, interface.xml, flagstr="--config")
        os.remove(interface.xml)
        vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name)
        new_nic = vmxml.get_devices(device_type="interface")[-1]

        # Modify new interface's IP
        vm.start()
        session = vm.wait_for_login()
        eth_name = utils_net.get_linux_ifname(session, new_nic.mac_address)
        eth_config_detail_list = [
            'DEVICE=%s' % eth_name,
            'HWADDR=%s' % new_nic.mac_address, 'ONBOOT=yes',
            'BOOTPROTO=static',
            'IPADDR=%s' % ip_addr
        ]
        remote_file = remote.RemoteFile(vm.get_address(), 'scp', 'root',
                                        params.get('password'), 22,
                                        eth_config_file)
        remote_file.truncate()
        remote_file.add(eth_config_detail_list)
        try:
            # Attached interface maybe already active
            session.cmd("ifdown %s" % eth_name)
        except aexpect.ShellCmdError:
            pass

        try:
            session.cmd("ifup %s" % eth_name)
        except aexpect.ShellCmdError:
            pass
        return session
Example #36
0
    def mtu_set(mtu):
        """
        Set server/client/host's mtu

        :param mtu: mtu value to be set
        """

        server_mtu_cmd = params.get("server_mtu_cmd")
        client_mtu_cmd = params.get("client_mtu_cmd")
        host_mtu_cmd = params.get("host_mtu_cmd")
        error_context.context("Changing the MTU of guest", logging.info)
        if params.get("os_type") == "linux":
            ethname = utils_net.get_linux_ifname(server_ctl, mac)
            ssh_cmd(server_ctl, server_mtu_cmd % (ethname, mtu))
        elif params.get("os_type") == "windows":
            connection_id = utils_net.get_windows_nic_attribute(
                server_ctl, "macaddress", mac, "netconnectionid")
            ssh_cmd(server_ctl, server_mtu_cmd % (connection_id, mtu))

        error_context.context("Changing the MTU of client", logging.info)
        ssh_cmd(client, client_mtu_cmd
                % (params.get("client_physical_nic"), mtu))

        netdst = params.get("netdst", "switch")
        host_bridges = utils_net.Bridge()
        br_in_use = host_bridges.list_br()
        if netdst in br_in_use:
            ifaces_in_use = host_bridges.list_iface()
            target_ifaces = list(ifaces_in_use + br_in_use)
        if params.get("netdst_nic1") in process.system_output(
                "ovs-vsctl list-br", ignore_status=True, shell=True).decode():
            ovs_list = "ovs-vsctl list-ports %s" % params["netdst_nic1"]
            ovs_port = process.system_output(ovs_list,
                                             shell=True).decode().splitlines()
            target_ifaces = target_ifaces + \
                params.objects("netdst_nic1") + ovs_port
        if vm.virtnet[0].nettype == "macvtap":
            target_ifaces.extend([vm.virtnet[0].netdst, vm.get_ifname(0)])
        error_context.context("Change all Bridge NICs MTU to %s"
                              % mtu, logging.info)
        for iface in target_ifaces:
            try:
                process.run(host_mtu_cmd % (iface, mtu), ignore_status=False,
                            shell=True)
            except process.CmdError as err:
                if "SIOCSIFMTU" in err.result.stderr.decode():
                    test.cancel("The ethenet device does not support jumbo,"
                                "cancel test")
Example #37
0
    def renew_ip_address(session, mac, guest_os_type):
        """
        Renew ip for plugged nic

        :param session: Vm session
        :param mac: The mac address of plugged interface
        :param guest_os_type: Guest os type, Linux or Windows
        """
        if guest_os_type == 'Windows':
            utils_net.restart_windows_guest_network_by_key(
                session, "macaddress", mac)
        ifname = utils_net.get_linux_ifname(session, mac)
        utils_net.create_network_script(ifname, mac, 'dhcp', '255.255.255.0')
        utils_net.restart_guest_network(session, mac)
        arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh"
        session.cmd_output_safe(arp_clean)
Example #38
0
 def renew_ip_address(session, mac, is_linux_guest=True):
     if not is_linux_guest:
         utils_net.restart_windows_guest_network_by_key(
             session, "macaddress", mac)
         return None
     ifname = utils_net.get_linux_ifname(session, mac)
     p_cfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % ifname
     cfg_con = "DEVICE=%s\nBOOTPROTO=dhcp\nONBOOT=yes" % ifname
     make_conf = "test -f %s || echo '%s' > %s" % (p_cfg, cfg_con, p_cfg)
     arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh"
     session.cmd_output_safe(make_conf)
     session.cmd_output_safe("ifconfig %s up" % ifname)
     session.cmd_output_safe("dhclient -r", timeout=240)
     session.cmd_output_safe("dhclient %s" % ifname, timeout=240)
     session.cmd_output_safe(arp_clean)
     return None
Example #39
0
    def guest_config(vm, ip_addr):
        """
        Add a new nic to guest and set a static ip address

        :param vm: Configured guest
        :param ip_addr: Set ip address
        """
        # Attach an interface device
        # Use attach-device, not attach-interface, because attach-interface
        # doesn't support 'direct'
        interface_class = vm_xml.VMXML.get_device_class('interface')
        interface = interface_class(type_name="direct")
        interface.source = dict(dev=str(eth_card_no), mode=str(iface_mode))
        interface.model = "virtio"
        interface.xmltreefile.write()
        if vm.is_alive():
            vm.destroy(gracefully=False)
        virsh.attach_device(vm.name, interface.xml, flagstr="--config")
        os.remove(interface.xml)
        vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name)
        new_nic = vmxml.get_devices(device_type="interface")[-1]

        # Modify new interface's IP
        vm.start()
        session = vm.wait_for_login()
        eth_name = utils_net.get_linux_ifname(session, new_nic.mac_address)
        eth_config_detail_list = ['DEVICE=%s' % eth_name,
                                  'HWADDR=%s' % new_nic.mac_address,
                                  'ONBOOT=yes',
                                  'BOOTPROTO=static',
                                  'IPADDR=%s' % ip_addr]
        remote_file = remote.RemoteFile(vm.get_address(), 'scp', 'root',
                                        params.get('password'), 22,
                                        eth_config_file)
        remote_file.truncate()
        remote_file.add(eth_config_detail_list, linesep='\n')
        try:
            # Attached interface maybe already active
            session.cmd("ifdown %s" % eth_name)
        except aexpect.ShellCmdError:
            raise error.TestFail("ifdown %s failed." % eth_name)

        try:
            session.cmd("ifup %s" % eth_name)
        except aexpect.ShellCmdError:
            raise error.TestFail("ifup %s failed." % eth_name)
        return session
Example #40
0
    def check_nics_num(expect_c, session):
        """
        Check whether guest NICs number match with params set in cfg file

        :param expect_c: expected nics no.
        :param session: in which session the guest runs in
        """
        txt = "Check whether guest NICs info match with params setting."
        error_context.context(txt, logging.info)
        nics_list = utils_net.get_linux_ifname(session)
        actual_c = len(nics_list)
        msg = "Expected NICs count is: %d\n" % expect_c
        msg += "Actual NICs count is: %d\n" % actual_c

        if not expect_c == actual_c:
            msg += "Nics count mismatch!\n"
            return (False, msg)
        return (True, msg + 'Nics count match')
Example #41
0
    def check_nics_num(expect_c, session):
        """
        Check whether guest NICs number match with params set in cfg file

        :param expect_c: expected nics no.
        :param session: in which session the guest runs in
        """
        txt = "Check whether guest NICs info match with params setting."
        error_context.context(txt, logging.info)
        nics_list = utils_net.get_linux_ifname(session)
        actual_c = len(nics_list)
        msg = "Expected NICs count is: %d\n" % expect_c
        msg += "Actual NICs count is: %d\n" % actual_c

        if not expect_c == actual_c:
            msg += "Nics count mismatch!\n"
            return (False, msg)
        return (True, msg + 'Nics count match')
Example #42
0
def run(test, params, env):
    """
    Test iface stat
    """
    vm_name = params.get('main_vm')
    case = params.get('case', '')
    vm = env.get_vm(vm_name)

    bk_xml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)

    try:
        if case == 'compare':
            host_ifname = utils_net.get_net_if(state="UP")[0]
            iface_dict = {
                k.replace('new_iface_', ''): v
                for k, v in params.items() if k.startswith('new_iface_')
            }
            iface_dict['source'] = iface_dict['source'] % host_ifname

            logging.debug('iface_dict is %s', iface_dict)
            libvirt.modify_vm_iface(vm_name, 'update_iface', iface_dict)
            vm.start()

            vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
            iface = vmxml.devices.by_device_tag("interface")[0]
            iface_mac = iface.mac_address
            iface_target_dev = iface.target['dev']

            session = vm.wait_for_serial_login(timeout=60)
            iface_in_vm = utils_net.get_linux_ifname(session, iface_mac)

            session.cmd('ping www.redhat.com -4 -c 20')
            host_iface_stat = get_host_iface_stat(vm_name, iface_target_dev)
            vm_iface_stat = get_vm_iface_stat(session, iface_in_vm)
            session.close()

            if not compare_iface_stat(vm_iface_stat, host_iface_stat, bar=0.2):
                test.fail('Iface stat of host and vm should be close.')

    finally:
        bk_xml.sync()
Example #43
0
 def renew_ip_address(session, mac, is_linux_guest=True):
     if not is_linux_guest:
         utils_net.restart_windows_guest_network_by_key(session,
                                                        "macaddress",
                                                        mac)
         return None
     ifname = utils_net.get_linux_ifname(session, mac)
     if params.get("make_change") == "yes":
         p_cfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % ifname
         cfg_con = "DEVICE=%s\nBOOTPROTO=dhcp\nONBOOT=yes" % ifname
         make_conf = "test -f %s || echo '%s' > %s" % (p_cfg, cfg_con, p_cfg)
     else:
         make_conf = "nmcli connection add type ethernet con-name %s ifname" \
                     " %s autoconnect yes" % (ifname, ifname)
     arp_clean = "arp -n|awk '/^[1-9]/{print \"arp -d \" $1}'|sh"
     session.cmd_output_safe(make_conf)
     session.cmd_output_safe("ip link set dev %s up" % ifname)
     session.cmd_output_safe("dhclient -r", timeout=240)
     session.cmd_output_safe("dhclient %s" % ifname, timeout=240)
     session.cmd_output_safe(arp_clean)
     return None
Example #44
0
def run_enable_mq(test, params, env):
    """
    Enable MULTI_QUEUE feature in guest

    1) Boot up VM(s)
    2) Login guests one by one
    3) Enable MQ for all virtio nics by ethtool -L

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

    login_timeout = int(params.get("login_timeout", 360))
    queues = int(params.get("queues", 1))
    vms = params.get("vms").split()
    if queues == 1:
        logging.info("No need to enable MQ feature for single queue")
        return

    for vm in vms:
        vm = env.get_vm(vm)
        vm.verify_alive()
        session = vm.wait_for_login(timeout=login_timeout)
        for i, nic in enumerate(vm.virtnet):
            if "virtio" in nic['nic_model']:
                ifname = utils_net.get_linux_ifname(session,
                                                    vm.get_mac_address(0))
                session.cmd_output("ethtool -L %s combined %d" %
                                   (ifname, queues))
                o = session.cmd_output("ethtool -l %s" % ifname)
                if len(re.findall("Combined:\s+%d\s" % queues, o)) != 2:
                    raise error.TestError("Fail to enable MQ feature of (%s)" %
                                          nic.nic_name)

                logging.info("MQ feature of (%s) is enabled" % nic.nic_name)

        session.close()
    def get_speed_duplex_linux(session):
        """
        Get the speed and duplex information on linux guests.

        return: a tuple of (speed, duplex), which speed is measured by mbps,
                and duplex is one of 'half' and 'full'.
        """
        error_context.context("Get speed & duplex info", logging.info)
        mac = vm.get_mac_address(0)
        ethname = utils_net.get_linux_ifname(session, mac)
        check_speed_cmd = params["check_speed_cmd"] % ethname
        status, output = session.cmd_status_output(check_speed_cmd)
        if status:
            test.fail("Failed to get speed info,"
                      "status=%s, ouput=%s" % (status, output))
        logging.info(output)
        result = re.findall(r"(?:Speed:\s+(\d+)Mb/s)|(?:Duplex:\s+(\w+))",
                            output)
        if len(result) < 2:
            test.error("Can't get speed or duplex info")
        speed = int(result[0][0])
        duplex = result[1][1].lower()
        return (speed, duplex)
Example #46
0
    def mtu_set(mtu):
        """
        Set server/client/host's mtu

        :param mtu: mtu value to be set
        """

        server_mtu_cmd = params.get("server_mtu_cmd")
        client_mtu_cmd = params.get("client_mtu_cmd")
        host_mtu_cmd = params.get("host_mtu_cmd")
        error_context.context("Changing the MTU of guest", logging.info)
        if params.get("os_type") == "linux":
            ethname = utils_net.get_linux_ifname(server_ctl, mac)
            ssh_cmd(server_ctl, server_mtu_cmd % (ethname, mtu))
        elif params.get("os_type") == "windows":
            connection_id = utils_net.get_windows_nic_attribute(
                server_ctl, "macaddress", mac, "netconnectionid")
            ssh_cmd(server_ctl, server_mtu_cmd % (connection_id, mtu))

        error_context.context("Changing the MTU of client", logging.info)
        ssh_cmd(client, client_mtu_cmd
                % (params.get("client_physical_nic"), mtu))

        netdst = params.get("netdst", "switch")
        host_bridges = utils_net.Bridge()
        br_in_use = host_bridges.list_br()
        if netdst in br_in_use:
            ifaces_in_use = host_bridges.list_iface()
            target_ifaces = list(ifaces_in_use + br_in_use)
        if vm.virtnet[0].nettype == "macvtap":
            target_ifaces.extend([vm.virtnet[0].netdst, vm.get_ifname(0)])
        error_context.context("Change all Bridge NICs MTU to %s"
                              % mtu, logging.info)
        for iface in target_ifaces:
            process.run(host_mtu_cmd % (iface, mtu), ignore_status=False,
                        shell=True)
Example #47
0
    def guest_config(vm, ip_addr):
        """
        Add a new nic to guest and set a static ip address

        :param vm: Configured guest
        :param ip_addr: Set ip address
        """
        # Attach an interface device
        # Use attach-device, not attach-interface, because attach-interface
        # doesn't support 'direct'
        interface_class = vm_xml.VMXML.get_device_class('interface')
        interface = interface_class(type_name="direct")
        interface.source = dict(dev=str(eth_card_no), mode=str(iface_mode))
        interface.model = "virtio"
        interface.xmltreefile.write()
        if vm.is_alive():
            vm.destroy(gracefully=False)
        virsh.attach_device(vm.name, interface.xml, flagstr="--config")
        os.remove(interface.xml)
        vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm.name)
        new_nic = vmxml.get_devices(device_type="interface")[-1]

        # Modify new interface's IP
        vm.start()
        session = vm.wait_for_login()
        eth_name = utils_net.get_linux_ifname(session, new_nic.mac_address)
        eth_config_detail = "DEVICE=%s\nHWADDR=%s\nONBOOT=yes\n"\
                            "BOOTPROTO=static\nIPADDR=%s"\
                            % (eth_name, new_nic.mac_address, ip_addr)
        add_cmd = "echo %s >> %s" % (eth_config_detail, eth_config_file)
        session.cmd(add_cmd)
        session.cmd("sync")
        try:
            session.cmd("ifup %s" % eth_name)
        except aexpect.ShellCmdError:
            pass
Example #48
0
        guest_netwok_connecting_check(guest_ip, link_up, change_queues)

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

    change_queues = False
    guest_ifname = ""
    guest_ip = vm.get_address()
    # Win guest '2' represent 'Connected', '7' represent 'Media disconnected'
    win_media_connected = params.get("win_media_connected", "2")
    win_media_disconnected = params.get("win_media_disconnected", "7")

    if params.get("os_type") == "linux":
        guest_ifname = utils_net.get_linux_ifname(session,
                                                  vm.get_mac_address())
        queues = int(params.get("queues", 1))
        if queues != 1 and vm.virtnet[0].nic_model == "virtio":
            change_queues = True

    session.close()

    netdev_id = vm.virtnet[0].netdev_id
    device_id = vm.virtnet[0].device_id
    expect_down_status = params.get("down-status", "down")
    expect_up_status = params.get("up-status", "up")
    operstate_always_up = params.get("operstate_always_up", "no") == "yes"

    error.context("Disable guest netdev link '%s' by set_link" % netdev_id,
                  logging.info)
    set_link_test(netdev_id, False, expect_down_status, operstate_always_up,
Example #49
0
def run(test, params, env):
    """
    Nic bonding test in guest.

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

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

    timeout = int(params.get("login_timeout", 1200))
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=timeout)
    ifnames = [utils_net.get_linux_ifname(session_serial,
                                          vm.get_mac_address(vlan))
               for vlan, nic in enumerate(vm.virtnet)]

    # get params of bonding
    nm_stop_cmd = "pidof NetworkManager && service NetworkManager stop; true"
    session_serial.cmd_output_safe(nm_stop_cmd)
    modprobe_cmd = "modprobe bonding"
    bonding_params = params.get("bonding_params")
    if bonding_params:
        modprobe_cmd += " %s" % bonding_params
    session_serial.cmd_output_safe(modprobe_cmd)
    session_serial.cmd_output_safe("ifconfig bond0 up")
    setup_cmd = "ifenslave bond0 " + " ".join(ifnames)
    session_serial.cmd_output_safe(setup_cmd)
    # do a pgrep to check if dhclient has already been running
    pgrep_cmd = "pgrep dhclient"
    try:
        session_serial.cmd_output_safe(pgrep_cmd)
    # if dhclient is there, killl it
    except aexpect.ShellCmdError:
        logging.info("it's safe to run dhclient now")
    else:
        logging.info("dhclient already is running,kill it")
        session_serial.cmd_output_safe("killall -9 dhclient")
        time.sleep(1)

    session_serial.cmd_output_safe("dhclient bond0")

    #get_bonding_nic_mac and ip
    try:
        logging.info("Test file transferring:")
        utils_test.run_file_transfer(test, params, env)

        logging.info("Failover test with file transfer")
        transfer_thread = utils.InterruptedThread(utils_test.run_file_transfer,
                                                  (test, params, env))
        transfer_thread.start()
        try:
            while transfer_thread.isAlive():
                for vlan, nic in enumerate(vm.virtnet):
                    device_id = nic.device_id
                    if not device_id:
                        raise error.TestError("Could not find peer device for"
                                              " nic device %s" % nic)
                    vm.set_link(device_id, up=False)
                    time.sleep(random.randint(1, 30))
                    vm.set_link(device_id, up=True)
                    time.sleep(random.randint(1, 30))
        except Exception:
            transfer_thread.join(suppress_exception=True)
            raise
        else:
            transfer_thread.join()
    finally:
        session_serial.sendline("ifenslave -d bond0 " + " ".join(ifnames))
        session_serial.sendline("kill -9 `pgrep dhclient`")
Example #50
0
def run(test, params, env):
    """
    Test Step
        1. boot up two virtual machine
        2. Transfer data: host <--> guest1 <--> guest2 <-->host via ipv6
        3. after data transfer, check data have no change
    Params:
        :param test: QEMU test object
        :param params: Dictionary with the test parameters
        :param env: Dictionary with test environment.
    """
    timeout = int(params.get("login_timeout", '360'))
    client = params.get("file_transfer_client")
    port = params.get("file_transfer_port")
    password = params.get("password")
    username = params.get("username")
    tmp_dir = params.get("tmp_dir", "/tmp/")
    filesize = int(params.get("filesize", '4096'))
    dd_cmd = params.get("dd_cmd")
    file_trans_timeout = int(params.get("file_trans_timeout", '1200'))
    file_md5_check_timeout = int(params.get("file_md5_check_timeout", '600'))

    def get_linux_ipv6_linklocal_address(ifname, session=None):
        """
        Get host/guest ipv6 linklocal address via ifname
        """
        if session is not None:
            o = session.cmd_output("ifconfig %s" % ifname)
        else:
            o = utils.system_output("ifconfig %s" % ifname)
        ipv6_address_reg = re.compile(r"(fe80::[^\s|/]*)")
        if o:
            ipv6_linklocal_address = ipv6_address_reg.findall(o)
            if not ipv6_linklocal_address:
                raise error.TestError("Can't get %s linklocal address"
                                      % ifname)
            return ipv6_linklocal_address[0]
        else:
            return None

    def get_file_md5sum(file_name, session, timeout):
        """
        Get file md5sum from guest.
        """
        logging.info("Get md5sum of the file:'%s'" % file_name)
        try:
            o = session.cmd_output("md5sum %s" % file_name, timeout=timeout)
            file_md5sum = re.findall("\w+", o)[0]
        except IndexError:
            raise error.TestError("Could not get file md5sum in guest")
        return file_md5sum

    sessions = {}
    addresses = {}
    inet_name = {}
    vms = []

    error.context("Boot vms for test", logging.info)
    for vm_name in params.get("vms", "vm1 vm2").split():
        vms.append(env.get_vm(vm_name))

    # config ipv6 address host and guest.
    host_ifname = params.get("netdst")

    for vm in vms:
        vm.verify_alive()
        sessions[vm] = vm.wait_for_login(timeout=timeout)
        inet_name[vm] = utils_net.get_linux_ifname(sessions[vm],
                                                   vm.get_mac_address())
        addresses[vm] = get_linux_ipv6_linklocal_address(inet_name[vm],
                                                         sessions[vm])

    # prepare test data
    guest_path = (tmp_dir + "src-%s" % utils_misc.generate_random_string(8))
    dest_path = (tmp_dir + "dst-%s" % utils_misc.generate_random_string(8))
    host_path = os.path.join(test.tmpdir, "tmp-%s" %
                             utils_misc.generate_random_string(8))
    logging.info("Test setup: Creating %dMB file on host", filesize)
    utils.run(dd_cmd % (host_path, filesize))

    try:
        src_md5 = (utils.hash_file(host_path, method="md5"))
        # transfer data
        for vm in vms:
            error.context("Transfer data from host to %s" % vm.name,
                          logging.info)
            remote.copy_files_to(addresses[vm],
                                 client, username, password, port,
                                 host_path, guest_path,
                                 timeout=file_trans_timeout,
                                 interface=host_ifname)
            dst_md5 = get_file_md5sum(guest_path, sessions[vm],
                                      timeout=file_md5_check_timeout)
            if dst_md5 != src_md5:
                raise error.TestFail("File changed after transfer host -> %s"
                                     % vm.name)

        for vm_src in addresses:
            for vm_dst in addresses:
                if vm_src != vm_dst:
                    error.context("Transferring data from %s to %s" %
                                  (vm_src.name, vm_dst.name), logging.info)
                    remote.scp_between_remotes(addresses[vm_src],
                                               addresses[vm_dst],
                                               port, password, password,
                                               username, username,
                                               guest_path, dest_path,
                                               timeout=file_trans_timeout,
                                               src_inter=host_ifname,
                                               dst_inter=inet_name[vm_src])
                    dst_md5 = get_file_md5sum(dest_path, sessions[vm_dst],
                                              timeout=file_md5_check_timeout)
                    if dst_md5 != src_md5:
                        raise error.TestFail("File changed transfer %s -> %s"
                                             % (vm_src.name, vm_dst.name))

        for vm in vms:
            error.context("Transfer data from %s to host" % vm.name,
                          logging.info)
            remote.copy_files_from(addresses[vm],
                                   client, username, password, port,
                                   dest_path, host_path,
                                   timeout=file_trans_timeout,
                                   interface=host_ifname)
            error.context("Check whether the file changed after trans",
                          logging.info)
            dst_md5 = (utils.hash_file(host_path, method="md5"))
            if dst_md5 != src_md5:
                raise error.TestFail("File changed after transfer (md5sum mismatch)")
            utils.system_output("rm -rf %s" % host_path, timeout=timeout)

    finally:
        utils.system("rm -rf %s" % host_path, timeout=timeout,
                     ignore_status=True)
        for vm in vms:
            sessions[vm].cmd("rm -rf %s %s || true" % (guest_path, dest_path),
                             timeout=timeout, ignore_all_errors=True)
            sessions[vm].close()
def run(test, params, env):
    """
    Test qmp event notification function:
    1) Boot up guest with qmp and macvtap.
    2) In guest, change network interface to promisc state.
    3) Try to catch qmp event notification in qmp monitor.
    4) Execute query-rx-filter in host qmp session.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environmen.
    """

    if not utils_misc.qemu_has_option("qmp"):
        error.TestNAError("This test case requires a host QEMU with QMP "
                          "monitor support")
    if params.get("nettype", "macvtap") != "macvtap":
        error.TestNAError("This test case test macvtap.")

    params["start_vm"] = "yes"
    vm_name = params.get("main_vm", "vm1")
    env_process.preprocess_vm(test, params, env, vm_name)

    vm = env.get_vm(vm_name)
    vm.verify_alive()

    event_cmd = params.get("event_cmd")
    event_cmd_type = params.get("event_cmd_type")
    event_check = params.get("event_check")
    timeout = int(params.get("check_timeout", 360))
    pre_cmd = params.get("pre_cmd")
    post_cmd = params.get("post_cmd")
    post_cmd_type = params.get("post_cmd_type")

    session = vm.wait_for_serial_login(timeout=int(params.get("login_timeout",
                                                              360)))

    callback = {"host_cmd": utils.system_output,
                "guest_cmd": session.get_command_output,
                "qmp_cmd": vm.get_monitors_by_type("qmp")[0].send_args_cmd}

    def send_cmd(cmd, cmd_type):
        if cmd_type in callback.keys():
            return callback[cmd_type](cmd)
        else:
            raise error.TestError("cmd_type is not supported")

    if pre_cmd:
        error.context("Run pre_cmd '%s'", logging.info)
        pre_cmd_type = params.get("pre_cmd_type", event_cmd_type)
        send_cmd(pre_cmd, pre_cmd_type)

    mac = vm.get_mac_address()
    interface_name = utils_net.get_linux_ifname(session, mac)

    error.context("In guest, change network interface to promisc state.",
                  logging.info)
    event_cmd = params.get("event_cmd") % interface_name
    send_cmd(event_cmd, event_cmd_type)

    error.context("Try to get qmp events in %s seconds!" % timeout,
                  logging.info)
    end_time = time.time() + timeout
    qmp_monitors = vm.get_monitors_by_type("qmp")
    qmp_num = len(qmp_monitors)
    while time.time() < end_time:
        for monitor in qmp_monitors:
            event = monitor.get_event(event_check)
            if event:
                txt = "Monitr %s " % monitor.name
                txt += "receive qmp %s event notification" % event_check
                logging.info(txt)
                qmp_num -= 1
                qmp_monitors.remove(monitor)
        time.sleep(5)
        if qmp_num <= 0:
            break
    if qmp_num > 0:
        output = session.cmd("ip link show")
        err = "Monitor(s) "
        for monitor in qmp_monitors:
            err += "%s " % monitor.name
        err += " did not receive qmp %s event notification." % event_check
        err += " ip link show command output in guest: %s" % output
        raise error.TestFail(err)

    if post_cmd:
        for nic in vm.virtnet:
            post_cmd = post_cmd % nic.device_id
            error.context("Run post_cmd '%s'" % post_cmd, logging.info)
            post_cmd_type = params.get("post_cmd_type", event_cmd_type)
            output = send_cmd(post_cmd, post_cmd_type)
            post_cmd_check = params.get("post_cmd_check")
            if post_cmd_check:
                if post_cmd_check not in str(output):
                    err = "Did not find '%s' in " % post_cmd_check
                    err += "'%s' command's output: %s" % (post_cmd, output)
                    raise error.TestFail(err)

    if session:
        session.close()
Example #52
0
def run(test, params, env):
    """
    MULTI_QUEUE chang queues number test

    1) Boot up VM, and login guest
    2) Check guest pci msi support and reset it as expection
    3) Enable the queues in guest
    4) Run bg_stress_test(pktgen, netperf or file copy) if needed
    5) Change queues number repeatly during stress test running
    6) Ping external host (local host, if external host not available)

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def change_queues_number(session, ifname, q_number, queues_status=None):
        """
        Change queues number
        """
        mq_set_cmd = "ethtool -L %s combined %d" % (ifname, q_number)
        if not queues_status:
            queues_status = get_queues_status(session, ifname)

        if (q_number != queues_status[1] and q_number <= queues_status[0] and
                q_number > 0):
            expect_status = 0
        else:
            expect_status = 1

        status, output = session.cmd_status_output(mq_set_cmd, safe=True)
        cur_queues_status = get_queues_status(session, ifname)
        if status != expect_status:
            err_msg = "Change queues number failed, "
            err_msg += "current queues set is %s, " % queues_status[1]
            err_msg += "max allow queues set is %s, " % queues_status[0]
            err_msg += "when run cmd: '%s', " % mq_set_cmd
            err_msg += "expect exit status is: %s, " % expect_status
            err_msg += "output: '%s'" % output
            raise error.TestFail(err_msg)
        if not status and cur_queues_status == queues_status:
            raise error.TestFail("params is right, but change queues failed")
        elif status and cur_queues_status != queues_status:
            raise error.TestFail("No need change queues number")
        return [int(_) for _ in cur_queues_status]

    def get_queues_status(session, ifname, timeout=240):
        """
        Get queues status
        """
        mq_get_cmd = "ethtool -l %s" % ifname
        nic_mq_info = session.cmd_output(mq_get_cmd, timeout=timeout,
                                         safe=True)
        queues_reg = re.compile(r"Combined:\s+(\d)", re.I)
        queues_info = queues_reg.findall(" ".join(nic_mq_info.splitlines()))
        if len(queues_info) != 2:
            err_msg = "Oops, get guest queues info failed, "
            err_msg += "make sure your guest support MQ.\n"
            err_msg += "Check cmd is: '%s', " % mq_get_cmd
            err_msg += "Command output is: '%s'." % nic_mq_info
            raise error.TestNAError(err_msg)
        return [int(x) for x in queues_info]

    def enable_multi_queues(vm):
        sess = vm.wait_for_serial_login(timeout=login_timeout)
        error.context("Enable multi queues in guest.", logging.info)
        for nic_index, nic in enumerate(vm.virtnet):
            ifname = utils_net.get_linux_ifname(sess, nic.mac)
            queues = int(nic.queues)
            change_queues_number(sess, ifname, queues)

    def ping_test(dest_ip, ping_time, lost_raito, session=None):
        status, output = utils_test.ping(dest=dest_ip, timeout=ping_time,
                                         session=session)
        packets_lost = utils_test.get_loss_ratio(output)
        if packets_lost > lost_raito:
            err = " %s%% packages lost during ping. " % packets_lost
            err += "Ping command log:\n %s" % "\n".join(output.splitlines()[-3:])
            raise error.TestFail(err)

    error.context("Init guest and try to login", logging.info)
    login_timeout = int(params.get("login_timeout", 360))
    bg_stress_test = params.get("run_bgstress")
    bg_stress_run_flag = params.get("bg_stress_run_flag")
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    vm.wait_for_login(timeout=login_timeout)

    if params.get("pci_nomsi", "no") == "yes":
        error.context("Disable pci msi in guest", logging.info)
        utils_test.update_boot_option(vm, args_added="pci=nomsi")
        vm.wait_for_login(timeout=login_timeout)

    enable_multi_queues(vm)

    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
    s_session = None
    bg_ping = params.get("bg_ping")
    b_ping_lost_ratio = int(params.get("background_ping_package_lost_ratio", 5))
    f_ping_lost_ratio = int(params.get("final_ping_package_lost_ratio", 5))
    guest_ip = vm.get_address()
    b_ping_time = int(params.get("background_ping_time", 60))
    f_ping_time = int(params.get("final_ping_time", 60))
    bg_test = None
    try:

        ifnames = []
        for nic_index, nic in enumerate(vm.virtnet):
            ifname = utils_net.get_linux_ifname(session_serial,
                                                vm.virtnet[nic_index].mac)
            ifnames.append(ifname)

        if bg_stress_test:
            error.context("Run test %s background" % bg_stress_test,
                          logging.info)
            stress_thread = ""
            wait_time = float(params.get("wait_bg_time", 60))
            env[bg_stress_run_flag] = False
            stress_thread = utils.InterruptedThread(
                utils_test.run_virt_sub_test, (test, params, env),
                {"sub_type": bg_stress_test})
            stress_thread.start()
            if bg_stress_run_flag:
                utils_misc.wait_for(lambda: env.get(bg_stress_run_flag),
                                    wait_time, 0, 5,
                                    "Wait %s start background" % bg_stress_test)
        if bg_ping == "yes":
            error.context("Ping guest from host", logging.info)
            args = (guest_ip, b_ping_time, b_ping_lost_ratio)
            bg_test = utils.InterruptedThread(ping_test, args)
            bg_test.start()

        error.context("Change queues number repeatly", logging.info)
        repeat_counts = int(params.get("repeat_counts", 10))
        for nic_index, nic in enumerate(vm.virtnet):
            if "virtio" not in nic['nic_model']:
                continue
            queues = int(vm.virtnet[nic_index].queues)
            if queues == 1:
                logging.info("Nic with single queue, skip and continue")
                continue
            ifname = ifnames[nic_index]
            default_change_list = xrange(1, int(queues + 1))
            change_list = params.get("change_list")
            if change_list:
                change_list = change_list.split(",")
            else:
                change_list = default_change_list

            for repeat_num in xrange(1, repeat_counts + 1):
                error.context("Change queues number -- %sth" % repeat_num,
                              logging.info)
                try:
                    queues_status = get_queues_status(session_serial, ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(session_serial,
                                                             ifname,
                                                             int(q_number),
                                                             queues_status)
                except aexpect.ShellProcessTerminatedError:
                    vm = env.get_vm(params["main_vm"])
                    session = vm.wait_for_serial_login(timeout=login_timeout)
                    session_serial = session
                    queues_status = get_queues_status(session_serial, ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(session_serial,
                                                             ifname,
                                                             int(q_number),
                                                             queues_status)

        if params.get("ping_after_changing_queues", "yes") == "yes":
            default_host = "www.redhat.com"
            try:
                ext_host = utils_net.get_host_default_gateway()
            except error.CmdError:
                logging.warn("Can't get specified host,"
                             " Fallback to default host '%s'", default_host)
                ext_host = default_host
            if not ext_host:
                # Fallback to a hardcode host, eg:
                ext_host = default_host
            s_session = vm.wait_for_login(timeout=login_timeout)
            txt = "ping %s after changing queues in guest."
            error.context(txt, logging.info)
            ping_test(ext_host, f_ping_time, f_ping_lost_ratio, s_session)

        if bg_stress_test:
            env[bg_stress_run_flag] = False
            if stress_thread:
                error.context("wait for background test finish", logging.info)
                try:
                    stress_thread.join()
                except Exception, err:
                    err_msg = "Run %s test background error!\n "
                    err_msg += "Error Info: '%s'"
                    raise error.TestError(err_msg % (bg_stress_test, err))

    finally:
        if bg_stress_test:
            env[bg_stress_run_flag] = False
        if session_serial:
            session_serial.close()
        if s_session:
            s_session.close()
        if bg_test:
            error.context("Wait for background ping test finish.",
                          logging.info)
            try:
                bg_test.join()
            except Exception, err:
                txt = "Fail to wait background ping test finish. "
                txt += "Got error message %s" % err
                raise error.TestFail(txt)
def run(test, params, env):
    """
    KVM migration test:
    1) Get a live VM and clone it.
    2) Verify that the source VM supports migration. If it does, proceed with
       the test.
    3) Hotplug a nic.
    4) Disable the primary link of guest.
    5) Check if new interface gets ip address.
    6) Ping guest's new ip from host.
    7) Re-enabling the primary link.
    8) Send a migration command to the source VM and wait until it's finished.
    9) Disable the primary link again.
    10) Ping guest's new ip from host.
    11) Re-enabling the primary link.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    error.context("Reboot guest and verify new nic works", logging.info)
    host_ip = utils_net.get_ip_address_by_interface(netdst)
    session = vm.reboot(session=session)
    status, output = utils_test.ping(dest=host_ip, count=100,
                                     timeout=240, session=session)
    if status != 0:
        raise error.TestFail("Fail to ping host form guest")
Example #54
0
def run_vlan(test, params, env):
    """
    Test 802.1Q vlan of NIC, config it by vconfig/ip command.

    1) Create two VMs.
    2) load 8021q module in guest.
    3) Setup vlans by vconfig/ip in guest and using hard-coded ip address.
    4) Enable arp_ignore for all ipv4 device in guest.
    5) Repeat steps 2 - 4 in every guest.
    6) Test by ping between same and different vlans of two VMs.
    7) Test by flood ping between same vlan of two VMs.
    8) Test by TCP data transfer between same vlan of two VMs.
    9) Remove the named vlan-device.
    10) Test maximal plumb/unplumb vlans.

    @param test: QEMU test object.
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
    def add_vlan(session, v_id, iface="eth0", cmd_type="ip"):
        """
        Creates a vlan-device on iface by cmd that assigned by cmd_type
        now only support 'ip' and 'vconfig'
        """
        txt = "Create a vlan-device on interface %s with vlan id %s" % (iface,
                                                                        v_id)
        error.context(txt, logging.info)
        if cmd_type == "vconfig":
            cmd = "vconfig add %s %s" % (iface, v_id)
        elif cmd_type == "ip":
            v_name = "%s.%s" % (iface, v_id)
            cmd = "ip link add link %s %s type vlan id %s " % (iface,
                                                               v_name, v_id)
        else:
            err_msg = "Unexpected vlan operation command: %s" %  cmd_type
            err_msg += "only support 'ip' and 'vconfig' now"
            raise error.TestError(err_msg)
        session.cmd(cmd)


    def set_ip_vlan(session, v_id, ip, iface="eth0"):
        """
        Set ip address of vlan interface
        """
        iface = "%s.%s" % (iface, v_id)
        txt = "Set ip to '%s' for interface '%s'" % (iface, ip)
        error.context(txt, logging.info)
        session.cmd("ifconfig %s %s" % (iface, ip))


    def set_arp_ignore(session):
        """
        Enable arp_ignore for all ipv4 device in guest
        """
        error.context("Enable arp_ignore for all ipv4 device in guest",
                       logging.info)
        ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore"
        session.cmd(ignore_cmd)


    def rem_vlan(session, v_id, iface="eth0", cmd_type="ip"):
        """
        Removes the named vlan interface(iface+v_id)
        """
        v_iface = '%s.%s' % (iface, v_id)
        if cmd_type == "vconfig":
            rem_vlan_cmd = "vconfig rem %s" % v_iface
        elif cmd_type == "ip":
            rem_vlan_cmd = "ip link delete %s" % v_iface
        else:
            err_msg = "Unexpected vlan operation command: %s" %  cmd_type
            err_msg += "only support 'ip' and 'vconfig' now"
            raise error.TestError(err_msg)

        send_cmd = "[ -e /proc/net/vlan/%s ] && %s" % (v_iface, rem_vlan_cmd)
        error.context("Remove the vlan-device '%s'." % v_iface, logging.info)
        return session.cmd_status(send_cmd)


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

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


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


    vm = []
    session = []
    ifname = []
    vm_ip = []
    digest_origin = []
    vlan_ip = ['', '']
    ip_unit = ['1', '2']
    subnet = params.get("subnet", "192.168")
    vlan_num = int(params.get("vlan_num", 5))
    maximal = int(params.get("maximal"))
    file_size = params.get("file_size", 4094)
    cmd_type = params.get("cmd_type", "ip")
    login_timeout = int(params.get("login_timeout", 360))

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

    for i in range(2):
        session.append(vm[i].wait_for_login(timeout=login_timeout))
        if not session[i] :
            raise error.TestError("Could not log into guest %s" % vm[i].name)
        logging.info("Logged in %s successfull" % vm[i].name)

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

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

        #stop firewall in vm
        session[i].cmd("service iptables stop; true")

        error.context("load 8021q module in guest %s" % vm[i].name,
                      logging.info)
        session[i].cmd("modprobe 8021q")

    try:
        for i in range(2):
            logging.info("Setup vlan environment in guest %s" % vm[i].name)
            for vlan_i in range(1, vlan_num+1):
                add_vlan(session[i], vlan_i, ifname[i], cmd_type)
                v_ip = "%s.%s.%s" % (subnet, vlan_i, ip_unit[i])
                set_ip_vlan(session[i], vlan_i, v_ip, ifname[i])
            set_arp_ignore(session[i])

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

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

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

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

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

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

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

    session[0].close()
    session[1].close()
Example #55
0
def run(test, params, env):
    """
    Run Pktgen test between host/guest

    1) Boot the main vm, or just grab it if it's already booted.
    2) Configure pktgen server(only linux)
    3) Run pktgen test, finish when timeout or env["pktgen_run"] != True

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

    login_timeout = float(params.get("login_timeout", 360))
    error.context("Init the VM, and try to login", logging.info)
    external_host = params.get("external_host")
    if not external_host:
        get_host_cmd = "ip route | awk '/default/ {print $3}'"
        external_host = utils.system_output(get_host_cmd)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=login_timeout)

    error.context("Pktgen server environment prepare", logging.info)
    # pktgen server only support linux, since pktgen is a linux kernel module
    pktgen_server = params.get("pktgen_server", "localhost")
    params_server = params.object_params("pktgen_server")
    s_shell_client = params_server.get("shell_client", "ssh")
    s_shell_port = params_server.get("shell_port", "22")
    s_username = params_server.get("username", "root")
    s_passwd = params_server.get("password", "123456")
    s_shell_prompt = params_server.get("shell_prompt")

    server_session = ""
    # pktgen server is autotest virtual guest(only linux)
    if pktgen_server in params.get("vms", "vm1 vm2"):
        vm_pktgen = env.get_vm(pktgen_server)
        vm_pktgen.verify_alive()
        server_session = vm_pktgen.wait_for_login(timeout=login_timeout)
        runner = server_session.cmd_output_safe
        pktgen_ip = vm_pktgen.get_address()
        pktgen_mac = vm_pktgen.get_mac_address()
        server_interface = utils_net.get_linux_ifname(server_session, pktgen_mac)
    # pktgen server is a external host assigned
    elif re.match(r"((\d){1,3}\.){3}(\d){1,3}", pktgen_server):
        pktgen_ip = pktgen_server
        server_session = remote.wait_for_login(
            s_shell_client, pktgen_ip, s_shell_port, s_username, s_passwd, s_shell_prompt
        )
        runner = server_session.cmd_output_safe
        server_interface = params.get("server_interface")
        if not server_interface:
            raise error.TestNAError("Must config server interface before test")
    else:
        # using host as a pktgen server
        server_interface = params.get("netdst", "switch")
        host_nic = utils_net.Interface(server_interface)
        pktgen_ip = host_nic.get_ip()
        pktgen_mac = host_nic.get_mac()
        runner = utils.system

    # copy pktgen_test scipt to the test server.
    local_path = os.path.join(data_dir.get_root_dir(), "shared/scripts/pktgen.sh")
    remote_path = "/tmp/pktgen.sh"
    remote.scp_to_remote(pktgen_ip, s_shell_port, s_username, s_passwd, local_path, remote_path)

    error.context("Run pktgen test", logging.info)
    run_threads = params.get("pktgen_threads", 1)
    pktgen_stress_timeout = float(params.get("pktgen_test_timeout", 600))
    exec_cmd = "%s %s %s %s %s" % (remote_path, vm.get_address(), vm.get_mac_address(), server_interface, run_threads)
    try:
        env["pktgen_run"] = True
        try:
            # Set a run flag in env, when other case call this case as a sub
            # backgroud process, can set run flag to False to stop this case.
            start_time = time.time()
            stop_time = start_time + pktgen_stress_timeout
            while env["pktgen_run"] and time.time() < stop_time:
                runner(exec_cmd, timeout=pktgen_stress_timeout)

        # using ping to kill the pktgen stress
        except aexpect.ShellTimeoutError:
            session.cmd("ping %s" % pktgen_ip, ignore_all_errors=True)
    finally:
        env["pktgen_run"] = False

    error.context("Verify Host and guest kernel no error and call trace", logging.info)
    vm.verify_kernel_crash()
    utils_misc.verify_host_dmesg()

    error.context("Ping external host after pktgen test", logging.info)
    status, output = utils_test.ping(dest=external_host, session=session, timeout=240, count=20)
    loss_ratio = utils_test.get_loss_ratio(output)
    if loss_ratio > int(params.get("packet_lost_ratio", 5)) or loss_ratio == -1:
        logging.debug("Ping %s output: %s" % (external_host, output))
        raise error.TestFail("Guest network connction unusable," + "packet lost ratio is '%d%%'" % loss_ratio)
    if server_session:
        server_session.close()
    if session:
        session.close()
Example #56
0
def run(test, params, env):
    """
    Test interafce xml options.

    1.Prepare test environment,destroy or suspend a VM.
    2.Edit xml and start the domain.
    3.Perform test operation.
    4.Recover test environment.
    5.Confirm the test result.
    """
    vm_name = params.get("main_vm")
    vm = env.get_vm(vm_name)
    virsh_dargs = {'debug': True, 'ignore_status': False}

    def create_iface_xml(iface_mac):
        """
        Create interface xml file
        """
        iface = Interface(type_name=iface_type)
        source = ast.literal_eval(iface_source)
        if source:
            iface.source = source
        iface.model = iface_model if iface_model else "virtio"
        iface.mac_address = iface_mac
        driver_dict = {}
        driver_host = {}
        driver_guest = {}
        if iface_driver:
            driver_dict = ast.literal_eval(iface_driver)
        if iface_driver_host:
            driver_host = ast.literal_eval(iface_driver_host)
        if iface_driver_guest:
            driver_guest = ast.literal_eval(iface_driver_guest)
        iface.driver = iface.new_driver(driver_attr=driver_dict,
                                        driver_host=driver_host,
                                        driver_guest=driver_guest)
        logging.debug("Create new interface xml: %s", iface)
        return iface

    def modify_iface_xml(update, status_error=False):
        """
        Modify interface xml options
        """
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        xml_devices = vmxml.devices
        iface_index = xml_devices.index(
            xml_devices.by_device_tag("interface")[0])
        iface = xml_devices[iface_index]
        if iface_model:
            iface.model = iface_model
        else:
            del iface.model
        if iface_type:
            iface.type_name = iface_type
        del iface.source
        source = ast.literal_eval(iface_source)
        if source:
            net_ifs = utils_net.get_net_if(state="UP")
            # Check source device is valid or not,
            # if it's not in host interface list, try to set
            # source device to first active interface of host
            if (iface.type_name == "direct" and
                    source.has_key('dev') and
                    source['dev'] not in net_ifs):
                logging.warn("Source device %s is not a interface"
                             " of host, reset to %s",
                             source['dev'], net_ifs[0])
                source['dev'] = net_ifs[0]
            iface.source = source
        backend = ast.literal_eval(iface_backend)
        if backend:
            iface.backend = backend
        driver_dict = {}
        driver_host = {}
        driver_guest = {}
        if iface_driver:
            driver_dict = ast.literal_eval(iface_driver)
        if iface_driver_host:
            driver_host = ast.literal_eval(iface_driver_host)
        if iface_driver_guest:
            driver_guest = ast.literal_eval(iface_driver_guest)
        iface.driver = iface.new_driver(driver_attr=driver_dict,
                                        driver_host=driver_host,
                                        driver_guest=driver_guest)
        if iface.address:
            del iface.address

        logging.debug("New interface xml file: %s", iface)
        if unprivileged_user:
            # Create disk image for unprivileged user
            disk_index = xml_devices.index(
                xml_devices.by_device_tag("disk")[0])
            disk_xml = xml_devices[disk_index]
            logging.debug("source: %s", disk_xml.source)
            disk_source = disk_xml.source.attrs["file"]
            cmd = ("cp -fZ {0} {1} && chown {2}:{2} {1}"
                   "".format(disk_source, dst_disk, unprivileged_user))
            utils.run(cmd)
            disk_xml.source = disk_xml.new_disk_source(
                attrs={"file": dst_disk})
            vmxml.devices = xml_devices
            # Remove all channels to avoid of permission problem
            channels = vmxml.get_devices(device_type="channel")
            for channel in channels:
                vmxml.del_device(channel)

            vmxml.xmltreefile.write()
            logging.debug("New VM xml: %s", vmxml)
            utils.run("chmod a+rw %s" % vmxml.xml)
            virsh.define(vmxml.xml, **virsh_dargs)
        # Try to modify interface xml by update-device or edit xml
        elif update:
            iface.xmltreefile.write()
            ret = virsh.update_device(vm_name, iface.xml,
                                      ignore_status=True)
            libvirt.check_exit_status(ret, status_error)
        else:
            vmxml.devices = xml_devices
            vmxml.xmltreefile.write()
            vmxml.sync()

    def check_offloads_option(if_name, driver_options, session=None):
        """
        Check interface offloads by ethtool output
        """
        offloads = {"csum": "tx-checksumming",
                    "gso": "generic-segmentation-offload",
                    "tso4": "tcp-segmentation-offload",
                    "tso6": "tx-tcp6-segmentation",
                    "ecn": "tx-tcp-ecn-segmentation",
                    "ufo": "udp-fragmentation-offload"}
        if session:
            ret, output = session.cmd_status_output("ethtool -k %s | head"
                                                    " -18" % if_name)
        else:
            out = utils.run("ethtool -k %s | head -18" % if_name)
            ret, output = out.exit_status, out.stdout
        if ret:
            raise error.TestFail("ethtool return error code")
        logging.debug("ethtool output: %s", output)
        for offload in driver_options.keys():
            if offloads.has_key(offload):
                if (output.count(offloads[offload]) and
                    not output.count("%s: %s" % (
                        offloads[offload], driver_options[offload]))):
                    raise error.TestFail("offloads option %s: %s isn't"
                                         " correct in ethtool output" %
                                         (offloads[offload],
                                          driver_options[offload]))

    def run_xml_test(iface_mac):
        """
        Test for interface options in vm xml
        """
        # Get the interface object according the mac address
        vmxml = vm_xml.VMXML.new_from_dumpxml(vm_name)
        iface_devices = vmxml.get_devices(device_type="interface")
        iface = None
        for iface_dev in iface_devices:
            if iface_dev.mac_address == iface_mac:
                iface = iface_dev
        if not iface:
            raise error.TestFail("Can't find interface with mac"
                                 " '%s' in vm xml" % iface_mac)
        driver_dict = {}
        if iface_driver:
            driver_dict = ast.literal_eval(iface_driver)
        for driver_opt in driver_dict.keys():
            if not driver_dict[driver_opt] == iface.driver.driver_attr[driver_opt]:
                raise error.TestFail("Can't see driver option %s=%s in vm xml"
                                     % (driver_opt, driver_dict[driver_opt]))
        if iface_target:
            if (not iface.target.has_key("dev") or
                    not iface.target["dev"].startswith(iface_target)):
                raise error.TestFail("Can't see device target dev in vm xml")
            # Check macvtap mode by ip link command
            if iface_target == "macvtap" and iface.source.has_key("mode"):
                cmd = "ip -d link show %s" % iface.target["dev"]
                output = utils.run(cmd).stdout
                logging.debug("ip link output: %s", output)
                mode = iface.source["mode"]
                if mode == "passthrough":
                    mode = "passthru"
                if not output.count("macvtap  mode %s" % mode):
                    raise error.TestFail("Failed to verify macvtap mode")

    def run_cmdline_test(iface_mac):
        """
        Test for qemu-kvm command line options
        """
        cmd = ("ps -ef | grep %s | grep -v grep " % vm_name)
        if test_vhost_net:
            cmd += " | grep 'vhost=on'"
        ret = utils.run(cmd)
        if ret.exit_status:
            raise error.TestFail("Can't parse qemu-kvm command line")

        logging.debug("Command line %s", ret.stdout)
        if iface_model == "virtio":
            model_option = "device virtio-net-pci"
        else:
            model_option = "device rtl8139"
        iface_cmdline = re.findall(r"%s,(.+),mac=%s" %
                                   (model_option, iface_mac), ret.stdout)
        if not iface_cmdline:
            raise error.TestFail("Can't see %s with mac %s in command"
                                 " line" % (model_option, iface_mac))

        cmd_opt = {}
        for opt in iface_cmdline[0].split(','):
            tmp = opt.rsplit("=")
            cmd_opt[tmp[0]] = tmp[1]
        logging.debug("Command line options %s", cmd_opt)

        driver_dict = {}
        # Test <driver> xml options.
        if iface_driver:
            iface_driver_dict = ast.literal_eval(iface_driver)
            for driver_opt in iface_driver_dict.keys():
                if driver_opt == "name":
                    continue
                elif driver_opt == "txmode":
                    if iface_driver_dict["txmode"] == "iothread":
                        driver_dict["tx"] = "bh"
                    else:
                        driver_dict["tx"] = iface_driver_dict["txmode"]
                elif driver_opt == "queues":
                    driver_dict["mq"] = "on"
                    driver_dict["vectors"] = str(int(
                        iface_driver_dict["queues"]) * 2 + 2)
                else:
                    driver_dict[driver_opt] = iface_driver_dict[driver_opt]
        # Test <driver><host/><driver> xml options.
        if iface_driver_host:
            driver_dict.update(ast.literal_eval(iface_driver_host))
        # Test <driver><guest/><driver> xml options.
        if iface_driver_guest:
            driver_dict.update(ast.literal_eval(iface_driver_guest))

        for driver_opt in driver_dict.keys():
            if (not cmd_opt.has_key(driver_opt) or
                    not cmd_opt[driver_opt] == driver_dict[driver_opt]):
                raise error.TestFail("Can't see option '%s=%s' in qemu-kvm "
                                     " command line" %
                                     (driver_opt, driver_dict[driver_opt]))
        if test_backend:
            guest_pid = ret.stdout.rsplit()[1]
            cmd = "lsof %s | grep %s" % (backend["tap"], guest_pid)
            if utils.system(cmd, ignore_status=True):
                raise error.TestFail("Guest process didn't open backend file"
                                     % backend["tap"])
            cmd = "lsof %s | grep %s" % (backend["vhost"], guest_pid)
            if utils.system(cmd, ignore_status=True):
                raise error.TestFail("Guest process didn't open backend file"
                                     % backend["tap"])

    def get_guest_ip(session, mac):
        """
        Wrapper function to get guest ip address
        """
        utils_net.restart_guest_network(session, mac)
        # Wait for IP address is ready
        utils_misc.wait_for(
            lambda: utils_net.get_guest_ip_addr(session, mac), 10)
        return utils_net.get_guest_ip_addr(session, mac)

    def check_user_network(session):
        """
        Check user network ip address on guest
        """
        vm_ips = []
        vm_ips.append(get_guest_ip(session, iface_mac_old))
        if attach_device:
            vm_ips.append(get_guest_ip(session, iface_mac))
        logging.debug("IP address on guest: %s", vm_ips)
        if len(vm_ips) != len(set(vm_ips)):
            raise error.TestFail("Duplicated IP address on guest. "
                                 "Check bug: https://bugzilla.redhat."
                                 "com/show_bug.cgi?id=1147238")

        for vm_ip in vm_ips:
            if vm_ip is None or not vm_ip.startswith("10.0.2."):
                raise error.TestFail("Found wrong IP address"
                                     " on guest")
        # Check gateway address
        gateway = utils_net.get_net_gateway(session.cmd_output)
        if gateway != "10.0.2.2":
            raise error.TestFail("The gateway on guest is not"
                                 " right")
        # Check dns server address
        ns_list = utils_net.get_net_nameserver(session.cmd_output)
        if "10.0.2.3" not in ns_list:
            raise error.TestFail("The dns server can't be found"
                                 " on guest")

    def check_mcast_network(session):
        """
        Check multicast ip address on guests
        """
        src_addr = ast.literal_eval(iface_source)['address']
        add_session = additional_vm.wait_for_serial_login()
        vms_sess_dict = {vm_name: session,
                         additional_vm.name: add_session}

        # Check mcast address on host
        cmd = "netstat -g | grep %s" % src_addr
        if utils.run(cmd, ignore_status=True).exit_status:
            raise error.TestFail("Can't find multicast ip address"
                                 " on host")
        vms_ip_dict = {}
        # Get ip address on each guest
        for vms in vms_sess_dict.keys():
            vm_mac = vm_xml.VMXML.get_first_mac_by_name(vms)
            vm_ip = get_guest_ip(vms_sess_dict[vms], vm_mac)
            if not vm_ip:
                raise error.TestFail("Can't get multicast ip"
                                     " address on guest")
            vms_ip_dict.update({vms: vm_ip})
        if len(set(vms_ip_dict.values())) != len(vms_sess_dict):
            raise error.TestFail("Got duplicated multicast ip address")
        logging.debug("Found ips on guest: %s", vms_ip_dict)

        # Run omping server on host
        if not utils_misc.yum_install(["omping"]):
            raise error.TestError("Failed to install omping"
                                  " on host")
        cmd = ("iptables -F;omping -m %s %s" %
               (src_addr, "192.168.122.1 %s" %
                ' '.join(vms_ip_dict.values())))
        # Run a backgroup job waiting for connection of client
        bgjob = utils.AsyncJob(cmd)

        # Run omping client on guests
        for vms in vms_sess_dict.keys():
            # omping should be installed first
            if not utils_misc.yum_install(["omping"], vms_sess_dict[vms]):
                raise error.TestError("Failed to install omping"
                                      " on guest")
            cmd = ("iptables -F; omping -c 5 -T 5 -m %s %s" %
                   (src_addr, "192.168.122.1 %s" %
                    vms_ip_dict[vms]))
            ret, output = vms_sess_dict[vms].cmd_status_output(cmd)
            logging.debug("omping ret: %s, output: %s", ret, output)
            if (not output.count('multicast, xmt/rcv/%loss = 5/5/0%') or
                    not output.count('unicast, xmt/rcv/%loss = 5/5/0%')):
                raise error.TestFail("omping failed on guest")
        # Kill the backgroup job
        bgjob.kill_func()

    status_error = "yes" == params.get("status_error", "no")
    start_error = "yes" == params.get("start_error", "no")
    unprivileged_user = params.get("unprivileged_user")

    # Interface specific attributes.
    iface_type = params.get("iface_type", "network")
    iface_source = params.get("iface_source", "{}")
    iface_driver = params.get("iface_driver")
    iface_model = params.get("iface_model")
    iface_target = params.get("iface_target")
    iface_backend = params.get("iface_backend", "{}")
    iface_driver_host = params.get("iface_driver_host")
    iface_driver_guest = params.get("iface_driver_guest")
    attach_device = params.get("attach_iface_device")
    change_option = "yes" == params.get("change_iface_options", "no")
    update_device = "yes" == params.get("update_iface_device", "no")
    additional_guest = "yes" == params.get("additional_guest", "no")
    serial_login = "******" == params.get("serial_login", "no")
    test_option_cmd = "yes" == params.get(
                      "test_iface_option_cmd", "no")
    test_option_xml = "yes" == params.get(
                      "test_iface_option_xml", "no")
    test_vhost_net = "yes" == params.get(
                     "test_vhost_net", "no")
    test_option_offloads = "yes" == params.get(
                           "test_option_offloads", "no")
    test_iface_user = "******" == params.get(
                      "test_iface_user", "no")
    test_iface_mcast = "yes" == params.get(
                       "test_iface_mcast", "no")
    test_libvirtd = "yes" == params.get("test_libvirtd", "no")
    test_guest_ip = "yes" == params.get("test_guest_ip", "no")
    test_backend = "yes" == params.get("test_backend", "no")

    if iface_driver_host or iface_driver_guest or test_backend:
        if not libvirt_version.version_compare(1, 2, 8):
            raise error.TestNAError("Offloading/backend options not "
                                    "supported in this libvirt version")
    if iface_driver and "queues" in ast.literal_eval(iface_driver):
        if not libvirt_version.version_compare(1, 0, 6):
            raise error.TestNAError("Queues options not supported"
                                    " in this libvirt version")

    if unprivileged_user:
        virsh_dargs["unprivileged_user"] = unprivileged_user
        # Create unprivileged user if needed
        cmd = ("grep {0} /etc/passwd || "
               "useradd {0}".format(unprivileged_user))
        utils.run(cmd)
        # Need another disk image for unprivileged user to access
        dst_disk = "/tmp/%s.img" % unprivileged_user

    # Destroy VM first
    if vm.is_alive():
        vm.destroy(gracefully=False)

    # Back up xml file.
    vmxml_backup = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
    iface_mac_old = vm_xml.VMXML.get_first_mac_by_name(vm_name)
    # iface_mac will update if attach a new interface
    iface_mac = iface_mac_old
    # Additional vm for test
    additional_vm = None
    libvirtd = utils_libvirtd.Libvirtd()

    try:
        # Build the xml and run test.
        try:
            # Prepare interface backend files
            if test_backend:
                if not os.path.exists("/dev/vhost-net"):
                    utils.run("modprobe vhost-net")
                backend = ast.literal_eval(iface_backend)
                backend_tap = "/dev/net/tun"
                backend_vhost = "/dev/vhost-net"
                if not backend:
                    backend["tap"] = backend_tap
                    backend["vhost"] = backend_vhost
                if not start_error:
                    # Create backend files for normal test
                    if not os.path.exists(backend["tap"]):
                        os.rename(backend_tap, backend["tap"])
                    if not os.path.exists(backend["vhost"]):
                        os.rename(backend_vhost, backend["vhost"])
            # Edit the interface xml.
            if change_option:
                modify_iface_xml(update=False)
            # Check vhost driver.
            if test_vhost_net:
                if os.path.exists("/dev/vhost-net"):
                    cmd = ("modprobe -r {0}; lsmod | "
                           "grep {0}".format("vhost_net"))
                    if not utils.system(cmd, ignore_status=True):
                        raise error.TestError("Can't remove "
                                              "vhost_net driver")

            # Attach a interface when vm is shutoff
            if attach_device == 'config':
                iface_mac = utils_net.generate_mac_address_simple()
                iface_xml_obj = create_iface_xml(iface_mac)
                iface_xml_obj.xmltreefile.write()
                ret = virsh.attach_device(vm_name, iface_xml_obj.xml,
                                          flagstr="--config",
                                          ignore_status=True)
                libvirt.check_exit_status(ret)

            # Clone additional vm
            if additional_guest:
                guest_name = "%s_%s" % (vm_name, '1')
                # Clone additional guest
                timeout = params.get("clone_timeout", 360)
                utils_libguestfs.virt_clone_cmd(vm_name, guest_name,
                                                True, timeout=timeout)
                additional_vm = vm.clone(guest_name)
                additional_vm.start()
                #additional_vm.wait_for_login()

            # Start the VM.
            if unprivileged_user:
                virsh.start(vm_name, **virsh_dargs)
                cmd = ("su - %s -c 'virsh console %s'"
                       % (unprivileged_user, vm_name))
                session = aexpect.ShellSession(cmd)
                session.sendline()
                remote.handle_prompts(session, params.get("username"),
                                      params.get("password"), "[\#\$]", 30)
                # Get ip address on guest
                if not get_guest_ip(session, iface_mac):
                    raise error.TestError("Can't get ip address on guest")
            else:
                # Will raise VMStartError exception if start fails
                vm.start()
                if serial_login:
                    session = vm.wait_for_serial_login()
                else:
                    session = vm.wait_for_login()
            if start_error:
                raise error.TestFail("VM started unexpectedly")

            if test_vhost_net:
                if utils.system("lsmod | grep vhost_net", ignore_status=True):
                    raise error.TestFail("vhost_net module can't be"
                                         " loaded automatically")

            # Attach a interface when vm is running
            if attach_device == 'live':
                iface_mac = utils_net.generate_mac_address_simple()
                iface_xml_obj = create_iface_xml(iface_mac)
                iface_xml_obj.xmltreefile.write()
                ret = virsh.attach_device(vm_name, iface_xml_obj.xml,
                                          flagstr="--live",
                                          ignore_status=True)
                libvirt.check_exit_status(ret)
                # Need sleep here for attachment take effect
                time.sleep(5)

            # Update a interface options
            if update_device:
                modify_iface_xml(update=True, status_error=status_error)

            # Run tests for qemu-kvm command line options
            if test_option_cmd:
                run_cmdline_test(iface_mac)
            # Run tests for vm xml
            if test_option_xml:
                run_xml_test(iface_mac)
            # Run tests for offloads options
            if test_option_offloads:
                if iface_driver_host:
                    ifname_guest = utils_net.get_linux_ifname(
                        session, iface_mac)
                    check_offloads_option(
                        ifname_guest, ast.literal_eval(
                            iface_driver_host), session)
                if iface_driver_guest:
                    ifname_host = libvirt.get_ifname_host(vm_name,
                                                          iface_mac)
                    check_offloads_option(
                        ifname_host, ast.literal_eval(iface_driver_guest))

            if test_iface_user:
                # Test user type network
                check_user_network(session)
            if test_iface_mcast:
                # Test mcast type network
                check_mcast_network(session)
            # Check guest ip address
            if test_guest_ip:
                if not get_guest_ip(session, iface_mac):
                    raise error.TestFail("Guest can't get a"
                                         " valid ip address")

            session.close()
            # Restart libvirtd and guest, then test again
            if test_libvirtd:
                libvirtd.restart()
                vm.destroy()
                vm.start()
                if test_option_xml:
                    run_xml_test(iface_mac)

            # Detach hot/cold-plugged interface at last
            if attach_device:
                ret = virsh.detach_device(vm_name, iface_xml_obj.xml,
                                          flagstr="", ignore_status=True)
                libvirt.check_exit_status(ret)

        except virt_vm.VMStartError, e:
            logging.info(str(e))
            if start_error:
                pass
            else:
                raise error.TestFail('VM Failed to start for some reason!')

    finally:
        # Recover VM.
        logging.info("Restoring vm...")
        # Restore interface backend files
        if test_backend:
            if not os.path.exists(backend_tap):
                os.rename(backend["tap"], backend_tap)
            if not os.path.exists(backend_vhost):
                os.rename(backend["vhost"], backend_vhost)
        if unprivileged_user:
            virsh.remove_domain(vm_name, "--remove-all-storage",
                                **virsh_dargs)
        if additional_vm:
            virsh.remove_domain(additional_vm.name,
                                "--remove-all-storage")
            # Kill all omping server process on host
            utils.system("pidof omping && killall omping",
                         ignore_status=True)
        if vm.is_alive():
            vm.destroy(gracefully=False)
        vmxml_backup.sync()
Example #57
0
def run(test, params, env):
    """
    Verify guest NIC numbers again whats provided in test config file.

    If the guest NICs info does not match whats in the params at first,
    try to fix these by operating the networking config file.
    1. Boot guest with multi NICs.
    2. Check whether guest NICs info match with params setting.
    3. Create configure file for every NIC interface in guest.
    4. Reboot guest.
    5. Check whether guest NICs info match with params setting.

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def check_nics_num(expect_c, session):
        txt = "Check whether guest NICs info match with params setting."
        error.context(txt, logging.info)
        nics_list = utils_net.get_linux_ifname(session)
        actual_c = len(nics_list)
        msg = "Expected NICs count is: %d\n" % expect_c
        msg += "Actual NICs count is: %d\n" % actual_c

        if not expect_c == actual_c:
            msg += "Nics count mismatch!\n"
            return (False, msg)
        return (True, msg + 'Nics count match')

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360)))
    # Redirect ifconfig output from guest to log file
    log_file = os.path.join(test.debugdir, "ifconfig")
    ifconfig_output = session.cmd("ifconfig")
    log_file_object = open(log_file, "w")
    log_file_object.write(ifconfig_output)

    # Get the ethernet cards number from params
    nics_num = len(params.objects("nics"))
    logging.info("[ %s ] NICs card specified in config file" % nics_num)

    # Pre-judgement for the ethernet interface
    logging.debug(check_nics_num(nics_num, session)[1])
    txt = "Create configure file for every NIC interface in guest."
    error.context(txt, logging.info)
    ifname_list = utils_net.get_linux_ifname(session)
    ifcfg_path = "/etc/sysconfig/network-scripts/ifcfg-%s"
    for ifname in ifname_list:
        eth_config_path = ifcfg_path % ifname

        eth_config = """DEVICE=%s
BOOTPROTO=dhcp
ONBOOT=yes
""" % ifname

        cmd = "echo '%s' > %s" % (eth_config, eth_config_path)
        s, o = session.get_command_status_output(cmd)
        if s != 0:
            err_msg = "Failed to create ether config file: %s\nReason is: %s"
            raise error.TestError(err_msg % (eth_config_path, o))

    # Reboot and check the configurations.
    new_session = vm.reboot(session)
    s, msg = check_nics_num(nics_num, new_session)
    if not s:
        raise error.TestFail(msg)

    # NICs matched.
    logging.info(msg)