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