NFVBENCH-155 Add options to disable extra stats, latency stats and latency streams
[nfvbench.git] / nfvbench / traffic_gen / trex_gen.py
index 989940a..53786f7 100644 (file)
@@ -245,11 +245,74 @@ class TRex(AbstractTrafficGenerator):
                 else:
                     latencies[port].min_usec = get_latency(lat['total_min'])
                     latencies[port].avg_usec = get_latency(lat['average'])
+                # pick up the HDR histogram if present (otherwise will raise KeyError)
+                latencies[port].hdrh = lat['hdrh']
             except KeyError:
                 pass
 
     def __combine_latencies(self, in_stats, results, port_handle):
-        """Traverse TRex result dictionary and combines chosen latency stats."""
+        """Traverse TRex result dictionary and combines chosen latency stats.
+
+          example of latency dict returned by trex (2 chains):
+         'latency': {256: {'err_cntrs': {'dropped': 0,
+                                 'dup': 0,
+                                 'out_of_order': 0,
+                                 'seq_too_high': 0,
+                                 'seq_too_low': 0},
+                            'latency': {'average': 26.5,
+                                        'hdrh': u'HISTFAAAAEx4nJNpmSgz...bFRgxi',
+                                        'histogram': {20: 303,
+                                                        30: 320,
+                                                        40: 300,
+                                                        50: 73,
+                                                        60: 4,
+                                                        70: 1},
+                                        'jitter': 14,
+                                        'last_max': 63,
+                                        'total_max': 63,
+                                        'total_min': 20}},
+                    257: {'err_cntrs': {'dropped': 0,
+                                        'dup': 0,
+                                        'out_of_order': 0,
+                                        'seq_too_high': 0,
+                                        'seq_too_low': 0},
+                            'latency': {'average': 29.75,
+                                        'hdrh': u'HISTFAAAAEV4nJN...CALilDG0=',
+                                        'histogram': {20: 261,
+                                                        30: 431,
+                                                        40: 3,
+                                                        50: 80,
+                                                        60: 225},
+                                        'jitter': 23,
+                                        'last_max': 67,
+                                        'total_max': 67,
+                                        'total_min': 20}},
+                    384: {'err_cntrs': {'dropped': 0,
+                                        'dup': 0,
+                                        'out_of_order': 0,
+                                        'seq_too_high': 0,
+                                        'seq_too_low': 0},
+                            'latency': {'average': 18.0,
+                                        'hdrh': u'HISTFAAAADR4nJNpm...MjCwDDxAZG',
+                                        'histogram': {20: 987, 30: 14},
+                                        'jitter': 0,
+                                        'last_max': 34,
+                                        'total_max': 34,
+                                        'total_min': 20}},
+                    385: {'err_cntrs': {'dropped': 0,
+                                    'dup': 0,
+                                    'out_of_order': 0,
+                                    'seq_too_high': 0,
+                                    'seq_too_low': 0},
+                            'latency': {'average': 19.0,
+                                        'hdrh': u'HISTFAAAADR4nJNpm...NkYmJgDdagfK',
+                                        'histogram': {20: 989, 30: 11},
+                                        'jitter': 0,
+                                        'last_max': 38,
+                                        'total_max': 38,
+                                        'total_min': 20}},
+                    'global': {'bad_hdr': 0, 'old_flow': 0}},
+        """
         total_max = 0
         average = 0
         total_min = float("inf")
@@ -359,7 +422,8 @@ class TRex(AbstractTrafficGenerator):
                                                l4_type=CTRexVmInsFixHwCs.L4_TYPE_UDP))
         pad = max(0, frame_size - len(pkt_base)) * 'x'
 
-        return STLPktBuilder(pkt=pkt_base / pad, vm=STLScVmRaw(vm_param))
+        return STLPktBuilder(pkt=pkt_base / pad,
+                             vm=STLScVmRaw(vm_param, cache_size=int(self.config.cache_size)))
 
     def generate_streams(self, port, chain_id, stream_cfg, l2frame, latency=True,
                          e2e=False):
@@ -374,6 +438,8 @@ class TRex(AbstractTrafficGenerator):
         """
         streams = []
         pg_id, lat_pg_id = self.get_pg_id(port, chain_id)
+        if self.config.no_flow_stats:
+            LOG.info("Traffic flow statistics are disabled.")
         if l2frame == 'IMIX':
             for ratio, l2_frame_size in zip(IMIX_RATIOS, IMIX_L2_SIZES):
                 pkt = self._create_pkt(stream_cfg, l2_frame_size)
@@ -384,11 +450,13 @@ class TRex(AbstractTrafficGenerator):
                     if stream_cfg['vxlan'] is True:
                         streams.append(STLStream(packet=pkt,
                                                  flow_stats=STLFlowStats(pg_id=pg_id,
-                                                                         vxlan=True),
+                                                                         vxlan=True)
+                                                 if not self.config.no_flow_stats else None,
                                                  mode=STLTXCont(pps=ratio)))
                     else:
                         streams.append(STLStream(packet=pkt,
-                                                 flow_stats=STLFlowStats(pg_id=pg_id),
+                                                 flow_stats=STLFlowStats(pg_id=pg_id)
+                                                 if not self.config.no_flow_stats else None,
                                                  mode=STLTXCont(pps=ratio)))
 
             if latency:
@@ -405,11 +473,13 @@ class TRex(AbstractTrafficGenerator):
                 if stream_cfg['vxlan'] is True:
                     streams.append(STLStream(packet=pkt,
                                              flow_stats=STLFlowStats(pg_id=pg_id,
-                                                                     vxlan=True),
+                                                                     vxlan=True)
+                                             if not self.config.no_flow_stats else None,
                                              mode=STLTXCont()))
                 else:
                     streams.append(STLStream(packet=pkt,
-                                             flow_stats=STLFlowStats(pg_id=pg_id),
+                                             flow_stats=STLFlowStats(pg_id=pg_id)
+                                             if not self.config.no_flow_stats else None,
                                              mode=STLTXCont()))
             # for the latency stream, the minimum payload is 16 bytes even in case of vlan tagging
             # without vlan, the min l2 frame size is 64
@@ -419,10 +489,19 @@ class TRex(AbstractTrafficGenerator):
                 pkt = self._create_pkt(stream_cfg, 68)
 
         if latency:
-            # TRex limitation: VXLAN skip is not supported for latency stream
-            streams.append(STLStream(packet=pkt,
-                                     flow_stats=STLFlowLatencyStats(pg_id=lat_pg_id),
-                                     mode=STLTXCont(pps=self.LATENCY_PPS)))
+            if self.config.no_latency_stats:
+                LOG.info("Latency flow statistics are disabled.")
+            if stream_cfg['vxlan'] is True:
+                streams.append(STLStream(packet=pkt,
+                                         flow_stats=STLFlowLatencyStats(pg_id=lat_pg_id,
+                                                                        vxlan=True)
+                                         if not self.config.no_latency_stats else None,
+                                         mode=STLTXCont(pps=self.LATENCY_PPS)))
+            else:
+                streams.append(STLStream(packet=pkt,
+                                         flow_stats=STLFlowLatencyStats(pg_id=lat_pg_id)
+                                         if not self.config.no_latency_stats else None,
+                                         mode=STLTXCont(pps=self.LATENCY_PPS)))
         return streams
 
     @timeout(5)
@@ -624,7 +703,10 @@ class TRex(AbstractTrafficGenerator):
                           chain_count)
                 break
 
-        self.client.set_service_mode(ports=self.port_handle, enabled=False)
+        # if the capture from the TRex console was started before the arp request step,
+        # it keeps 'service_mode' enabled, otherwise, it disables the 'service_mode'
+        if not self.config.service_mode:
+            self.client.set_service_mode(ports=self.port_handle, enabled=False)
         if len(arp_dest_macs) == len(self.port_handle):
             return arp_dest_macs
         return None
@@ -766,7 +848,10 @@ class TRex(AbstractTrafficGenerator):
         if self.capture_id:
             self.client.stop_capture(capture_id=self.capture_id['id'])
             self.capture_id = None
-            self.client.set_service_mode(ports=self.port_handle, enabled=False)
+            # if the capture from TRex console was started before the connectivity step,
+            # it keeps 'service_mode' enabled, otherwise, it disables the 'service_mode'
+            if not self.config.service_mode:
+                self.client.set_service_mode(ports=self.port_handle, enabled=False)
 
     def cleanup(self):
         """Cleanup Trex driver."""
@@ -777,3 +862,7 @@ class TRex(AbstractTrafficGenerator):
             except STLError:
                 # TRex does not like a reset while in disconnected state
                 pass
+
+    def set_service_mode(self, enabled=True):
+        """Enable/disable the 'service_mode'."""
+        self.client.set_service_mode(ports=self.port_handle, enabled=enabled)