Merge "Change PTL informatin in INFO"
[bottlenecks.git] / testsuites / vstf / vstf_scripts / vstf / agent / perf / pktgen.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 time
12 import logging
13 import vstf.agent.perf.utils as utils
14 import vstf.common.decorator as deco
15 from vstf.common.utils import my_popen
16
17 LOG = logging.getLogger(__name__)
18
19
20 class Pktgen(object):
21
22     def __init__(self):
23         utils.modprobe_pktgen()
24         self._send_processes = []
25
26     def _psetpg(self, dev):
27         self._dev = dev
28
29     def _vsetpg(self, key, value=''):
30         with open(self._dev, 'w') as f:
31             txt = "%(key)s %(value)s\n" % {'key': key, 'value': value}
32             f.write(txt)
33             LOG.info("write(%s) to %s", txt.strip(), self._dev)
34
35     def _start(self):
36         cmd = 'echo start > /proc/net/pktgen/pgctrl'
37         process = my_popen(
38             cmd,
39             shell=True,
40             stdout=subprocess.PIPE,
41             stderr=subprocess.PIPE)
42         LOG.info('running pid:%s', process.pid)
43         time.sleep(0.5)
44         ret = process.poll()
45         if ret is None:
46             ret = 0
47             self._send_processes.append(process)
48             error_str = "start pktgen send success"
49         else:
50             error_str = "start pktgen send failed, stdout:%s,stderr:%s" % (
51                 process.stdout.read(), process.stderr.read())
52             LOG.info(error_str)
53         return ret, error_str
54
55     def _rem_device_all(self):
56         cpu_num = utils.get_cpu_num()
57         for thread in range(0, cpu_num - 1):
58             self._psetpg("/proc/net/pktgen/kpktgend_%s" % thread)
59             self._vsetpg('rem_device_all')
60         return True
61
62     @deco.check("protocol", choices=['udp_bw'], defaults='udp_bw')
63     @deco.check("namespace", defaults=None)
64     @deco.check("dst")
65     @deco.check("src")
66     @deco.check("size", defaults=64)
67     @deco.check("threads", defaults=utils.get_default_threads())
68     @deco.check("clone_skb", defaults=1)
69     @deco.check("count", defaults=0)
70     @deco.check("ratep", defaults=0)
71     def send_start(self, **kwargs):
72         # ensure that all sends is exit
73         self.send_stop()
74
75         interface_num = len(kwargs['src'])
76         interfaces = []
77         for i in range(interface_num):
78             device = kwargs['src'][i]['iface']
79             interfaces.append(device)
80             utils.iface_up(device)
81
82         self._rem_device_all()
83
84         threads = kwargs['threads']
85         for i in range(interface_num):
86             dev_min = i * threads
87             dev_max = (i + 1) * threads
88             device = interfaces[i]
89             for dev_id in range(dev_min, dev_max):
90                 queue_id = dev_id % threads
91                 self._psetpg("/proc/net/pktgen/kpktgend_%s" % dev_id)
92                 self._vsetpg('add_device', "%s@%s" % (device, queue_id))
93                 self._psetpg("/proc/net/pktgen/%s@%s" % (device, queue_id))
94                 self._vsetpg('pkt_size', kwargs['size'])
95                 self._vsetpg('clone_skb', kwargs['clone_skb'])
96                 self._vsetpg('dst_mac', kwargs['dst'][i]['mac'])
97                 self._vsetpg('src_mac', kwargs['src'][i]['mac'])
98                 self._vsetpg('count', kwargs['count'])
99                 if kwargs['ratep']:
100                     self._vsetpg('ratep', kwargs['ratep'])
101         return self._start()
102
103     def send_stop(self, **kwargs):
104         results = []
105         ret = 0
106         for process in self._send_processes:
107             process.kill()
108             process.wait()
109             LOG.info("process.kill(pktgen:%s)", process.pid)
110             results.append((ret, process.stdout.read()))
111         self._send_processes = []
112         return results
113
114     def receive_start(self, **kwargs):
115         ret = 0
116         error_str = "%s pktgen neednt receive start" % (self.__class__)
117         LOG.debug(error_str)
118         return ret, error_str
119
120     def receive_stop(self, **kwargs):
121         ret = 0
122         error_str = "pktgen neednt receive stop"
123         LOG.debug(error_str)
124         return ret, error_str
125
126     def clean(self):
127         self.send_stop()
128         return True
129
130     def force_clean(self):
131         LOG.info("%s %s start", self.__class__, self.force_clean.__name__)
132         return self.clean()
133
134
135 def unit_test():
136     perf = Pktgen()
137     print perf.receive_start()
138     send = {
139         "src": [
140             {"iface": 'eth4', "mac": "90:e2:ba:20:1f:d8"}
141         ],
142         "dst": [
143             {"mac": '90:e2:ba:20:1f:d9'}
144         ],
145         "size": 64,
146         "threads": 1,
147         'ratep': 0
148     }
149     print perf.send_start(**send)
150     time.sleep(30)
151     print perf.send_stop()
152     print perf.receive_stop()
153
154
155 if __name__ == "__main__":
156     from vstf.common.log import setup_logging
157
158     setup_logging(
159         level=logging.DEBUG,
160         log_file="/var/log/vstf/vstf-pktgen.log",
161         clevel=logging.DEBUG)
162     unit_test()