Merge "Adding multi-port support for ixia taffic generator"
[yardstick.git] / yardstick / network_services / traffic_profile / ixia_rfc2544.py
1 # Copyright (c) 2016-2017 Intel Corporation
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 from __future__ import absolute_import
16 import logging
17 import json
18
19 from yardstick.network_services.traffic_profile.traffic_profile import \
20     TrexProfile
21
22 LOG = logging.getLogger(__name__)
23
24
25 class IXIARFC2544Profile(TrexProfile):
26
27     def _get_ixia_traffic_profile(self, profile_data, mac=None, xfile=None, static_traffic=None):
28         if mac is None:
29             mac = {}
30
31         if static_traffic is None:
32             static_traffic = {}
33
34         result = {}
35         if xfile:
36             with open(xfile) as stream:
37                 try:
38                     static_traffic = json.load(stream)
39                 except Exception as exc:
40                     LOG.debug(exc)
41
42         for traffickey, trafficvalue in static_traffic.items():
43             traffic = static_traffic[traffickey]
44             # outer_l2
45             index = 0
46             try:
47                 for key, value in profile_data[traffickey].items():
48                     framesize = value['outer_l2']['framesize']
49                     traffic['outer_l2']['framesize'] = framesize
50                     traffic['framesPerSecond'] = True
51                     traffic['bidir'] = False
52                     traffic['outer_l2']['srcmac'] = \
53                         mac["src_mac_{}".format(traffic['id'])]
54                     traffic['outer_l2']['dstmac'] = \
55                         mac["dst_mac_{}".format(traffic['id'])]
56
57                     # outer_l3
58                     if "outer_l3v6" in list(value.keys()):
59                         traffic['outer_l3'] = value['outer_l3v6']
60                         srcip4 = value['outer_l3v6']['srcip6']
61                         traffic['outer_l3']['srcip4'] = srcip4.split("-")[0]
62                         dstip4 = value['outer_l3v6']['dstip6']
63                         traffic['outer_l3']['dstip4'] = dstip4.split("-")[0]
64                     else:
65                         traffic['outer_l3'] = value['outer_l3v4']
66                         srcip4 = value['outer_l3v4']['srcip4']
67                         traffic['outer_l3']['srcip4'] = srcip4.split("-")[0]
68                         dstip4 = value['outer_l3v4']['dstip4']
69                         traffic['outer_l3']['dstip4'] = dstip4.split("-")[0]
70
71                     traffic['outer_l3']['type'] = key
72                     traffic['outer_l3']['count'] = value['outer_l3v4']['count']
73                     # outer_l4
74                     traffic['outer_l4'] = value['outer_l4']
75                     index = index + 1
76             except Exception:
77                 continue
78
79             result.update({traffickey: traffic})
80
81         return result
82
83     def _ixia_traffic_generate(self, traffic_generator, traffic, ixia_obj):
84         for key, value in traffic.items():
85             if key.startswith((self.UPLINK, self.DOWNLINK)):
86                 value["iload"] = str(self.rate)
87         ixia_obj.ix_update_frame(traffic)
88         ixia_obj.ix_update_ether(traffic)
89         ixia_obj.add_ip_header(traffic, 4)
90         ixia_obj.ix_start_traffic()
91         self.tmp_drop = 0
92         self.tmp_throughput = 0
93
94     def update_traffic_profile(self, traffic_generator):
95         def port_generator():
96             for vld_id, intfs in sorted(traffic_generator.networks.items()):
97                 if not vld_id.startswith((self.UPLINK, self.DOWNLINK)):
98                     continue
99                 profile_data = self.params.get(vld_id)
100                 if not profile_data:
101                     continue
102                 self.profile_data = profile_data
103                 self.get_streams(self.profile_data)
104                 self.full_profile.update({vld_id: self.profile_data})
105                 for intf in intfs:
106                     yield traffic_generator.vnfd_helper.port_num(intf)
107
108         self.ports = [port for port in port_generator()]
109
110     def execute_traffic(self, traffic_generator, ixia_obj, mac=None, xfile=None):
111         if mac is None:
112             mac = {}
113         if self.first_run:
114             self.full_profile = {}
115             self.pg_id = 0
116             self.update_traffic_profile(traffic_generator)
117             traffic = \
118                 self._get_ixia_traffic_profile(self.full_profile, mac, xfile)
119             self.max_rate = self.rate
120             self.min_rate = 0
121             self.get_multiplier()
122             self._ixia_traffic_generate(traffic_generator, traffic, ixia_obj)
123
124     def get_multiplier(self):
125         self.rate = round((self.max_rate + self.min_rate) / 2.0, 2)
126         multiplier = round(self.rate / self.pps, 2)
127         return str(multiplier)
128
129     def start_ixia_latency(self, traffic_generator, ixia_obj,
130                            mac=None, xfile=None):
131         if mac is None:
132             mac = {}
133         self.update_traffic_profile(traffic_generator)
134         traffic = \
135             self._get_ixia_traffic_profile(self.full_profile, mac, xfile)
136         self._ixia_traffic_generate(traffic_generator, traffic, ixia_obj)
137
138     def get_drop_percentage(self, traffic_generator, samples, tol_min,
139                             tolerance, ixia_obj, mac=None, xfile=None):
140         if mac is None:
141             mac = {}
142         status = 'Running'
143         drop_percent = 100
144         in_packets = sum([samples[iface]['in_packets'] for iface in samples])
145         out_packets = sum([samples[iface]['out_packets'] for iface in samples])
146         rx_throughput = \
147             sum([samples[iface]['RxThroughput'] for iface in samples])
148         tx_throughput = \
149             sum([samples[iface]['TxThroughput'] for iface in samples])
150         packet_drop = abs(out_packets - in_packets)
151         try:
152             drop_percent = round((packet_drop / float(out_packets)) * 100, 2)
153         except ZeroDivisionError:
154             LOG.info('No traffic is flowing')
155         samples['TxThroughput'] = round(tx_throughput / 1.0, 2)
156         samples['RxThroughput'] = round(rx_throughput / 1.0, 2)
157         samples['CurrentDropPercentage'] = drop_percent
158         samples['Throughput'] = self.tmp_throughput
159         samples['DropPercentage'] = self.tmp_drop
160         if drop_percent > tolerance and self.tmp_throughput == 0:
161             samples['Throughput'] = round(rx_throughput / 1.0, 2)
162             samples['DropPercentage'] = drop_percent
163         if self.first_run:
164             max_supported_rate = out_packets / 30.0
165             self.rate = max_supported_rate
166             self.first_run = False
167             if drop_percent <= tolerance:
168                 status = 'Completed'
169         if drop_percent > tolerance:
170             self.max_rate = self.rate
171         elif drop_percent < tol_min:
172             self.min_rate = self.rate
173             if drop_percent >= self.tmp_drop:
174                 self.tmp_drop = drop_percent
175                 self.tmp_throughput = round((rx_throughput / 1.0), 2)
176                 samples['Throughput'] = round(rx_throughput / 1.0, 2)
177                 samples['DropPercentage'] = drop_percent
178         else:
179             samples['Throughput'] = round(rx_throughput / 1.0, 2)
180             samples['DropPercentage'] = drop_percent
181             return status, samples
182         self.get_multiplier()
183         traffic = self._get_ixia_traffic_profile(self.full_profile, mac, xfile)
184         self._ixia_traffic_generate(traffic_generator, traffic, ixia_obj)
185         return status, samples