Merge "kubernetes_utils: avoid 404 error code in delete_network()"
[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 import logging
16
17 from yardstick.network_services.traffic_profile import base as tp_base
18 from yardstick.network_services.traffic_profile import trex_traffic_profile
19
20
21 LOG = logging.getLogger(__name__)
22
23
24 class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
25
26     UPLINK = 'uplink'
27     DOWNLINK = 'downlink'
28     DROP_PERCENT_ROUND = 6
29     RATE_ROUND = 5
30
31     def __init__(self, yaml_data):
32         super(IXIARFC2544Profile, self).__init__(yaml_data)
33         self.rate = self.config.frame_rate
34         self.rate_unit = self.config.rate_unit
35
36     def _get_ixia_traffic_profile(self, profile_data, mac=None):
37         mac = {} if mac is None else mac
38         result = {}
39         for traffickey, values in profile_data.items():
40             if not traffickey.startswith((self.UPLINK, self.DOWNLINK)):
41                 continue
42
43             try:
44                 # values should be single-item dict, so just grab the first item
45                 try:
46                     key, value = next(iter(values.items()))
47                 except StopIteration:
48                     result[traffickey] = {}
49                     continue
50
51                 port_id = value.get('id', 1)
52                 port_index = port_id - 1
53                 try:
54                     ip = value['outer_l3v6']
55                 except KeyError:
56                     ip = value['outer_l3v4']
57                     src_key, dst_key = 'srcip4', 'dstip4'
58                 else:
59                     src_key, dst_key = 'srcip6', 'dstip6'
60
61                 result[traffickey] = {
62                     'bidir': False,
63                     'id': port_id,
64                     'rate': self.rate,
65                     'rate_unit': self.rate_unit,
66                     'outer_l2': {
67                         'framesize': value['outer_l2']['framesize'],
68                         'framesPerSecond': True,
69                         'srcmac': mac['src_mac_{}'.format(port_index)],
70                         'dstmac': mac['dst_mac_{}'.format(port_index)],
71                     },
72                     'outer_l3': {
73                         'count': ip['count'],
74                         'dscp': ip['dscp'],
75                         'ttl': ip['ttl'],
76                         src_key: ip[src_key].split("-")[0],
77                         dst_key: ip[dst_key].split("-")[0],
78                         'type': key,
79                         'proto': ip['proto'],
80                     },
81                     'outer_l4': value['outer_l4'],
82                 }
83             except KeyError:
84                 continue
85
86         return result
87
88     def _ixia_traffic_generate(self, traffic, ixia_obj):
89         ixia_obj.update_frame(traffic)
90         ixia_obj.update_ip_packet(traffic)
91         ixia_obj.start_traffic()
92
93     def update_traffic_profile(self, traffic_generator):
94         def port_generator():
95             for vld_id, intfs in sorted(traffic_generator.networks.items()):
96                 if not vld_id.startswith((self.UPLINK, self.DOWNLINK)):
97                     continue
98                 profile_data = self.params.get(vld_id)
99                 if not profile_data:
100                     continue
101                 self.profile_data = profile_data
102                 self.full_profile.update({vld_id: self.profile_data})
103                 for intf in intfs:
104                     yield traffic_generator.vnfd_helper.port_num(intf)
105
106         self.ports = [port for port in port_generator()]
107
108     def execute_traffic(self, traffic_generator, ixia_obj=None, mac=None):
109         mac = {} if mac is None else mac
110         first_run = self.first_run
111         if self.first_run:
112             self.first_run = False
113             self.full_profile = {}
114             self.pg_id = 0
115             self.update_traffic_profile(traffic_generator)
116             self.max_rate = self.rate
117             self.min_rate = 0.0
118         else:
119             self.rate = round(float(self.max_rate + self.min_rate) / 2.0,
120                               self.RATE_ROUND)
121
122         traffic = self._get_ixia_traffic_profile(self.full_profile, mac)
123         self._ixia_traffic_generate(traffic, ixia_obj)
124         return first_run
125
126     def get_drop_percentage(self, samples, tol_min, tolerance, duration=30.0,
127                             first_run=False):
128         completed = False
129         drop_percent = 100
130         num_ifaces = len(samples)
131         in_packets_sum = sum(
132             [samples[iface]['in_packets'] for iface in samples])
133         out_packets_sum = sum(
134             [samples[iface]['out_packets'] for iface in samples])
135         rx_throughput = sum(
136             [samples[iface]['RxThroughput'] for iface in samples])
137         rx_throughput = round(float(rx_throughput), 2)
138         tx_throughput = sum(
139             [samples[iface]['TxThroughput'] for iface in samples])
140         tx_throughput = round(float(tx_throughput), 2)
141         packet_drop = abs(out_packets_sum - in_packets_sum)
142
143         try:
144             drop_percent = round(
145                 (packet_drop / float(out_packets_sum)) * 100,
146                 self.DROP_PERCENT_ROUND)
147         except ZeroDivisionError:
148             LOG.info('No traffic is flowing')
149
150         samples['TxThroughput'] = tx_throughput
151         samples['RxThroughput'] = rx_throughput
152         samples['DropPercentage'] = drop_percent
153
154         if first_run:
155             completed = True if drop_percent <= tolerance else False
156         if (first_run and
157                 self.rate_unit == tp_base.TrafficProfileConfig.RATE_FPS):
158             self.rate = out_packets_sum / duration / num_ifaces
159
160         if drop_percent > tolerance:
161             self.max_rate = self.rate
162         elif drop_percent < tol_min:
163             self.min_rate = self.rate
164         else:
165             completed = True
166
167         return completed, samples