예제 #1
0
def run(test, params, env):
    """
    Check guest time monotonicity during migration:

    1) Log into a guest.
    2) Take time from guest.
    3) Migrate the guest.
    4) Keep guest running for a period after migration,
       and record the time log.
    5) Analyse log if it is exist.

    :param test: QEMU test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
    """
    def get_time(cmd, test_time, session):
        if os.path.isfile(host_path):
            os.remove(host_path)
        lasttv = "0"
        cmd_timeout = int(params.get("cmd_timeout"))
        start_time = time.time()
        while (time.time() - start_time) < test_time:
            tv = session.cmd_output(cmd, timeout=cmd_timeout)
            if params.get("os_type") == 'windows':
                list = re.split('[:]', tv)
                tv = str(int(list[0]) * 3600 + int(
                    list[1]) * 60 + float(list[2]))
            if float(tv) < float(lasttv):
                p_tv = "time value = " + tv + "\n"
                p_lasttv = "last time value = " + lasttv + "\n"
                with open(host_path, 'a') as time_log:
                    time_log.write("time went backwards:\n" + p_tv + p_lasttv)
            lasttv = tv
            time.sleep(0.1)

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()

    boot_option_added = params.get("boot_option_added")
    boot_option_removed = params.get("boot_option_removed")
    if boot_option_added or boot_option_removed:
        utils_test.update_boot_option(vm,
                                      args_removed=boot_option_removed,
                                      args_added=boot_option_added)

    timeout = int(params.get("login_timeout", 360))
    session1 = vm.wait_for_login(timeout=timeout)

    host_path = params.get("host_path")
    cmd = params.get("cmd_get_time")
    test_time = int(params.get("time_linger", "60"))

    try:
        # take time
        logging.info("Start take guest time")
        bg = utils_misc.InterruptedThread(get_time, (cmd, test_time, session1))
        bg.start()

        # migration
        logging.info("Start migration")
        vm.migrate()

        # log in
        logging.info("Logging in after migration...")
        session2 = vm.wait_for_login(timeout=timeout)
        if not session2:
            test.fail("Could not log in after migration")
        logging.info("Logged in after migration")

        # linger a while
        time.sleep(test_time)

        # analyse the result
        if os.path.isfile(host_path):
            log_dir = os.path.join(test.outputdir,
                                   "timedrift-monotonicity-result.txt")
            shutil.copyfile(host_path, log_dir)
            with open(host_path, 'r') as myfile:
                for line in myfile:
                    if "time went backwards" in line:
                        test.fail("Failed Time Monotonicity testing, "
                                  "Please check log %s" % host_path)
    finally:
        session1.close()
        # remove flags add for this test.
        if boot_option_added or boot_option_removed:
            utils_test.update_boot_option(vm,
                                          args_removed=boot_option_added,
                                          args_added=boot_option_removed)
예제 #2
0
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) Reboot the VM
    4) Send a migration command to the source VM and wait until it's finished.
    5) Kill off the source VM.
    6) Log into the destination VM after the migration is finished.

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

    mig_timeout = float(params.get("mig_timeout", "3600"))
    mig_protocol = params.get("migration_protocol", "tcp")
    mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2
    migration_exec_cmd_src = params.get("migration_exec_cmd_src")
    migration_exec_cmd_dst = params.get("migration_exec_cmd_dst")
    pre_migrate = migration.get_functions(params.get("pre_migrate"),
                                          migration.__dict__)
    post_migrate = migration.get_functions(params.get("post_migrate"),
                                           migration.__dict__)
    if migration_exec_cmd_src and "%s" in migration_exec_cmd_src:
        mig_file = os.path.join(
            tempfile.mkdtemp(prefix="migrate", dir=test.workdir),
            "migrate_file")
        migration_exec_cmd_src %= mig_file
        migration_exec_cmd_dst %= mig_file

    try:
        # Reboot the VM in the background
        bg = utils_misc.InterruptedThread(vm.reboot,
                                          kwargs={
                                              'session': session,
                                              'timeout': login_timeout
                                          })
        bg.start()
        try:
            while bg.isAlive():
                for func in pre_migrate:
                    func(vm, params, test)
                vm.migrate(mig_timeout,
                           mig_protocol,
                           mig_cancel_delay,
                           env=env,
                           migration_exec_cmd_src=migration_exec_cmd_src,
                           migration_exec_cmd_dst=migration_exec_cmd_dst)
                # run some functions after migrate finish.
                for func in post_migrate:
                    func(vm, params, test)
        except Exception:
            # If something bad happened in the main thread, ignore exceptions
            # raised in the background thread
            bg.join(suppress_exception=True)
            raise
        else:
            session = bg.join()
    finally:
        session.close()
예제 #3
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)]

    ssh_login_cmd = (
        "echo LoginGraceTime 5m  >> /etc/ssh/sshd_config &&"
        " systemctl restart sshd.service || service sshd restart")
    session_serial.cmd_output_safe(ssh_login_cmd)

    # 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 is already 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_misc.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:
                        test.error("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()

        logging.info("Failover test 2 with file transfer")
        transfer_thread = utils_misc.InterruptedThread(
            utils_test.run_file_transfer, (test, params, env))
        transfer_thread.start()
        try:
            nic_num = len(vm.virtnet)
            up_index = 0
            while transfer_thread.isAlive():
                up_index = up_index % nic_num
                for num in range(nic_num):
                    device_id = vm.virtnet[num].device_id
                    if not device_id:
                        test.error("Could not find peer device for"
                                   " nic device %s" % nic)
                    if num == up_index:
                        vm.set_link(device_id, up=True)
                    else:
                        vm.set_link(device_id, up=False)
                time.sleep(random.randint(1, 5))
                up_index += 1
        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`")
        session_serial.sendline("sed -i '$ d' /etc/ssh/sshd_config")
예제 #4
0
 def run_bg_test(target, args=(), kwargs={}):
     """ Run the test background. """
     error_context.context(target.__doc__, logging.info)
     thread = utils_misc.InterruptedThread(target, args, kwargs)
     thread.start()
     return thread
예제 #5
0
def run(test, params, env):
    """
    iperf testing with multicast/multiqueue.

    1) Boot up VM
    2) Prepare the iperf environment
    3) Select guest or host to start iperf server/client
    4) Execute iperf tests, analyze the result
    5) Finish test and cleanup host environment

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

    def iperf_compile(src_path, dst_path, session=None):
        """Compile iperf and return its binary file path."""
        iperf_version = params["iperf_version"]
        iperf_source_path = os.path.join(dst_path, iperf_version)
        compile_cmd = params["linux_compile_cmd"] % (src_path, dst_path,
                                                     iperf_source_path)
        try:
            if session:
                logging.info("Compiling %s in guest..." % iperf_version)
                session.cmd(compile_cmd)
            else:
                logging.info("Compiling %s in host..." % iperf_version)
                process.run(compile_cmd, shell=True, verbose=False)
        except (process.CmdError, ShellCmdError) as err_msg:
            logging.error(err_msg)
            test.error("Failed to compile iperf")
        else:
            iperf_bin_name = re.sub(r'[-2]', '', iperf_version.split('.')[0])
            return os.path.join(iperf_source_path, 'src', iperf_bin_name)

    def iperf_start(session, iperf_path, options, catch_data):
        """Start iperf session, analyze result if catch_data."""
        iperf_cmd = iperf_path + options
        try:
            info_text = "Start iperf session in %s with cmd: %s"
            if session:
                logging.info(info_text % ("guest", iperf_cmd))
                data_info = session.cmd_output(iperf_cmd, timeout=120)
            else:
                logging.info(info_text % ("host", iperf_cmd))
                data_info = process.system_output(iperf_cmd, timeout=120,
                                                  verbose=False).decode()
        except Exception as err_msg:
            logging.error(str(err_msg))
            test.error("Failed to start iperf session")
        else:
            if catch_data:
                logging.debug("Full connection log:\n%s" % data_info)
                parallel_cur = len(re.findall(catch_data, data_info))
                parallel_exp = int(params.get("parallel_num", 0))
                if not parallel_cur:
                    test.fail("iperf client not connected to server")
                elif parallel_exp and parallel_cur != parallel_exp:
                    test.fail("Number of parallel threads running(%d) is "
                              "inconsistent with expectations(%d)"
                              % (parallel_cur, parallel_exp))
                logging.info("iperf client successfully connected to server")

    def is_iperf_running(name_pattern, session=None):
        if session:
            check_iperf_cmd = params["check_iperf_cmd"] % name_pattern
            status = serial_session.cmd_status(check_iperf_cmd)
        else:
            status = process.system("pgrep -f %s" % name_pattern,
                                    ignore_status=True, verbose=False)
        return status == 0

    os_type = params["os_type"]
    login_timeout = int(params.get("login_timeout", 360))
    fw_stop_cmd = params["fw_stop_cmd"]
    tmp_dir = params.get("tmp_dir", "/tmp/")
    iperf_test_duration = int(params["iperf_test_duration"])
    iperf_deps_dir = data_dir.get_deps_dir("iperf")
    host_iperf_file = params["host_iperf_file"]
    guest_iperf_file = params.get('guest_iperf_file', host_iperf_file)
    host_iperf_src_path = os.path.join(iperf_deps_dir, host_iperf_file)
    guest_iperf_remote_path = os.path.join(iperf_deps_dir, guest_iperf_file)
    guest_iperf_path = params.get('guest_iperf_path', tmp_dir)
    guest_iperf_src_path = os.path.join(guest_iperf_path, guest_iperf_file)

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    serial_session = vm.wait_for_serial_login(timeout=login_timeout)
    guest_session = vm.wait_for_login(timeout=login_timeout)
    guest_session.cmd(fw_stop_cmd, ignore_all_errors=True)

    vm.copy_files_to(guest_iperf_remote_path, guest_iperf_path)
    host_ip_addr = utils_net.get_host_ip_address(params)
    guest_ip_addr = vm.get_address()
    host_iperf_bin = iperf_compile(host_iperf_src_path, tmp_dir)

    if os_type == 'linux':
        if not utils_package.package_install("gcc-c++", guest_session):
            test.cancel("Please install gcc-c++ to proceed")
        guest_iperf__bin = iperf_compile(guest_iperf_src_path, tmp_dir, guest_session)
    else:
        guest_iperf__bin = guest_iperf_src_path
        iperf_deplist = params.get("iperf_deplist")
        if iperf_deplist:
            for d_name in iperf_deplist.split(','):
                dep_path = os.path.join(data_dir.get_deps_dir("iperf"), d_name)
                vm.copy_files_to(dep_path, guest_iperf_path)

    search_pattern = {'host': host_iperf_bin.replace('src/', 'src/.*'),
                      'linux': guest_iperf__bin.replace('src/', 'src/.*'),
                      'windows': guest_iperf_file}

    if params.get("iperf_server") == params["main_vm"]:
        s_ip = params.get("multicast_addr", guest_ip_addr)
        s_info = [search_pattern[os_type], s_ip, guest_session, guest_iperf__bin]
        c_info = [search_pattern["host"], host_ip_addr, None, host_iperf_bin]
    else:
        s_ip = params.get("multicast_addr", host_ip_addr)
        s_info = [search_pattern["host"], s_ip, None, host_iperf_bin]
        c_info = [search_pattern[os_type], guest_ip_addr, guest_session, guest_iperf__bin]

    s_catch_data = params["catch_data"] % (s_info[1], c_info[1])
    s_options = params["iperf_server_options"]
    c_options = params["iperf_client_options"] % (s_info[1], c_info[1],
                                                  iperf_test_duration)
    s_info.extend([s_options, s_catch_data])
    c_info.extend([c_options, None])

    try:
        s_start_args = tuple(s_info[-4:])
        c_start_args = tuple(c_info[-4:])
        bg_server = utils_misc.InterruptedThread(iperf_start, s_start_args)
        bg_client = utils_misc.InterruptedThread(iperf_start, c_start_args)

        bg_server.start()
        if not utils_misc.wait_for(lambda: is_iperf_running(s_info[0],
                                                            s_info[2]), 5, 2):
            test.error("Failed to start iperf server.")
        error_context.context("iperf server has started.", logging.info)
        bg_client.start()
        if not utils_misc.wait_for(lambda: is_iperf_running(c_info[0],
                                                            c_info[2]), 5):
            test.error("Failed to start iperf client.")
        error_context.context("iperf client has started.", logging.info)
        utils_misc.wait_for(lambda: not is_iperf_running(c_info[0], c_info[2]),
                            iperf_test_duration, 0, 5,
                            "Waiting for iperf test to finish.")
        bg_server.join(timeout=60)
        bg_client.join(timeout=60)
    finally:
        logging.info("Cleanup host environment...")
        if is_iperf_running(search_pattern["host"]):
            process.run('pkill -9 -f %s' % search_pattern["host"],
                        verbose=False, ignore_status=True)
        shutil.rmtree(host_iperf_bin.rsplit('/', 2)[0], ignore_errors=True)
        guest_session.close()
        serial_session.close()
예제 #6
0
def run(test, params, env):
    """
    Run NTttcp on Windows guest

    1) Install NTttcp in server/client side by Autoit
    2) Start NTttcp in server/client side
    3) Get test results

    :param test: kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    login_timeout = int(params.get("login_timeout", 360))
    results_path = os.path.join(test.resultsdir,
                                'raw_output_%s' % test.iteration)
    platform = "x86"
    if "64" in params["vm_arch_name"]:
        platform = "x64"
    buffers = params.get("buffers").split()
    buf_num = params.get("buf_num", 200000)
    session_num = params.get("session_num")
    timeout = int(params.get("timeout")) * int(session_num)
    driver_name = params.get("driver_name", "netkvm")

    vm_sender = env.get_vm(params["main_vm"])
    vm_sender.verify_alive()
    # verify driver
    _verify_vm_driver(vm_sender, test, driver_name)

    logging.debug(
        process.system("numactl --hardware", ignore_status=True, shell=True))
    logging.debug(
        process.system("numactl --show", ignore_status=True, shell=True))
    # pin guest vcpus/memory/vhost threads to last numa node of host by default
    if params.get('numa_node'):
        numa_node = int(params.get('numa_node'))
        node = utils_misc.NumaNode(numa_node)
        utils_test.qemu.pin_vm_threads(vm_sender, node)

    vm_receiver = env.get_vm("vm2")
    vm_receiver.verify_alive()
    _verify_vm_driver(vm_receiver, test, driver_name)
    try:
        sess = None
        sess = vm_receiver.wait_for_login(timeout=login_timeout)
        receiver_addr = vm_receiver.get_address()
        if not receiver_addr:
            test.error("Can't get receiver(%s) ip address" % vm_receiver.name)
        if params.get('numa_node'):
            utils_test.qemu.pin_vm_threads(vm_receiver, node)
    finally:
        if sess:
            sess.close()

    @error_context.context_aware
    def install_ntttcp(session):
        """ Install ntttcp through a remote session """
        logging.info("Installing NTttcp ...")
        try:
            # Don't install ntttcp if it's already installed
            error_context.context("NTttcp directory already exists")
            session.cmd(params.get("check_ntttcp_cmd"))
        except aexpect.ShellCmdError:
            ntttcp_install_cmd = params.get("ntttcp_install_cmd")
            ntttcp_install_cmd = utils_misc.set_winutils_letter(
                session, ntttcp_install_cmd)
            error_context.context("Installing NTttcp on guest")
            session.cmd(ntttcp_install_cmd % (platform, platform), timeout=200)

    def receiver():
        """ Receive side """
        logging.info("Starting receiver process on %s", receiver_addr)
        session = vm_receiver.wait_for_login(timeout=login_timeout)
        install_ntttcp(session)
        ntttcp_receiver_cmd = params.get("ntttcp_receiver_cmd")
        global _receiver_ready
        f = open(results_path + ".receiver", 'a')
        for b in buffers:
            utils_misc.wait_for(lambda: not _wait(), timeout)
            _receiver_ready = True
            rbuf = params.get("fixed_rbuf", b)
            cmd = ntttcp_receiver_cmd % (session_num, receiver_addr, rbuf,
                                         buf_num)
            r = session.cmd_output(cmd,
                                   timeout=timeout,
                                   print_func=logging.debug)
            f.write("Send buffer size: %s\n%s\n%s" % (b, cmd, r))
        f.close()
        session.close()

    def _wait():
        """ Check if receiver is ready """
        global _receiver_ready
        if _receiver_ready:
            return _receiver_ready
        return False

    def sender():
        """ Send side """
        logging.info("Sarting sender process ...")
        session = vm_sender.wait_for_login(timeout=login_timeout)
        install_ntttcp(session)
        ntttcp_sender_cmd = params.get("ntttcp_sender_cmd")
        f = open(results_path + ".sender", 'a')
        try:
            global _receiver_ready
            for b in buffers:
                cmd = ntttcp_sender_cmd % (session_num, receiver_addr, b,
                                           buf_num)
                # Wait until receiver ready
                utils_misc.wait_for(_wait, timeout)
                r = session.cmd_output(cmd,
                                       timeout=timeout,
                                       print_func=logging.debug)
                _receiver_ready = False
                f.write("Send buffer size: %s\n%s\n%s" % (b, cmd, r))
        finally:
            f.close()
            session.close()

    def parse_file(resultfile):
        """ Parse raw result files and generate files with standard format """
        fileobj = open(resultfile, "r")
        lst = []
        found = False
        for line in fileobj.readlines():
            o = re.findall(r"Send buffer size: (\d+)", line)
            if o:
                bfr = o[0]
            if "Total Throughput(Mbit/s)" in line:
                found = True
            if found:
                fields = line.split()
                if len(fields) == 0:
                    continue
                try:
                    [float(i) for i in fields]
                    lst.append([bfr, fields[-1]])
                except ValueError:
                    continue
                found = False
        return lst

    try:
        bg = utils_misc.InterruptedThread(receiver, ())
        bg.start()
        if bg.is_alive():
            sender()
            bg.join(suppress_exception=True)
        else:
            test.error("Can't start backgroud receiver thread")
    finally:
        for i in glob.glob("%s.receiver" % results_path):
            f = open("%s.RHS" % results_path, "w")
            raw = "  buf(k)| throughput(Mbit/s)"
            logging.info(raw)
            f.write("#ver# %s\n#ver# host kernel: %s\n" %
                    (process.system_output("rpm -q qemu-kvm",
                                           shell=True,
                                           verbose=False,
                                           ignore_status=True), os.uname()[2]))
            desc = """#desc# The tests are sessions of "NTttcp", send buf"
" number is %s. 'throughput' was taken from ntttcp's report.
#desc# How to read the results:
#desc# - The Throughput is measured in Mbit/sec.
#desc#
""" % (buf_num)
            f.write(desc)
            f.write(raw + "\n")
            for j in parse_file(i):
                raw = "%8s| %8s" % (j[0], j[1])
                logging.info(raw)
                f.write(raw + "\n")
            f.close()
예제 #7
0
def run(test, params, env):
    """
    Test failover by team driver

    1) Boot a vm with 4 nics.
    2) inside guest, configure the team driver.
    3) inside guest, ping host
    4) inside guest, repeated down the slaves one by one.
    5) check ping_result.

    :param test: Kvm test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def team_port_add(ifnames, team_if):
        """Team0 add ports and return the ip link result for debuging"""
        for port in ifnames:
            session_serial.cmd_output_safe(params["clearip_cmd"] % port)
            session_serial.cmd_output_safe(params["setdown_cmd"] % port)
            session_serial.cmd_output_safe(params["addport_cmd"] % port)
        output_teamnl = session_serial.cmd_output_safe(params["portchk_cmd"])
        ports = re.findall(r"%s" % params["ptn_teamnl"], output_teamnl)
        for port in ifnames:
            if port not in ports:
                test.fail("Add %s to %s failed." % (port, team_if))
        session_serial.cmd_output_safe(params["killdhclient_cmd"])
        output = session_serial.cmd_output_safe(params["getip_cmd"],
                                                timeout=300)
        team_ip = re.search(r"%s" % params["ptn_ipv4"], output).group()
        if not team_ip:
            test.fail("Failed to get ip address of %s" % team_if)
        return ports, team_ip

    def failover(ifnames, timeout):
        """func for failover"""
        time.sleep(3)
        starttime = time.time()
        while True:
            pid_ping = session_serial.cmd_output_safe("pidof ping")
            pid = re.findall(r"(\d+)", pid_ping)
            if not pid:
                break
                # if ping finished, will break the loop.
            for port in ifnames:
                session_serial.cmd_output_safe(params["setdown_cmd"] % port)
                time.sleep(random.randint(5, 30))
                session_serial.cmd_output_safe(params["setup_cmd"] % port)
            endtime = time.time()
            timegap = endtime - starttime
            if timegap > timeout:
                break

    def check_ping(status, output):
        """ ratio <5% is acceptance."""
        if status != 0:
            test.fail("Ping failed, staus:%s, output:%s" % (status, output))
        # if status != 0 the ping process seams hit issue.
        ratio = utils_test.get_loss_ratio(output)
        if ratio == -1:
            test.fail("The ratio is %s, and status is %s, "
                      "output is %s" % (ratio, status, output))
        elif ratio > int(params["failed_ratio"]):
            test.fail("The loss raito is %s, test failed" % ratio)
        logging.info("ping pass with loss raito:%s, that less than %s" %
                     (ratio, params["failed_ratio"]))

    def team_if_exist():
        """ judge if team is alive well."""
        team_exists_cmd = params.get("team_if_exists_cmd")
        return session_serial.cmd_status(team_exists_cmd) == 0

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 1200))
    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)
    ]
    session_serial.cmd_output_safe(params["nm_stop_cmd"])
    team_if = params.get("team_if")
    # initial

    error_context.context("Step1: Configure the team environment",
                          logging.info)
    # steps of building the teaming environment starts
    modprobe_cmd = "modprobe team"
    session_serial.cmd_output_safe(modprobe_cmd)
    session_serial.cmd_output_safe(params["createteam_cmd"])
    # this cmd is to create the team0 and correspoding userspace daemon
    if not team_if_exist():
        test.fail("Interface %s is not created." % team_if)
    # check if team0 is created successfully
    ports, team_ip = team_port_add(ifnames, team_if)
    logging.debug("The list of the ports that added to %s : %s" %
                  (team_if, ports))
    logging.debug("The ip address of %s : %s" % (team_if, team_ip))
    output = session_serial.cmd_output_safe(params["team_debug_cmd"])
    logging.debug("team interface configuration: %s" % output)
    route_cmd = session_serial.cmd_output_safe(params["route_cmd"])
    logging.debug("The route table of guest: %s" % route_cmd)
    # this is not this case checkpoint, just to check if route works fine
    # steps of building finished

    try:
        error_context.context("Login in guest via ssh", logging.info)
        # steps of testing this case starts
        session = vm.wait_for_login(timeout=timeout)
        dest = utils_net.get_ip_address_by_interface(params["netdst"])
        count = params.get("count")
        timeout = float(count) * 2
        error_context.context("Step2: Check if guest can ping out:",
                              logging.info)
        status, output = utils_test.ping(dest=dest,
                                         count=10,
                                         interface=team_if,
                                         timeout=30,
                                         session=session)
        check_ping(status, output)
        # small ping check if the team0 works w/o failover
        error_context.context(
            "Step3: Start failover testing until "
            "ping finished", logging.info)
        failover_thread = utils_misc.InterruptedThread(failover,
                                                       (ifnames, timeout))
        failover_thread.start()
        # start failover loop until ping finished
        error_context.context("Step4: Start ping host for %s counts" % count,
                              logging.info)
        if failover_thread.is_alive():
            status, output = utils_test.ping(dest=dest,
                                             count=count,
                                             interface=team_if,
                                             timeout=float(count) * 1.5,
                                             session=session)
            error_context.context("Step5: Check if ping succeeded",
                                  logging.info)
            check_ping(status, output)
        else:
            test.error("The failover thread is not alive")
        time.sleep(3)
        try:
            timeout = timeout * 1.5
            failover_thread.join(timeout)
        except Exception:
            test.error("Failed to join the failover thread")
        # finish the main steps and check the result
        session_serial.cmd_output_safe(params["killteam_cmd"])
        if team_if_exist():
            test.fail("Remove %s failed" % team_if)
        logging.info("%s removed" % team_if)
        # remove the team0 and the daemon, check if succeed
    finally:
        if session:
            session.close()
예제 #8
0
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) Transfer file from host to guest.
    4) Repeatedly migrate VM and wait until transfer's finished.
    5) Transfer file from guest back to host.
    6) Repeatedly migrate VM and wait until transfer's finished.

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

    mig_timeout = float(params.get("mig_timeout", "3600"))
    mig_protocol = params.get("migration_protocol", "tcp")
    mig_cancel_delay = int(params.get("mig_cancel") == "yes") * 2

    host_path = "/tmp/file-%s" % utils_misc.generate_random_string(6)
    host_path_returned = "%s-returned" % host_path
    guest_path = params.get("guest_path", "/tmp/file")
    file_size = params.get("file_size", "500")
    transfer_timeout = int(params.get("transfer_timeout", "240"))
    migrate_between_vhost_novhost = params.get("migrate_between_vhost_novhost")

    try:
        process.run("dd if=/dev/urandom of=%s bs=1M count=%s" %
                    (host_path, file_size))

        def run_and_migrate(bg):
            bg.start()
            try:
                while bg.is_alive():
                    logging.info(
                        "File transfer not ended, starting a round of "
                        "migration...")
                    if migrate_between_vhost_novhost == "yes":
                        vhost_status = vm.params.get("vhost")
                        if vhost_status == "vhost=on":
                            vm.params["vhost"] = "vhost=off"
                        elif vhost_status == "vhost=off":
                            vm.params["vhost"] = "vhost=on"
                    vm.migrate(mig_timeout,
                               mig_protocol,
                               mig_cancel_delay,
                               env=env)
            except Exception:
                # If something bad happened in the main thread, ignore
                # exceptions raised in the background thread
                bg.join(suppress_exception=True)
                raise
            else:
                bg.join()

        error_context.context("transferring file to guest while migrating",
                              logging.info)
        bg = utils_misc.InterruptedThread(
            vm.copy_files_to, (host_path, guest_path),
            dict(verbose=True, timeout=transfer_timeout))
        run_and_migrate(bg)

        error_context.context("transferring file back to host while migrating",
                              logging.info)
        bg = utils_misc.InterruptedThread(
            vm.copy_files_from, (guest_path, host_path_returned),
            dict(verbose=True, timeout=transfer_timeout))
        run_and_migrate(bg)

        # Make sure the returned file is identical to the original one
        error_context.context("comparing hashes", logging.info)
        orig_hash = crypto.hash_file(host_path)
        returned_hash = crypto.hash_file(host_path_returned)
        if orig_hash != returned_hash:
            test.fail("Returned file hash (%s) differs from "
                      "original one (%s)" % (returned_hash, orig_hash))
        error_context.context()

    finally:
        session.close()
        if os.path.isfile(host_path):
            os.remove(host_path)
        if os.path.isfile(host_path_returned):
            os.remove(host_path_returned)
예제 #9
0
def run(test, params, env):
    """
    Qemu guest pxe boot test:
    1). check npt/ept function enable, then boot vm
    2). execute query/info cpus in loop
    3). verify vm not paused during pxe booting

    params:
    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    def stopVMS(params, env):
        """
        Kill all VMS for relaod kvm_intel/kvm_amd module;
        """
        for vm in env.get_all_vms():
            if vm:
                vm.destroy()
                env.unregister_vm(vm.name)

        qemu_bin = os.path.basename(params["qemu_binary"])
        process.run("killall -g %s" % qemu_bin, ignore_status=True)
        time.sleep(5)

    enable_mmu_cmd = None
    check_mmu_cmd = None
    restore_mmu_cmd = None
    error_context.context("Enable ept(npt)", logging.info)
    try:
        flag = list(
            filter(lambda x: x in utils_misc.get_cpu_flags(),
                   ['ept', 'npt']))[0]
    except IndexError:
        logging.warn("Host doesn't support ept(npt)")
    else:
        enable_mmu_cmd = params["enable_mmu_cmd_%s" % flag]
        check_mmu_cmd = params["check_mmu_cmd_%s" % flag]
        status = process.system(check_mmu_cmd,
                                timeout=120,
                                ignore_status=True,
                                shell=True)
        if status != 0:
            stopVMS(params, env)
            process.run(enable_mmu_cmd, shell=True)
            restore_mmu_cmd = params["restore_mmu_cmd_%s" % flag]

    params["start_vm"] = "yes"
    params["kvm_vm"] = "yes"
    params["paused_after_start_vm"] = "yes"

    env_process.preprocess_vm(test, params, env, params["main_vm"])
    bg = utils_misc.InterruptedThread(utils_test.run_virt_sub_test,
                                      args=(
                                          test,
                                          params,
                                          env,
                                      ),
                                      kwargs={"sub_type": "pxe_boot"})
    count = 0
    try:
        bg.start()
        error_context.context("Query cpus in loop", logging.info)
        vm = env.get_vm(params["main_vm"])
        vm.resume()
        while True:
            count += 1
            try:
                vm.monitor.info("cpus")
                vm.verify_status("running")
                if not bg.is_alive():
                    break
            except qemu_monitor.MonitorSocketError:
                test.fail("Qemu looks abnormally, please read the log")
        logging.info("Execute info/query cpus %d times", count)
    finally:
        bg.join()
        if restore_mmu_cmd:
            stopVMS(params, env)
            process.run(restore_mmu_cmd, shell=True)
예제 #10
0
def run(test, params, env):
    """
    MULTI_QUEUE chang queues number test
    1) Boot up VM, and login guest
    2) Enable the queues in guest
    3) Run netperf_and_ping test
    4) Change queues number repeatedly during netperf_and_ping stress testing
    5) Reboot VM
    6) Repeat above 1-4 steps
    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def change_queues_number(ifname, q_number, queues_status=None):
        """
        change queues number
        """
        if not queues_status:
            queues_status = get_queues_status(ifname)
        mq_set_cmd = "ethtool -L %s combined %d" % (ifname, q_number)
        output = session_serial.cmd_output_safe(mq_set_cmd)
        cur_queues_status = get_queues_status(ifname)

        err_msg = ""
        expect_q_number = q_number
        if q_number != queues_status[1] and q_number <= queues_status[0]:
            if (cur_queues_status[1] != q_number
                    or cur_queues_status[0] != queues_status[0]):
                err_msg = "Param is valid, but change queues failed, "
        elif cur_queues_status != queues_status:
            if q_number != queues_status[1]:
                err_msg = "Param is invalid, "
            err_msg += "Current queues value is not expected, "
            expect_q_number = queues_status[1]

        if len(err_msg) > 0:
            err_msg += "current queues set is %s, " % cur_queues_status[1]
            err_msg += "max allow queues set is %s, " % cur_queues_status[0]
            err_msg += "when run cmd: '%s', " % mq_set_cmd
            err_msg += "expect queues are %s," % expect_q_number
            err_msg += "expect max allow queues are %s, " % queues_status[0]
            err_msg += "output: '%s'" % output
            test.fail(err_msg)

        return cur_queues_status

    def get_queues_status(ifname):
        """
        Get queues status
        """
        mq_get_cmd = "ethtool -l %s" % ifname
        nic_mq_info = session_serial.cmd_output_safe(mq_get_cmd)
        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
            test.cancel(err_msg)
        return [int(x) for x in queues_info]

    def ping_test(dest_ip, ping_time, ping_lost_ratio):
        """
        ping guest from host,until change queues finished.
        """
        _, output = utils_net.ping(dest=dest_ip, timeout=ping_time)
        packets_lost = utils_test.get_loss_ratio(output)
        if packets_lost > ping_lost_ratio:
            err = " %s%% packages lost during ping. " % packets_lost
            err += "Ping command log:\n %s" % "\n".join(
                output.splitlines()[-3:])
            test.fail(err)

    def netperf_test():
        """
        Netperf stress test for nic option.
        """
        try:
            n_server.start()
            # Run netperf with message size defined in range.
            netperf_test_duration = params.get_numeric("netperf_test_duration")
            test_protocols = params.get("test_protocols", "TCP_STREAM")
            netperf_output_unit = params.get("netperf_output_unit")
            test_option = params.get("test_option", "")
            test_option += " -l %s" % netperf_test_duration
            if netperf_output_unit in "GMKgmk":
                test_option += " -f %s" % netperf_output_unit
            t_option = "%s -t %s" % (test_option, test_protocols)
            n_client.bg_start(utils_net.get_host_ip_address(params),
                              t_option,
                              params.get_numeric("netperf_para_sessions"),
                              params.get("netperf_cmd_prefix", ""),
                              package_sizes=params.get("netperf_sizes"))
            if utils_misc.wait_for(n_client.is_netperf_running, 10, 0, 1,
                                   "Wait netperf test start"):
                logging.info("Netperf test start successfully.")
            else:
                test.error("Can not start netperf client.")
            utils_misc.wait_for(
                lambda: not n_client.is_netperf_running(),
                netperf_test_duration, 0, 5,
                "Wait netperf test finish %ss" % netperf_test_duration)
        finally:
            n_server.stop()

    login_timeout = params.get_numeric("login_timeout", 360)
    netperf_stress = params.get("run_bgstress")
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    vm.wait_for_serial_login(timeout=login_timeout)
    guest_ip = vm.get_address()
    n_client = utils_netperf.NetperfClient(
        guest_ip,
        params.get("client_path"),
        netperf_source=os.path.join(data_dir.get_deps_dir("netperf"),
                                    params.get("netperf_client_link")),
        client=params.get("shell_client"),
        username=params.get("username"),
        password=params.get("password"),
        compile_option=params.get("compile_option", ""))
    n_server = utils_netperf.NetperfServer(
        utils_net.get_host_ip_address(params),
        params.get("server_path", "/var/tmp"),
        netperf_source=os.path.join(data_dir.get_deps_dir("netperf"),
                                    params.get("netperf_server_link")),
        password=params.get("hostpassword"),
        compile_option=params.get("compile_option", ""))
    wait_time = params.get_numeric("wait_bg_time")
    ping_lost_ratio = params.get_numeric("background_ping_package_lost_ratio",
                                         5)
    ping_time = params.get_numeric("background_ping_time")
    required_reboot = True
    bg_test = True
    try:
        while bg_test:
            session_serial = vm.wait_for_serial_login(timeout=login_timeout)
            n_client.session = session_serial
            error_context.context("Enable multi queues in guest.",
                                  logging.info)
            for nic in vm.virtnet:
                ifname = utils_net.get_linux_ifname(session_serial, nic.mac)
                queues = int(nic.queues)
                change_queues_number(ifname, queues)
            error_context.context("Run test %s background" % netperf_stress,
                                  logging.info)
            stress_thread = utils_misc.InterruptedThread(netperf_test)
            stress_thread.start()
            utils_misc.wait_for(lambda: wait_time, 0, 5,
                                "Wait %s start background" % netperf_stress)

            # ping test
            error_context.context("Ping guest from host", logging.info)
            args = (guest_ip, ping_time, ping_lost_ratio)
            bg_ping = utils_misc.InterruptedThread(ping_test, args)
            bg_ping.start()

            error_context.context("Change queues number repeatedly",
                                  logging.info)
            repeat_counts = params.get_numeric("repeat_counts")
            for nic in vm.virtnet:
                queues = int(nic.queues)
                if queues == 1:
                    logging.info("Nic with single queue, skip and continue")
                    continue
                ifname = utils_net.get_linux_ifname(session_serial, nic.mac)
                change_list = params.get("change_list").split(",")
                for repeat_num in range(repeat_counts):
                    error_context.context(
                        "Change queues number -- %sth" % repeat_num,
                        logging.info)
                    queues_status = get_queues_status(ifname)
                    for q_number in change_list:
                        queues_status = change_queues_number(
                            ifname, int(q_number), queues_status)

            logging.info("wait for background test finish")
            try:
                stress_thread.join()
            except Exception as err:
                err_msg = "Run %s test background error!\n "
                err_msg += "Error Info: '%s'"
                test.error(err_msg % (netperf_stress, err))

            logging.info("Wait for background ping test finish.")
            try:
                bg_ping.join()
            except Exception as err:
                txt = "Fail to wait background ping test finish. "
                txt += "Got error message %s" % err
                test.fail(txt)

            if required_reboot:
                logging.info("Rebooting guest ...")
                vm.reboot()
                required_reboot = False
            else:
                bg_test = False
    finally:
        n_server.cleanup(True)
        n_client.cleanup(True)
        if session_serial:
            session_serial.close()
예제 #11
0
def test(vt_test, test_params, env):
    """Playback of audio stream tests for remote-viewer.

    Parameters
    ----------
    vt_test : avocado.core.plugins.vt.VirtTest
        QEMU test object.
    test_params : virttest.utils_params.Params
        Dictionary with the test parameters.
    env : virttest.utils_env.Env
        Dictionary with test environment.

    Raises
    ------
    TestFail
        Test fails for expected behaviour.

    """
    test = stest.ClientGuestTest(vt_test, test_params, env)
    cfg = test.cfg
    act.x_active(test.vmi_c)
    act.x_active(test.vmi_g)
    ssn_c = act.new_ssn(test.vmi_c)
    ssn_g = act.new_ssn(test.vmi_g)
    # Get default sink at the client.
    cmd = r"pacmd stat | grep 'Default sink name' | " \
        r"sed -e 's/^.*[[:space:]]//'"
    try:
        def_sink = ssn_c.cmd(cmd).rstrip('\r\n')
    except aexpect.ShellCmdError as excp:
        raise utils.SpiceTestFail(test, "Test failed: %s" % str(excp))
    logging.info("Default sink at client is: %s", def_sink)
    # Create RV session
    env_local = {}
    if cfg.rv_record:
        env_local["PULSE_SOURCE"] = "%s.monitor" % def_sink
    ssn = act.new_ssn(test.vmi_c)
    act.rv_connect(test.vmi_c, ssn, env=env_local)
    ret, out = commands.getstatusoutput(MAKE_WAV)
    if ret:
        errmsg = "Cannot generate specimen WAV file: %s" % out
        raise utils.SpiceTestFail(test, errmsg)
    play_cmd = "aplay %s &> /dev/null &" % cfg.audio_tgt
    rec_cmd = "arecord -d %s -f cd %s" % (cfg.audio_time, cfg.audio_rec)
    # Check test type
    if cfg.rv_record:
        logging.info("Recording test. Player is client. Recorder is guest.")
        player = ssn_c
        recorder = ssn_g
        vm_recorder = test.vm_g
        vm_player = test.vm_c
    else:
        logging.info("Playback test. Player is guest. Recorder is client.")
        env_var = "PULSE_SOURCE=%s.monitor" % def_sink
        rec_cmd = env_var + " " + rec_cmd
        player = ssn_g
        recorder = ssn_c
        vm_recorder = test.vm_c
        vm_player = test.vm_g
    vm_player.copy_files_to(SPECIMEN_FILE, cfg.audio_tgt)
    time.sleep(2)  # wait till everything is set up
    player.cmd(play_cmd)
    if cfg.config_test == "migration":
        bguest = utils_misc.InterruptedThread(test.vm_g.migrate, kwargs={})
        bguest.start()
    try:
        recorder.cmd(rec_cmd, timeout=500)
    except aexpect.ShellCmdError as excp:
        raise utils.SpiceTestFail(test, str(excp))
    if cfg.config_test == "migration":
        bguest.join()
    vm_recorder.copy_files_from(cfg.audio_rec, RECORDED_FILE)
    if not verify_recording(RECORDED_FILE, cfg):
        raise utils.SpiceTestFail(test, "Cannot verify recorded file.")
    if cfg.rv_reconnect:
        act.rv_disconnect(test.vmi_c)
        act.rv_connect(test.vmi_c, ssn)
        try:
            recorder.cmd(rec_cmd, timeout=500)
        except aexpect.ShellCmdError as excp:
            raise utils.SpiceTestFail(test, str(excp))
        vm_recorder.copy_files_from(cfg.audio_rec, RECORDED_FILE)
        if not verify_recording(RECORDED_FILE, cfg):
            raise utils.SpiceTestFail(test, "Cannot verify recorded file.")
예제 #12
0
def run(test, params, env):
    """
    Multicast test using iperf.

    1) Boot up VM(s)
    2) Prepare the test environment in server/client/host,install iperf
    3) Execute iperf tests, analyze the results

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def server_start(cmd, catch_data):
        """
        Start the iperf server in host, and check whether the guest have connected
        this server through multicast address of the server
        """
        try:
            process.run(cmd)
        except process.CmdError as e:
            if not re.findall(catch_data, str(e)):
                test.fail("Client not connected '%s'" % str(e))
            logging.info("Client multicast test pass "
                         % re.findall(catch_data, str(e)))

    os_type = params.get("os_type")
    win_iperf_url = params.get("win_iperf_url")
    linux_iperf_url = params.get("linux_iperf_url")
    iperf_version = params.get("iperf_version", "2.0.5")
    transfer_timeout = int(params.get("transfer_timeout", 360))
    login_timeout = int(params.get("login_timeout", 360))

    dir_name = test.tmpdir
    tmp_dir = params.get("tmp_dir", "/tmp/")
    host_path = os.path.join(dir_name, "iperf")

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=login_timeout)
    clean_cmd = ""
    client_ip = vm.get_address(0)

    try:
        error_context.context("Test Env setup")
        iperf_downloaded = 0
        iperf_url = linux_iperf_url

        app_check_cmd = params.get("linux_app_check_cmd", "false")
        app_check_exit_status = int(params.get("linux_app_check_exit_status",
                                               "0"))
        exit_status = process.system(app_check_cmd, ignore_status=True,
                                     shell=True)

        # Install iperf in host if not available
        default_install_cmd = "tar zxvf %s; cd iperf-%s;"
        default_install_cmd += " ./configure; make; make install"
        install_cmd = params.get("linux_install_cmd", default_install_cmd)
        if not exit_status == app_check_exit_status:
            error_context.context("install iperf in host", logging.info)
            download.get_file(iperf_url, host_path)
            iperf_downloaded = 1
            process.system(install_cmd % (host_path, iperf_version),
                           shell=True)

        # The guest may not be running Linux, see if we should update the
        # app_check variables
        if not os_type == "linux":
            app_check_cmd = params.get("win_app_check_cmd", "false")
            app_check_exit_status = int(params.get("win_app_check_exit_status",
                                                   "0"))

        # Install iperf in guest if not available
        if not session.cmd_status(app_check_cmd) == app_check_exit_status:
            error_context.context("install iperf in guest", logging.info)
            if not iperf_downloaded:
                download.get_file(iperf_url, host_path)
            if os_type == "linux":
                guest_path = (tmp_dir + "iperf.tgz")
                clean_cmd = "rm -rf %s iperf-%s" % (guest_path, iperf_version)
            else:
                guest_path = (tmp_dir + "iperf.exe")
                iperf_url = win_iperf_url
                download.get_file(iperf_url, host_path)
                clean_cmd = "del %s" % guest_path
            vm.copy_files_to(host_path, guest_path, timeout=transfer_timeout)

            if os_type == "linux":
                session.cmd(install_cmd % (guest_path, iperf_version))

        muliticast_addr = params.get("muliticast_addr", "225.0.0.3")
        multicast_port = params.get("multicast_port", "5001")

        step_msg = "Start iperf server, bind host to multicast address %s "
        error_context.context(step_msg % muliticast_addr, logging.info)
        server_start_cmd = ("iperf -s -u -B %s -p %s " %
                            (muliticast_addr, multicast_port))

        default_flag = "%s port %s connected with %s"
        connected_flag = params.get("connected_flag", default_flag)
        catch_data = connected_flag % (muliticast_addr, multicast_port,
                                       client_ip)
        t = utils_misc.InterruptedThread(server_start,
                                         (server_start_cmd, catch_data))
        t.start()
        if not _process_is_alive("iperf"):
            test.error("Start iperf server failed cmd: %s" % server_start_cmd)
        logging.info("Server start successfully")

        step_msg = "In client try to connect server and transfer file "
        step_msg += " through multicast address %s"
        error_context.context(step_msg % muliticast_addr, logging.info)
        if os_type == "linux":
            client_cmd = "iperf"
        else:
            client_cmd = guest_path
        start_cmd = params.get("start_client_cmd", "%s -c %s -u -p %s")
        start_client_cmd = start_cmd % (client_cmd, muliticast_addr,
                                        multicast_port)
        session.cmd(start_client_cmd)
        logging.info("Client start successfully")

        error_context.context("Test finish, check the result", logging.info)
        process.system("pkill -2 iperf")
        t.join()

    finally:
        if _process_is_alive("iperf"):
            process.system("killall -9 iperf")
        process.system("rm -rf %s" % host_path)
        if session:
            if clean_cmd:
                session.cmd(clean_cmd)
            session.close()
예제 #13
0
def run(test, params, env):
    """
    Nic teaming test in guest.

    1) Start guest with four nic devices.
    2) Setup Team in guest.
    3) Execute file transfer from host to guest.
    4) Repeatedly set enable/disable interfaces by 'netsh interface set'
    5) Execute file transfer from guest to host.

    :param test: Kvm test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    tmp_dir = params["tmp_dir"]
    filesize = params.get_numeric("filesize")
    dd_cmd = params["dd_cmd"]
    delete_cmd = params["delete_cmd"]
    login_timeout = params.get_numeric("login_timeout", 1200)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
    nics = params.objects("nics")
    ifnames = ()
    for i in range(len(nics)):
        mac = vm.get_mac_address(i)
        connection_id = utils_net.get_windows_nic_attribute(
            session_serial, "macaddress", mac, "netconnectionid")
        ifnames += (connection_id, )

    # get params of teaming
    setup_cmd = params["setup_cmd"]
    status, output = session_serial.cmd_status_output(setup_cmd % ifnames)
    if status:
        test.fail("Failed to setup team nic from powershell,"
                  "status=%s, output=%s" % (status, output))

    # prepare test data
    guest_path = (tmp_dir + "src-%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)
    process.run(dd_cmd % host_path, shell=True)

    try:
        netsh_set_cmd = "netsh interface set interface \"%s\" %s"
        # transfer data
        original_md5 = crypto.hash_file(host_path, algorithm="md5")
        logging.info("md5 value of data original: %s", original_md5)
        logging.info("Failover test with file transfer")
        transfer_thread = utils_misc.InterruptedThread(vm.copy_files_to,
                                                       (host_path, guest_path))
        transfer_thread.start()
        try:
            while transfer_thread.is_alive():
                for ifname in ifnames:
                    session_serial.cmd(netsh_set_cmd % (ifname, "disable"))
                    time.sleep(random.randint(1, 30))
                    session_serial.cmd(netsh_set_cmd % (ifname, "enable"))
                    time.sleep(random.randint(1, 30))
        except aexpect.ShellProcessTerminatedError:
            transfer_thread.join(suppress_exception=True)
            raise
        else:
            transfer_thread.join()

        os.remove(host_path)
        logging.info('Cleaning temp file on host')
        logging.info("Failover test 2 with file transfer")
        transfer_thread = utils_misc.InterruptedThread(vm.copy_files_from,
                                                       (guest_path, host_path))
        transfer_thread.start()
        try:
            nic_num = len(ifnames)
            index = 0
            while transfer_thread.is_alive():
                index = index % nic_num
                for i in range(nic_num):
                    session_serial.cmd(netsh_set_cmd % (ifnames[i], "enable"))
                    for j in range(nic_num):
                        if i != j:
                            session_serial.cmd(netsh_set_cmd %
                                               (ifnames[j], "disable"))
                time.sleep(random.randint(1, 5))
                index += 1
        except aexpect.ShellProcessTerminatedError:
            transfer_thread.join(suppress_exception=True)
            raise
        else:
            transfer_thread.join()
        current_md5 = crypto.hash_file(host_path, algorithm="md5")
        logging.info("md5 value of data current: %s", current_md5)
        if original_md5 != current_md5:
            test.fail("File changed after transfer host -> guest "
                      "and guest -> host")
    finally:
        os.remove(host_path)
        session_serial.cmd(delete_cmd % guest_path,
                           timeout=login_timeout,
                           ignore_all_errors=True)
        session_serial.close()
예제 #14
0
 def _run_backgroud(args):
     thread_session = vm.wait_for_login(timeout=360)
     thread = utils_misc.InterruptedThread(thread_session.cmd, args)
     thread.start()
예제 #15
0
def run(test, params, env):
    """
    Qemu guest irqbalance inactive/active test:
    1) Setup host for sr-iov test.
    2) Boot VM with sr-iov vf/pf assigned and multi vcpu.
    3) Update irqbalance service status in guest. stop/start this server
       according to request.
    4) Get available network interface name in guest.
    5) Start background network stress in guest.
    6) Get irq number assigned to attached vfs/pfs.
    7) Get the cpu number the irq running.
    8) Check specified IRQ count grow on specified cpu.
    9) Repeat step 7 for every 10s.
    10) Balance IRQs generated by vfs/pfs to different vcpus (optional)
       e.g.
       echo 4 > /proc/irq/num/smp_affinity
    11) Repeat step 6, 7
    12) Check that specified IRQ count grow on every cpu. (optional)

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = int(params.get("login_timeout", 360))
    session = vm.wait_for_login(timeout=timeout)
    irqbalance_check_count = int(params.get("irqbalance_check_count", 36))
    nic_interface_filter = params["nic_interface_filter"]

    error_context.context("Make sure that guest have at least 2 vCPUs.",
                          logging.info)
    cpu_count = vm.get_cpu_count()
    if cpu_count < 2:
        test.cancel("Test requires at least 2 vCPUs.")

    msg = "Update irqbalance service status in guest if not match request."
    error_context.context(msg, logging.info)
    irqbalance_status = params.get("irqbalance_status", "active")
    status = utils_misc.get_guest_service_status(session=session,
                                                 service="irqbalance")
    service_cmd = ""
    if status == "active" and irqbalance_status == "inactive":
        service_cmd = "service irqbalance stop"
    elif status == "inactive" and irqbalance_status == "active":
        service_cmd = "service irqbalance start"
    if service_cmd:
        status, output = session.cmd_status_output(service_cmd)
        if status:
            msg = "Fail to update irqbalance service status in guest."
            msg += " Command output in guest: %s" % output
            test.error(msg)

    error_context.context("Get first network interface name in guest.",
                          logging.info)
    devname = get_first_network_devname(test, session, nic_interface_filter)

    error_context.context("Start background network stress in guest.",
                          logging.info)
    host_ip = utils_net.get_ip_address_by_interface(params.get('netdst'))
    ping_cmd = "ping %s  -f -q" % host_ip
    ping_timeout = irqbalance_check_count * 10 + 100
    ping_session = vm.wait_for_login(timeout=timeout)
    bg_stress = utils_misc.InterruptedThread(utils_test.raw_ping,
                                             kwargs={'command': ping_cmd,
                                                     'timeout': ping_timeout,
                                                     'session': ping_session,
                                                     'output_func': None})
    bg_stress.start()
    try:
        error_context.context("Get irq number assigned to attached "
                              "VF/PF in guest", logging.info)
        irq_nums_dict = get_guest_irq_info(test, session, devname, cpu_count)
        if irq_nums_dict:
            irqs = irq_nums_dict.keys()

        msg = "Check specified IRQ count grow on specified cpu."
        error_context.context(msg, logging.info)
        check_irqbalance(test, session, devname, cpu_count, irqs)
        irq_cpus_dict = {}
        for irq in irqs:
            cpus = get_irq_smp_affinity(test, session, irq)
            irq_cpus_dict[irq] = cpus

        if irqbalance_status == "inactive":
            msg = "balance IRQs generated by vfs/pfs to different vcpus."
            error_context.context(msg, logging.info)
            post_irq_cpus_dict = {}
            for irq in irq_cpus_dict:
                balance_cpu_count = 1
                cpus = []
                for cpu in range(cpu_count):
                    if cpu not in irq_cpus_dict[irq]:
                        cpus.append(cpu)
                        if len(cpus) == balance_cpu_count:
                            break
                set_irq_smp_affinity(test, session, irq, cpus)
                post_irq_cpus_dict[irq] = cpus

            for irq in irqs:
                cpus = get_irq_smp_affinity(test, session, irq)
                msg = "Fail to balance IRQs generated by vf/pf to different cpu"
                if cpus != post_irq_cpus_dict[irq]:
                    test.fail(msg)

        msg = "Check specified IRQ count grow on specified cpu."
        error_context.context(msg, logging.info)
        check_irqbalance(test, session, devname,
                         cpu_count, irqs,
                         count=irqbalance_check_count)

        if irqbalance_status == "active":
            msg = "Check that specified IRQ count grow on every cpu."
            error_context.context(msg, logging.info)
            post_irq_nums_dict = get_guest_irq_info(test, session, devname,
                                                    cpu_count)

            for irq in irqs:
                if irq not in post_irq_nums_dict.keys():
                    post_irqs = post_irq_nums_dict.keys()
                    msg = "Different irq detected: '%s' and '%s'." % (irqs,
                                                                      post_irqs)
                    test.error(msg)
                for cpu in range(cpu_count):
                    if (int(irq_nums_dict[irq][cpu]) >=
                            int(post_irq_nums_dict[irq][cpu])):
                        msg = "'Cpu%s' did not handle more interrupt" % cpu
                        msg += "for irq '%s'." % irq
                        msg += "IRQ balance information for IRQ '%s'\n" % irq
                        msg += "First time: %s\n" % irq_nums_dict
                        msg += "Just now: %s" % post_irq_nums_dict
                        test.fail(msg)
    finally:
        if bg_stress.isAlive():
            bg_stress.join(suppress_exception=True)
        else:
            logging.warn("Background stress test already finished")
예제 #16
0
def run(test, params, env):
    """
    Special hardware test case.
    FC host: ibm-x3650m4-05.lab.eng.pek2.redhat.com
    Disk serial name: scsi-360050763008084e6e0000000000001a4
    # multipath -ll
    mpathb (360050763008084e6e0000000000001a8) dm-4 IBM,2145
    size=100G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
    |-+- policy='service-time 0' prio=50 status=active
    | `- 2:0:1:0 sde 8:64 active ready running
    `-+- policy='service-time 0' prio=10 status=enabled
      `- 2:0:0:0 sdd 8:48 active ready running
    mpatha (360050763008084e6e0000000000001a4) dm-3 IBM,2145
    size=100G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
    |-+- policy='service-time 0' prio=50 status=active
    | `- 1:0:1:0 sdc 8:32 active ready running
    `-+- policy='service-time 0' prio=10 status=enabled
      `- 1:0:0:0 sdb 8:16 active ready running
    Customer Bug ID: 1741937  1673546

    Test if VM paused/resume when fc storage offline/online.

    1) pass-through /dev/mapper/mpatha
    2) install guest on pass-through disk
    3) Disconnect the storage during installation
    4) Check if VM status is 'paused'
    5) Connect the storage, Wait until the storage is accessible again
    6) resume the vm
    7) Check if VM status is 'running'
    8) installation completed successfully
    9) re-pass-through /dev/mapper/mpatha
    10) fio test on pass-through disk
    11) Disconnect any path of multipath during fio testing
    12) Check if VM status is 'paused'
    13) Connect the storage, Wait until the storage is accessible again
    14) resume the vm
    15) fio testing completed successfully

    :param test: kvm test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def check_vm_status(vm, status):
        """
        Check if VM has the given status or not.

        :param vm: VM object.
        :param status: String with desired status.
        :return: True if VM status matches our desired status.
        :return: False if VM status does not match our desired status.
        """
        try:
            current_status = vm.monitor.get_status()
            vm.verify_status(status)
        except (virt_vm.VMStatusError, qemu_monitor.MonitorLockError):
            logging.info("Failed to check vm status, it is '%s' "
                         "instead of '%s'" % (current_status, status))
            return False
        except Exception as e:
            logging.info("Failed to check vm status: %s" % six.text_type(e))
            logging.info("vm status is '%s' instead of"
                         " '%s'" % (current_status, status))
            return False
        else:
            logging.info("Check vm status successfully. It is '%s'" % status)
            return True

    def get_multipath_disks(mpath_name="mpatha"):
        """
        Get all disks of multiple paths.
        multipath like below:
        mpatha (360050763008084e6e0000000000001a4) dm-3 IBM,2145
        size=100G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
        |-+- policy='service-time 0' prio=50 status=active
        | `- 1:0:1:0 sdc 8:32  active ready running
        `-+- policy='service-time 0' prio=10 status=enabled
          `- 1:0:0:0 sdb 8:16  active ready running

        :param mpath_name: multi-path name.
        :return: a list. if get disks successfully or raise a error
        """
        logging.info("get_multipath_disks:" + mpath_name)
        disks = []
        disk_str = []
        outputs = process.run("multipath -ll " + mpath_name,
                              shell=True).stdout.decode()
        outputs = outputs.split(mpath_name)[-1]
        disk_str.append("active ready running")
        disk_str.append("active faulty offline")
        disk_str.append("failed faulty offline")
        disk_str.append("failed ready running")
        for line in outputs.splitlines():
            if disk_str[0] in line or disk_str[1] in line or disk_str[2] \
                    in line or disk_str[3] in line:
                disks.append(line.split()[-5])
        if not disks:
            test.fail("Failed to get disks by 'multipath -ll'")
        else:
            return disks

    def get_multipath_disks_status(mpath_name="mpatha"):
        """
        Get status of multiple paths.
        multipath like below:
        mpatha (360050763008084e6e0000000000001a4) dm-3 IBM,2145
        size=100G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
        |-+- policy='service-time 0' prio=50 status=active
        | `- 1:0:1:0 sdc 8:32  active ready running
        `-+- policy='service-time 0' prio=10 status=enabled
          `- 1:0:0:0 sdb 8:16  active ready running

        :param mpath_name: multi-path name.
        :return: a dict. e.g. {"sdb": "running", "sdc": "running"}
        """
        disks = get_multipath_disks(mpath_name)
        disks_status = {}
        outputs = process.run("multipath -ll " + mpath_name,
                              shell=True).stdout.decode()
        outputs = outputs.split(mpath_name)[-1]
        for line in outputs.splitlines():
            for i in range(len(disks)):
                if disks[i] in line:
                    disks_status[disks[i]] = line.strip().split()[-1]
                    break
        if not disks_status or len(disks_status) != len(disks):
            logging.info("Failed to get disks status by 'multipath -ll'")
            return {}
        else:
            return disks_status

    def compare_onepath_status(status, disk):
        """
        Compare status whether equal to the given status.
        This function just focus on all paths are running or all are offline.

        :param status: the state of disks.
        :param disk: disk kname.
        :return: True, if equal to the given status or False
        """
        status_dict = get_multipath_disks_status(mpath_name)
        logging.debug("compare_onepath_status disk:", disk, status_dict,
                      status)
        if disk in status_dict.keys() and status == status_dict[disk]:
            return True
        else:
            return False

    def compare_multipath_status(status, mpath_name="mpatha"):
        """
        Compare status whether equal to the given status.
        This function just focus on all paths are running or all are offline.

        :param status: the state of disks.
        :param mpath_name: multi-path name.
        :return: True, if equal to the given status or False
        """
        status_dict = get_multipath_disks_status(mpath_name)
        logging.debug("compare_multipath_status mpath_name:", mpath_name,
                      status_dict, status)
        if len(set(
                status_dict.values())) == 1 and status in status_dict.values():
            return True
        else:
            return False

    def set_disk_status_to_online_offline(disk, status):
        """
        set disk state to online/offline.
        multipath like below:
        mpatha (360050763008084e6e0000000000001a4) dm-3 IBM,2145
        size=100G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
        |-+- policy='service-time 0' prio=50 status=active
        | `- 1:0:1:0 sdc 8:32  active ready running
        `-+- policy='service-time 0' prio=10 status=enabled
          `- 1:0:0:0 sdb 8:16 failed faulty offline

        :param disk: disk name.
        :param status: the state of disk.
        :return: by default
        """
        error_context.context("Set disk '%s' to status '%s'." % (disk, status),
                              logging.info)
        process.run("echo %s >  /sys/block/%s/device/state" % (status, disk),
                    shell=True)

    def set_multipath_disks_status(disks, status):
        """
        set multiple paths to same status. all disks online or offline.
        multipath like below:
        mpatha (360050763008084e6e0000000000001a4) dm-3 IBM,2145
        size=100G features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
        |-+- policy='service-time 0' prio=50 status=active
        | `- 1:0:1:0 sdc 8:32  active ready running
        `-+- policy='service-time 0' prio=10 status=enabled
          `- 1:0:0:0 sdb 8:16 failed faulty offline

        :param disks: disk list.
        :param status: the state of disk. online/offline
        :return: by default
        """
        for disk in disks:
            set_disk_status_to_online_offline(disk, status)
            time.sleep(2)
        if len(disks) == 1:
            wait.wait_for(lambda: compare_onepath_status(status, disks[0]),
                          first=wait_time,
                          step=3,
                          timeout=60)
        else:
            wait.wait_for(lambda: compare_multipath_status(status),
                          first=wait_time,
                          step=3,
                          timeout=60)

    def get_lvm_dm_name(blkdevs_used):
        """
        Get dm name for lvm. such as rhel_ibm--x3650m4--05-root in below
        NAME                           MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
        sda                              8:0    0 278.9G  0 disk
        ├─sda1                           8:1    0     1G  0 part  /boot
        └─sda2                           8:2    0 277.9G  0 part
            ├─rhel_ibm--x3650m4--05-root 253:0    0    50G  0 lvm   /
            ├─rhel_ibm--x3650m4--05-swap 253:1    0  15.7G  0 lvm   [SWAP]
            └─rhel_ibm--x3650m4--05-home 253:2    0 212.2G  0 lvm   /home
        # ls /dev/mapper/* -l
        crw-------. 1 root root 10, 236 Oct 25 02:07 /dev/mapper/control
        lrwxrwxrwx. 1 root root       7 Oct 25 09:26 /dev/mapper/mpatha -> ../dm-3
        lrwxrwxrwx. 1 root root       7 Oct 25 09:26 /dev/mapper/mpatha1 -> ../dm-5
        lrwxrwxrwx. 1 root root       7 Oct 25 09:26 /dev/mapper/mpatha2 -> ../dm-6
        lrwxrwxrwx. 1 root root       7 Oct 25 06:49 /dev/mapper/mpathb -> ../dm-4
        lrwxrwxrwx. 1 root root       7 Oct 25 09:17 /dev/mapper/rhel_bootp--73--199--5-home -> ../dm-8
        lrwxrwxrwx. 1 root root       7 Oct 25 09:17 /dev/mapper/rhel_bootp--73--199--5-root -> ../dm-9
        lrwxrwxrwx. 1 root root       7 Oct 25 09:17 /dev/mapper/rhel_bootp--73--199--5-swap -> ../dm-7
        lrwxrwxrwx. 1 root root       7 Oct 25 02:07 /dev/mapper/rhel_ibm--x3650m4--05-home -> ../dm-2
        lrwxrwxrwx. 1 root root       7 Oct 25 02:07 /dev/mapper/rhel_ibm--x3650m4--05-root -> ../dm-0
        lrwxrwxrwx. 1 root root       7 Oct 25 02:07 /dev/mapper/rhel_ibm--x3650m4--05-swap -> ../dm-1
        -rw-r--r--. 1 root root       0 Oct 25 07:52 /dev/mapper/vg_raid10-lv_home
        # dmsetup info -c -o name,blkdevs_used
        Name                        BlkDevNamesUsed
        rhel_bootp--73--199--5-home dm-6
        mpathb                      sdd,sde
        mpatha                      sdb,sdc
        mpatha2                     dm-3
        rhel_bootp--73--199--5-swap dm-6
        rhel_bootp--73--199--5-root dm-6
        mpatha1                     dm-3
        rhel_ibm--x3650m4--05-home  sda2
        rhel_ibm--x3650m4--05-swap  sda2
        rhel_ibm--x3650m4--05-root  sda2

        :param blkdevs_used: block name, e.g. sda2
        :return: a list contains all dm name for one blkdev
        """
        dm_list = []
        logging.info("Get dm name for '%s'" % blkdevs_used)
        output = process.run("ls /dev/mapper/* -l", shell=True).stdout.decode()
        for line in output.splitlines():
            if blkdevs_used in line:
                dm_name = line.split("/")[-1]
                break
        output = process.run("dmsetup info -c -o name,blkdevs_used",
                             shell=True).stdout.decode()
        for line in output.splitlines():
            if dm_name == line.split()[-1]:
                dm_list.append(line.split()[0])
        return dm_list

    def delete_lvm_on_multipath(mpath_name="mpatha"):
        """
        Delete lvm on the given multipath.

        :param mpath_name: multi-path name.
        :return: by default.
        """
        output = process.run("pvscan", shell=True).stdout.decode()
        pv_list = []
        vg_list = []
        lv_list = []
        for line in output.splitlines():
            if mpath_name in line:
                if line.split()[1] not in pv_list:
                    pv_list.append(line.split()[1])
                if line.split()[3] not in vg_list:
                    vg_list.append(line.split()[3])
        output = process.run("lvscan", shell=True).stdout.decode()
        for line in output.splitlines():
            for vg in vg_list:
                lv = "/dev/%s/" % vg
                if lv in line and line.split("'")[1] not in lv_list:
                    lv_list.append(line.split("'")[1])
        logging.info("pv list: %s" % pv_list)
        logging.info("vg list: %s" % vg_list)
        logging.info("lv list: %s" % lv_list)
        for lv in lv_list:
            logging.info("Remove lvm '%s'." % lv)
            process.run("lvremove -y %s" % lv, ignore_status=True, shell=True)
        for vg in vg_list:
            logging.info("Remove vg '%s'." % vg)
            process.run("vgremove -y %s" % vg, ignore_status=True, shell=True)
        for pv in pv_list:
            pv_name = pv.split("/")[-1]
            for dm in get_lvm_dm_name(pv_name):
                process.run("dmsetup remove %s" % dm,
                            ignore_status=True,
                            shell=True)
            logging.info("Remove pv '%s'." % pv)
            process.run("pvremove -y %s" % pv, ignore_status=True, shell=True)

    def delete_partition_on_host(did):
        """
        Delete partitions on the given disk.

        :param did: disk ID. disk kname. e.g. 'sdb', 'nvme0n1'
        :return: by default.
        """
        # process.run("partprobe /dev/%s" % did, shell=True)
        list_disk_cmd = "lsblk -o KNAME,MOUNTPOINT"
        output = process.run(list_disk_cmd, shell=True).stdout.decode()
        regex_str = did + "\w*(\d+)"
        rm_cmd = 'parted -s "/dev/%s" rm %s'
        for line in output.splitlines():
            partition = re.findall(regex_str, line, re.I | re.M)
            if partition:
                if "/" in line.split()[-1]:
                    process.run("umount %s" % line.split()[-1], shell=True)
        list_partition_number = "parted -s /dev/%s print|awk '/^ / {print $1}'"
        partition_numbers = process.run(list_partition_number % did,
                                        ignore_status=True,
                                        shell=True).stdout.decode()
        ignore_err_msg = "unrecognised disk label"
        if ignore_err_msg in partition_numbers:
            logging.info("no partition to delete on %s" % did)
        else:
            partition_numbers = partition_numbers.splitlines()
            for number in partition_numbers:
                logging.info("remove partition %s on %s" % (number, did))
                process.run(rm_cmd % (did, number),
                            ignore_status=True,
                            shell=True)
            process.run("partprobe /dev/%s" % did, shell=True)

    def delete_multipath_partition_on_host(mpath_name="mpatha"):
        """
        Delete partitions on the given multipath.

        :param mpath_name: multi-path name.
        :return: by default.
        """
        # process.run("partprobe /dev/mapper/%s" % mpath_name, shell=True)
        output = process.run("lsblk", shell=True).stdout.decode()
        mpath_dict = {}
        pattern = r'%s(\d+)' % mpath_name
        rm_cmd = 'parted -s "/dev/mapper/%s" rm %s'
        for line in output.splitlines():
            for part_num in re.findall(pattern, line, re.I | re.M):
                if part_num not in mpath_dict.keys():
                    mpath_dict[part_num] = line.split()[-1]
        for key, value in mpath_dict.items():
            if "/" in value:
                process.run("umount %s" % value, shell=True)
            logging.info("remove partition %s on %s" % (key, mpath_name))
            process.run(rm_cmd % (mpath_name, key),
                        ignore_status=True,
                        shell=True)
        output = process.run("dmsetup ls", shell=True).stdout.decode()
        for line in output.splitlines():
            for key in mpath_dict.keys():
                if (mpath_name + key) in line:
                    process.run("dmsetup remove %s%s" % (mpath_name, key),
                                ignore_status=True,
                                shell=True)
        process.run("partprobe /dev/mapper/%s" % mpath_name, shell=True)

    def clean_partition_on_host(mpath_name="mpatha"):
        """
        Delete partitions on multi-path disks.

        :param mpath_name: multi-path name.
        :return: by default
        """
        delete_multipath_partition_on_host(mpath_name)
        disks = get_multipath_disks(mpath_name)
        for disk in disks:
            delete_partition_on_host(disk)

    def _run_fio_background(session, filename):
        """run fio testing by thread"""

        logging.info("Start fio in background.")
        cmd = fio_multipath.cfg.fio_path + params['fio_options'] % filename
        logging.info(cmd)
        session.cmdline(cmd)
        # args = (params['fio_options'] % filename, 3600)
        # fio_thread = utils_misc.InterruptedThread(fio_multipath.run, args)
        # fio_thread.start()
        # if not utils_misc.wait_for(lambda: fio_thread.is_alive, 60):
        #     test.fail("Failed to start fio thread.")
        # return fio_thread

    # def _run_fio_background(filename):
    #     """run fio testing by thread"""
    #
    #     logging.info("Start fio in background.")
    #     args = (params['fio_options'] % filename, 3600)
    #     fio_thread = utils_misc.InterruptedThread(fio_multipath.run, args)
    #     fio_thread.start()
    #     if not utils_misc.wait_for(lambda: fio_thread.is_alive, 60):
    #         test.fail("Failed to start fio thread.")
    #     return fio_thread

    def _get_windows_disks_index(session, image_size):
        """
        Get all disks index which show in 'diskpart list disk'.
        except for system disk.
        in diskpart: if disk size < 8GB: it displays as MB
                     else: it displays as GB

        :param session: session object to guest.
        :param image_size: image size. e.g. 40M
        :return: a list with all disks index except for system disk.
        """
        disk = "disk_" + ''.join(
            random.sample(string.ascii_letters + string.digits, 4))
        disk_indexs = []
        list_disk_cmd = "echo list disk > " + disk
        list_disk_cmd += " && echo exit >> " + disk
        list_disk_cmd += " && diskpart /s " + disk
        list_disk_cmd += " && del /f " + disk
        disks = session.cmd_output(list_disk_cmd)
        size_type = image_size[-1] + "B"
        if size_type == "MB":
            disk_size = image_size[:-1] + " MB"
        elif size_type == "GB" and int(image_size[:-1]) < 8:
            disk_size = str(int(image_size[:-1]) * 1024) + " MB"
        else:
            disk_size = image_size[:-1] + " GB"
        regex_str = 'Disk (\d+).*?%s' % disk_size
        for disk in disks.splitlines():
            if disk.startswith("  Disk"):
                o = re.findall(regex_str, disk, re.I | re.M)
                if o:
                    disk_indexs.append(o[0])
        return disk_indexs

    def resume_vm_plus(vm, timeout=120):
        """resume vm when it is paused.

        :param vm: VM object.
        :param timeout: re-try times, if it is still paused after resume
        :return: True or None.
                 If resume successfully return True or return None
        """
        logging.info("Try to resume vm within %s seconds." % timeout)
        try:
            vm_status = vm.resume(timeout=timeout)
        except Exception as e:
            logging.error("Failed to resume vm: %s" % six.text_type(e))
        return vm_status

    def resume_vm(vm, n_repeat=2):
        """resume vm when it is paused.

        :param vm: VM object.
        :param n_repeat: re-try times, if it is still paused after resume
        :return: True or False.
                 If resume successfully return True or return False
        """
        for i in range(1, n_repeat + 1):
            logging.info("Try to resume vm %s time(s)" % i)
            try:
                vm.resume()
                time.sleep(wait_time * 15)
            except Exception as e:
                logging.error("Failed to resume vm: %s" % six.text_type(e))
            finally:
                if check_vm_status(vm, "running"):
                    return True
                if vm.is_paused() and i == 3:
                    return False

    error_context.context("Get FC host name:", logging.info)
    hostname = process.run("hostname", shell=True).stdout.decode().strip()
    if hostname != params["special_host"]:
        test.cancel("The special host is not '%s', cancel the test." %
                    params["special_host"])
    error_context.context("Get FC disk serial name:", logging.info)
    outputs = process.run("multipath -ll",
                          shell=True).stdout.decode().splitlines()
    stg_serial_name = params["stg_serial_name"]
    image_name_stg = params["image_name_stg"]
    mpath_name = image_name_stg.split("/")[-1]
    for output in outputs:
        if stg_serial_name in output and mpath_name in output:
            break
    else:
        test.cancel("The special disk is not '%s', cancel the test." %
                    stg_serial_name)
    wait_time = float(params.get("sub_test_wait_time", 0))
    repeat_times = int(params.get("repeat_times", 2))
    multi_disks = get_multipath_disks(mpath_name)
    error_context.context(
        "Get all disks for '%s': %s" % (mpath_name, multi_disks), logging.info)
    error_context.context(
        "Verify all paths are running for %s before"
        "start vm." % mpath_name, logging.info)
    if compare_multipath_status("running", mpath_name):
        logging.info("All paths are running for %s." % mpath_name)
    else:
        logging.info("Not all paths are running for %s, set "
                     "them to running." % mpath_name)
        set_multipath_disks_status(multi_disks, "running")
    error_context.context(
        "Delete lvm on multipath disks on host "
        "before testing.", logging.info)
    delete_lvm_on_multipath(mpath_name)
    error_context.context("Delete partitions on host before testing.",
                          logging.info)
    clean_partition_on_host(mpath_name)
    vm = env.get_vm(params["main_vm"])
    try:
        if params.get("need_install") == "yes":
            error_context.context("Install guest on passthrough disk:",
                                  logging.info)
            args = (test, params, env)
            bg = utils_misc.InterruptedThread(
                utils_test.run_virt_sub_test, args,
                {"sub_type": "unattended_install"})
            bg.start()
            utils_misc.wait_for(bg.is_alive, timeout=10)
            time.sleep(random.uniform(60, 180))
        else:
            vm.create(params=params)
            session = vm.wait_for_login(
                timeout=int(params.get("timeout", 240)))
            fio_multipath = generate_instance(params, vm, 'fio')
            image_size_stg = params["image_size_stg"]
            image_num_stg = int(params["image_num_stg"])
            os_type = params["os_type"]
    except Exception as e:
        test.error("failed to create VM: %s" % six.text_type(e))
    try:
        error_context.context("Make sure guest is running before test",
                              logging.info)
        if vm.is_paused():
            vm.resume()
        vm.verify_status("running")
        if "fio_multipath" in locals().keys():
            if os_type == "windows":
                error_context.context(
                    "Get windows disk index that to "
                    "be formatted", logging.info)
                disks = _get_windows_disks_index(session, image_size_stg)
                if len(disks) != image_num_stg:
                    test.fail(
                        "Failed to list all disks by image size. The expected "
                        "is %s, actual is %s" % (image_num_stg, len(disks)))
                error_context.context(
                    "Clear readonly for all disks and online "
                    "them in windows guest.", logging.info)
                if not utils_disk.update_windows_disk_attributes(
                        session, disks):
                    test.fail("Failed to update windows disk attributes.")
            else:
                error_context.context("Get linux disk that to be "
                                      "formatted", logging.info)
                disks = sorted(utils_disk.get_linux_disks(session).keys())
                if len(disks) != image_num_stg:
                    test.fail(
                        "Failed to list all disks by image size. The expected "
                        "is %s, actual is %s" % (image_num_stg, len(disks)))
            file_system = [_.strip() for _ in params["file_system"].split()]
            labeltype = params.get("labeltype", "gpt")
            for n, disk in enumerate(disks):
                error_context.context("Format disk in guest: '%s'" % disk,
                                      logging.info)
                # Random select one file system from file_system
                index = random.randint(0, (len(file_system) - 1))
                fstype = file_system[index].strip()
                partitions = utils_disk.configure_empty_disk(
                    session,
                    disk,
                    image_size_stg,
                    os_type,
                    fstype=fstype,
                    labeltype=labeltype)
                if not partitions:
                    test.fail("Fail to format disks.")
            fio_file_name = params["fio_file_name"] % partitions[0]
            # fio_thread = _run_fio_background(fio_file_name)
            _run_fio_background(session, fio_file_name)
        # disk = random.sample(multi_disks, 1)
        for disk in multi_disks:
            error_context.context(
                "Disable disk %s during guest running" % disk, logging.info)
            set_multipath_disks_status([disk], "offline")
            time.sleep(wait_time * 15)
            if vm.is_paused():
                logging.info("vm is paused, will resume it.")
                if not resume_vm(vm, repeat_times):
                    test.fail("Failed to resume guest after disable one disk")
                logging.info("Has resumed vm already. Then verify it running.")
                if not utils_misc.wait_for(
                        lambda: check_vm_status(vm, "running"), 60):
                    test.fail("Guest is not running after disable one disk")
            error_context.context("Enable disk %s during guest running" % disk,
                                  logging.info)
            set_multipath_disks_status([disk], "running")
            time.sleep(wait_time * 15)
        error_context.context(
            "Disable multipath '%s' during guest "
            "running." % mpath_name, logging.info)
        set_multipath_disks_status(multi_disks, "offline")
        time.sleep(wait_time * 15)
        error_context.context("Check if VM status is 'paused'", logging.info)
        if not utils_misc.wait_for(lambda: check_vm_status(vm, "paused"), 120):
            test.fail("Guest is not paused after all disks offline")
        error_context.context(
            "Re-connect fc storage, wait until the "
            "storage is accessible again", logging.info)
        set_multipath_disks_status(multi_disks, "running")
        time.sleep(wait_time * 15)
        error_context.context("vm is paused, resume it.", logging.info)
        if not resume_vm(vm, repeat_times):
            test.fail("Failed to resume guest after enable multipath.")
        logging.info("Has resumed vm already. Then verify it running.")
        time.sleep(wait_time * 15)
        error_context.context("Check if VM status is 'running'", logging.info)
        if not utils_misc.wait_for(lambda: check_vm_status(vm, "running"),
                                   120):
            test.fail("Guest is not running after all disks online")
        if "bg" in locals().keys() and bg.is_alive and not vm.is_paused():
            bg.join()
        # wq comment ,why need wait fio
        # if "fio_thread" in locals().keys() and fio_thread.is_alive \
        #         and not vm.is_paused():
        #     fio_thread.join()
        error_context.context(
            "Verify Host and guest kernel no error "
            "and call trace", logging.info)
        vm.verify_kernel_crash()
    # except Exception as e:
    #     logging.error(e)
    finally:
        logging.info("Finally, clean environment.")
예제 #17
0
def _transfer_data(session, host_cmd, guest_cmd, timeout, sender):
    """
    Send transfer data command and check result via output

    :param session: guest session
    :param host_cmd: host script command
    :param guest_cmd: guest script command
    :param timeout: timeout for data transfer
    :param sender: who send data file
    :return: True if pass, False and error message if check fail
    """
    md5_host = "1"
    md5_guest = "2"

    def check_output(sender, output):
        if sender == "both":
            if "Md5MissMatch" in output:
                err = "Data lost during file transfer. Md5 miss match."
                err += " Script output:\n%s" % output
                return False, err
            return True, 0
        else:
            md5_re = "md5_sum = (\\w{32})"
            try:
                md5 = re.findall(md5_re, output)[0]
            except Exception:
                err = "Fail to get md5, script may fail."
                err += " Script output:\n%s" % output
                return False, err
            return True, md5

    try:
        kwargs = {'cmd': host_cmd,
                  'shell': True,
                  'timeout': timeout}
        error_context.context("Send host command: %s"
                              % host_cmd, logging.info)
        host_thread = utils_misc.InterruptedThread(process.getoutput,
                                                   kwargs=kwargs)
        host_thread.start()
        time.sleep(3)
        g_output = session.cmd_output(guest_cmd, timeout=timeout)
        result = check_output(sender, g_output)
        if result[0] is False:
            return result
        else:
            md5_guest = result[1]
    finally:
        if host_thread:
            output = host_thread.join(10)
            result = check_output(sender, output)
            if result[0] is False:
                return result
            else:
                md5_host = result[1]
        if sender != "both" and md5_host != md5_guest:
            err = "Data lost during file transfer. Md5 miss match."
            err += " Guest script output:\n %s" % g_output
            err += " Host script output:\n%s" % output
            return False, err
    return True
예제 #18
0
def run(test, params, env):
    """
    Test Step:
        1. boot up three virtual machine
        2. transfer file from guest1 to guest2, check md5
        3. in guest 3 try to capture the packets(guest1 <-> guest2)
    Params:
        :param test: QEMU test object
        :param params: Dictionary with the test parameters
        :param env: Dictionary with test environment.
    """
    def _is_process_finished(session, process_name):
        """
        Check whether the target process is finished running
        param session: a guest session to send command
        param process_name: the target process name

        return: True if process does not exists,
                False if still exists
        """
        check_proc_cmd = check_proc_temp % process_name
        status, output = session.cmd_status_output(check_proc_cmd)
        if status:
            return False
        return process_name not in output

    def data_mon(session, cmd, timeout):
        try:
            session.cmd(cmd, timeout)
        except ShellCmdError as e:
            if re.findall(catch_date % (addresses[1], addresses[0]), str(e)):
                test.fail("God! Capture the transfet data:'%s'" % str(e))
            logging.info("Guest3 catch data is '%s'", str(e))

    timeout = int(params.get("login_timeout", '360'))
    password = params.get("password")
    username = params.get("username")
    shell_port = params.get("shell_port")
    tmp_dir = params.get("tmp_dir", "/tmp/")
    clean_cmd = params.get("clean_cmd", "rm -f")
    filesize = int(params.get("filesize", '100'))

    wireshark_name = params.get("wireshark_name")
    check_proc_temp = params.get("check_proc_temp")
    tcpdump_cmd = params.get("tcpdump_cmd")
    dd_cmd = params.get("dd_cmd")
    catch_date = params.get("catch_data", "%s.* > %s.ssh")
    md5_check = params.get("md5_check", "md5sum %s")
    mon_process_timeout = int(params.get("mon_process_timeout", "1200"))
    sessions = []
    addresses = []
    vms = []

    error_context.context("Init boot the vms")
    for vm_name in params.get("vms", "vm1 vm2 vm3").split():
        vms.append(env.get_vm(vm_name))
    for vm in vms:
        vm.verify_alive()
        sessions.append(vm.wait_for_login(timeout=timeout))
        addresses.append(vm.get_address())
    mon_session = vms[2].wait_for_login(timeout=timeout)
    mon_macaddr = vms[2].get_mac_address()

    src_file = (tmp_dir + "src-%s" % utils_misc.generate_random_string(8))
    dst_file = (tmp_dir + "dst-%s" % utils_misc.generate_random_string(8))

    try:
        # Before transfer, run tcpdump to try to catche data
        error_msg = "In guest3, try to capture the packets(guest1 <-> guest2)"
        error_context.context(error_msg, logging.info)
        if params.get("os_type") == "linux":
            if_func = utils_net.get_linux_ifname
            args = (mon_session, mon_macaddr)
        else:
            if_func = utils_net.get_windows_nic_attribute
            args = (mon_session, "macaddress", mon_macaddr, "netconnectionid")
            error_context.context("Install wireshark", logging.info)
            install_wireshark_cmd = params.get("install_wireshark_cmd")
            install_wireshark_cmd = utils_misc.set_winutils_letter(
                sessions[2], install_wireshark_cmd)
            status, output = sessions[2].cmd_status_output(
                install_wireshark_cmd, timeout=timeout)
            if status:
                test.error(
                    "Failed to install wireshark, status=%s, output=%s" %
                    (status, output))
            logging.info("Wait for wireshark installation to complete")
            utils_misc.wait_for(
                lambda: _is_process_finished(sessions[2], wireshark_name),
                timeout, 20, 3)
            logging.info("Wireshark is already installed")
        interface_name = if_func(*args)
        tcpdump_cmd = tcpdump_cmd % (addresses[1], addresses[0],
                                     interface_name)
        dthread = utils_misc.InterruptedThread(
            data_mon, (sessions[2], tcpdump_cmd, mon_process_timeout))

        logging.info("Tcpdump mon start ...")
        logging.info("Creating %dMB file on guest1", filesize)
        sessions[0].cmd(dd_cmd % (src_file, filesize), timeout=timeout)
        dthread.start()

        error_context.context("Transferring file guest1 -> guest2",
                              logging.info)
        if params.get("os_type") == "windows":
            cp_cmd = params["copy_cmd"]
            cp_cmd = cp_cmd % (addresses[1], params['file_transfer_port'],
                               src_file, dst_file)
            sessions[0].cmd_output(cp_cmd)
        else:
            remote.scp_between_remotes(addresses[0], addresses[1], shell_port,
                                       password, password, username, username,
                                       src_file, dst_file)

        error_context.context("Check the src and dst file is same",
                              logging.info)
        src_md5 = sessions[0].cmd_output(md5_check % src_file).split()[0]
        dst_md5 = sessions[1].cmd_output(md5_check % dst_file).split()[0]

        if dst_md5 != src_md5:
            debug_msg = "Files md5sum mismatch!"
            debug_msg += "source file md5 is '%s', after transfer md5 is '%s'"
            test.fail(debug_msg % (src_md5, dst_md5), logging.info)
        logging.info("Files md5sum match, file md5 is '%s'", src_md5)

        error_context.context("Checking network private", logging.info)
        tcpdump_check_cmd = params["tcpdump_check_cmd"]
        tcpdump_kill_cmd = params["tcpdump_kill_cmd"]
        tcpdump_check_cmd = re.sub("ADDR0", addresses[0], tcpdump_check_cmd)
        tcpdump_check_cmd = re.sub("ADDR1", addresses[1], tcpdump_check_cmd)
        status = mon_session.cmd_status(tcpdump_check_cmd)
        if status:
            test.error("Tcpdump process terminate exceptly")
        mon_session.cmd(tcpdump_kill_cmd)
        dthread.join()

    finally:
        sessions[0].cmd(" %s %s " % (clean_cmd, src_file))
        sessions[1].cmd(" %s %s " % (clean_cmd, src_file))
        if mon_session:
            mon_session.close()
        for session in sessions:
            if session:
                session.close()
예제 #19
0
def run(test, params, env):
    """
    Qemu host nic bonding test:
    1) Load bonding module with mode 802.3ad
    2) Bring up bond interface
    3) Add nics to bond interface
    4) Add a new bridge and add bond interface to it
    5) Get ip address for bridge
    6) Boot up guest with the bridge
    7) Checking guest netowrk via ping
    8) Start file transfer between guest and host
    9) Disable and enable physical interfaces during file transfer

    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    bond_iface = params.get("bond_iface", "bond0")
    bond_br_name = params.get("bond_br_name", "br_bond0")
    timeout = int(params.get("login_timeout", 240))
    remote_host = params.get("dsthost")
    ping_timeout = int(params.get("ping_timeout", 240))
    bonding_timeout = int(params.get("bonding_timeout", 1))
    bonding_mode = params.get("bonding_mode", "1")
    bonding_miimon = params.get("bonding_miimon", "100")
    params['netdst'] = bond_br_name
    host_bridges = utils_net.Bridge()

    error_context.context("Load bonding module with mode 802.3ad",
                          logging.info)
    if not process.system("lsmod|grep bonding", ignore_status=True,
                          shell=True):
        process.system("modprobe -r bonding")

    process.system(
        "modprobe bonding mode=%s miimon=%s" %
        (bonding_mode, bonding_miimon))

    error_context.context("Bring up %s" % bond_iface, logging.info)
    host_ifaces = utils_net.get_host_iface()

    if bond_iface not in host_ifaces:
        test.error("Can not find bond0 in host")

    bond_iface = utils_net.Interface(bond_iface)
    bond_iface.up()
    bond_mac = bond_iface.get_mac()

    host_ph_iface_pre = params.get("host_ph_iface_prefix", "en")
    host_iface_bonding = int(params.get("host_iface_bonding", 2))

    ph_ifaces = [_ for _ in host_ifaces if re.match(host_ph_iface_pre, _)]
    host_ph_ifaces = [_ for _ in ph_ifaces if utils_net.Interface(_).is_up()]

    ifaces_in_use = host_bridges.list_iface()
    host_ph_ifaces_un = list(set(host_ph_ifaces) - set(ifaces_in_use))

    if (len(host_ph_ifaces_un) < 2 or
            len(host_ph_ifaces_un) < host_iface_bonding):
        test.cancel("Host need %s nics at least." % host_iface_bonding)

    error_context.context("Add nics to %s" % bond_iface.name, logging.info)
    host_ifaces_bonding = host_ph_ifaces_un[:host_iface_bonding]
    ifenslave_cmd = "ifenslave %s" % bond_iface.name
    op_ifaces = []
    for host_iface_bonding in host_ifaces_bonding:
        op_ifaces.append(utils_net.Interface(host_iface_bonding))
        ifenslave_cmd += " %s" % host_iface_bonding
    process.system(ifenslave_cmd)

    error_context.context("Add a new bridge and add %s to it."
                          % bond_iface.name, logging.info)
    if bond_br_name not in host_bridges.list_br():
        host_bridges.add_bridge(bond_br_name)
    host_bridges.add_port(bond_br_name, bond_iface.name)

    error_context.context("Get ip address for bridge", logging.info)
    process.system("dhclient -r; dhclient %s" % bond_br_name, shell=True)

    error_context.context("Boot up guest with bridge %s" % bond_br_name,
                          logging.info)
    params["start_vm"] = "yes"
    vm_name = params.get("main_vm")
    env_process.preprocess_vm(test, params, env, vm_name)
    vm = env.get_vm(vm_name)
    session = vm.wait_for_login(timeout=timeout)

    error_context.context("Checking guest netowrk via ping.", logging.info)
    ping_cmd = params.get("ping_cmd")
    ping_cmd = re.sub("REMOTE_HOST", remote_host, ping_cmd)
    session.cmd(ping_cmd, timeout=ping_timeout)

    error_context.context("Start file transfer", logging.info)
    f_transfer = utils_misc.InterruptedThread(
        utils_test.run_virt_sub_test,
        args=(test, params, env,),
        kwargs={"sub_type": "file_transfer"})
    f_transfer.start()
    utils_misc.wait_for(
        lambda: process.system_output("pidof scp", ignore_status=True), 30)

    error_context.context("Disable and enable physical "
                          "interfaces in %s" % bond_br_name, logging.info)
    while True:
        for op_iface in op_ifaces:
            logging.debug("Turn down %s" % op_iface.name)
            op_iface.down()
            time.sleep(bonding_timeout)
            logging.debug("Bring up %s" % op_iface.name)
            op_iface.up()
            time.sleep(bonding_timeout)
        if not f_transfer.is_alive():
            break
    f_transfer.join()
예제 #20
0
def run(test, params, env):
    """
    Test nic driver load/unload.

    1) Boot a VM.
    2) Get the NIC driver name.
    3) Multi-session TCP transfer on test interface.
    4) Repeatedly unload/load NIC driver during file transfer.
    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.
    """
    def reset_guest_udevrules(session, rules_file, rules_content):
        """
        Write guest udev rules, then reboot the guest and
        return the new session
        """
        set_cmd = "echo '%s' > %s" % (rules_content, rules_file)
        session.cmd_output_safe(set_cmd)
        return vm.reboot()

    def all_threads_done(threads):
        """
        Check whether all threads have finished
        """
        for thread in threads:
            if thread.is_alive():
                return False
            else:
                continue
        return True

    def all_threads_alive(threads):
        """
        Check whether all threads is alive
        """
        for thread in threads:
            if not thread.is_alive():
                return False
            else:
                continue
        return True

    timeout = int(params.get("login_timeout", 360))
    transfer_timeout = int(params.get("transfer_timeout", 1000))
    filesize = int(params.get("filesize", 512))

    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session = vm.wait_for_login(timeout=timeout)
    vm_mac_address = vm.get_mac_address()
    udev_rules_file = "/etc/udev/rules.d/70-persistent-net.rules"
    rules = params.get("rules")
    if not session.cmd_status("[ -e %s ]" % udev_rules_file):
        if not rules:
            test.cancel("You must set udev rules before test")
        rules = rules % vm_mac_address
        session = reset_guest_udevrules(session, udev_rules_file, rules)

    error_context.base_context("Test env prepare")
    error_context.context("Get NIC interface name in guest.", logging.info)
    ethname = utils_net.get_linux_ifname(session, 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.cmd("%s %s" % (readlink_cmd, sys_path)).strip())
    logging.info("The guest interface %s using driver %s", ethname, driver)

    error_context.context(
        "Host test file prepare, create %dMB file on host" % filesize,
        logging.info)
    tmp_dir = data_dir.get_tmp_dir()
    host_path = os.path.join(
        tmp_dir, "host_file_%s" % utils_misc.generate_random_string(8))
    guest_path = os.path.join(
        "/home", "guest_file_%s" % utils_misc.generate_random_string(8))
    cmd = "dd if=/dev/zero of=%s bs=1M count=%d" % (host_path, filesize)
    process.run(cmd)
    file_checksum = crypto.hash_file(host_path, algorithm="md5")

    error_context.context(
        "Guest test file prepare, Copy file %s from host to "
        "guest" % host_path, logging.info)
    vm.copy_files_to(host_path, guest_path, timeout=transfer_timeout)
    if session.cmd_status("md5sum %s | grep %s" % (guest_path, file_checksum)):
        test.cancel("File MD5SUMs changed after copy to guest")
    logging.info("Test env prepare successfully")

    error_context.base_context("Nic driver load/unload testing", logging.info)
    session_serial = vm.wait_for_serial_login(timeout=timeout)
    try:
        error_context.context("Transfer file between host and guest",
                              logging.info)
        threads = []
        file_paths = []
        host_file_paths = []
        for sess_index in range(int(params.get("sessions_num", "10"))):
            sess_path = os.path.join("/home", "dst-%s" % sess_index)
            host_sess_path = os.path.join(tmp_dir, "dst-%s" % sess_index)

            thread1 = utils_misc.InterruptedThread(
                vm.copy_files_to, (host_path, sess_path),
                {"timeout": transfer_timeout})

            thread2 = utils_misc.InterruptedThread(
                vm.copy_files_from, (guest_path, host_sess_path),
                {"timeout": transfer_timeout})
            thread1.start()
            threads.append(thread1)
            thread2.start()
            threads.append(thread2)
            file_paths.append(sess_path)
            host_file_paths.append(host_sess_path)

        utils_misc.wait_for(lambda: all_threads_alive(threads), 60, 10, 1)

        time.sleep(5)
        error_context.context(
            "Repeatedly unload/load NIC driver during file "
            "transfer", logging.info)
        while not all_threads_done(threads):
            error_context.context("Shutdown the driver for NIC interface.",
                                  logging.info)
            session_serial.cmd_output_safe("ifconfig %s down" % ethname)
            error_context.context("Unload  NIC driver.", logging.info)
            session_serial.cmd_output_safe("modprobe -r %s" % driver)
            error_context.context("Load NIC driver.", logging.info)
            session_serial.cmd_output_safe("modprobe %s" % driver)
            error_context.context("Activate NIC driver.", logging.info)
            session_serial.cmd_output_safe("ifconfig %s up" % ethname)
            session_serial.cmd_output_safe("sleep %s" % random.randint(10, 60))

        # files md5sums check
        error_context.context("File transfer finished, checking files md5sums",
                              logging.info)
        err_info = []
        for copied_file in file_paths:
            if session_serial.cmd_status("md5sum %s | grep %s" %
                                         (copied_file, file_checksum)):
                err_msg = "Guest file %s md5sum changed"
                err_info.append(err_msg % copied_file)
        for copied_file in host_file_paths:
            if process.system("md5sum %s | grep %s" %
                              (copied_file, file_checksum),
                              shell=True):
                err_msg = "Host file %s md5sum changed"
                err_info.append(err_msg % copied_file)
        if err_info:
            test.error("files MD5SUMs changed after copying %s" % err_info)
    except Exception:
        for thread in threads:
            thread.join(suppress_exception=True)
            raise
    else:
        for thread in threads:
            thread.join()
        for copied_file in file_paths:
            session_serial.cmd("rm -rf %s" % copied_file)
        for copied_file in host_file_paths:
            process.system("rm -rf %s" % copied_file)
        session_serial.cmd("%s %s" % ("rm -rf", guest_path))
        os.remove(host_path)
        session.close()
        session_serial.close()
예제 #21
0
def run(test, params, env):
    """
    KVM guest stop test:
    1) Log into a guest
    2) Copy a file into guest
    3) Stop guest
    4) Check the status through monitor
    5) Check the session
    6) Migrat the vm to a file twice and compare them.

    :param test: kvm test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    timeout = float(params.get("login_timeout", 240))
    session = vm.wait_for_login(timeout=timeout)

    save_path = params.get("save_path", "/tmp")
    clean_save = params.get("clean_save") == "yes"
    save1 = os.path.join(save_path, "save1")
    save2 = os.path.join(save_path, "save2")

    guest_path = params.get("guest_path", "/tmp")
    file_size = params.get("file_size", "1000")

    try:
        process.run("dd if=/dev/zero of=/tmp/file bs=1M count=%s" % file_size)
        # Transfer file from host to guest, we didn't expect the finish of
        # transfer, we just let it to be a kind of stress in guest.
        bg = utils_misc.InterruptedThread(vm.copy_files_to,
                                          ("/tmp/file", guest_path),
                                          dict(verbose=True, timeout=60))
        test.log.info("Start the background transfer")
        bg.start()

        try:
            # wait for the transfer start
            time.sleep(5)
            test.log.info("Stop the VM")
            vm.pause()

            # check with monitor
            test.log.info("Check the status through monitor")
            if not vm.monitor.verify_status("paused"):
                status = str(vm.monitor.info("status"))
                test.fail("Guest did not pause after sending stop,"
                          " guest status is %s" % status)

            # check through session
            test.log.info("Check the session")
            if session.is_responsive():
                test.fail("Session still alive after sending stop")

            # Check with the migration file
            test.log.info("Save and check the state files")
            for p in [save1, save2]:
                vm.save_to_file(p)
                time.sleep(1)
                if not os.path.isfile(p):
                    test.fail("VM failed to save state file %s" % p)

            # Fail if we see deltas
            md5_save1 = crypto.hash_file(save1)
            md5_save2 = crypto.hash_file(save2)
            if md5_save1 != md5_save2:
                test.fail("The produced state files differ")
        finally:
            bg.join(suppress_exception=True)

    finally:
        session.close()
        if clean_save:
            test.log.debug("Clean the state files")
            if os.path.isfile(save1):
                os.remove(save1)
            if os.path.isfile(save2):
                os.remove(save2)
        vm.resume()
예제 #22
0
def run(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
    4) Run netperf on guest
    5) check vhost threads on host, if vhost is enable
    6) check cpu affinity if smp == queues

    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    def get_virtio_queues_irq(session):
        """
        Return multi queues input irq list
        """
        guest_irq_info = session.cmd_output("cat /proc/interrupts")
        virtio_queues_irq = re.findall(r"(\d+):.*virtio\d+-input.\d", guest_irq_info)
        if not virtio_queues_irq:
            test.error('Could not find any "virtio-input" interrupts')
        return virtio_queues_irq

    def get_cpu_affinity_hint(session, irq_number):
        """
        Return the cpu affinity_hint of irq_number
        """
        cmd_get_cpu_affinity = r"cat /proc/irq/%s/affinity_hint" % irq_number
        return session.cmd_output(cmd_get_cpu_affinity).strip()

    def get_cpu_index(cpu_id):
        """
        Transfer cpu_id to cpu index
        """
        cpu_used_index = []
        for cpu_index in range(int(vm.cpuinfo.smp)):
            if int(cpu_id) & (1 << cpu_index) != 0:
                cpu_used_index.append(cpu_index)
        return cpu_used_index

    def set_cpu_affinity(session):
        """
        Set cpu affinity
        """
        cmd_set_cpu_affinity = r"echo $(cat /proc/irq/%s/affinity_hint)"
        cmd_set_cpu_affinity += " > /proc/irq/%s/smp_affinity"
        irq_list = get_virtio_queues_irq(session)
        for irq in irq_list:
            session.cmd(cmd_set_cpu_affinity % (irq, irq))

    def get_cpu_irq_statistics(session, irq_number, cpu_id=None):
        """
        Get guest interrupts statistics
        """
        online_cpu_number_cmd = r"cat /proc/interrupts | head -n 1 | wc -w"
        cmd = r"cat /proc/interrupts | sed -n '/^\s*%s:/p'" % irq_number
        online_cpu_number = int(session.cmd_output_safe(online_cpu_number_cmd))
        irq_statics = session.cmd_output(cmd)
        irq_statics_list = list(map(int, irq_statics.split()[1:online_cpu_number]))
        if irq_statics_list:
            if cpu_id and cpu_id < len(irq_statics_list):
                return irq_statics_list[cpu_id]
            if not cpu_id:
                return irq_statics_list
        return []

    login_timeout = int(params.get("login_timeout", 360))
    bg_stress_run_flag = params.get("bg_stress_run_flag")
    stress_thread = None
    queues = int(params.get("queues", 1))
    vms = params.get("vms").split()
    if queues == 1:
        test.log.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(i))
                session.cmd_output("ethtool -L %s combined %d" % (ifname,
                                                                  queues))
                o = session.cmd_output("ethtool -l %s" % ifname)
                if len(re.findall(r"Combined:\s+%d\s" % queues, o)) != 2:
                    test.error("Fail to enable MQ feature of (%s)" %
                               nic.nic_name)
                test.log.info("MQ feature of (%s) is enabled", nic.nic_name)

        taskset_cpu = params.get("netperf_taskset_cpu")
        if taskset_cpu:
            taskset_cmd = "taskset -c %s " % " ".join(taskset_cpu)
            params["netperf_cmd_prefix"] = taskset_cmd

        check_cpu_affinity = params.get("check_cpu_affinity", 'no')
        check_vhost = params.get("check_vhost_threads", 'yes')
        if check_cpu_affinity == 'yes' and (vm.cpuinfo.smp == queues):
            process.system("systemctl stop irqbalance.service")
            session.cmd("systemctl stop irqbalance.service")
            set_cpu_affinity(session)

        bg_sub_test = params.get("bg_sub_test")
        n_instance = int(params.get("netperf_para_sessions", queues))
        try:
            if bg_sub_test:
                error_context.context("Run test %s background" % bg_sub_test,
                                      test.log.info)

                # Set flag, when the sub test really running, will change this
                # flag to True
                stress_thread = utils_misc.InterruptedThread(
                    utils_test.run_virt_sub_test, (test, params, env),
                    {"sub_type": bg_sub_test})
                stress_thread.start()

            if params.get("vhost") == 'vhost=on' and check_vhost == 'yes':
                vhost_thread_pattern = params.get("vhost_thread_pattern",
                                                  r"\w+\s+(\d+)\s.*\[vhost-%s\]")
                vhost_threads = vm.get_vhost_threads(vhost_thread_pattern)
                time.sleep(120)
                error_context.context("Check vhost threads on host",
                                      test.log.info)
                top_cmd = (r'top -n 1 -bis | tail -n +7 | grep -E "^ *%s "'
                           % ' |^ *'.join(map(str, vhost_threads)))
                top_info = None
                while session.cmd_status("ps -C netperf") == 0:
                    top_info = process.system_output(top_cmd, ignore_status=True,
                                                     shell=True).decode()
                    if top_info:
                        break
                test.log.info(top_info)
                vhost_re = re.compile(r"(0:00.\d{2}).*vhost-\d+[\d|+]")
                invalid_vhost_thread = len(vhost_re.findall(top_info, re.I))
                running_threads = (len(top_info.splitlines()) -
                                   int(invalid_vhost_thread))

                n_instance = min(n_instance, int(queues), int(vm.cpuinfo.smp))
                if running_threads != n_instance:
                    err_msg = "Run %s netperf session, but %s queues works"
                    test.fail(err_msg % (n_instance, running_threads))

            # check cpu affinity
            if check_cpu_affinity == 'yes' and (vm.cpuinfo.smp == queues):
                error_context.context("Check cpu affinity", test.log.info)
                vectors = params.get("vectors", None)
                enable_msix_vectors = params.get("enable_msix_vectors")
                expect_vectors = 2 * int(queues) + 2
                if (not vectors) and (enable_msix_vectors == "yes"):
                    vectors = expect_vectors
                if vectors and (vectors >= expect_vectors) and taskset_cpu:
                    cpu_irq_affinity = {}
                    for irq in get_virtio_queues_irq(session):
                        cpu_id = get_cpu_affinity_hint(session, irq)
                        cpu_index = get_cpu_index(cpu_id)
                        if cpu_index:
                            for cpu in cpu_index:
                                cpu_irq_affinity["%s" % cpu] = irq
                        else:
                            test.error("Can not get the cpu")

                    irq_number = cpu_irq_affinity[taskset_cpu]
                    irq_ori = get_cpu_irq_statistics(session, irq_number)
                    test.log.info("Cpu irq info: %s", irq_ori)
                    time.sleep(10)
                    irq_cur = get_cpu_irq_statistics(session, irq_number)
                    test.log.info("After 10s, cpu irq info: %s", irq_cur)

                    irq_change_list = [x[0] - x[1] for x in zip(irq_cur, irq_ori)]
                    cpu_affinity = irq_change_list.index(max(irq_change_list))
                    if cpu_affinity != int(taskset_cpu):
                        err_msg = "Error, taskset on cpu %s, "
                        err_msg += "but queues use cpu %s"
                        test.fail(err_msg % (taskset_cpu, cpu_affinity))
            if bg_sub_test and stress_thread:
                env[bg_stress_run_flag] = False
                try:
                    stress_thread.join()
                except Exception as e:
                    err_msg = "Run %s test background error!\n "
                    err_msg += "Error Info: '%s'"
                    test.error(err_msg % (bg_sub_test, e))
        finally:
            if session:
                session.close()
            if check_cpu_affinity == 'yes' and (vm.cpuinfo.smp == queues):
                process.system("systemctl start irqbalance.service")
예제 #23
0
def run(test, params, env):
    """
    Test Steps:

    1. boot up guest with sndbuf=1048576 or other value.
    2. Transfer file between host and guest.
    3. Run netperf between host and guest.
    4. During netperf testing, from an external host ping the host whitch
       booting the guest.

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

    dst_ses = None
    try:
        error_context.context("Transfer file between host and guest",
                              test.log.info)
        utils_test.run_file_transfer(test, params, env)

        dsthost = params.get("dsthost")
        login_timeout = int(params.get("login_timeout", 360))
        if dsthost:
            params_host = params.object_params("dsthost")
            dst_ses = remote.wait_for_login(params_host.get("shell_client"),
                                            dsthost,
                                            params_host.get("shell_port"),
                                            params_host.get("username"),
                                            params_host.get("password"),
                                            params_host.get("shell_prompt"),
                                            timeout=login_timeout)
        else:
            vm = env.get_vm(params["main_vm"])
            vm.verify_alive()
            dst_ses = vm.wait_for_login(timeout=login_timeout)
            dsthost = vm.get_address()

        bg_stress_test = params.get("background_stress_test", 'netperf_stress')
        error_context.context(
            ("Run subtest %s between host and guest." % bg_stress_test),
            test.log.info)

        wait_time = float(params.get("wait_bg_time", 60))
        bg_stress_run_flag = params.get("bg_stress_run_flag")
        env[bg_stress_run_flag] = False
        stress_thread = utils_misc.InterruptedThread(
            utils_test.run_virt_sub_test, (test, params, env),
            {"sub_type": bg_stress_test})
        stress_thread.start()
        if not utils_misc.wait_for(lambda: env.get(bg_stress_run_flag),
                                   wait_time, 0, 1,
                                   "Wait %s test start" % bg_stress_test):
            err = "Fail to start netperf test between guest and host"
            test.error(err)

        ping_timeout = int(params.get("ping_timeout", 60))
        host_ip = utils_net.get_host_ip_address(params)
        txt = "Ping %s from %s during netperf testing" % (host_ip, dsthost)
        error_context.context(txt, test.log.info)
        status, output = utils_test.ping(host_ip,
                                         session=dst_ses,
                                         timeout=ping_timeout)
        if status != 0:
            test.fail("Ping returns non-zero value %s" % output)

        package_lost = utils_test.get_loss_ratio(output)
        package_lost_ratio = float(params.get("package_lost_ratio", 5))
        txt = "%s%% packeage lost when ping %s from %s." % (package_lost,
                                                            host_ip, dsthost)
        if package_lost > package_lost_ratio:
            test.fail(txt)
        test.log.info(txt)

    finally:
        try:
            stress_thread.join(60)
        except Exception:
            pass
        if dst_ses:
            dst_ses.close()
예제 #24
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
            test.fail(err_msg)
        if not status and cur_queues_status == queues_status:
            test.fail("params is right, but change queues failed")
        elif status and cur_queues_status != queues_status:
            test.fail("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
            test.cancel(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.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:])
            test.fail(err)

    error_context.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.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.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_misc.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.context("Ping guest from host", logging.info)
            args = (guest_ip, b_ping_time, b_ping_lost_ratio)
            bg_test = utils_misc.InterruptedThread(ping_test, args)
            bg_test.start()

        error_context.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 = range(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 range(1, repeat_counts + 1):
                error_context.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"
            ext_host = utils_net.get_host_default_gateway()
            if not ext_host:
                # Fallback to a hardcode host, eg:
                logging.warn("Can't get specified host,"
                             " Fallback to default host '%s'", default_host)
                ext_host = default_host
            s_session = vm.wait_for_login(timeout=login_timeout)
            txt = "ping %s after changing queues in guest."
            error_context.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.context("wait for background test finish",
                                      logging.info)
                try:
                    stress_thread.join()
                except Exception as err:
                    err_msg = "Run %s test background error!\n "
                    err_msg += "Error Info: '%s'"
                    test.error(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.context("Wait for background ping test finish.",
                                  logging.info)
            try:
                bg_test.join()
            except Exception as err:
                txt = "Fail to wait background ping test finish. "
                txt += "Got error message %s" % err
                test.fail(txt)
예제 #25
0
def run(test, params, env):
    """
    Qemu guest pxe boot test:
    1). check npt/ept function enable, then boot vm
    2). execute query/info cpus in loop
    3). verify vm not paused during pxe booting

    params:
    :param test: QEMU test object
    :param params: Dictionary with the test parameters
    :param env: Dictionary with test environment.
    """
    restore_mmu_cmd = None
    pxe_timeout = int(params.get("pxe_timeout", 60))

    error_context.context("Enable ept/npt", logging.info)
    try:
        flag = list(filter(lambda x: x in cpu.get_cpu_flags(),
                           ['ept', 'npt']))[0]
    except IndexError:
        logging.info("Host doesn't support ept/npt, skip the configuration")
    else:
        enable_mmu_cmd = params["enable_mmu_cmd_%s" % flag]
        check_mmu_cmd = params["check_mmu_cmd_%s" % flag]
        restore_mmu_cmd = params["restore_mmu_cmd_%s" % flag]
        status = process.system(check_mmu_cmd,
                                timeout=120,
                                ignore_status=True,
                                shell=True)
        if status != 0:
            _kill_vms(params, env)
            process.run(enable_mmu_cmd, shell=True)

    params["start_vm"] = "yes"
    params["kvm_vm"] = "yes"
    params["paused_after_start_vm"] = "yes"

    error_context.context("Try to boot from NIC", logging.info)
    env_process.preprocess_vm(test, params, env, params["main_vm"])
    vm = env.get_vm(params["main_vm"])
    bg = utils_misc.InterruptedThread(_capture_tftp, (test, vm, pxe_timeout))

    count = 0
    try:
        bg.start()
        error_context.context("Query cpus in loop", logging.info)
        vm.resume()
        while True:
            count += 1
            try:
                vm.monitor.info("cpus", debug=False)
                if params.get('machine_type').startswith("s390"):
                    if vm.monitor.get_status()['status'] in [
                            'running', 'guest-panicked'
                    ]:
                        pass
                    else:
                        raise virt_vm.VMStatusError(
                            'Unexpected VM status: "%s"' %
                            vm.monitor.get_status())
                else:
                    vm.verify_status("running")
                if not bg.is_alive():
                    break
            except qemu_monitor.MonitorSocketError:
                test.fail("Qemu looks abnormally, please read the log")
        logging.info("Execute info/query cpus %d times", count)
    finally:
        bg.join()
        if restore_mmu_cmd:
            _kill_vms(params, env)
            process.run(restore_mmu_cmd, shell=True)
예제 #26
0
def run(test, params, env):
    """
    Nic bonding test in guest.

    1) Start guest with four nic devices.
    2) Setup bond0 in guest.
    3) Execute file transfer test between guest and host.
    4) Repeatedly put down/up interfaces by 'ip link'
    5) Execute file transfer test between guest and host.
    6) Check md5 value after transfered.

    :param test: Kvm test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
    """
    tmp_dir = params["tmp_dir"]
    filesize = params.get_numeric("filesize")
    dd_cmd = params["dd_cmd"]
    login_timeout = params.get_numeric("login_timeout", 1200)
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
    ifnames = utils_net.get_linux_ifname(session_serial)

    ssh_login_cmd = ("echo LoginGraceTime 5m  >> /etc/ssh/sshd_config &&"
                     " systemctl restart sshd.service || service sshd restart")
    session_serial.cmd_output_safe(ssh_login_cmd)

    # get params of bonding
    nm_stop_cmd = "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 is already running, kill it")
        session_serial.cmd_output_safe("killall -9 dhclient")
        time.sleep(1)

    session_serial.cmd_output_safe("dhclient bond0")
    # prepare test data
    guest_path = os.path.join(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)
    process.run(dd_cmd % host_path, shell=True)

    # get_bonding_nic_mac and ip
    try:
        link_set_cmd = "ip link set dev %s %s"
        # transfer data
        original_md5 = crypto.hash_file(host_path, algorithm="md5")
        logging.info("md5 value of data original: %s", original_md5)
        logging.info("Failover test with file transfer")
        transfer_thread = utils_misc.InterruptedThread(vm.copy_files_to,
                                                       (host_path, guest_path))
        transfer_thread.start()
        try:
            while transfer_thread.is_alive():
                for ifname in ifnames:
                    session_serial.cmd(link_set_cmd % (ifname, "down"))
                    time.sleep(random.randint(1, 30))
                    session_serial.cmd(link_set_cmd % (ifname, "up"))
                    time.sleep(random.randint(1, 30))
        except aexpect.ShellProcessTerminatedError:
            transfer_thread.join(suppress_exception=True)
            raise
        else:
            transfer_thread.join()

        logging.info('Cleaning temp file on host')
        os.remove(host_path)
        logging.info("Failover test 2 with file transfer")
        transfer_thread = utils_misc.InterruptedThread(vm.copy_files_from,
                                                       (guest_path, host_path))
        transfer_thread.start()
        try:
            nic_num = len(ifnames)
            up_index = 0
            while transfer_thread.is_alive():
                nic_indexes = list(range(nic_num))
                up_index = up_index % nic_num
                session_serial.cmd(link_set_cmd % (ifnames[up_index], "up"))
                nic_indexes.remove(up_index)
                for num in nic_indexes:
                    session_serial.cmd(link_set_cmd % (ifnames[num], "down"))
                time.sleep(random.randint(3, 5))
                up_index += 1
        except aexpect.ShellProcessTerminatedError:
            transfer_thread.join(suppress_exception=True)
            raise
        else:
            transfer_thread.join()
        current_md5 = crypto.hash_file(host_path, algorithm="md5")
        logging.info("md5 value of data current: %s", current_md5)
        if original_md5 != current_md5:
            test.fail("File changed after transfer host -> guest "
                      "and guest -> host")

    finally:
        session_serial.sendline("ifenslave -d bond0 " + " ".join(ifnames))
        session_serial.sendline("kill -9 `pgrep dhclient`")
        session_serial.sendline("sed -i '$ d' /etc/ssh/sshd_config")