Merge "Change PTL informatin in INFO"
[bottlenecks.git] / testsuites / vstf / vstf_scripts / vstf / agent / perf / netperf.py
1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9
10 import time
11 import subprocess
12 import vstf.common.constants as cst
13 import vstf.common.decorator as deco
14 from vstf.common import perfmark as mark
15 from vstf.common.utils import kill_by_name, my_popen
16
17 import logging
18
19 LOG = logging.getLogger(__name__)
20
21
22 class Netperf(object):
23
24     def __init__(self):
25         self._send_processes = []
26         self._islat = False
27         self._typemap = {
28             "tcp_lat": "TCP_STREAM",
29             "tcp_bw": "TCP_STREAM",
30             "udp_lat": "UDP_STREAM",
31             "udp_bw": "UDP_STREAM",
32         }
33
34     @deco.check("protocol", choices=cst.PROTOCOLS)
35     @deco.check("namespace", defaults=None)
36     @deco.check("dst")
37     @deco.check("time", defaults=0)
38     @deco.check("size", defaults=64)
39     @deco.check("threads", defaults=1)
40     def send_start(self, **kwargs):
41         threads = kwargs.pop('threads')
42         kwargs['buf'] = cst.SOCKET_BUF
43         if kwargs['protocol'] in ['tcp_lat', 'udp_lat']:
44             self._islat = True
45         else:
46             kwargs['time'] = 0
47
48         cmd = self.format_send_start(**kwargs)
49         LOG.info("cmd:%s", cmd)
50
51         for _ in range(threads):
52             process = my_popen(
53                 cmd.split(),
54                 stdout=subprocess.PIPE,
55                 stderr=subprocess.PIPE)
56             self._send_processes.append(process)
57         time.sleep(0.5)
58         for process in self._send_processes:
59             ret = process.poll()
60             if ret is None:
61                 ret = 0
62                 error_str = "start netperf send success"
63             else:
64                 error_str = "start netperf send failed, %s" % (str(kwargs))
65                 process.wait()
66                 self._send_processes.remove(process)
67
68         return ret, error_str
69
70     def send_stop(self, **kwargs):
71         LOG.info("send_stop")
72         results = []
73         ret = 0
74         for process in self._send_processes:
75             poll = process.poll()
76             if poll is None:
77                 if not self._islat:
78                     process.kill()
79                     read = "process is stopped by killed"
80                 else:
81                     ret = process.wait()
82                     read = process.stdout.read()
83                     read = self._parse_data(read)
84                 results.append((ret, read))
85         self._send_processes = []
86         self._islat = False
87         return results
88
89     @staticmethod
90     def _parse_data(data):
91         buf = data.splitlines()
92         data = buf[2].strip().split(',')
93         result = {
94             mark.minLatency: float(data[0]),
95             mark.avgLatency: float(data[1]),
96             mark.maxLatency: float(data[2])
97         }
98         return result
99
100     @deco.namespace()
101     def format_send_start(self, **kwargs):
102         #       cmd = "netperf -H %(dst_ip)s -t %(type)s -l %(time)s -- -m %(pkt_size)s "
103         cmd = "netperf -H %(dst_ip)s -t %(type)s -l %(time)s  " \
104               "-- -m %(pkt_size)s -s %(buf)s -S %(buf)s -o  MIN_LATENCY,MEAN_LATENCY,MAX_LATENCY"
105         context = {
106             'dst_ip': kwargs['dst'][0]['ip'],
107             'type': self._typemap[kwargs['protocol']],
108             'time': kwargs['time'],
109             'pkt_size': kwargs['size'],
110             'buf': kwargs['buf'],
111         }
112         cmd = cmd % context
113         return cmd
114
115     @deco.namespace()
116     def format_receive_start(self, **kwargs):
117         cmd = 'netserver'
118         return cmd
119
120     @deco.check("namespace")
121     def receive_start(self, **kwargs):
122
123         cmd = self.format_receive_start(**kwargs)
124         LOG.info("cmd:%s", cmd)
125
126         process = my_popen(
127             cmd.split(),
128             stdout=subprocess.PIPE,
129             stderr=subprocess.PIPE)
130         time.sleep(0.5)
131         ret = process.poll()
132         if ret:
133             error_str = "start netserver failed, %s" % (str(kwargs))
134         else:
135             ret = 0
136             error_str = "start netserver success"
137
138         return ret, error_str
139
140     def receive_stop(self, **kwargs):
141         LOG.info("receive_stop")
142         ret = 0
143         kill_by_name('netserver')
144         time.sleep(0.5)
145         error_str = "stop netserver success"
146         return ret, error_str
147
148     def clean(self):
149         self.send_stop()
150         self.receive_stop()
151         return True
152
153     def force_clean(self):
154         LOG.info("%s %s start", self.__class__, self.force_clean.__name__)
155         kill_by_name('netserver')
156         kill_by_name('netperf')
157         self._send_processes = []
158         self._receive_processes = []
159         return True
160
161
162 def unit_test():
163     perf = Netperf()
164     ret = perf.receive_start(namespace='receive')
165     print "*********receive_start***********"
166     print ret
167     send = {
168         "namespace": "send",
169         "protocol": "udp_lat",
170         "dst": [
171             {"ip": "192.168.1.102"}
172         ],
173         "size": 64,
174         "threads": 1,
175         "time": 10,
176     }
177     print perf.send_start(**send)
178     print perf._send_processes
179     time.sleep(10)
180     print perf.send_stop()
181     print perf.receive_stop()
182
183
184 if __name__ == "__main__":
185     from vstf.common.log import setup_logging
186
187     setup_logging(
188         level=logging.DEBUG,
189         log_file="/var/log/vstf/vstf-netperf.log",
190         clevel=logging.DEBUG)
191     unit_test()