summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/common
diff options
context:
space:
mode:
authorDan Klein <danklein10@gmail.com>2016-01-08 13:54:36 +0200
committerDan Klein <danklein10@gmail.com>2016-01-08 13:54:36 +0200
commit8e037c2bd51844dc7c42ce7b2339806d9dcb964b (patch)
treecd45e5214e3db13f214a0e68b3fd37f366438b80 /scripts/automation/trex_control_plane/common
parent8db09096b9dcf030b7dc744fbd7ee463d8e6fd1b (diff)
parent9fc980b8aa43cf53446eeeb5184f10a86476da28 (diff)
Merge branch 'dan_stateless'
Added the support for "streams" command Missing: 1. "--full" output 2. sync with server after crash 3. merging output for identical port streams
Diffstat (limited to 'scripts/automation/trex_control_plane/common')
-rwxr-xr-xscripts/automation/trex_control_plane/common/trex_stats.py46
-rwxr-xr-xscripts/automation/trex_control_plane/common/trex_streams.py34
2 files changed, 67 insertions, 13 deletions
diff --git a/scripts/automation/trex_control_plane/common/trex_stats.py b/scripts/automation/trex_control_plane/common/trex_stats.py
index f2a965b2..f792ab9b 100755
--- a/scripts/automation/trex_control_plane/common/trex_stats.py
+++ b/scripts/automation/trex_control_plane/common/trex_stats.py
@@ -55,10 +55,9 @@ def calculate_diff_raw (samples):
return total
-
-class CTRexStatsGenerator(object):
+class CTRexInfoGenerator(object):
"""
- This object is responsible of generating stats from objects maintained at
+ This object is responsible of generating stats and information from objects maintained at
CTRexStatelessClient and the ports.
"""
@@ -78,6 +77,19 @@ class CTRexStatsGenerator(object):
# ignore by returning empty object
return {}
+ def generate_streams_info(self, port_id_list, stream_id_list):
+ relevant_ports = self.__get_relevant_ports(port_id_list)
+
+ return_data = {}
+ for port_obj in relevant_ports:
+ streams_data = self._generate_single_port_streams_info(port_obj, stream_id_list)
+ hdr_key = "Port {port}: {yaml_file}".format(port= port_obj.port_id,
+ yaml_file= streams_data.raw_data.get('referring_file', ''))
+
+ # TODO: test for other ports with same stream structure, and join them
+ return_data[hdr_key] = streams_data
+ return return_data
+
def _generate_global_stats(self):
# stats_obj = self._async_stats.get_general_stats()
stats_data = self._global_stats.generate_stats()
@@ -170,6 +182,27 @@ class CTRexStatsGenerator(object):
return {"port_status": ExportableStats(return_stats_data, stats_table)}
+ def _generate_single_port_streams_info(self, port_obj, stream_id_list):
+
+ return_streams_data = port_obj.generate_loaded_streams_sum(stream_id_list)
+
+ # FORMAT VALUES ON DEMAND
+ for stream_id, stream_id_sum in return_streams_data['streams'].iteritems():
+ stream_id_sum['rate_pps'] = CTRexStats.format_num(stream_id_sum['rate_pps'], suffix='pps')
+ stream_id_sum['packet_type'] = self._trim_packet_headers(stream_id_sum['packet_type'], 20)
+
+ info_table = text_tables.TRexTextTable()
+ info_table.set_cols_align(["c"] + ["l"] + ["r"] + ["c"] + ["r"] + ["c"])
+ info_table.set_cols_width([4] + [20] + [8] + [16] + [10] + [12])
+
+ info_table.add_rows([v.values()
+ for k, v in return_streams_data['streams'].iteritems()],
+ header=False)
+ info_table.header(["ID", "packet type", "length", "mode", "rate", "next stream"])
+
+ return ExportableStats(return_streams_data, info_table)
+
+
def __get_relevant_ports(self, port_id_list):
# fetch owned ports
ports = [port_obj
@@ -187,6 +220,13 @@ class CTRexStatsGenerator(object):
if key in dict_dest_ref:
dict_dest_ref[key].append(val)
+ @staticmethod
+ def _trim_packet_headers(headers_str, trim_limit):
+ if len(headers_str) < trim_limit:
+ # do nothing
+ return headers_str
+ else:
+ return (headers_str[:trim_limit-3] + "...")
diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py
index 007e2464..800b6d49 100755
--- a/scripts/automation/trex_control_plane/common/trex_streams.py
+++ b/scripts/automation/trex_control_plane/common/trex_streams.py
@@ -10,7 +10,7 @@ import copy
import os
StreamPack = namedtuple('StreamPack', ['stream_id', 'stream'])
-LoadedStreamList = namedtuple('LoadedStreamList', ['loaded', 'compiled'])
+LoadedStreamList = namedtuple('LoadedStreamList', ['name', 'loaded', 'compiled'])
class CStreamList(object):
@@ -176,9 +176,11 @@ class CStream(object):
def __init__(self):
self.is_loaded = False
self._is_compiled = False
+ self._pkt_bld_obj = CTRexPktBuilder()
for field in CStream.FIELDS:
setattr(self, field, None)
+
def load_data(self, **kwargs):
try:
for k in CStream.FIELDS:
@@ -206,8 +208,13 @@ class CStream(object):
binary = kwargs[k]["binary"]
if isinstance(binary, list):
setattr(self, k, kwargs[k])
+ # TODO: load to _pkt_bld_obj also when passed as byte array!
elif isinstance(binary, str) and binary.endswith(".pcap"):
- self.load_packet_from_pcap(binary, kwargs[k]["meta"])
+ # self.load_packet_from_pcap(binary, kwargs[k]["meta"])
+ self._pkt_bld_obj.load_packet_from_pcap(binary)
+ self._pkt_bld_obj.metadata = kwargs[k]["meta"]
+ self.packet = self._pkt_bld_obj.dump_pkt()
+
else:
raise ValueError("Packet binary attribute has been loaded with unsupported value."
"Supported values are reference to pcap file with SINGLE packet, "
@@ -254,6 +261,10 @@ class CStream(object):
else:
raise RuntimeError("CStream object isn't loaded with data. Use 'load_data' method.")
+ def get_stream_layers(self, depth_limit=Ellipsis):
+ stream_layers = self._pkt_bld_obj.get_packet_layers(depth_limit)
+ return "/".join(stream_layers)
+
# describes a stream DB
@@ -271,20 +282,23 @@ class CStreamsDB(object):
stream_list = CStreamList()
loaded_obj = stream_list.load_yaml(filename)
- compiled_streams = stream_list.compile_streams()
- rc = self.load_streams(stream_pack_name,
- LoadedStreamList(loaded_obj,
- [StreamPack(v.stream_id, v.stream.dump())
- for k, v in compiled_streams.items()]))
+ try:
+ compiled_streams = stream_list.compile_streams()
+ rc = self.load_streams(LoadedStreamList(stream_pack_name,
+ loaded_obj,
+ [StreamPack(v.stream_id, v.stream.dump())
+ for k, v in compiled_streams.items()]))
+ except Exception as e:
+ return None
return self.get_stream_pack(stream_pack_name)
- def load_streams(self, name, LoadedStreamList_obj):
- if name in self.stream_packs:
+ def load_streams(self, LoadedStreamList_obj):
+ if LoadedStreamList_obj.name in self.stream_packs:
return False
else:
- self.stream_packs[name] = LoadedStreamList_obj
+ self.stream_packs[LoadedStreamList_obj.name] = LoadedStreamList_obj
return True
def remove_stream_packs(self, *names):