Merge "Cleanup unittests for test_attacker_baremetal"
[yardstick.git] / yardstick / network_services / traffic_profile / ixia_rfc2544.py
index c32e9d8..3503889 100644 (file)
@@ -13,6 +13,7 @@
 # limitations under the License.
 
 import logging
+import collections
 
 from yardstick.common import utils
 from yardstick.network_services.traffic_profile import base as tp_base
@@ -28,11 +29,14 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
     DOWNLINK = 'downlink'
     DROP_PERCENT_ROUND = 6
     RATE_ROUND = 5
+    STATUS_SUCCESS = "Success"
+    STATUS_FAIL = "Failure"
 
     def __init__(self, yaml_data):
         super(IXIARFC2544Profile, self).__init__(yaml_data)
         self.rate = self.config.frame_rate
         self.rate_unit = self.config.rate_unit
+        self.full_profile = {}
 
     def _get_ip_and_mask(self, ip_range):
         _ip_range = ip_range.split('-')
@@ -42,6 +46,13 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
         mask = utils.get_mask_from_ip_range(_ip_range[0], _ip_range[1])
         return _ip_range[0], mask
 
+    def _get_fixed_and_mask(self, port_range):
+        _port_range = str(port_range).split('-')
+        if len(_port_range) == 1:
+            return int(_port_range[0]), 0
+
+        return int(_port_range[0]), int(_port_range[1])
+
     def _get_ixia_traffic_profile(self, profile_data, mac=None):
         mac = {} if mac is None else mac
         result = {}
@@ -49,59 +60,96 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
             if not traffickey.startswith((self.UPLINK, self.DOWNLINK)):
                 continue
 
+            # values should be single-item dict, so just grab the first item
             try:
-                # values should be single-item dict, so just grab the first item
-                try:
-                    key, value = next(iter(values.items()))
-                except StopIteration:
-                    result[traffickey] = {}
-                    continue
-
-                port_id = value.get('id', 1)
-                port_index = port_id - 1
-
-                if value.get('outer_l3v4'):
-                    ip = value['outer_l3v4']
-                    src_key, dst_key = 'srcip4', 'dstip4'
-                else:
-                    ip = value['outer_l3v6']
-                    src_key, dst_key = 'srcip6', 'dstip6'
-
-                srcip, srcmask = self._get_ip_and_mask(ip[src_key])
-                dstip, dstmask = self._get_ip_and_mask(ip[dst_key])
-
-                result[traffickey] = {
-                    'bidir': False,
-                    'id': port_id,
-                    'rate': self.rate,
-                    'rate_unit': self.rate_unit,
-                    'outer_l2': {
-                        'framesize': value['outer_l2']['framesize'],
-                        'framesPerSecond': True,
-                        'srcmac': mac['src_mac_{}'.format(port_index)],
-                        'dstmac': mac['dst_mac_{}'.format(port_index)],
-                    },
-                    'outer_l3': {
-                        'count': ip['count'],
-                        'dscp': ip['dscp'],
-                        'ttl': ip['ttl'],
-                        'srcip': srcip,
-                        'dstip': dstip,
-                        'srcmask': srcmask,
-                        'dstmask': dstmask,
-                        'type': key,
-                        'proto': ip['proto'],
-                    },
-                    'outer_l4': value['outer_l4'],
-                }
-            except KeyError:
+                key, value = next(iter(values.items()))
+            except StopIteration:
+                result[traffickey] = {}
                 continue
 
+            port_id = value.get('id', 1)
+            port_index = port_id - 1
+
+            result[traffickey] = {
+                'bidir': False,
+                'id': port_id,
+                'rate': self.rate,
+                'rate_unit': self.rate_unit,
+                'outer_l2': {},
+                'outer_l3': {},
+                'outer_l4': {},
+            }
+
+            frame_rate = value.get('frame_rate')
+            if frame_rate:
+                flow_rate, flow_rate_unit = self.config.parse_rate(frame_rate)
+                result[traffickey]['rate'] = flow_rate
+                result[traffickey]['rate_unit'] = flow_rate_unit
+
+            outer_l2 = value.get('outer_l2')
+            if outer_l2:
+                result[traffickey]['outer_l2'].update({
+                    'framesize': outer_l2.get('framesize'),
+                    'framesPerSecond': True,
+                    'QinQ': outer_l2.get('QinQ'),
+                    'srcmac': mac.get('src_mac_{}'.format(port_index)),
+                    'dstmac': mac.get('dst_mac_{}'.format(port_index)),
+                })
+
+            if value.get('outer_l3v4'):
+                outer_l3 = value['outer_l3v4']
+                src_key, dst_key = 'srcip4', 'dstip4'
+            else:
+                outer_l3 = value.get('outer_l3v6')
+                src_key, dst_key = 'srcip6', 'dstip6'
+            if outer_l3:
+                srcip = srcmask = dstip = dstmask = None
+                if outer_l3.get(src_key):
+                    srcip, srcmask = self._get_ip_and_mask(outer_l3[src_key])
+                if outer_l3.get(dst_key):
+                    dstip, dstmask = self._get_ip_and_mask(outer_l3[dst_key])
+
+                result[traffickey]['outer_l3'].update({
+                    'count': outer_l3.get('count', 1),
+                    'dscp': outer_l3.get('dscp'),
+                    'ttl': outer_l3.get('ttl'),
+                    'srcseed': outer_l3.get('srcseed', 1),
+                    'dstseed': outer_l3.get('dstseed', 1),
+                    'srcip': srcip,
+                    'dstip': dstip,
+                    'srcmask': srcmask,
+                    'dstmask': dstmask,
+                    'type': key,
+                    'proto': outer_l3.get('proto'),
+                    'priority': outer_l3.get('priority')
+                })
+
+            outer_l4 = value.get('outer_l4')
+            if outer_l4:
+                src_port = src_port_mask = dst_port = dst_port_mask = None
+                if outer_l4.get('srcport'):
+                    src_port, src_port_mask = (
+                        self._get_fixed_and_mask(outer_l4['srcport']))
+
+                if outer_l4.get('dstport'):
+                    dst_port, dst_port_mask = (
+                        self._get_fixed_and_mask(outer_l4['dstport']))
+
+                result[traffickey]['outer_l4'].update({
+                    'srcport': src_port,
+                    'dstport': dst_port,
+                    'srcportmask': src_port_mask,
+                    'dstportmask': dst_port_mask,
+                    'count': outer_l4.get('count', 1),
+                    'seed': outer_l4.get('seed', 1),
+                })
+
         return result
 
     def _ixia_traffic_generate(self, traffic, ixia_obj):
-        ixia_obj.update_frame(traffic)
+        ixia_obj.update_frame(traffic, self.config.duration)
         ixia_obj.update_ip_packet(traffic)
+        ixia_obj.update_l4(traffic)
         ixia_obj.start_traffic()
 
     def update_traffic_profile(self, traffic_generator):
@@ -124,9 +172,7 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
         first_run = self.first_run
         if self.first_run:
             self.first_run = False
-            self.full_profile = {}
             self.pg_id = 0
-            self.update_traffic_profile(traffic_generator)
             self.max_rate = self.rate
             self.min_rate = 0.0
         else:
@@ -137,21 +183,18 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
         self._ixia_traffic_generate(traffic, ixia_obj)
         return first_run
 
-    def get_drop_percentage(self, samples, tol_min, tolerance, duration=30.0,
+    def get_drop_percentage(self, samples, tol_min, tolerance, precision,
                             first_run=False):
         completed = False
         drop_percent = 100
         num_ifaces = len(samples)
+        duration = self.config.duration
         in_packets_sum = sum(
             [samples[iface]['in_packets'] for iface in samples])
         out_packets_sum = sum(
             [samples[iface]['out_packets'] for iface in samples])
-        rx_throughput = sum(
-            [samples[iface]['RxThroughput'] for iface in samples])
-        rx_throughput = round(float(rx_throughput), 2)
-        tx_throughput = sum(
-            [samples[iface]['TxThroughput'] for iface in samples])
-        tx_throughput = round(float(tx_throughput), 2)
+        rx_throughput = round(float(in_packets_sum) / duration, 3)
+        tx_throughput = round(float(out_packets_sum) / duration, 3)
         packet_drop = abs(out_packets_sum - in_packets_sum)
 
         try:
@@ -161,15 +204,11 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
         except ZeroDivisionError:
             LOG.info('No traffic is flowing')
 
-        samples['TxThroughput'] = tx_throughput
-        samples['RxThroughput'] = rx_throughput
-        samples['DropPercentage'] = drop_percent
-
         if first_run:
             completed = True if drop_percent <= tolerance else False
         if (first_run and
                 self.rate_unit == tp_base.TrafficProfileConfig.RATE_FPS):
-            self.rate = out_packets_sum / duration / num_ifaces
+            self.rate = float(out_packets_sum) / duration / num_ifaces
 
         if drop_percent > tolerance:
             self.max_rate = self.rate
@@ -178,4 +217,59 @@ class IXIARFC2544Profile(trex_traffic_profile.TrexProfile):
         else:
             completed = True
 
+        LOG.debug("tolerance=%s, tolerance_precision=%s drop_percent=%s "
+                  "completed=%s", tolerance, precision, drop_percent,
+                  completed)
+
+        latency_ns_avg = float(
+            sum([samples[iface]['Store-Forward_Avg_latency_ns']
+            for iface in samples])) / num_ifaces
+        latency_ns_min = float(
+            sum([samples[iface]['Store-Forward_Min_latency_ns']
+            for iface in samples])) / num_ifaces
+        latency_ns_max = float(
+            sum([samples[iface]['Store-Forward_Max_latency_ns']
+            for iface in samples])) / num_ifaces
+
+        samples['Status'] = self.STATUS_FAIL
+        if round(drop_percent, precision) <= tolerance:
+            samples['Status'] = self.STATUS_SUCCESS
+
+        samples['TxThroughput'] = tx_throughput
+        samples['RxThroughput'] = rx_throughput
+        samples['DropPercentage'] = drop_percent
+        samples['latency_ns_avg'] = latency_ns_avg
+        samples['latency_ns_min'] = latency_ns_min
+        samples['latency_ns_max'] = latency_ns_max
+
         return completed, samples
+
+
+class IXIARFC2544PppoeScenarioProfile(IXIARFC2544Profile):
+    """Class handles BNG PPPoE scenario tests traffic profile"""
+
+    def __init__(self, yaml_data):
+        super(IXIARFC2544PppoeScenarioProfile, self).__init__(yaml_data)
+        self.full_profile = collections.OrderedDict()
+
+    def _get_flow_groups_params(self):
+        flows_data = [key for key in self.params.keys()
+                      if key.split('_')[0] in [self.UPLINK, self.DOWNLINK]]
+        for i in range(len(flows_data)):
+            uplink = '_'.join([self.UPLINK, str(i)])
+            downlink = '_'.join([self.DOWNLINK, str(i)])
+            if uplink in flows_data:
+                self.full_profile.update({uplink: self.params[uplink]})
+            if downlink in flows_data:
+                self.full_profile.update({downlink: self.params[downlink]})
+
+    def update_traffic_profile(self, traffic_generator):
+        def port_generator():
+            for vld_id, intfs in sorted(traffic_generator.networks.items()):
+                if not vld_id.startswith((self.UPLINK, self.DOWNLINK)):
+                    continue
+                for intf in intfs:
+                    yield traffic_generator.vnfd_helper.port_num(intf)
+
+        self._get_flow_groups_params()
+        self.ports = [port for port in port_generator()]