netperf.py 23.3 KB
Newer Older
L
Lucas Meneghel Rodrigues 已提交
1 2 3 4 5 6
import logging
import os
import commands
import threading
import re
import time
7
from autotest.client import utils
L
Lucas Meneghel Rodrigues 已提交
8
from autotest.client.shared import error
9
from virttest import utils_test, utils_misc, remote, data_dir
10 11


12 13 14 15
def format_result(result, base="12", fbase="2"):
    """
    Format the result to a fixed length string.

L
Lucas Meneghel Rodrigues 已提交
16 17 18
    :param result: result need to convert
    :param base: the length of converted string
    :param fbase: the decimal digit for float
19 20 21 22 23 24 25 26 27 28 29 30 31 32
    """
    if isinstance(result, str):
        value = "%" + base + "s"
    elif isinstance(result, int):
        value = "%" + base + "d"
    elif isinstance(result, float):
        value = "%" + base + "." + fbase + "f"
    return value % result


def netperf_record(results, filter_list, header=False, base="12", fbase="2"):
    """
    Record the results in a certain format.

L
Lucas Meneghel Rodrigues 已提交
33 34
    :param results: a dict include the results for the variables
    :param filter_list: variable list which is wanted to be shown in the
35
                        record file, also fix the order of variables
L
Lucas Meneghel Rodrigues 已提交
36 37 38
    :param header: if record the variables as a column name before the results
    :param base: the length of a variable
    :param fbase: the decimal digit for float
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    """
    key_list = []
    for key in filter_list:
        if results.has_key(key):
            key_list.append(key)

    record = ""
    if header:
        for key in key_list:
            record += "%s|" % format_result(key, base=base, fbase=fbase)
        record = record.rstrip("|")
        record += "\n"
    for key in key_list:
        record += "%s|" % format_result(results[key], base=base, fbase=fbase)
    record = record.rstrip("|")
    return record, key_list


Y
Yunping Zheng 已提交
57 58 59 60 61 62 63 64 65
def start_netserver_win(session, start_cmd):
    check_reg = re.compile(r"NETSERVER.*EXE", re.I)
    if not check_reg.findall(session.cmd_output("tasklist")):
        session.sendline(start_cmd)
        if not utils_misc.wait_for(lambda: check_reg.findall(
                                   session.cmd_output("tasklist")),
                                   30, 5, 1, "Wait netserver start"):
            msg = "Can not start netserver with command %s" % start_cmd
            raise error.TestError(msg)
Y
Yiqiao Pu 已提交
66 67


68
@error.context_aware
69
def run(test, params, env):
70 71 72 73 74 75 76 77
    """
    Network stress test with netperf.

    1) Boot up VM(s), setup SSH authorization between host
       and guest(s)/external host
    2) Prepare the test environment in server/client/host
    3) Execute netperf tests, collect and analyze the results

L
Lucas Meneghel Rodrigues 已提交
78 79 80
    :param test: QEMU test object.
    :param params: Dictionary with the test parameters.
    :param env: Dictionary with test environment.
81
    """
82
    def env_setup(session, ip, user, port, password):
83
        error.context("Setup env for %s" % ip)
Y
Yunping Zheng 已提交
84
        ssh_cmd(session, "iptables -F; true")
85
        ssh_cmd(session, "service iptables stop; true")
86
        ssh_cmd(session, "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore")
87

Y
Yunping Zheng 已提交
88 89 90 91 92
        download_link = params.get("netperf_download_link")
        download_dir = data_dir.get_download_dir()
        md5sum = params.get("pkg_md5sum")
        pkg = utils.unmap_url_cache(download_dir, download_link, md5sum)
        remote.scp_to_remote(ip, shell_port, username, password, pkg, "/tmp")
93
        ssh_cmd(session, params.get("setup_cmd"))
94

L
Lucas Meneghel Rodrigues 已提交
95
        agent_path = os.path.join(test.virtdir, "scripts/netperf_agent.py")
96
        remote.scp_to_remote(ip, shell_port, username, password,
Y
Yunping Zheng 已提交
97
                             agent_path, "/tmp")
98 99 100 101 102

    def _pin_vm_threads(vm, node):
        if node:
            if not isinstance(node, utils_misc.NumaNode):
                node = utils_misc.NumaNode(int(node))
103
            utils_test.qemu.pin_vm_threads(vm, node)
104 105 106

        return node

107 108 109
    vm = env.get_vm(params["main_vm"])
    vm.verify_alive()
    login_timeout = int(params.get("login_timeout", 360))
110

111
    session = vm.wait_for_login(timeout=login_timeout)
112 113 114 115 116 117 118 119 120 121 122 123
    config_cmds = params.get("config_cmds")
    if config_cmds:
        for config_cmd in config_cmds.split(","):
            cmd = params.get(config_cmd.strip())
            if cmd:
                s, o = session.cmd_status_output(cmd)
                if s:
                    msg = "Config command %s failed. Output: %s" % (cmd, o)
                    raise error.TestError(msg)
        if params.get("reboot_after_config", "yes") == "yes":
            session = vm.reboot(session=session, timeout=login_timeout)

124 125 126 127
    if params.get("rh_perf_envsetup_script"):
        utils_test.service_setup(vm, session, test.virtdir)
    session.close()

128
    server_ip = vm.wait_for_get_address(0, timeout=5)
129 130
    server_ctl = vm.wait_for_login(timeout=login_timeout)
    server_ctl_ip = server_ip
131
    if (params.get("os_type") == "windows"
L
Lucas Meneghel Rodrigues 已提交
132
            and params.get("use_cygwin") == "yes"):
Y
Yunping Zheng 已提交
133
        cygwin_prompt = params.get("cygwin_prompt", r"\$\s+$")
Y
Yiqiao Pu 已提交
134 135 136 137 138 139 140
        cygwin_start = params.get("cygwin_start")
        server_cyg = vm.wait_for_login(timeout=login_timeout)
        server_cyg.set_prompt(cygwin_prompt)
        server_cyg.cmd_output(cygwin_start)
    else:
        server_cyg = None

141
    if len(params.get("nics", "").split()) > 1:
Y
Yunping Zheng 已提交
142
        vm.wait_for_login(nic_index=1, timeout=login_timeout)
143
        server_ctl_ip = vm.wait_for_get_address(1, timeout=5)
144

145 146 147
    logging.debug(commands.getoutput("numactl --hardware"))
    logging.debug(commands.getoutput("numactl --show"))
    # pin guest vcpus/memory/vhost threads to last numa node of host by default
148 149
    numa_node = _pin_vm_threads(vm, params.get("numa_node"))

150 151 152
    host = params.get("host", "localhost")
    host_ip = host
    if host != "localhost":
L
Lucas Meneghel Rodrigues 已提交
153
        params_host = params.object_params("host")
154 155 156 157 158 159
        host = remote.wait_for_login(params_host.get("shell_client"),
                                     host_ip,
                                     params_host.get("shell_port"),
                                     params_host.get("username"),
                                     params_host.get("password"),
                                     params_host.get("shell_prompt"))
160

161
    client = params.get("client", "localhost")
162 163
    client_ip = client
    clients = []
164 165
    # client session 1 for control, session 2 for data communication
    for i in range(2):
Y
Yiqiao Pu 已提交
166
        if client in params.get("vms"):
167
            vm_client = env.get_vm(client)
Y
Yiqiao Pu 已提交
168
            tmp = vm_client.wait_for_login(timeout=login_timeout)
169
            client_ip = vm_client.wait_for_get_address(0, timeout=5)
Y
Yiqiao Pu 已提交
170
        elif client != "localhost":
171 172 173 174 175 176
            tmp = remote.wait_for_login(params.get("shell_client_client"),
                                        client_ip,
                                        params.get("shell_port_client"),
                                        params.get("username_client"),
                                        params.get("password_client"),
                                        params.get("shell_prompt_client"))
177 178 179 180 181
        else:
            tmp = "localhost"
        clients.append(tmp)
    client = clients[0]

182 183 184
    vms_list = params["vms"].split()
    if len(vms_list) > 1:
        vm2 = env.get_vm(vms_list[-1])
185 186 187 188
        vm2.verify_alive()
        session2 = vm2.wait_for_login(timeout=login_timeout)
        if params.get("rh_perf_envsetup_script"):
            utils_test.service_setup(vm2, session2, test.virtdir)
189 190
        client = vm2.wait_for_login(timeout=login_timeout)
        client_ip = vm2.get_address()
191
        session2.close()
192
        _pin_vm_threads(vm2, numa_node)
193

194
    error.context("Prepare env of server/client/host", logging.info)
Y
Yiqiao Pu 已提交
195 196 197 198 199 200
    prepare_list = set([server_ctl, client, host])
    tag_dict = {server_ctl: "server", client: "client", host: "host"}
    ip_dict = {server_ctl: server_ctl_ip, client: client_ip, host: host_ip}
    for i in prepare_list:
        params_tmp = params.object_params(tag_dict[i])
        if params_tmp.get("os_type") == "linux":
201 202 203
            shell_port = int(params_tmp["shell_port"])
            password = params_tmp["password"]
            username = params_tmp["username"]
Y
Yiqiao Pu 已提交
204
            env_setup(i, ip_dict[i], username, shell_port, password)
205

206
    env.stop_tcpdump()
207

208
    error.context("Start netperf testing", logging.info)
209
    start_test(server_ip, server_ctl, host, clients, test.resultsdir,
210 211 212 213 214 215 216
               l=int(params.get('l')),
               sessions_rr=params.get('sessions_rr'),
               sessions=params.get('sessions'),
               sizes_rr=params.get('sizes_rr'),
               sizes=params.get('sizes'),
               protocols=params.get('protocols'),
               ver_cmd=params.get('ver_cmd', "rpm -q qemu-kvm"),
217
               netserver_port=params.get('netserver_port', "12865"),
Y
Yiqiao Pu 已提交
218
               params=params, server_cyg=server_cyg, test=test)
219 220


Y
Yiqiao Pu 已提交
221
@error.context_aware
A
Amos Kong 已提交
222
def start_test(server, server_ctl, host, clients, resultsdir, l=60,
223 224 225
               sessions_rr="50 100 250 500", sessions="1 2 4",
               sizes_rr="64 256 512 1024 2048",
               sizes="64 256 512 1024 2048 4096",
226
               protocols="TCP_STREAM TCP_MAERTS TCP_RR TCP_CRR", ver_cmd=None,
Y
Yiqiao Pu 已提交
227
               netserver_port=None, params={}, server_cyg=None, test=None):
228 229 230
    """
    Start to test with different kind of configurations

L
Lucas Meneghel Rodrigues 已提交
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
    :param server: netperf server ip for data connection
    :param server_ctl: ip to control netperf server
    :param host: localhost ip
    :param clients: netperf clients' ip
    :param resultsdir: directory to restore the results
    :param l: test duration
    :param sessions_rr: sessions number list for RR test
    :param sessions: sessions number list
    :param sizes_rr: request/response sizes (TCP_RR, UDP_RR)
    :param sizes: send size (TCP_STREAM, UDP_STREAM)
    :param protocols: test type
    :param ver_cmd: command to check kvm version
    :param netserver_port: netserver listen port
    :param params: Dictionary with the test parameters.
    :param server_cyg: shell session for cygwin in windows guest
246 247
    """

Y
Yiqiao Pu 已提交
248
    guest_ver_cmd = params.get("guest_ver_cmd", "uname -r")
249
    fd = open("%s/netperf-result.%s.RHS" % (resultsdir, time.time()), "w")
250

L
Lucas Meneghel Rodrigues 已提交
251 252 253 254 255
    test.write_test_keyval({'kvm-userspace-ver':
                            commands.getoutput(ver_cmd).strip()})
    test.write_test_keyval({'guest-kernel-ver': ssh_cmd(server_ctl,
                                                        guest_ver_cmd).strip()})
    test.write_test_keyval({'session-length': l})
256

L
Lucas Meneghel Rodrigues 已提交
257 258
    fd.write('### kvm-userspace-ver : %s\n' %
             commands.getoutput(ver_cmd).strip())
259
    fd.write('### guest-kernel-ver : %s\n' % ssh_cmd(server_ctl,
L
Lucas Meneghel Rodrigues 已提交
260 261 262
                                                     guest_ver_cmd).strip())
    fd.write('### kvm_version : %s\n' % os.uname()[2])
    fd.write('### session-length : %s\n' % l)
263 264 265

    record_list = ['size', 'sessions', 'throughput', 'trans.rate', 'CPU',
                   'thr_per_CPU', 'rx_pkts', 'tx_pkts', 'rx_byts', 'tx_byts',
Y
Yiqiao Pu 已提交
266
                   're_pkts', 'rx_intr', 'tx_intr', 'io_exit', 'irq_inj',
267 268 269 270
                   'tpkt_per_exit', 'rpkt_per_irq']
    base = params.get("format_base", "12")
    fbase = params.get("format_fbase", "2")

271
    output = ssh_cmd(host, "mpstat 1 1 |grep CPU")
Y
Yunping Zheng 已提交
272
    mpstat_head = re.findall(r"CPU\s+.*", output)[0].split()
273 274 275 276 277 278
    mpstat_key = params.get("mpstat_key", "%idle")
    if mpstat_key in mpstat_head:
        mpstat_index = mpstat_head.index(mpstat_key) + 1
    else:
        mpstat_index = 0

279
    for protocol in protocols.split():
280
        error.context("Testing %s protocol" % protocol, logging.info)
281
        if protocol in ("TCP_RR", "TCP_CRR"):
282 283
            sessions_test = sessions_rr.split()
            sizes_test = sizes_rr.split()
Y
Yiqiao Pu 已提交
284
            protocol_log = protocol
285 286 287
        else:
            sessions_test = sessions.split()
            sizes_test = sizes.split()
Y
Yiqiao Pu 已提交
288 289 290 291
            if protocol == "TCP_STREAM":
                protocol_log = protocol + " (RX)"
            elif protocol == "TCP_MAERTS":
                protocol_log = protocol + " (TX)"
L
Lucas Meneghel Rodrigues 已提交
292
        fd.write("Category:" + protocol_log + "\n")
Y
Yiqiao Pu 已提交
293

294
        record_header = True
295 296
        for i in sizes_test:
            for j in sessions_test:
297
                if protocol in ("TCP_RR", "TCP_CRR"):
Y
Yunping Zheng 已提交
298 299 300
                    nf_args = "-t %s -v 1 -- -r %s,%s" % (protocol, i, i)
                elif (protocol == "TCP_MAERTS"):
                    nf_args = "-C -c -t %s -- -m ,%s" % (protocol, i)
301
                else:
Y
Yunping Zheng 已提交
302 303 304 305
                    nf_args = "-C -c -t %s -- -m %s" % (protocol, i)

                ret = launch_client(j, server, server_ctl, host, clients, l,
                                    nf_args, netserver_port, params, server_cyg)
A
Amos Kong 已提交
306 307

                thu = float(ret['thu'])
308
                cpu = 100 - float(ret['mpstat'].split()[mpstat_index])
309
                normal = thu / cpu
310
                if ret.get('rx_pkts') and ret.get('irq_inj'):
A
Amos Kong 已提交
311
                    ret['rpkt_per_exit'] = float(
L
Lucas Meneghel Rodrigues 已提交
312
                        ret['rx_pkts']) / float(ret['irq_inj'])
313
                if ret.get('tx_pkts') and ret.get('io_exit'):
A
Amos Kong 已提交
314
                    ret['tpkt_per_irq'] = float(
L
Lucas Meneghel Rodrigues 已提交
315
                        ret['tx_pkts']) / float(ret['io_exit'])
316 317
                ret['size'] = int(i)
                ret['sessions'] = int(j)
318
                if protocol in ("TCP_RR", "TCP_CRR"):
Y
Yiqiao Pu 已提交
319 320 321
                    ret['trans.rate'] = thu
                else:
                    ret['throughput'] = thu
322 323
                ret['CPU'] = cpu
                ret['thr_per_CPU'] = normal
L
Lucas Meneghel Rodrigues 已提交
324 325 326 327
                row, key_list = netperf_record(ret, record_list,
                                               header=record_header,
                                               base=base,
                                               fbase=fbase)
328 329 330 331
                if record_header:
                    record_header = False
                    category = row.split('\n')[0]

L
Lucas Meneghel Rodrigues 已提交
332
                test.write_test_keyval({'category': category})
333 334
                prefix = '%s--%s--%s' % (protocol, i, j)
                for key in key_list:
L
Lucas Meneghel Rodrigues 已提交
335 336
                    test.write_perf_keyval(
                        {'%s--%s' % (prefix, key): ret[key]})
337

338 339 340 341
                logging.info(row)
                fd.write(row + "\n")

                fd.flush()
342 343

                kill_cmd = "killall netperf"
344
                if params.get("os_type") == "windows":
345
                    kill_cmd = "taskkill /F /IM netperf*"
346
                ssh_cmd(clients[-1], kill_cmd, ignore_status=True)
347

348
                logging.debug("Remove temporary files")
A
Amos Kong 已提交
349
                commands.getoutput("rm -f /tmp/netperf.%s.nf" % ret['pid'])
350
                logging.info("Netperf thread completed successfully")
351 352 353
    fd.close()


354
def ssh_cmd(session, cmd, timeout=120, ignore_status=False):
355 356 357
    """
    Execute remote command and return the output

L
Lucas Meneghel Rodrigues 已提交
358 359 360
    :param session: a remote shell session or tag for localhost
    :param cmd: executed command
    :param timeout: timeout for the command
361
    """
362
    if session == "localhost":
363 364
        o = utils.system_output(cmd, timeout=timeout,
                                ignore_status=ignore_status)
365
    else:
366 367
        o = session.cmd(cmd, timeout=timeout, ignore_all_errors=ignore_status)
    return o
368 369


370
@error.context_aware
A
Amos Kong 已提交
371
def launch_client(sessions, server, server_ctl, host, clients, l, nf_args,
Y
Yiqiao Pu 已提交
372
                  port, params, server_cyg):
373 374
    """ Launch netperf clients """

Y
Yunping Zheng 已提交
375 376 377
    netperf_version = params.get("netperf_version", "2.6.0")
    client_path = "/tmp/netperf-%s/src/netperf" % netperf_version
    server_path = "/tmp/netperf-%s/src/netserver" % netperf_version
Y
Yiqiao Pu 已提交
378
    # Start netserver
379
    error.context("Start Netserver on guest", logging.info)
Y
Yiqiao Pu 已提交
380 381
    if params.get("os_type") == "windows":
        timeout = float(params.get("timeout", "240"))
Y
Yunping Zheng 已提交
382 383
        cdrom_drv = utils_misc.get_winutils_vol(server_ctl)
        get_status_flag = False
384
        if params.get("use_cygwin") == "yes":
Y
Yunping Zheng 已提交
385 386
            netserv_start_cmd = params.get("netserv_start_cmd")
            netperf_src = params.get("netperf_src") % cdrom_drv
387
            cygwin_root = params.get("cygwin_root")
Y
Yunping Zheng 已提交
388
            netserver_path = params.get("netserver_path")
389
            netperf_install_cmd = params.get("netperf_install_cmd")
Y
Yunping Zheng 已提交
390 391 392
            start_session = server_cyg
            logging.info("Start netserver with cygwin, cmd is: %s" %
                         netserv_start_cmd)
393
            if "netserver" not in server_ctl.cmd_output("tasklist"):
Y
Yunping Zheng 已提交
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
                netperf_pack = "netperf-%s" % params.get("netperf_version")
                s_check_cmd = "dir %s" % netserver_path
                p_check_cmd = "dir %s" % cygwin_root
                if not ("netserver.exe" in server_ctl.cmd(s_check_cmd) and
                        netperf_pack in server_ctl.cmd(p_check_cmd)):
                    error.context("Install netserver in Windows guest cygwin",
                                  logging.info)
                    cmd = "xcopy %s %s /S /I /Y" % (netperf_src, cygwin_root)
                    server_ctl.cmd(cmd)
                    server_cyg.cmd_output(netperf_install_cmd, timeout=timeout)
                    if "netserver.exe" not in server_ctl.cmd(s_check_cmd):
                        err_msg = "Install netserver cygwin failed"
                        raise error.TestNAError(err_msg)
                    logging.info("Install netserver in cygwin successfully")

409
        else:
Y
Yunping Zheng 已提交
410 411 412 413 414 415 416
            start_session = server_ctl
            netserv_start_cmd = params.get("netserv_start_cmd") % cdrom_drv
            logging.info("Start netserver without cygwin, cmd is: %s" %
                         netserv_start_cmd)

        error.context("Start netserver on windows guest", logging.info)
        start_netserver_win(start_session, netserv_start_cmd)
417

Y
Yiqiao Pu 已提交
418
    else:
419
        logging.info("Netserver start cmd is '%s'" % server_path)
Y
Yiqiao Pu 已提交
420 421 422
        ssh_cmd(server_ctl, "pidof netserver || %s" % server_path)
        get_status_flag = True
        ncpu = ssh_cmd(server_ctl, "cat /proc/cpuinfo |grep processor |wc -l")
Y
Yunping Zheng 已提交
423
        ncpu = re.findall(r"\d+", ncpu)[0]
Y
Yiqiao Pu 已提交
424

425
    logging.info("Netserver start successfully")
426 427 428

    def count_interrupt(name):
        """
L
Lucas Meneghel Rodrigues 已提交
429
        :param name: the name of interrupt, such as "virtio0-input"
430 431 432
        """
        intr = 0
        stat = ssh_cmd(server_ctl, "cat /proc/interrupts |grep %s" % name)
433
        stat = stat.strip().split("\n")[-1]
434
        for cpu in range(int(ncpu)):
L
Lucas Meneghel Rodrigues 已提交
435
            intr += int(stat.split()[cpu + 1])
436 437 438 439 440
        return intr

    def get_state():
        for i in ssh_cmd(server_ctl, "ifconfig").split("\n\n"):
            if server in i:
Y
Yunping Zheng 已提交
441
                ifname = re.findall(r"(\w+\d+)[:\s]", i)[0]
442 443 444

        path = "find /sys/devices|grep net/%s/statistics" % ifname
        cmd = "%s/rx_packets|xargs cat;%s/tx_packets|xargs cat;" \
L
Lucas Meneghel Rodrigues 已提交
445 446
            "%s/rx_bytes|xargs cat;%s/tx_bytes|xargs cat" % (path,
                                                             path, path, path)
447
        output = ssh_cmd(server_ctl, cmd).split()[-4:]
448 449 450 451 452 453

        nrx = int(output[0])
        ntx = int(output[1])
        nrxb = int(output[2])
        ntxb = int(output[3])

454
        nre = int(ssh_cmd(server_ctl, "grep Tcp /proc/net/snmp|tail -1"
L
Lucas Meneghel Rodrigues 已提交
455
                          ).split()[12])
456 457 458 459 460 461 462 463 464 465 466 467 468 469
        state_list = ['rx_pkts', nrx, 'tx_pkts', ntx, 'rx_byts', nrxb,
                      'tx_byts', ntxb, 're_pkts', nre]
        try:
            nrx_intr = count_interrupt("virtio.-input")
            ntx_intr = count_interrupt("virtio.-output")
            state_list.append('rx_intr')
            state_list.append(nrx_intr)
            state_list.append('tx_intr')
            state_list.append(ntx_intr)
        except IndexError:
            ninit = count_interrupt("virtio.")
            state_list.append('intr')
            state_list.append(ninit)

470
        io_exit = int(ssh_cmd(host, "cat /sys/kernel/debug/kvm/io_exits"))
L
Lucas Meneghel Rodrigues 已提交
471 472
        irq_inj = int(
            ssh_cmd(host, "cat /sys/kernel/debug/kvm/irq_injections"))
473 474 475 476 477 478
        state_list.append('io_exit')
        state_list.append(io_exit)
        state_list.append('irq_inj')
        state_list.append(irq_inj)
        return state_list

Y
Yunping Zheng 已提交
479
    def netperf_thread(i, numa_enable, client_s, timeout):
480
        cmd = ""
A
Amos Kong 已提交
481
        fname = "/tmp/netperf.%s.nf" % pid
482 483
        if numa_enable:
            output = ssh_cmd(client_s, "numactl --hardware")
Y
Yunping Zheng 已提交
484
            n = int(re.findall(r"available: (\d+) nodes", output)[0]) - 1
485
            cmd += "numactl --cpunodebind=%s --membind=%s " % (n, n)
486
        cmd += "/tmp/netperf_agent.py %d %s -D 1 -H %s -l %s %s" % (i,
L
Lucas Meneghel Rodrigues 已提交
487
               client_path, server, int(l) * 1.5, nf_args)
A
Amos Kong 已提交
488
        cmd += " >> %s" % fname
489
        logging.info("Start netperf thread by cmd '%s'" % cmd)
490
        ssh_cmd(client_s, cmd)
A
Amos Kong 已提交
491

Y
Yunping Zheng 已提交
492 493 494 495 496 497 498 499 500 501
    def all_clients_up():
        try:
            content = ssh_cmd(clients[-1], "cat %s" % fname)
        except:
            content = ""
            return False
        if int(sessions) == len(re.findall("MIGRATE", content)):
            return True
        return False

A
Amos Kong 已提交
502 503 504 505 506
    def parse_demo_result(fname, sessions):
        """
        Process the demo result, remove the noise from head,
        and compute the final throughout.

L
Lucas Meneghel Rodrigues 已提交
507 508
        :param fname: result file name
        :param sessions: sessions' number
A
Amos Kong 已提交
509 510 511 512 513
        """
        fd = open(fname)
        lines = fd.readlines()
        fd.close()

L
Lucas Meneghel Rodrigues 已提交
514
        for i in range(1, len(lines) + 1):
A
Amos Kong 已提交
515 516 517 518 519 520 521 522 523 524
            if "AF_INET" in lines[-i]:
                break
        nresult = i - 1
        if nresult < int(sessions):
            raise error.TestError("We couldn't expect this parallism,"
                                  "expect %s get %s" % (sessions, nresult))

        niteration = nresult / sessions
        result = 0.0
        for this in lines[-sessions * niteration:]:
A
Amos Kong 已提交
525
            if "Interim" in this:
Y
Yunping Zheng 已提交
526
                result += float(re.findall(r"Interim result: *(\S+)", this)[0])
A
Amos Kong 已提交
527 528 529
        result = result / niteration
        logging.debug("niteration: %s" % niteration)
        return result
530

531
    error.context("Start netperf client threads", logging.info)
532
    pid = str(os.getpid())
A
Amos Kong 已提交
533 534
    fname = "/tmp/netperf.%s.nf" % pid
    ssh_cmd(clients[-1], "rm -f %s" % fname)
535
    numa_enable = params.get("netperf_with_numa", "yes") == "yes"
536
    timeout_netperf_start = int(l) * 0.5
537 538
    client_thread = threading.Thread(target=netperf_thread,
                                     kwargs={"i": int(sessions),
L
Lucas Meneghel Rodrigues 已提交
539
                                             "numa_enable": numa_enable,
Y
Yunping Zheng 已提交
540 541
                                             "client_s": clients[0],
                                             "timeout": timeout_netperf_start})
542 543
    client_thread.start()

544 545
    ret = {}
    ret['pid'] = pid
A
Amos Kong 已提交
546

547
    if utils_misc.wait_for(all_clients_up, timeout_netperf_start, 0.0, 0.2,
Y
Yunping Zheng 已提交
548 549 550 551
                           "Wait until all netperf clients start to work"):
        logging.debug("All netperf clients start to work.")
    else:
        raise error.TestNAError("Error, not all netperf clients at work")
A
Amos Kong 已提交
552 553 554 555

    # real & effective test starts
    if get_status_flag:
        start_state = get_state()
556
    ret['mpstat'] = ssh_cmd(host, "mpstat 1 %d |tail -n 1" % (l - 1))
A
Amos Kong 已提交
557
    finished_result = ssh_cmd(clients[-1], "cat %s" % fname)
558

A
Amos Kong 已提交
559
    # real & effective test ends
Y
Yiqiao Pu 已提交
560 561
    if get_status_flag:
        end_state = get_state()
562 563 564 565 566 567 568 569 570
        if len(start_state) != len(end_state):
            msg = "Initial state not match end state:\n"
            msg += "  start state: %s\n" % start_state
            msg += "  end state: %s\n" % end_state
            logging.warn(msg)
        else:
            for i in range(len(end_state) / 2):
                ret[end_state[i * 2]] = (end_state[i * 2 + 1]
                                         - start_state[i * 2 + 1])
571 572

    client_thread.join()
A
Amos Kong 已提交
573

574
    error.context("Testing Results Treatment and Report", logging.info)
A
Amos Kong 已提交
575 576 577
    f = open(fname, "w")
    f.write(finished_result)
    f.close()
A
Amos Kong 已提交
578
    ret['thu'] = parse_demo_result(fname, int(sessions))
579
    return ret