JIRA: BOTTLENECKS-29
[bottlenecks.git] / vstf / vstf / agent / perf / iperf.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 subprocess
11 import signal
12 import os
13 import time
14 import logging
15
16 import vstf.common.decorator as deco
17 import vstf.agent.perf.utils as utils
18 from vstf.common.utils import kill_by_name
19
20 LOG = logging.getLogger(__name__)
21
22
23 class Iperf(object):
24     def __init__(self):
25         self._send_processes = []
26         self._receive_processes = []
27         self._typemap = {
28             "tcp_bw": "",
29             "udp_bw": " -u ",
30         }
31
32     @deco.check("protocol", choices=['tcp_bw', 'udp_bw'])
33     @deco.check("namespace", defaults=None)
34     @deco.check("dst")
35     @deco.check("time", defaults=600)
36     @deco.check("size", defaults=64)
37     @deco.check("threads", defaults=1)
38     def send_start(self, **kwargs):
39
40         cmd = self.format_send_start(**kwargs)
41         LOG.debug("cmd:%s", cmd)
42
43         process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
44         time.sleep(1)
45         ret = process.poll()
46         if ret is None:
47             ret = 0
48             error_str = "start iperf send success"
49             self._send_processes.append(process)
50         else:
51             print ret
52             error_str = "start iperf send failed, %s", (str(kwargs))
53
54         return ret, error_str
55
56     @deco.namespace()
57     def format_send_start(self, **kwargs):
58         cmd = "iperf %(type)s -c %(dst_ip)s -i 1 -l %(pkt_size)s -t %(time)s  -P %(threads)s "
59         context = {
60             'type': self._typemap[kwargs['protocol']],
61             'dst_ip': kwargs['dst'][0]['ip'],
62             'time': kwargs['time'],
63             'pkt_size': kwargs['size'],
64             'threads': kwargs['threads'],
65         }
66         cmd = cmd % context
67         return cmd
68
69     def send_stop(self):
70         results = []
71         for process in self._send_processes:
72             poll = process.poll()
73             if poll is None:
74                 process.kill()
75                 ret = 0
76                 read = "process is stopped by killed"
77                 results.append((ret, read))
78
79         self._send_processes = []
80         return results
81
82     @deco.namespace()
83     def format_receive_start(self, **kwargs):
84         cmd = 'iperf %s -s ' % (self._typemap[kwargs['protocol']])
85         return cmd
86
87     @deco.check("protocol", choices=['tcp_bw', 'udp_bw'])
88     @deco.check("namespace", defaults=None)
89     def receive_start(self, **kwargs):
90         cmd = self.format_receive_start(**kwargs)
91         LOG.debug("cmd:%s", cmd)
92
93         process = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
94         time.sleep(1)
95         ret = process.poll()
96         if ret is None:
97             ret = 0
98             error_str = "start iperf receive success"
99             self._receive_processes.append(process)
100         else:
101             print ret
102             error_str = "start iperf receive failed, %s" % (str(kwargs))
103         return ret, error_str
104
105     def receive_stop(self):
106         ret = 0
107         for process in self._receive_processes:
108             process.kill()
109             ret = process.wait()
110         self._receive_processes = []
111         return ret
112
113     def receive_kill(self):
114         ret = 0
115         receive_pids = utils.get_pid_by_name('iperf')
116         for pid in receive_pids:
117             os.kill(pid, signal.SIGKILL)
118             time.sleep(0.5)
119         error_str = "stop iperf receive success"
120         LOG.debug(error_str)
121         return ret, error_str
122
123     def force_clean(self):
124         LOG.info("%s %s start", self.__class__, self.force_clean.__name__)
125         kill_by_name('iperf')
126         self._send_processes = []
127         self._receive_processes = []
128         return True
129
130
131 def unit_test():
132     perf = Iperf()
133     pro = 'udp_bw'
134     print perf.receive_start(namespace='receive', protocol=pro)
135
136     send = {
137         "namespace": "send",
138         "protocol": "udp_bw",
139         "dst": [
140             {"ip": "192.168.1.102"}
141         ],
142         "size": 64,
143         "time": 5,
144     }
145     print perf.send_start(**send)
146     time.sleep(10)
147     print perf.send_stop()
148     print perf.receive_stop()
149
150
151 if __name__ == "__main__":
152     from vstf.common.log import setup_logging
153
154     setup_logging(level=logging.DEBUG, log_file="/var/log/vstf-iperf.log", clevel=logging.DEBUG)
155     unit_test()