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