diff options
author | 2016-01-08 13:54:36 +0200 | |
---|---|---|
committer | 2016-01-08 13:54:36 +0200 | |
commit | 8e037c2bd51844dc7c42ce7b2339806d9dcb964b (patch) | |
tree | cd45e5214e3db13f214a0e68b3fd37f366438b80 /scripts/automation/trex_control_plane/common | |
parent | 8db09096b9dcf030b7dc744fbd7ee463d8e6fd1b (diff) | |
parent | 9fc980b8aa43cf53446eeeb5184f10a86476da28 (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-x | scripts/automation/trex_control_plane/common/trex_stats.py | 46 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/common/trex_streams.py | 34 |
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): |