From 7772d0893579d0627c10515aeb6d9c9c8204316d Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Wed, 29 Jun 2016 16:18:13 +0300 Subject: flow stat/latency error counters code + documentation --- .../stl/trex_stl_lib/trex_stl_client.py | 51 ++++++++++++++++------ .../stl/trex_stl_lib/trex_stl_stats.py | 18 ++++++++ 2 files changed, 56 insertions(+), 13 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 c1833754..acedf24f 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 @@ -1284,7 +1284,7 @@ class STLClient(object): **total** and per port statistics contain dictionary with following format. - Most of the bytes counters (unless specified otherwise) are in L2 layer including the FCS. e.g. minimum packet size in 64 bytes + Most of the bytes counters (unless specified otherwise) are in L2 layer, including the Ethernet FCS. e.g. minimum packet size is 64 bytes =============================== =============== key Meaning @@ -1303,21 +1303,34 @@ class STLClient(object): .. _flow_stats: - **flow_stats** contains dictionaries per packet group id (pg id). Each one with the following structure. + **flow_stats** contains :ref:`global dictionary `, and dictionaries per packet group id (pg id). See structures below. + + **per pg_id flow stat** dictionaries have following structure: ================= =============== key Meaning ================= =============== - rx_bps Receivd bytes per second rate - rx_bps_l1 Receivd bytes per second rate, including layer one + rx_bps Received bytes per second rate + rx_bps_l1 Received 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_bps Transmit bytes per second rate + tx_bps_l1 Transmit 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 + tx_pps Transmit packets per second rate + ================= =============== + + .. _flow_stats_global: + + **global flow stats** dictionary has the following structure: + + ================= =============== + key Meaning + ================= =============== + rx_err Number of flow statistics packets received that we could not associate to any pg_id. This can happen if latency on the used setup is large. See :ref:`wait_on_traffic ` rx_delay_ms parameter for details. + tx_err Number of flow statistics packets transmitted that we could not associate to any pg_id. This is never expected. If you see this different than 0, please report. ================= =============== .. _global: @@ -1340,7 +1353,9 @@ class STLClient(object): .. _latency: - **latency** contains dictionary per packet group id (pg id). Each one with the following structure. + **latency** contains :ref:`global dictionary `, and dictionaries per packet group id (pg id). Each one with the following structure. + + **per pg_id latency stat** dictionaries have following structure: =========================== =============== key Meaning @@ -1394,7 +1409,16 @@ class STLClient(object): total_min Minimum latency measured over the stream lifetime (in usec). ================= =============== + .. _lat_stats_global: + **global latency stats** dictionary has the following structure: + + ================= =============== + key Meaning + ================= =============== + old_flow Number of latency statistics packets received that we could not associate to any pg_id. This can happen if latency on the used setup is large. See :ref:`wait_on_traffic ` rx_delay_ms parameter for details. + bad_hdr Number of latency packets received with bad latency data. This can happen becuase of garbage packets in the network, or if the DUT causes packet corruption. + ================= =============== :raises: None @@ -2274,6 +2298,8 @@ class STLClient(object): @__api_check(True) def wait_on_traffic (self, ports = None, timeout = 60, rx_delay_ms = 10): """ + .. _wait_on_traffic: + Block until traffic on specified port(s) has ended :parameters: @@ -2284,12 +2310,11 @@ class STLClient(object): timeout in seconds rx_delay_ms : int - time to wait until RX filters are removed - this value should reflect the time it takes - packets which were transmitted to arrive + Time to wait (in milliseconds) after last packet was sent, until RX filters used for + measuring flow statistics and latency are removed. + This value should reflect the time it takes packets which were transmitted to arrive to the destination. - after this time the RX filters will be removed - + After this time, RX filters will be removed, and packets arriving for per flow statistics feature and latency flows will be counted as errors. :raises: + :exc:`STLTimeoutError` - in case timeout has expired 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 3effa1f0..f74c8fa5 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 @@ -1010,6 +1010,13 @@ class CLatencyStats(CTRexStats): snapshot = {} output = {} + output['global'] = {} + for field in ['bad_hdr', 'old_flow']: + if 'global' in snapshot and field in snapshot['global']: + output['global'][field] = snapshot['global'][field] + else: + output['global'][field] = 0 + # we care only about the current active keys pg_ids = list(filter(is_intable, snapshot.keys())) @@ -1107,6 +1114,14 @@ class CRxStats(CTRexStats): # copy timestamp field output['ts'] = current['ts'] + # global (not per pg_id) error counters + output['global'] = {} + for field in ['rx_err', 'tx_err']: + output['global'][field] = {} + if 'global' in current and field in current['global']: + for port in current['global'][field]: + output['global'][field][int(port)] = current['global'][field][port] + # we care only about the current active keys pg_ids = list(filter(is_intable, current.keys())) @@ -1254,6 +1269,9 @@ class CRxStats(CTRexStats): for pg_id, value in self.latest_stats.items(): # skip non ints if not is_intable(pg_id): + # 'global' stats are in the same level of the pg_ids. We do want them to go to the user + if pg_id == 'global': + stats[pg_id] = value continue # bare counters stats[int(pg_id)] = {} -- cgit 1.2.3-korg