From b646f5c0d88d90322291a5a0a021d77a4824187a Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Sun, 5 Jun 2016 16:38:22 +0300 Subject: remove STLSim from pcap example, remove search of BP-sim path --- .../trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py index 11e80b9a..62724e64 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py @@ -40,18 +40,11 @@ class BpSimException(Exception): # stateless simulation class STLSim(object): - def __init__ (self, bp_sim_path = None, handler = 0, port_id = 0, api_h = "dummy"): + def __init__ (self, bp_sim_path, handler = 0, port_id = 0, api_h = "dummy"): - if not bp_sim_path: - # auto find scripts - m = re.match(".*/trex-core", os.getcwd()) - if not m: - raise STLError('cannot find BP sim path, please provide it') - - self.bp_sim_path = os.path.join(m.group(0), 'scripts') - - else: - self.bp_sim_path = bp_sim_path + self.bp_sim_path = os.path.abspath(bp_sim_path) + if not os.path.exists(self.bp_sim_path): + raise STLError('BP sim path %s does not exist' % self.bp_sim_path) # dummies self.handler = handler -- cgit 1.2.3-korg From 07d5732a49bab856ab773e4a4762a7983cb5a538 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Thu, 9 Jun 2016 11:55:31 +0300 Subject: typo (GitHub pull request #14) --- scripts/automation/trex_control_plane/stl/trex_stl_lib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/__init__.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/__init__.py index ba9459c1..c6e14df3 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/__init__.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/__init__.py @@ -1,7 +1,7 @@ import sys if sys.version_info < (2, 7): - print("\n**** TRex STL pacakge requires Python version >= 2.7 ***\n") + print("\n**** TRex STL package requires Python version >= 2.7 ***\n") exit(-1) from . import trex_stl_ext -- cgit 1.2.3-korg From 0422016ab056245449e0e5bdf0dceef2c4f06e31 Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 20 Jun 2016 14:30:46 +0300 Subject: bug: multiplier can be string or unicode --- .../stl/trex_stl_lib/trex_stl_client.py | 41 +++++++++------------- .../stl/trex_stl_lib/trex_stl_exceptions.py | 8 ++++- .../stl/trex_stl_lib/utils/common.py | 1 + .../stl/trex_stl_lib/utils/parsing_opts.py | 4 --- 4 files changed, 25 insertions(+), 29 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index 22895a75..4d1125c8 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -1700,6 +1700,11 @@ class STLClient(object): ports = self._validate_port_list(ports) + validate_type('mult', mult, basestring) + validate_type('force', force, bool) + validate_type('duration', duration, (int, float)) + validate_type('total', total, bool) + # verify multiplier mult_obj = parsing_opts.decode_multiplier(mult, allow_update = False, @@ -1707,17 +1712,6 @@ class STLClient(object): if not mult_obj: raise STLArgumentError('mult', mult) - # some type checkings - - if not type(force) is bool: - raise STLArgumentError('force', force) - - if not isinstance(duration, (int, float)): - raise STLArgumentError('duration', duration) - - if not type(total) is bool: - raise STLArgumentError('total', total) - # verify ports are stopped or force stop them active_ports = list(set(self.get_active_ports()).intersection(ports)) @@ -1762,11 +1756,12 @@ class STLClient(object): """ - ports = ports if ports is not None else self.get_active_ports() - ports = self._validate_port_list(ports) + if ports is None: + ports = self.get_active_ports() + if not ports: + return - if not ports: - return + ports = self._validate_port_list(ports) self.logger.pre_cmd("Stopping traffic on port(s) {0}:".format(ports)) rc = self.__stop(ports) @@ -1815,6 +1810,9 @@ class STLClient(object): ports = ports if ports is not None else self.get_active_ports() ports = self._validate_port_list(ports) + validate_type('mult', mult, basestring) + validate_type('force', force, bool) + validate_type('total', total, bool) # verify multiplier mult_obj = parsing_opts.decode_multiplier(mult, @@ -1823,10 +1821,6 @@ class STLClient(object): if not mult_obj: raise STLArgumentError('mult', mult) - # verify total - if not type(total) is bool: - raise STLArgumentError('total', total) - # call low level functions self.logger.pre_cmd("Updating traffic on port(s) {0}:".format(ports)) @@ -2050,6 +2044,10 @@ class STLClient(object): ports = ports if ports is not None else self.get_acquired_ports() ports = self._validate_port_list(ports) + validate_type('mult', mult, basestring) + validate_type('duration', duration, (int, float)) + validate_type('total', total, bool) + # verify multiplier mult_obj = parsing_opts.decode_multiplier(mult, @@ -2058,11 +2056,6 @@ class STLClient(object): if not mult_obj: raise STLArgumentError('mult', mult) - - if not isinstance(duration, (int, float)): - raise STLArgumentError('duration', duration) - - self.logger.pre_cmd("Validating streams on port(s) {0}:".format(ports)) rc = self.__validate(ports) self.logger.post_cmd(rc) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py index 3c443ba6..b6fad865 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py @@ -4,6 +4,11 @@ import linecache from .utils.text_opts import * +try: + basestring +except NameError: + basestring = str + # basic error for API class STLError(Exception): def __init__ (self, msg): @@ -56,7 +61,8 @@ class STLArgumentError(STLError): # raised when argument type is not valid for operation class STLTypeError(STLError): def __init__ (self, arg_name, arg_type, valid_types): - self.msg = "Argument: '%s' invalid type: %s, expecting type(s): %s." % (arg_name, arg_type, valid_types) + self.msg = "Argument: '%s' invalid type: '%s', expecting type(s): %s." % (arg_name, arg_type.__name__, + [t.__name__ for t in valid_types] if isinstance(valid_types, tuple) else valid_types.__name__) # raised when timeout occurs class STLTimeoutError(STLError): diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py index b4903e81..6835ea5f 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py @@ -64,3 +64,4 @@ def list_difference (l1, l2): def is_sub_list (l1, l2): return set(l1) <= set(l2) + diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py index 98e3ca6a..9ef14612 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py @@ -90,10 +90,6 @@ match_multiplier_help = """Multiplier should be passed in the following format: # value should be divided def decode_multiplier(val, allow_update = False, divide_count = 1): - # must be string - if not isinstance(val, str): - return None - # do we allow updates ? +/- if not allow_update: match = re.match("^(\d+(\.\d+)?)(bps|kbps|mbps|gbps|pps|kpps|mpps|%?)$", val) -- cgit 1.2.3-korg From 3bf54917e0d8817dbadaae73a7545a011676cccf Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Tue, 21 Jun 2016 15:30:16 +0300 Subject: profile fixes --- .../stl/trex_stl_lib/utils/parsing_opts.py | 12 +++---- scripts/stl/burst_3st_1000pkt.py | 10 +++--- scripts/stl/burst_3st_600pkt.py | 10 +++--- scripts/stl/burst_3st_loop_x_times.py | 10 +++--- scripts/stl/flow_stats.py | 34 +++++++++++-------- scripts/stl/flow_stats_latency.py | 38 ++++++++++++++-------- scripts/stl/imix.py | 2 +- scripts/stl/multi_burst_2st_1000pkt.py | 8 ++--- scripts/stl/simple_3st.py | 6 ++-- scripts/stl/udp_1pkt.py | 4 +-- scripts/stl/udp_1pkt_1mac.py | 4 +-- scripts/stl/udp_1pkt_1mac_override.py | 4 +-- scripts/stl/udp_1pkt_1mac_step.py | 4 +-- scripts/stl/udp_1pkt_mac.py | 4 +-- scripts/stl/udp_1pkt_mac_mask1.py | 4 +-- scripts/stl/udp_1pkt_mac_mask2.py | 4 +-- scripts/stl/udp_1pkt_mac_mask3.py | 4 +-- scripts/stl/udp_1pkt_mac_mask5.py | 4 +-- scripts/stl/udp_1pkt_mac_step.py | 4 +-- scripts/stl/udp_1pkt_range_clients.py | 4 +-- scripts/stl/udp_1pkt_range_clients_split.py | 4 +-- scripts/stl/udp_1pkt_range_clients_split_garp.py | 2 +- scripts/stl/udp_1pkt_src_ip_split.py | 4 +-- scripts/stl/udp_1pkt_src_ip_split_latency.py | 4 +-- scripts/stl/udp_1pkt_tuple_gen.py | 2 +- scripts/stl/udp_1pkt_tuple_gen_split.py | 4 +-- scripts/stl/udp_3pkt_pcap.py | 6 ++-- 27 files changed, 109 insertions(+), 91 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py index 9ef14612..bb28d3af 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py @@ -240,26 +240,24 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'type': int}), PROMISCUOUS: ArgumentPack(['--prom'], - {'help': "sets port promiscuous on", + {'help': "Sets port promiscuous on", 'dest': "prom", 'default': None, 'action': "store_true"}), - TUNABLES: ArgumentPack(['-t'], - {'help': "sets tunable for a profile", + {'help': "Sets tunables for a profile. Example: '-t fsize=100,pg_id=7'", + 'metavar': 'T1=VAL[,T2=VAL ...]', 'dest': "tunables", 'default': None, 'type': decode_tunables}), - NO_PROMISCUOUS: ArgumentPack(['--no_prom'], - {'help': "sets port promiscuous off", + {'help': "Sets port promiscuous off", 'dest': "prom", 'default': None, 'action': "store_false"}), - PORT_LIST: ArgumentPack(['--port', '-p'], {"nargs": '+', 'dest':'ports', @@ -465,4 +463,4 @@ def gen_parser(stateless_client, op_name, description, *args): if __name__ == "__main__": - pass \ No newline at end of file + pass diff --git a/scripts/stl/burst_3st_1000pkt.py b/scripts/stl/burst_3st_1000pkt.py index 8fcdca57..88a30c84 100644 --- a/scripts/stl/burst_3st_1000pkt.py +++ b/scripts/stl/burst_3st_1000pkt.py @@ -10,27 +10,27 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt1 = Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt2 = Ether()/IP(src="16.0.0.3",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' - return STLProfile( [ STLStream( isg = 10.0, # star in delay + return STLProfile( [ STLStream( isg = 10.0, # start in delay name ='S0', packet = STLPktBuilder(pkt = base_pkt/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = self.burst_size), next = 'S1'), # point to next stream - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S0 name ='S1', packet = STLPktBuilder(pkt = base_pkt1/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = self.burst_size), next = 'S2' ), - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S1 name ='S2', packet = STLPktBuilder(pkt = base_pkt2/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = self.burst_size ) diff --git a/scripts/stl/burst_3st_600pkt.py b/scripts/stl/burst_3st_600pkt.py index 978c8920..b81f256b 100644 --- a/scripts/stl/burst_3st_600pkt.py +++ b/scripts/stl/burst_3st_600pkt.py @@ -9,27 +9,27 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt1 = Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt2 = Ether()/IP(src="16.0.0.3",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' - return STLProfile( [ STLStream( isg = 10.0, # star in delay + return STLProfile( [ STLStream( isg = 10.0, # start in delay name ='S0', packet = STLPktBuilder(pkt = base_pkt/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = 10), next = 'S1'), # point to next stream - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S0 name ='S1', packet = STLPktBuilder(pkt = base_pkt1/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = 20), next = 'S2' ), - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S1 name ='S2', packet = STLPktBuilder(pkt = base_pkt2/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = 30 ) diff --git a/scripts/stl/burst_3st_loop_x_times.py b/scripts/stl/burst_3st_loop_x_times.py index 175b8315..ec217e9f 100644 --- a/scripts/stl/burst_3st_loop_x_times.py +++ b/scripts/stl/burst_3st_loop_x_times.py @@ -9,27 +9,27 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt1 = Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt2 = Ether()/IP(src="16.0.0.3",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' - return STLProfile( [ STLStream( isg = 10.0, # star in delay + return STLProfile( [ STLStream( isg = 10.0, # start in delay name ='S0', packet = STLPktBuilder(pkt = base_pkt/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = 1), next = 'S1'), # point to next stream - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S0 name ='S1', packet = STLPktBuilder(pkt = base_pkt1/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = 2), next = 'S2' ), - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S1 name ='S2', packet = STLPktBuilder(pkt = base_pkt2/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = 3 ), diff --git a/scripts/stl/flow_stats.py b/scripts/stl/flow_stats.py index cbb5ac21..a50ba848 100644 --- a/scripts/stl/flow_stats.py +++ b/scripts/stl/flow_stats.py @@ -1,21 +1,29 @@ from trex_stl_lib.api import * -import os - -# stream from pcap file. continues pps 10 in sec -CP = os.path.join(os.path.dirname(__file__)) class STLS1(object): - - def get_streams (self, direction = 0, **kwargs): - return [STLStream(packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_64B_no_crc.pcap")), # path relative to pwd - mode = STLTXCont(pps=1000), - flow_stats = STLFlowStats(pg_id = 7)), - - STLStream(packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_594B_no_crc.pcap")), # path relative to pwd - mode = STLTXCont(pps=5000), - flow_stats = STLFlowStats(pg_id = 12)) + """ + Create flow stat stream of UDP packet. + Can specify using tunables the packet length (fsize) and packet group id (pg_id) + """ + def __init__ (self): + self.fsize = 64 + self.pg_id = 0 + + def _create_stream (self): + size = self.fsize - 4; # HW will add 4 bytes ethernet CRC + base_pkt = Ether() / IP(src = "16.0.0.1", dst = "48.0.0.1") / UDP(dport = 12, sport = 1025) + pad = max(0, size - len(base_pkt)) * 'x' + pkt = STLPktBuilder(pkt = base_pkt/pad) + + return [STLStream(packet = pkt, + mode = STLTXCont(pps=1), + flow_stats = STLFlowStats(pg_id = self.pg_id)) ] + def get_streams (self, fsize = 64, pg_id = 7, **kwargs): + self.fsize = fsize + self.pg_id = pg_id + return self._create_stream() # dynamic load - used for trex console or simulator def register(): diff --git a/scripts/stl/flow_stats_latency.py b/scripts/stl/flow_stats_latency.py index e1541272..8460fcfc 100644 --- a/scripts/stl/flow_stats_latency.py +++ b/scripts/stl/flow_stats_latency.py @@ -1,21 +1,33 @@ from trex_stl_lib.api import * -import os - -# stream from pcap file. continues pps 10 in sec -CP = os.path.join(os.path.dirname(__file__)) class STLS1(object): - - def get_streams (self, direction = 0, **kwargs): - return [STLStream(packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_64B_no_crc.pcap")), # path relative to pwd - mode = STLTXCont(pps=1000), - flow_stats = STLFlowLatencyStats(pg_id = 1 + kwargs['port_id'])), - - STLStream(packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_594B_no_crc.pcap")), # path relative to pwd - mode = STLTXCont(pps=5000), - flow_stats = STLFlowLatencyStats(pg_id = 50 + kwargs['port_id'])) + """ + Create flow stat latency stream of UDP packet. + Can specify using tunables the packet length (fsize) and packet group id (pg_id) + Since we can't have two latency streams with same pg_id, in order to be able to start this profile + on more than one port, we add port_id to the pg_id + """ + + def __init__ (self): + self.fsize = 64 + self.pg_id = 0 + + def _create_stream (self): + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS + base_pkt = Ether() / IP(src = "16.0.0.1", dst = "48.0.0.1") / UDP(dport = 12, sport = 1025) + pad = max(0, size - len(base_pkt)) * 'x' + pkt = STLPktBuilder(pkt = base_pkt/pad) + + return [STLStream(packet = pkt, + mode = STLTXCont(pps=1), + flow_stats = STLFlowLatencyStats(pg_id = self.pg_id)) ] + def get_streams (self, fsize = 64, pg_id = 7, **kwargs): + self.fsize = fsize + self.pg_id = pg_id + kwargs['port_id'] + return self._create_stream() + # dynamic load - used for trex console or simulator def register(): diff --git a/scripts/stl/imix.py b/scripts/stl/imix.py index 82edbfa5..c9b1ff17 100644 --- a/scripts/stl/imix.py +++ b/scripts/stl/imix.py @@ -18,7 +18,7 @@ class STLImix(object): def create_stream (self, size, pps, isg, vm ): - # create a base packet and pad it to size + # Create base packet and pad it to size base_pkt = Ether()/IP()/UDP() pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/multi_burst_2st_1000pkt.py b/scripts/stl/multi_burst_2st_1000pkt.py index 1a43ae96..fe4b4eac 100644 --- a/scripts/stl/multi_burst_2st_1000pkt.py +++ b/scripts/stl/multi_burst_2st_1000pkt.py @@ -10,20 +10,20 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt1 = Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' - return STLProfile( [ STLStream( isg = 10.0, # star in delay + return STLProfile( [ STLStream( isg = 10.0, # start in delay name ='S0', packet = STLPktBuilder(pkt = base_pkt/pad), mode = STLTXSingleBurst( pps = 10, total_pkts = self.burst_size), next = 'S1'), # point to next stream - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S0 name ='S1', packet = STLPktBuilder(pkt = base_pkt1/pad), mode = STLTXMultiBurst( pps = 1000,pkts_per_burst = 4,ibg = 1000000.0,count = 5) diff --git a/scripts/stl/simple_3st.py b/scripts/stl/simple_3st.py index 8979057c..ae388f13 100644 --- a/scripts/stl/simple_3st.py +++ b/scripts/stl/simple_3st.py @@ -8,15 +8,15 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt1 = Ether()/IP(src="16.0.0.2",dst="48.0.0.1")/UDP(dport=12,sport=1025) base_pkt2 = Ether()/IP(src="16.0.0.3",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' - return STLProfile( [ STLStream( isg = 1.0, # star in delay in usec + return STLProfile( [ STLStream( isg = 1.0, # start in delay in usec packet = STLPktBuilder(pkt = base_pkt/pad), mode = STLTXCont( pps = 10), ), diff --git a/scripts/stl/udp_1pkt.py b/scripts/stl/udp_1pkt.py index 13516ecd..f2601d79 100644 --- a/scripts/stl/udp_1pkt.py +++ b/scripts/stl/udp_1pkt.py @@ -18,8 +18,8 @@ class STLS1(object): return t[self.mode] def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = self.create_pkt_base () diff --git a/scripts/stl/udp_1pkt_1mac.py b/scripts/stl/udp_1pkt_1mac.py index 4adffd7a..ade5b592 100644 --- a/scripts/stl/udp_1pkt_1mac.py +++ b/scripts/stl/udp_1pkt_1mac.py @@ -8,8 +8,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_1mac_override.py b/scripts/stl/udp_1pkt_1mac_override.py index 04700420..410c2630 100644 --- a/scripts/stl/udp_1pkt_1mac_override.py +++ b/scripts/stl/udp_1pkt_1mac_override.py @@ -10,8 +10,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS # Ether(src="00:bb:12:34:56:01") this will tell TRex to take the src-mac from packet and not from config file base_pkt = Ether(src="00:bb:12:34:56:01")/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) diff --git a/scripts/stl/udp_1pkt_1mac_step.py b/scripts/stl/udp_1pkt_1mac_step.py index 1e5e4bd8..69a84d67 100644 --- a/scripts/stl/udp_1pkt_1mac_step.py +++ b/scripts/stl/udp_1pkt_1mac_step.py @@ -9,8 +9,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_mac.py b/scripts/stl/udp_1pkt_mac.py index 598e2074..93376aff 100644 --- a/scripts/stl/udp_1pkt_mac.py +++ b/scripts/stl/udp_1pkt_mac.py @@ -9,8 +9,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_mac_mask1.py b/scripts/stl/udp_1pkt_mac_mask1.py index efb45da7..9a4862a9 100644 --- a/scripts/stl/udp_1pkt_mac_mask1.py +++ b/scripts/stl/udp_1pkt_mac_mask1.py @@ -9,8 +9,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_mac_mask2.py b/scripts/stl/udp_1pkt_mac_mask2.py index b95a32e3..748ddbb1 100644 --- a/scripts/stl/udp_1pkt_mac_mask2.py +++ b/scripts/stl/udp_1pkt_mac_mask2.py @@ -9,8 +9,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_mac_mask3.py b/scripts/stl/udp_1pkt_mac_mask3.py index 7a5d2864..f3593ccb 100644 --- a/scripts/stl/udp_1pkt_mac_mask3.py +++ b/scripts/stl/udp_1pkt_mac_mask3.py @@ -9,8 +9,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_mac_mask5.py b/scripts/stl/udp_1pkt_mac_mask5.py index 75f9bbf1..901c2d98 100644 --- a/scripts/stl/udp_1pkt_mac_mask5.py +++ b/scripts/stl/udp_1pkt_mac_mask5.py @@ -9,8 +9,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_mac_step.py b/scripts/stl/udp_1pkt_mac_step.py index 0ebd035d..a2444905 100644 --- a/scripts/stl/udp_1pkt_mac_step.py +++ b/scripts/stl/udp_1pkt_mac_step.py @@ -9,8 +9,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_range_clients.py b/scripts/stl/udp_1pkt_range_clients.py index 9bd3c335..f1fc57f4 100644 --- a/scripts/stl/udp_1pkt_range_clients.py +++ b/scripts/stl/udp_1pkt_range_clients.py @@ -16,8 +16,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether(src="00:00:dd:dd:00:01")/IP(src="55.55.1.1",dst="58.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_range_clients_split.py b/scripts/stl/udp_1pkt_range_clients_split.py index a8c71c0a..9bf09ba4 100644 --- a/scripts/stl/udp_1pkt_range_clients_split.py +++ b/scripts/stl/udp_1pkt_range_clients_split.py @@ -16,8 +16,8 @@ class STLS1(object): def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether(src="00:00:dd:dd:00:01")/IP(src="55.55.1.1",dst="58.0.0.1")/UDP(dport=12,sport=1025) pad = max(0, size - len(base_pkt)) * 'x' diff --git a/scripts/stl/udp_1pkt_range_clients_split_garp.py b/scripts/stl/udp_1pkt_range_clients_split_garp.py index d7f48ed7..4bad8afd 100644 --- a/scripts/stl/udp_1pkt_range_clients_split_garp.py +++ b/scripts/stl/udp_1pkt_range_clients_split_garp.py @@ -10,7 +10,7 @@ class STLS1(object): self.num_clients =3000; # max is 16bit def create_stream (self): - # create a base packet and pad it to size + # Create base packet and pad it to size base_pkt = Ether(src="00:00:dd:dd:00:01",dst="ff:ff:ff:ff:ff:ff")/ARP(psrc="55.55.1.1",hwsrc="00:00:dd:dd:00:01", hwdst="00:00:dd:dd:00:01", pdst="55.55.1.1") vm = STLScVmRaw( [ STLVmFlowVar(name="mac_src", min_value=1, max_value=self.num_clients, size=2, op="inc"), diff --git a/scripts/stl/udp_1pkt_src_ip_split.py b/scripts/stl/udp_1pkt_src_ip_split.py index 778ccf54..48e02433 100644 --- a/scripts/stl/udp_1pkt_src_ip_split.py +++ b/scripts/stl/udp_1pkt_src_ip_split.py @@ -9,8 +9,8 @@ class STLS1(object): self.fsize =64; def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) diff --git a/scripts/stl/udp_1pkt_src_ip_split_latency.py b/scripts/stl/udp_1pkt_src_ip_split_latency.py index 2d81f756..4b297d70 100644 --- a/scripts/stl/udp_1pkt_src_ip_split_latency.py +++ b/scripts/stl/udp_1pkt_src_ip_split_latency.py @@ -16,8 +16,8 @@ class STLS1(object): def create_stream (self, dir,port_id): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS if dir==0: src_ip="16.0.0.1" diff --git a/scripts/stl/udp_1pkt_tuple_gen.py b/scripts/stl/udp_1pkt_tuple_gen.py index 4e9ab12d..733d511b 100644 --- a/scripts/stl/udp_1pkt_tuple_gen.py +++ b/scripts/stl/udp_1pkt_tuple_gen.py @@ -3,7 +3,7 @@ from trex_stl_lib.api import * class STLS1(object): def create_stream (self, packet_len): - # create a base packet and pad it to size + # Create base packet and pad it to size base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) diff --git a/scripts/stl/udp_1pkt_tuple_gen_split.py b/scripts/stl/udp_1pkt_tuple_gen_split.py index e7a33b22..cc9eb5fc 100644 --- a/scripts/stl/udp_1pkt_tuple_gen_split.py +++ b/scripts/stl/udp_1pkt_tuple_gen_split.py @@ -9,8 +9,8 @@ class STLS1(object): self.fsize =64; def create_stream (self): - # create a base packet and pad it to size - size = self.fsize - 4; # no FCS + # Create base packet and pad it to size + size = self.fsize - 4; # HW will add 4 bytes ethernet FCS base_pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025) diff --git a/scripts/stl/udp_3pkt_pcap.py b/scripts/stl/udp_3pkt_pcap.py index 19ff46bc..2983f9a1 100644 --- a/scripts/stl/udp_3pkt_pcap.py +++ b/scripts/stl/udp_3pkt_pcap.py @@ -9,19 +9,19 @@ class STLS1(object): def create_stream (self): - return STLProfile( [ STLStream( isg = 10.0, # star in delay + return STLProfile( [ STLStream( isg = 10.0, # start in delay name ='S0', packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_64B_no_crc.pcap")), mode = STLTXSingleBurst( pps = 10, total_pkts = 10), next = 'S1'), # point to next stream - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S0 name ='S1', packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_594B_no_crc.pcap")), mode = STLTXSingleBurst( pps = 10, total_pkts = 20), next = 'S2' ), - STLStream( self_start = False, # stream is disabled enable trow S0 + STLStream( self_start = False, # Stream is disabled. Will run because it is pointed from S1 name ='S2', packet = STLPktBuilder(pkt = os.path.join(CP, "yaml/udp_1518B_no_crc.pcap")), mode = STLTXSingleBurst( pps = 10, total_pkts = 30 ) -- cgit 1.2.3-korg From 9a1356bc05d663555b9b62971aff6219e17a767c Mon Sep 17 00:00:00 2001 From: imarom Date: Tue, 21 Jun 2016 09:54:04 +0300 Subject: FLOW_STATS: extract start_stream from the compiler to start_traffic --- .../trex_control_plane/common/text_opts.py | 3 + .../stl/trex_stl_lib/utils/text_opts.py | 3 + src/stateless/cp/trex_stateless_port.cpp | 73 ++++++++++++++++++++-- src/stateless/cp/trex_streams_compiler.cpp | 31 +++++---- src/stateless/cp/trex_streams_compiler.h | 4 +- 5 files changed, 91 insertions(+), 23 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/common/text_opts.py b/scripts/automation/trex_control_plane/common/text_opts.py index 78a0ab1f..ab0fd2f2 100755 --- a/scripts/automation/trex_control_plane/common/text_opts.py +++ b/scripts/automation/trex_control_plane/common/text_opts.py @@ -61,6 +61,9 @@ def format_time (t_sec): if t_sec < 0: return "infinite" + if t_sec == 0: + return "zero" + if t_sec < 1: # low numbers for unit in ['ms', 'usec', 'ns']: diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py index 7e0bf9e4..26e64dae 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py @@ -61,6 +61,9 @@ def format_time (t_sec): if t_sec < 0: return "infinite" + if t_sec == 0: + return "zero" + if t_sec < 1: # low numbers for unit in ['ms', 'usec', 'ns']: diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 4dc3e449..d736d09e 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -87,6 +87,68 @@ protected: } }; +/************************************* + * Streams Feeder + * A class that holds a temporary + * clone of streams that can be + * manipulated + * + * this is a RAII object meant for + * graceful cleanup + ************************************/ +class StreamsFeeder { +public: + StreamsFeeder(TrexStatelessPort *port) { + + /* start pesimistic */ + m_success = false; + + /* fetch the original streams */ + port->get_object_list(m_in_streams); + + for (const TrexStream *in_stream : m_in_streams) { + TrexStream *out_stream = in_stream->clone(true); + + get_stateless_obj()->m_rx_flow_stat.start_stream(out_stream); + + m_out_streams.push_back(out_stream); + } + } + + void set_status(bool status) { + m_success = status; + } + + vector &get_streams() { + return m_out_streams; + } + + /** + * RAII + */ + ~StreamsFeeder() { + for (int i = 0; i < m_out_streams.size(); i++) { + TrexStream *out_stream = m_out_streams[i]; + TrexStream *in_stream = m_in_streams[i]; + + if (m_success) { + /* success path */ + get_stateless_obj()->m_rx_flow_stat.copy_state(out_stream, in_stream); + } else { + /* fail path */ + get_stateless_obj()->m_rx_flow_stat.stop_stream(out_stream); + } + delete out_stream; + } + } + +private: + vector m_in_streams; + vector m_out_streams; + bool m_success; +}; + + /*************************** * trex stateless port * @@ -193,10 +255,7 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, /* caclulate the effective factor for DP */ double factor = calculate_effective_factor(mul, force); - /* fetch all the streams from the table */ - vector streams; - get_object_list(streams); - + StreamsFeeder feeder(this); /* compiler it */ std::vector compiled_objs; @@ -204,15 +263,19 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration, TrexStreamsCompiler compiler; bool rc = compiler.compile(m_port_id, - streams, + feeder.get_streams(), compiled_objs, get_dp_core_count(), factor, &fail_msg); + if (!rc) { + feeder.set_status(false); throw TrexException(fail_msg); } + feeder.set_status(true); + /* generate a message to all the relevant DP cores to start transmitting */ assert(m_pending_async_stop_event == TrexDpPortEvents::INVALID_ID); m_pending_async_stop_event = m_dp_events.create_event(new AsyncStopEvent()); diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp index d2fe416a..e54c5f9c 100644 --- a/src/stateless/cp/trex_streams_compiler.cpp +++ b/src/stateless/cp/trex_streams_compiler.cpp @@ -382,7 +382,13 @@ TrexStreamsCompiler::compile(uint8_t port_id, assert(dp_core_count > 0); try { - return compile_internal(port_id,streams,objs,dp_core_count,factor,fail_msg); + return compile_internal(port_id, + streams, + objs, + dp_core_count, + factor, + fail_msg); + } catch (const TrexException &ex) { if (fail_msg) { *fail_msg = ex.what(); @@ -411,7 +417,6 @@ TrexStreamsCompiler::compile_internal(uint8_t por GraphNodeMap nodes; - /* compile checks */ pre_compile_check(streams, nodes); @@ -474,7 +479,7 @@ TrexStreamsCompiler::compile_on_single_core(uint8_t } /* compile all the streams */ - for (auto stream : streams) { + for (auto const stream : streams) { /* skip non-enabled streams */ if (!stream->m_enabled) { @@ -507,7 +512,7 @@ TrexStreamsCompiler::compile_on_all_cores(uint8_t } /* compile all the streams */ - for (auto stream : streams) { + for (auto const stream : streams) { /* skip non-enabled streams */ if (!stream->m_enabled) { @@ -527,7 +532,7 @@ TrexStreamsCompiler::compile_on_all_cores(uint8_t * */ void -TrexStreamsCompiler::compile_stream(TrexStream *stream, +TrexStreamsCompiler::compile_stream(const TrexStream *stream, double factor, uint8_t dp_core_count, std::vector &objs, @@ -543,31 +548,25 @@ TrexStreamsCompiler::compile_stream(TrexStream *stream, new_next_id = nodes.get(stream->m_next_stream_id)->m_compressed_stream_id; } - TrexStream *fixed_rx_flow_stat_stream = stream->clone(true); - - get_stateless_obj()->m_rx_flow_stat.start_stream(fixed_rx_flow_stat_stream); - // CFlowStatRuleMgr keeps state of the stream object. We duplicated the stream here (in order not - // change the packet kept in the stream). We want the state to be saved in the original stream. - get_stateless_obj()->m_rx_flow_stat.copy_state(fixed_rx_flow_stat_stream, stream); - - fixed_rx_flow_stat_stream->update_rate_factor(factor); + /* we clone because we alter the stream now */ + std::unique_ptr tmp_stream(stream->clone(true)); + tmp_stream->update_rate_factor(factor); /* can this stream be split to many cores ? */ if ( (dp_core_count == 1) || (!stream->is_splitable(dp_core_count)) ) { - compile_stream_on_single_core(fixed_rx_flow_stat_stream, + compile_stream_on_single_core(tmp_stream.get(), dp_core_count, objs, new_id, new_next_id); } else { - compile_stream_on_all_cores(fixed_rx_flow_stat_stream, + compile_stream_on_all_cores(tmp_stream.get(), dp_core_count, objs, new_id, new_next_id); } - delete fixed_rx_flow_stat_stream; } /** diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h index 0ce71b49..7e674364 100644 --- a/src/stateless/cp/trex_streams_compiler.h +++ b/src/stateless/cp/trex_streams_compiler.h @@ -141,7 +141,7 @@ private: bool all_continues); - void compile_stream(TrexStream *stream, + void compile_stream(const TrexStream *stream, double factor, uint8_t dp_core_count, std::vector &objs, @@ -244,7 +244,7 @@ public: } double get_factor_pps(double req_pps) const { - if ( (req_pps - m_fixed.m_pps) <= 0 ) { + if ( (req_pps - m_fixed.m_pps) < 0 ) { std::stringstream ss; ss << "current stream configuration enforces a minimum rate of '" << m_fixed.m_pps << "' pps"; throw TrexException(ss.str()); -- cgit 1.2.3-korg From 9249859480c57960905f37282e9fa8047cf17484 Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Wed, 22 Jun 2016 14:22:54 +0300 Subject: STL Python API stats - add histogram key if it's absent --- scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py index 0ec98a0d..88a94865 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py @@ -1036,6 +1036,7 @@ class CLatencyStats(CTRexStats): output[int_pg_id]['latency']['total_min'] = min_val else: output[int_pg_id]['latency']['total_min'] = StatNotAvailable('total_min') + output[int_pg_id]['latency']['histogram'] = {} self.latest_stats = output return True -- cgit 1.2.3-korg From 24c22cf22f429c5214b1f1beba5145e7c4a2c4a8 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Thu, 23 Jun 2016 09:19:54 +0300 Subject: get_stats documentation --- .../stl/trex_stl_lib/trex_stl_client.py | 153 ++++++++++++++++++++- scripts/stl/flow_stats_latency.py | 4 +- 2 files changed, 151 insertions(+), 6 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib') diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index 4d1125c8..6dec6fa7 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -1254,18 +1254,161 @@ class STLClient(object): # get stats - def get_stats (self, ports = None, async_barrier = True): + def get_stats (self, ports = None, sync_now = True): + """ + Return dictionary containing statistics information gathered from the server. + + :parameters: + + ports - List of ports to retreive stats on. + If None, assume the request is for all acquired ports. + + sync_now - Boolean - If true, create a call to the server to get latest stats, and wait for result to arrive. Otherwise, return last stats saved in client cache. + Downside of putting True is a slight delay (few 10th msecs) in getting the result. For practical uses, value should be True. + :return: + Statistics dictionary of dictionaries with the following format: + + =============================== =============== + key Meaning + =============================== =============== + :ref:`numbers (0,1,..` Statistcs per port number + :ref:`total ` Sum of port statistics + :ref:`flow_stats ` Per flow statistics + :ref:`global ` Global statistics + :ref:`latency ` Per flow statistics regarding flow latency + =============================== =============== + + Below is description of each of the inner dictionaries. + + .. _total: + + **total** and per port statistics contain dictionary with following format. + + =============================== =============== + key Meaning + =============================== =============== + ibytes Number of input bytes + ierrors Number of input errors + ipackets Number of input packets + obytes Number of output bytes + oerrors Number of output errors + opackets Number of output packets + rx_bps Receive bytes per second rate + rx_pps Receive packet per second rate + tx_bps Transmit bytes per second rate + tx_pps Transmit packet per second rate + =============================== =============== + + .. _flow_stats: + + **flow_stats** contains dictionaries per packet group id (pg id). Each one with the following structure. + + ================= =============== + key Meaning + ================= =============== + rx_bps Receivd bytes per second rate + rx_bps_l1 Receivd bytes per second rate, including layer one + rx_bytes Total number of received bytes + rx_pkts Total number of received packets + rx_pps Received packets per second + tx_bps Transmitted bytes per second rate + tx_bps_l1 Transmitted bytes per second rate, including layer one + tx_bytes Total number of sent bytes + tx_pkts Total number of sent packets + tx_pps Transmit packets per second + ================= =============== + + .. _global: + + **global** + + ================= =============== + key Meaning + ================= =============== + bw_per_core Estimated byte rate Trex can support per core. This is calculated by extrapolation of current rate and load on transmitting cores. + cpu_util Estimate of the average utilization percentage of the transimitting cores + queue_full Total number of packets we could not transmit because NIC TX queue was full. This usually indicates that the rate we trying to transmit is too high for this port + rx_cpu_util Estimate of the utilization percentage of the core handling RX traffic + rx_drop_bps Received bytes per second drop rate + rx_bps Received bytes per second rate + rx_pps Received packets per second rate + tx_bps Transmit bytes per second rate + tx_pps Transmit packets per second rate + ================= =============== + + .. _latency: + + **latency** contains dictionary per packet group id (pg id). Each one with the following structure. + + =========================== =============== + key Meaning + =========================== =============== + :ref:`err_cntrs` Counters describing errors that occured with this pg id + :ref:`latency` Information regarding packet latency + =========================== =============== + + Following are the inner dictionaries of latency + + .. _err-cntrs: + + **err-cntrs** + + ================= =============== + key Meaning (see better explanation below the table) + ================= =============== + dropped How many packets were dropped. + dup How many packets were duplicated. + out_of_order How many packets we received out of order. + seq_too_high How many events of packet with sequence number too high we saw. + seq_too_low How many events of packet with sequence number too low we saw. + ================= =============== + + For calculating packet error events, we add sequence number to each packet's payload. We decide what went wrong only according to sequence number + of last packet received and that of the previous packet. 'seq_too_low' and 'seq_too_high' count events we see. 'dup', 'out_of_order' and 'dropped' + are heuristics we apply to try and understand what happened. They will be accurate in common error scenarios. + We describe few scenarios below to help understand this. + + Scenario 1: Received packet with seq num 10, and another one with seq num 10. We increment 'dup' and 'seq_too_low' by 1. + + Scenario 2: Received pacekt with seq num 10 and then packet with seq num 15. We assume 4 packets were dropped, and increment 'dropped' by 4, and 'seq_too_high' by 1. + We expect next packet to arrive with sequence number 16. + + Scenario 2 continue: Received packet with seq num 11. We increment 'seq_too_low' by 1. We increment 'out_of_order' by 1. We *decrement* 'dropped' by 1. + (We assume here that one of the packets we considered as dropped before, actually arrived out of order). + + + .. _lat_inner: + + **latency** + + ================= =============== + key Meaning + ================= =============== + average Average latency over the stream lifetime (usec). Total average is computed each sampling period by following formula: = /2 + /2 + histogram Dictionary describing logarithmic distribution histogram of packet latencies. Keys in the dictionary represent range of latencies (in usec). Values are the total number of packets received in this latency range. For example, an entry {100:13} would mean that we saw 13 packets with latency in the range between 100 and 200 usec. + jitter Jitter of latency samples, computed as described in :rfc:`3550#appendix-A.8` + last_max Maximum latency measured between last two data reads from server. + total_max Maximum latency measured over the stream lifetime (in usec). + total_min Minimum latency measured over the stream lifetime (in usec). + ================= =============== + + + + :raises: + None + + """ # by default use all acquired ports ports = ports if ports is not None else self.get_acquired_ports() ports = self._validate_port_list(ports) # check async barrier - if not type(async_barrier) is bool: - raise STLArgumentError('async_barrier', async_barrier) + if not type(sync_now) is bool: + raise STLArgumentError('sync_now', sync_now) # if the user requested a barrier - use it - if async_barrier: + if sync_now: rc = self.async_client.barrier() if not rc: raise STLError(rc) @@ -1279,7 +1422,7 @@ class STLClient(object): :parameters: ev_type_filter - 'info', 'warning' or a list of those - default is no filter + default: no filter :return: logged events diff --git a/scripts/stl/flow_stats_latency.py b/scripts/stl/flow_stats_latency.py index 8460fcfc..e053549e 100644 --- a/scripts/stl/flow_stats_latency.py +++ b/scripts/stl/flow_stats_latency.py @@ -6,6 +6,8 @@ class STLS1(object): Can specify using tunables the packet length (fsize) and packet group id (pg_id) Since we can't have two latency streams with same pg_id, in order to be able to start this profile on more than one port, we add port_id to the pg_id + Notice that for perfomance reasons, latency streams are not affected by -m flag, so + you can only change the pps value by editing the code. """ def __init__ (self): @@ -19,7 +21,7 @@ class STLS1(object): pkt = STLPktBuilder(pkt = base_pkt/pad) return [STLStream(packet = pkt, - mode = STLTXCont(pps=1), + mode = STLTXCont(pps=1000), flow_stats = STLFlowLatencyStats(pg_id = self.pg_id)) ] -- cgit 1.2.3-korg