Merge "Add service in kubernetes context"
[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             for key, value in profile_data[traffickey].items():
47                 framesize = value['outer_l2']['framesize']
48                 traffic['outer_l2']['framesize'] = framesize
49                 traffic['framesPerSecond'] = True
50                 traffic['bidir'] = False
51                 traffic['outer_l2']['srcmac'] = \
52                     mac["src_mac_{}".format(traffic['id'])]
53                 traffic['outer_l2']['dstmac'] = \
54                     mac["dst_mac_{}".format(traffic['id'])]
55
56                 # outer_l3
57                 if "outer_l3v6" in list(value.keys()):
58                     traffic['outer_l3'] = value['outer_l3v6']
59                     srcip4 = value['outer_l3v6']['srcip6']
60                     traffic['outer_l3']['srcip4'] = srcip4.split("-")[0]
61                     dstip4 = value['outer_l3v6']['dstip6']
62                     traffic['outer_l3']['dstip4'] = dstip4.split("-")[0]
63                 else:
64                     traffic['outer_l3'] = value['outer_l3v4']
65                     srcip4 = value['outer_l3v4']['srcip4']
66                     traffic['outer_l3']['srcip4'] = srcip4.split("-")[0]
67                     dstip4 = value['outer_l3v4']['dstip4']
68                     traffic['outer_l3']['dstip4'] = dstip4.split("-")[0]
69
70                 traffic['outer_l3']['type'] = key
71                 traffic['outer_l3']['count'] = value['outer_l3v4']['count']
72                 # outer_l4
73                 traffic['outer_l4'] = value['outer_l4']
74                 index = index + 1
75             result.update({traffickey: traffic})
76
77         return result
78
79     def _ixia_traffic_generate(self, traffic_generator, traffic, ixia_obj):
80         for key, value in traffic.items():
81             if key.startswith((self.UPLINK, self.DOWNLINK)):
82                 value["iload"] = str(self.rate)
83         ixia_obj.ix_update_frame(traffic)
84         ixia_obj.ix_update_ether(traffic)
85         ixia_obj.add_ip_header(traffic, 4)
86         ixia_obj.ix_start_traffic()
87         self.tmp_drop = 0
88         self.tmp_throughput = 0
89
90     def update_traffic_profile(self, traffic_generator):
91         def port_generator():
92             for vld_id, intfs in sorted(traffic_generator.networks.items()):
93                 if not vld_id.startswith((self.UPLINK, self.DOWNLINK)):
94                     continue
95                 profile_data = self.params.get(vld_id)
96                 if not profile_data:
97                     continue
98                 self.profile_data = profile_data
99                 self.get_streams(self.profile_data)
100                 self.full_profile.update({vld_id: self.profile_data})
101                 for intf in intfs:
102                     yield traffic_generator.vnfd_helper.port_num(intf)
103
104         self.ports = [port for port in port_generator()]
105
106     def execute_traffic(self, traffic_generator, ixia_obj, mac=None, xfile=None):
107         if mac is None:
108             mac = {}
109         if self.first_run:
110             self.full_profile = {}
111             self.pg_id = 0
112             self.update_traffic_profile(traffic_generator)
113             traffic = \
114                 self._get_ixia_traffic_profile(self.full_profile, mac, xfile)
115             self.max_rate = self.rate
116             self.min_rate = 0
117             self.get_multiplier()
118             self._ixia_traffic_generate(traffic_generator, traffic, ixia_obj)
119
120     def get_multiplier(self):
121         self.rate = round((self.max_rate + self.min_rate) / 2.0, 2)
122         multiplier = round(self.rate / self.pps, 2)
123         return str(multiplier)
124
125     def start_ixia_latency(self, traffic_generator, ixia_obj,
126                            mac=None, xfile=None):
127         if mac is None:
128             mac = {}
129         self.update_traffic_profile(traffic_generator)
130         traffic = \
131             self._get_ixia_traffic_profile(self.full_profile, mac, xfile)
132         self._ixia_traffic_generate(traffic_generator, traffic, ixia_obj)
133
134     def get_drop_percentage(self, traffic_generator, samples, tol_min,
135                             tolerance, ixia_obj, mac=None, xfile=None):
136         if mac is None:
137             mac = {}
138         status = 'Running'
139         drop_percent = 100
140         in_packets = sum([samples[iface]['in_packets'] for iface in samples])
141         out_packets = sum([samples[iface]['out_packets'] for iface in samples])
142         rx_throughput = \
143             sum([samples[iface]['RxThroughput'] for iface in samples])
144         tx_throughput = \
145             sum([samples[iface]['TxThroughput'] for iface in samples])
146         packet_drop = abs(out_packets - in_packets)
147         try:
148             drop_percent = round((packet_drop / float(out_packets)) * 100, 2)
149         except ZeroDivisionError:
150             LOG.info('No traffic is flowing')
151         samples['TxThroughput'] = round(tx_throughput / 1.0, 2)
152         samples['RxThroughput'] = round(rx_throughput / 1.0, 2)
153         samples['CurrentDropPercentage'] = drop_percent
154         samples['Throughput'] = self.tmp_throughput
155         samples['DropPercentage'] = self.tmp_drop
156         if drop_percent > tolerance and self.tmp_throughput == 0:
157             samples['Throughput'] = round(rx_throughput / 1.0, 2)
158             samples['DropPercentage'] = drop_percent
159         if self.first_run:
160             max_supported_rate = out_packets / 30.0
161             self.rate = max_supported_rate
162             self.first_run = False
163             if drop_percent <= tolerance:
164                 status = 'Completed'
165         if drop_percent > tolerance:
166             self.max_rate = self.rate
167         elif drop_percent < tol_min:
168             self.min_rate = self.rate
169             if drop_percent >= self.tmp_drop:
170                 self.tmp_drop = drop_percent
171                 self.tmp_throughput = round((rx_throughput / 1.0), 2)
172                 samples['Throughput'] = round(rx_throughput / 1.0, 2)
173                 samples['DropPercentage'] = drop_percent
174         else:
175             samples['Throughput'] = round(rx_throughput / 1.0, 2)
176             samples['DropPercentage'] = drop_percent
177             return status, samples
178         self.get_multiplier()
179         traffic = self._get_ixia_traffic_profile(self.full_profile, mac, xfile)
180         self._ixia_traffic_generate(traffic_generator, traffic, ixia_obj)
181         return status, samples