diff options
author | 2016-01-10 04:13:39 -0500 | |
---|---|---|
committer | 2016-01-10 04:13:39 -0500 | |
commit | 773e9d1c67c314aca8f6f88f676b4dd2d777863d (patch) | |
tree | 99f664f967787f8ab4a35aa0d28dfd3c4e10ce41 /scripts/automation/trex_control_plane/client | |
parent | 505d0dcd8b094cc11a20986f4417facc0a7a9dd7 (diff) | |
parent | 859a72101c94a26296efcc713882b472caf6ff8e (diff) |
Merge branch 'master' of https://github.com/danklein10/trex-core into danklein10-master
Diffstat (limited to 'scripts/automation/trex_control_plane/client')
-rw-r--r-- | scripts/automation/trex_control_plane/client/trex_port.py | 72 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/client/trex_stateless_client.py | 47 |
2 files changed, 102 insertions, 17 deletions
diff --git a/scripts/automation/trex_control_plane/client/trex_port.py b/scripts/automation/trex_control_plane/client/trex_port.py index 54b4945e..fc63cf0d 100644 --- a/scripts/automation/trex_control_plane/client/trex_port.py +++ b/scripts/automation/trex_control_plane/client/trex_port.py @@ -1,8 +1,9 @@ -from collections import namedtuple +from collections import namedtuple, OrderedDict from common.trex_types import * from common import trex_stats - +from client_utils import packet_builder +StreamOnPort = namedtuple('StreamOnPort', ['compiled_stream', 'metadata']) ########## utlity ############ def mult_to_factor (mult, max_bps, max_pps, line_util): @@ -47,6 +48,7 @@ class Port(object): self.streams = {} self.profile = None self.session_id = session_id + self.loaded_stream_pack = None self.port_stats = trex_stats.CPortStats(self) @@ -124,7 +126,9 @@ class Port(object): elif port_state == "PAUSE": self.state = self.STATE_PAUSE else: - raise Exception("port {0}: bad state received from server '{1}'".format(self.port_id, sync_data['state'])) + raise Exception("port {0}: bad state received from server '{1}'".format(self.port_id, port_state)) + + # TODO: handle syncing the streams into stream_db return self.ok() @@ -151,7 +155,7 @@ class Port(object): return self.err(rc.err()) # add the stream - self.streams[stream_id] = stream_obj + self.streams[stream_id] = StreamOnPort(stream_obj, Port._generate_stream_metadata(stream_id, stream_obj)) # the only valid state now self.state = self.STATE_STREAMS @@ -159,14 +163,17 @@ class Port(object): return self.ok() # add multiple streams - def add_streams (self, streams_list): + def add_streams (self, LoadedStreamList_obj): batch = [] - for stream in streams_list: + self.loaded_stream_pack = LoadedStreamList_obj + compiled_stream_list = LoadedStreamList_obj.compiled + + for stream_pack in compiled_stream_list: params = {"handler": self.handler, "port_id": self.port_id, - "stream_id": stream.stream_id, - "stream": stream.stream} + "stream_id": stream_pack.stream_id, + "stream": stream_pack.stream} cmd = RpcCmdData('add_stream', params) batch.append(cmd) @@ -178,8 +185,10 @@ class Port(object): # validate that every action succeeded # add the stream - for stream in streams_list: - self.streams[stream.stream_id] = stream.stream + for stream_pack in compiled_stream_list: + self.streams[stream_pack.stream_id] = StreamOnPort(stream_pack.stream, + Port._generate_stream_metadata(stream_pack.stream_id, + stream_pack.stream)) # the only valid state now self.state = self.STATE_STREAMS @@ -203,7 +212,7 @@ class Port(object): self.streams[stream_id] = None - self.state = self.STATE_STREAMS if len(self.streams > 0) else self.STATE_IDLE + self.state = self.STATE_STREAMS if (len(self.streams) > 0) else self.STATE_IDLE return self.ok() @@ -408,6 +417,47 @@ class Port(object): def invalidate_stats(self): return self.port_stats.invalidate() + ################# stream printout ###################### + def generate_loaded_streams_sum(self, stream_id_list): + if self.state == self.STATE_DOWN or self.state == self.STATE_STREAMS: + return {} + elif self.loaded_stream_pack is None: + # avoid crashing when sync with remote server isn't operational + # TODO: MAKE SURE TO HANDLE THIS CASE FOR BETTER UX + return {} + streams_data = {} + + if not stream_id_list: + # if no mask has been provided, apply to all streams on port + stream_id_list = self.streams.keys() + + + streams_data = {stream_id: self.streams[stream_id].metadata.get('stream_sum', ["N/A"] * 6) + for stream_id in stream_id_list + if stream_id in self.streams} + + + return {"referring_file" : self.loaded_stream_pack.name, + "streams" : streams_data} + + @staticmethod + def _generate_stream_metadata(stream_id, compiled_stream_obj): + meta_dict = {} + # create packet stream description + pkt_bld_obj = packet_builder.CTRexPktBuilder() + pkt_bld_obj.load_from_stream_obj(compiled_stream_obj) + # generate stream summary based on that + + next_stream = "None" if compiled_stream_obj['next_stream_id']==-1 else compiled_stream_obj['next_stream_id'] + + meta_dict['stream_sum'] = OrderedDict([("id", stream_id), + ("packet_type", "/".join(pkt_bld_obj.get_packet_layers())), + ("length", pkt_bld_obj.get_packet_length()), + ("mode", compiled_stream_obj['mode']['type']), + ("rate_pps", compiled_stream_obj['mode']['pps']), + ("next_stream", next_stream) + ]) + return meta_dict ################# events handler ###################### def async_event_port_stopped (self): diff --git a/scripts/automation/trex_control_plane/client/trex_stateless_client.py b/scripts/automation/trex_control_plane/client/trex_stateless_client.py index 58fa53c9..42d5031e 100755 --- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py +++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py @@ -61,7 +61,7 @@ class CTRexStatelessClient(object): self.global_stats = trex_stats.CGlobalStats(self._connection_info, self.server_version, self.ports) - self.stats_generator = trex_stats.CTRexStatsGenerator(self.global_stats, + self.stats_generator = trex_stats.CTRexInfoGenerator(self.global_stats, self.ports) self.events = [] @@ -538,14 +538,14 @@ class CTRexStatelessClient(object): - def add_stream_pack(self, stream_pack_list, port_id_list = None): + def add_stream_pack(self, stream_pack, port_id_list = None): port_id_list = self.__ports(port_id_list) rc = RC() for port_id in port_id_list: - rc.add(self.ports[port_id].add_streams(stream_pack_list)) + rc.add(self.ports[port_id].add_streams(stream_pack)) return rc @@ -821,7 +821,7 @@ class CTRexStatelessClient(object): return rc - rc = self.add_stream_pack(stream_list.compiled, port_id_list) + rc = self.add_stream_pack(stream_list, port_id_list) rc.annotate("Attaching {0} streams to port(s) {1}:".format(len(stream_list.compiled), port_id_list)) if rc.bad(): return rc @@ -861,6 +861,12 @@ class CTRexStatelessClient(object): stats_obj.update(self.stats_generator.generate_single_statistic(port_id_list, stats_type)) return stats_obj + def cmd_streams(self, port_id_list, streams_mask=set()): + + streams_obj = self.stats_generator.generate_streams_info(port_id_list, streams_mask) + + return streams_obj + ############## High Level API With Parser ################ @@ -916,7 +922,7 @@ class CTRexStatelessClient(object): else: # load streams from file - stream_list = None; + stream_list = None try: stream_list = self.streams_db.load_yaml_file(opts.file[0]) except Exception as e: @@ -1050,9 +1056,38 @@ class CTRexStatelessClient(object): for stat_type, stat_data in stats.iteritems(): text_tables.print_table_with_header(stat_data.text_table, stat_type) - return RC_OK() + def cmd_streams_line(self, line): + '''Fetch streams statistics from TRex server by port\n''' + # define a parser + parser = parsing_opts.gen_parser(self, + "streams", + self.cmd_streams_line.__doc__, + parsing_opts.PORT_LIST_WITH_ALL, + parsing_opts.STREAMS_MASK)#, + #parsing_opts.FULL_OUTPUT) + + opts = parser.parse_args(line.split()) + + if opts is None: + return RC_ERR("bad command line parameters") + + streams = self.cmd_streams(opts.ports, set(opts.streams)) + if not streams: + # we got no streams running + + print format_text("No streams found with desired filter.\n", "bold", "magenta") + return RC_ERR("No streams found with desired filter.") + else: + # print stats to screen + for stream_hdr, port_streams_data in streams.iteritems(): + text_tables.print_table_with_header(port_streams_data.text_table, + header= stream_hdr.split(":")[0] + ":", + untouched_header= stream_hdr.split(":")[1]) + return RC_OK() + + @timing |