nicdriver_unload.py 6.9 KB
Newer Older
1
import logging, os, time, random
2
from autotest.client import utils
3
from autotest.client.shared import error
4
from virttest import utils_misc, utils_net, aexpect, data_dir
5

6
@error.context_aware
7 8
def run_nicdriver_unload(test, params, env):
    """
9
    Test nic driver load/unload.
10 11 12

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

17
    @param test: QEMU test object.
18 19 20
    @param params: Dictionary with the test parameters.
    @param env: Dictionary with test environment.
    """
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
    def send_cmd_safe(session, cmd, timeout=60):
        logging.debug("Sending command: %s", cmd)
        session.sendline(cmd)
        output = ""
        start_time = time.time()
        # Wait for shell prompt until timeout.
        while (time.time() - start_time) < timeout:
            session.sendline()
            try:
                output += session.read_up_to_prompt(0.5)
                break
            except aexpect.ExpectTimeoutError:
                pass
        return output


    def all_threads_done(threads):
        for thread in threads:
            if thread.isAlive():
                return False
            else:
                continue
        return True
44 45


46 47 48 49 50 51 52 53
    def all_threads_alive(threads):
        for thread in threads:
            if not thread.isAlive():
                return False
            else:
                continue
        return True

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

58 59
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
60
    session = vm.wait_for_login(timeout=timeout)
61

62
    error.base_context("Test env prepare")
63
    error.context("Get NIC interface name in guest.", logging.info)
64
    ethname = utils_net.get_linux_ifname(session, vm.get_mac_address(0))
65 66 67 68 69 70
    # 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")
71 72 73
    driver = os.path.basename(session.cmd("%s %s" % (readlink_cmd,
                                          sys_path)).strip())
    logging.info("The guest interface %s using driver %s" % (ethname, driver))
74

75 76 77 78 79 80 81 82 83 84
    error.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)
    utils.run(cmd)
    file_checksum = utils.hash_file(host_path, "md5")
85

86 87 88 89 90 91 92 93 94 95
    error.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)):
        raise error.TestNAError("File MD5SUMs changed after copy to guest")
    logging.info("Test env prepare successfully")

    error.base_context("Nic driver load/unload testing", logging.info)
    session_serial = vm.wait_for_serial_login(timeout=timeout)
96
    try:
97
        error.context("Transfer file between host and guest", logging.info)
98
        threads = []
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
        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.InterruptedThread(vm.copy_files_to,
                                             (host_path, sess_path),
                                             {"timeout":transfer_timeout})

            thread2 = utils.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("Repeatedly unload/load NIC driver during file transfer",
                      logging.info)
        while not all_threads_done(threads):
            error.context("Shutdown the driver for NIC interface.",
                          logging.info)
            send_cmd_safe(session_serial, "ifconfig %s down" % ethname)
128
            error.context("Unload  NIC driver.", logging.info)
129
            send_cmd_safe(session_serial, "modprobe -r %s" % driver)
130
            error.context("Load NIC driver.", logging.info)
131
            send_cmd_safe(session_serial, "modprobe %s" % driver)
132
            error.context("Activate NIC driver.", logging.info)
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
            send_cmd_safe(session_serial, "ifconfig %s up" % ethname)
            send_cmd_safe(session_serial, "sleep %s" %
                          random.randint(10, 60))
        #files md5sums check
        error.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 utils.system("md5sum %s | grep %s" %
                            (copied_file, file_checksum)):
                err_msg = "Host file %s md5sum changed"
                err_info.append(err_msg % copied_file)
        if err_info:
            raise error.TestError("files MD5SUMs changed after copying %s" %
                                  err_info)
153 154 155 156 157 158 159
    except Exception:
        for thread in threads:
            thread.join(suppress_exception=True)
            raise
    else:
        for thread in threads:
            thread.join()
160 161 162 163 164 165 166 167
        for copied_file in file_paths:
            session_serial.cmd("rm -rf %s" % copied_file)
        for copied_file in host_file_paths:
            utils.system("rm -rf %s" % copied_file)
        session_serial.cmd("%s %s" % ("rm -rf", guest_path))
        os.remove(host_path)
        session.close()
        session_serial.close()