JIRA: BOTTLENECKS-29
[bottlenecks.git] / vstf / vstf / agent / perf / netmap.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.decorator as deco
13 from vstf.common.utils import kill_by_name, my_popen
14
15 import logging
16
17 LOG = logging.getLogger(__name__)
18
19
20 class Netmap(object):
21     def __init__(self):
22         self._send_processes = []
23         self._receive_processes = []
24
25     @deco.check("protocol", choices=['udp_bw'], defaults='udp_bw')
26     @deco.check("namespace", defaults=None)
27     @deco.check("dst")
28     @deco.check("src")
29     @deco.check("size", defaults=64)
30     @deco.check("threads", defaults=1)
31     @deco.check("ratep", defaults=0)
32     def send_start(self, **kwargs):
33         cmd = self.format_send_start(**kwargs)
34         LOG.info("cmd:%s", cmd)
35
36         process = my_popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
37         self._send_processes.append(process)
38         time.sleep(0.5)
39
40         ret = process.poll()
41         if ret is None:
42             ret = 0
43             error_str = "start netmap send success"
44         else:
45             error_str = "start netmap send failed, %s" % (str(kwargs))
46             process.wait()
47             self._send_processes.remove(process)
48
49         return ret, error_str
50
51     def send_stop(self, **kwargs):
52         LOG.info("send_stop")
53         results = []
54         ret = 0
55         for process in self._send_processes:
56             process.kill()
57             process.wait()
58             error_str = "stop netmap send success"
59             results.append((ret, error_str))
60         self._send_processes = []
61         return results
62
63     def format_send_start(self, **kwargs):
64         cmd = "pkt-gen -i %(src_iface)s -f tx -l %(pkt_size)s -p %(threads)s -D %(dst_mac)s -R %(ratep)s"
65         context = {
66             'src_iface': kwargs['src'][0]['iface'],
67             'dst_mac': kwargs['dst'][0]['mac'],
68             'pkt_size': kwargs['size'],
69             'threads': kwargs['threads'],
70             'ratep': kwargs['ratep']
71         }
72         cmd = cmd % context
73         return cmd
74
75     @deco.namespace()
76     def format_receive_start(self, **kwargs):
77         cmd = "pkt-gen -i %(iface)s -f rx"
78         context = {
79             'iface': kwargs['dst'][0]['iface']
80         }
81         cmd = cmd % context
82         return cmd
83
84     @deco.check("protocol", choices=['udp_bw'], defaults='udp_bw')
85     @deco.check("namespace", defaults=None)
86     @deco.check("dst")
87     def receive_start(self, **kwargs):
88
89         cmd = self.format_receive_start(**kwargs)
90         LOG.info("cmd:%s", cmd)
91
92         process = my_popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
93         self._receive_processes.append(process)
94         time.sleep(0.5)
95
96         ret = process.poll()
97         if ret is None:
98             ret = 0
99             error_str = "start netmap receive success"
100         else:
101             error_str = "start netmap receive failed, %s" % (str(kwargs))
102             process.wait()
103             self._receive_processes.remove(process)
104
105         return ret, error_str
106
107     def receive_stop(self, **kwargs):
108         LOG.info("receive_stop")
109         ret = 0
110         for process in self._receive_processes:
111             process.kill()
112             process.wait()
113         self._receive_processes = []
114         error_str = "stop netmap receive success"
115         self._receive_processes = []
116         return ret, error_str
117
118     def clean(self):
119         self.send_stop()
120         self.receive_stop()
121         return True
122
123     def force_clean(self):
124         LOG.info("%s %s start", self.__class__, self.force_clean.__name__)
125         kill_by_name('pkt-gen')
126         self._send_processes = []
127         self._receive_processes = []
128         return True
129
130
131 def unit_test():
132     perf = Netmap()
133     receive = {
134         "protocol": "udp_bw",
135         # "namespace": "receive",
136         "dst": [
137             {"iface": "p57p2"}
138         ],
139     }
140     ret = perf.receive_start(**receive)
141     LOG.info("*********receive_start***********")
142     LOG.info("ret")
143     send = {
144         # "namespace": "send",
145         "protocol": "udp_bw",
146         "src": [
147             {"iface": "eth4", "mac": "90:e2:ba:20:1f:d8"}
148         ],
149         "dst": [
150             {"mac": "90:e2:ba:20:1f:d9"}
151         ],
152         "size": 64,
153         "threads": 1,
154         "ratep": 0
155     }
156     print perf.send_start(**send)
157     print perf._send_processes
158     time.sleep(10)
159
160     print perf.send_stop()
161     print perf.receive_stop()
162
163
164 if __name__ == "__main__":
165     from vstf.common.log import setup_logging
166
167     setup_logging(level=logging.DEBUG, log_file="/var/log/vstf/vstf-netmap.log", clevel=logging.INFO)
168     unit_test()