From fdc012345f5ab9dc40d5a571855a7d2010d88475 Mon Sep 17 00:00:00 2001 From: imarom Date: Wed, 13 Jan 2016 03:54:06 -0500 Subject: added 'total' line to stats --- .../client_utils/parsing_opts.py | 6 +-- .../trex_control_plane/common/trex_stats.py | 62 ++++++++++++++++++---- .../trex_control_plane/console/trex_console.py | 26 ++++++--- 3 files changed, 74 insertions(+), 20 deletions(-) (limited to 'scripts') diff --git a/scripts/automation/trex_control_plane/client_utils/parsing_opts.py b/scripts/automation/trex_control_plane/client_utils/parsing_opts.py index 43c97a1d..230ff822 100755 --- a/scripts/automation/trex_control_plane/client_utils/parsing_opts.py +++ b/scripts/automation/trex_control_plane/client_utils/parsing_opts.py @@ -47,10 +47,10 @@ def check_negative(value): def match_time_unit(val): '''match some val against time shortcut inputs ''' - match = re.match("^(\d+)([m|h]?)$", val) + match = re.match("^(\d+(\.\d+)?)([m|h]?)$", val) if match: - digit = int(match.group(1)) - unit = match.group(2) + digit = float(match.group(1)) + unit = match.group(3) if not unit: return digit elif unit == 'm': diff --git a/scripts/automation/trex_control_plane/common/trex_stats.py b/scripts/automation/trex_control_plane/common/trex_stats.py index 6d617b3c..e88a1148 100755 --- a/scripts/automation/trex_control_plane/common/trex_stats.py +++ b/scripts/automation/trex_control_plane/common/trex_stats.py @@ -96,7 +96,6 @@ class CTRexInfoGenerator(object): return return_data def _generate_global_stats(self): - # stats_obj = self._async_stats.get_general_stats() stats_data = self._global_stats.generate_stats() # build table representation @@ -135,24 +134,36 @@ class CTRexInfoGenerator(object): ] ) + total_stats = CPortStats(None) + for port_obj in relevant_ports: # fetch port data port_stats = port_obj.generate_port_stats() + total_stats += port_obj.port_stats + # populate to data structures return_stats_data[port_obj.port_id] = port_stats self.__update_per_field_dict(port_stats, per_field_stats) + total_cols = len(relevant_ports) + header = ["port"] + [port.port_id for port in relevant_ports] + + if (total_cols > 1): + self.__update_per_field_dict(total_stats.generate_stats(), per_field_stats) + header += ['total'] + total_cols += 1 + stats_table = text_tables.TRexTextTable() - stats_table.set_cols_align(["l"] + ["r"]*len(relevant_ports)) - stats_table.set_cols_width([10] + [20] * len(relevant_ports)) - stats_table.set_cols_dtype(['t'] + ['t'] * len(relevant_ports)) + stats_table.set_cols_align(["l"] + ["r"] * total_cols) + stats_table.set_cols_width([10] + [17] * total_cols) + stats_table.set_cols_dtype(['t'] + ['t'] * total_cols) stats_table.add_rows([[k] + v for k, v in per_field_stats.iteritems()], - header=False) - stats_table.header(["port"] + [port.port_id - for port in relevant_ports]) + header=False) + + stats_table.header(header) return {"port_statistics": ExportableStats(return_stats_data, stats_table)} @@ -428,10 +439,43 @@ class CPortStats(CTRexStats): super(CPortStats, self).__init__() self._port_obj = port_obj + @staticmethod + def __merge_dicts (target, src): + for k, v in src.iteritems(): + if k in target: + target[k] += v + else: + target[k] = v + + + def __add__ (self, x): + if not isinstance(x, CPortStats): + raise TypeError("cannot add non stats object to stats") + + # main stats + self.__merge_dicts(self.latest_stats, x.latest_stats) + + # reference stats + if x.reference_stats: + if not self.reference_stats: + self.reference_stats = x.reference_stats.copy() + else: + self.__merge_dicts(self.reference_stats, x.reference_stats) + + # history + if not self.history: + self.history = copy.deepcopy(x.history) + else: + for h1, h2 in zip(self.history, x.history): + self.__merge_dicts(h1, h2) + + return self + + def generate_stats(self): - return {"owner": self._port_obj.user, - "state": self._port_obj.get_port_state_name(), + return {"owner": self._port_obj.user if self._port_obj else "", + "state": self._port_obj.get_port_state_name() if self._port_obj else "", "--": " ", "opackets" : self.get_rel("opackets"), "obytes" : self.get_rel("obytes"), diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py index 3e9dec47..a6090832 100755 --- a/scripts/automation/trex_control_plane/console/trex_console.py +++ b/scripts/automation/trex_control_plane/console/trex_console.py @@ -102,12 +102,6 @@ class TRexGeneralCmd(cmd.Cmd): dotext = 'do_'+text return [a[3:]+' ' for a in self.get_names() if a.startswith(dotext)] - def precmd(self, line): - # before doing anything, save history snapshot of the console - # this is done before executing the command in case of ungraceful application exit - self.save_console_history() - return line - # # main console object @@ -133,7 +127,7 @@ class TRexConsole(TRexGeneralCmd): ################### internal section ######################## def prompt_redraw (self): - sys.stdout.write(self.prompt) + sys.stdout.write(self.prompt + readline.get_line_buffer()) def verify_connected(f): @wraps(f) @@ -186,6 +180,22 @@ class TRexConsole(TRexGeneralCmd): if name.startswith(prefix): self.__dict__[name] = getattr(self.trex_console, name) + def precmd(self, line): + # before doing anything, save history snapshot of the console + # this is done before executing the command in case of ungraceful application exit + self.save_console_history() + + lines = line.split(';') + + for line in lines: + stop = self.onecmd(line) + stop = self.postcmd(stop, line) + if stop: + return "quit" + + return "" + + def postcmd(self, stop, line): if not self.stateless_client.is_connected(): @@ -488,7 +498,7 @@ class TRexConsole(TRexGeneralCmd): exe += './trex-console -t -q -s {0} -p {1}'.format(self.stateless_client.get_server_ip(), self.stateless_client.get_server_port()) - cmd = ['xterm', '-geometry', '105x42', '-title', 'trex_tui', '-e', exe] + cmd = ['xterm', '-geometry', '111x42', '-title', 'trex_tui', '-e', exe] subprocess.Popen(cmd) return -- cgit 1.2.3-korg