netperf.py revision 22434d4311581dde7a3bb51eef03a27d757aa263
1import logging, os, signal
2from autotest_lib.client.common_lib import error
3from autotest_lib.client.bin import utils
4from autotest_lib.client.virt import aexpect, virt_utils
5
6def run_netperf(test, params, env):
7    """
8    Network stress test with netperf.
9
10    1) Boot up a VM with multiple nics.
11    2) Launch netserver on guest.
12    3) Execute multiple netperf clients on host in parallel
13       with different protocols.
14    4) Output the test result.
15
16    @param test: KVM test object.
17    @param params: Dictionary with the test parameters.
18    @param env: Dictionary with test environment.
19    """
20    vm = env.get_vm(params["main_vm"])
21    vm.verify_alive()
22    login_timeout = int(params.get("login_timeout", 360))
23    session = vm.wait_for_login(timeout=login_timeout)
24    session.close()
25    session_serial = vm.wait_for_serial_login(timeout=login_timeout)
26
27    netperf_dir = os.path.join(os.environ['AUTODIR'], "tests/netperf2")
28    setup_cmd = params.get("setup_cmd")
29
30    firewall_flush = "iptables -F"
31    session_serial.cmd_output(firewall_flush)
32    try:
33        utils.run("iptables -F")
34    except:
35        pass
36
37    for i in params.get("netperf_files").split():
38        vm.copy_files_to(os.path.join(netperf_dir, i), "/tmp")
39
40    try:
41        session_serial.cmd(firewall_flush)
42    except aexpect.ShellError:
43        logging.warning("Could not flush firewall rules on guest")
44
45    session_serial.cmd(setup_cmd % "/tmp", timeout=200)
46    session_serial.cmd(params.get("netserver_cmd") % "/tmp")
47
48    tcpdump = env.get("tcpdump")
49    pid = None
50    if tcpdump:
51        # Stop the background tcpdump process
52        try:
53            pid = int(utils.system_output("pidof tcpdump"))
54            logging.debug("Stopping the background tcpdump")
55            os.kill(pid, signal.SIGSTOP)
56        except:
57            pass
58
59    def netperf(i=0):
60        guest_ip = vm.get_address(i)
61        logging.info("Netperf_%s: netserver %s" % (i, guest_ip))
62        result_file = os.path.join(test.resultsdir, "output_%s_%s"
63                                   % (test.iteration, i ))
64        list_fail = []
65        result = open(result_file, "w")
66        result.write("Netperf test results\n")
67
68        for p in params.get("protocols").split():
69            packet_size = params.get("packet_size", "1500")
70            for size in packet_size.split():
71                cmd = params.get("netperf_cmd") % (netperf_dir, p,
72                                                   guest_ip, size)
73                logging.info("Netperf_%s: protocol %s" % (i, p))
74                try:
75                    netperf_output = utils.system_output(cmd,
76                                                         retain_output=True)
77                    result.write("%s\n" % netperf_output)
78                except:
79                    logging.error("Test of protocol %s failed", p)
80                    list_fail.append(p)
81
82        result.close()
83        if list_fail:
84            raise error.TestFail("Some netperf tests failed: %s" %
85                                 ", ".join(list_fail))
86
87    try:
88        logging.info("Setup and run netperf clients on host")
89        utils.run(setup_cmd % netperf_dir)
90
91        bg = []
92        nic_num = len(params.get("nics").split())
93        for i in range(nic_num):
94            bg.append(virt_utils.Thread(netperf, (i,)))
95            bg[i].start()
96
97        completed = False
98        while not completed:
99            completed = True
100            for b in bg:
101                if b.is_alive():
102                    completed = False
103    finally:
104        for b in bg:
105            if b:
106                b.join()
107        session_serial.cmd_output("killall netserver")
108        if tcpdump and pid:
109            logging.debug("Resuming the background tcpdump")
110            logging.info("pid is %s" % pid)
111            os.kill(pid, signal.SIGCONT)
112