NFVBENCH-153 Add support for python3
[nfvbench.git] / nfvbench / traffic_gen / trex_gen.py
index a472774..c2e0854 100644 (file)
@@ -25,12 +25,6 @@ from nfvbench.traffic_server import TRexTrafficServer
 from nfvbench.utils import cast_integer
 from nfvbench.utils import timeout
 from nfvbench.utils import TimeoutError
-from traffic_base import AbstractTrafficGenerator
-from traffic_base import TrafficGeneratorException
-import traffic_utils as utils
-from traffic_utils import IMIX_AVG_L2_FRAME_SIZE
-from traffic_utils import IMIX_L2_SIZES
-from traffic_utils import IMIX_RATIOS
 
 # pylint: disable=import-error
 from trex.common.services.trex_service_arp import ServiceARP
@@ -57,9 +51,15 @@ from trex.stl.api import ThreeBytesField
 from trex.stl.api import UDP
 from trex.stl.api import XByteField
 
-
 # pylint: enable=import-error
 
+from .traffic_base import AbstractTrafficGenerator
+from .traffic_base import TrafficGeneratorException
+from . import traffic_utils as utils
+from .traffic_utils import IMIX_AVG_L2_FRAME_SIZE
+from .traffic_utils import IMIX_L2_SIZES
+from .traffic_utils import IMIX_RATIOS
+
 class VXLAN(Packet):
     """VxLAN class."""
 
@@ -422,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):
@@ -437,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)
@@ -447,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:
@@ -468,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
@@ -482,14 +489,18 @@ class TRex(AbstractTrafficGenerator):
                 pkt = self._create_pkt(stream_cfg, 68)
 
         if latency:
+            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),
+                                                                        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),
+                                         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
 
@@ -500,7 +511,7 @@ class TRex(AbstractTrafficGenerator):
     def __connect_after_start(self):
         # after start, Trex may take a bit of time to initialize
         # so we need to retry a few times
-        for it in xrange(self.config.generic_retry_count):
+        for it in range(self.config.generic_retry_count):
             try:
                 time.sleep(1)
                 self.client.connect()
@@ -508,7 +519,7 @@ class TRex(AbstractTrafficGenerator):
             except Exception as ex:
                 if it == (self.config.generic_retry_count - 1):
                     raise
-                LOG.info("Retrying connection to TRex (%s)...", ex.message)
+                LOG.info("Retrying connection to TRex (%s)...", ex.msg)
 
     def connect(self):
         """Connect to the TRex server."""
@@ -573,7 +584,7 @@ class TRex(AbstractTrafficGenerator):
             if os.path.isfile(logpath):
                 # Wait for TRex to finish writing error message
                 last_size = 0
-                for _ in xrange(self.config.generic_retry_count):
+                for _ in range(self.config.generic_retry_count):
                     size = os.path.getsize(logpath)
                     if size == last_size:
                         # probably not writing anymore
@@ -598,7 +609,7 @@ class TRex(AbstractTrafficGenerator):
         LOG.info("Restarting TRex ...")
         self.__stop_server()
         # Wait for server stopped
-        for _ in xrange(self.config.generic_retry_count):
+        for _ in range(self.config.generic_retry_count):
             time.sleep(1)
             if not self.client.is_connected():
                 LOG.info("TRex is stopped...")
@@ -614,7 +625,7 @@ class TRex(AbstractTrafficGenerator):
                     self.client.release(ports=ports)
                 self.client.server_shutdown()
             except STLError as e:
-                LOG.warn('Unable to stop TRex. Error: %s', e)
+                LOG.warning('Unable to stop TRex. Error: %s', e)
         else:
             LOG.info('Using remote TRex. Unable to stop TRex')
 
@@ -679,12 +690,12 @@ class TRex(AbstractTrafficGenerator):
                     arp_dest_macs[port] = dst_macs
                     LOG.info('ARP resolved successfully for port %s', port)
                     break
-                else:
-                    retry = attempt + 1
-                    LOG.info('Retrying ARP for: %s (retry %d/%d)',
-                             unresolved, retry, self.config.generic_retry_count)
-                    if retry < self.config.generic_retry_count:
-                        time.sleep(self.config.generic_poll_sec)
+
+                retry = attempt + 1
+                LOG.info('Retrying ARP for: %s (retry %d/%d)',
+                         unresolved, retry, self.config.generic_retry_count)
+                if retry < self.config.generic_retry_count:
+                    time.sleep(self.config.generic_poll_sec)
             else:
                 LOG.error('ARP timed out for port %s (resolved %d out of %d)',
                           port,
@@ -692,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
@@ -834,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."""
@@ -845,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)