diff options
author | 2016-07-31 11:56:41 +0300 | |
---|---|---|
committer | 2016-07-31 11:56:41 +0300 | |
commit | 893d0feef9ba6fa3fb36c49f4b5bcad47cb2bf60 (patch) | |
tree | 689a09fa656f990672d2d62143dc173a46fe0316 /scripts/automation/trex_control_plane/stl/trex_stl_lib/utils | |
parent | abf329075bd14f5f41c3753d560260ac809ec4f3 (diff) | |
parent | dceb010b01e9f8a0e9c905370d39f149f01cab7e (diff) |
Merge branch 'master' into scapy_server
Diffstat (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib/utils')
3 files changed, 101 insertions, 69 deletions
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py index b4903e81..6835ea5f 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py @@ -64,3 +64,4 @@ def list_difference (l1, l2): def is_sub_list (l1, l2): return set(l1) <= set(l2) + diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py index 98e3ca6a..af7e90c1 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py @@ -1,6 +1,9 @@ import argparse from collections import namedtuple from .common import list_intersect, list_difference +from .text_opts import format_text +from ..trex_stl_types import * + import sys import re import os @@ -33,12 +36,15 @@ NO_PROMISCUOUS = 20 PROMISCUOUS_SWITCH = 21 TUNABLES = 22 REMOTE_FILE = 23 +LOCKED = 24 GLOBAL_STATS = 50 PORT_STATS = 51 PORT_STATUS = 52 STREAMS_STATS = 53 STATS_MASK = 54 +CPU_STATS = 55 +MBUF_STATS = 56 STREAMS_MASK = 60 # ALL_STREAMS = 61 @@ -90,82 +96,74 @@ match_multiplier_help = """Multiplier should be passed in the following format: # value should be divided def decode_multiplier(val, allow_update = False, divide_count = 1): - # must be string - if not isinstance(val, str): - return None + factor_table = {None: 1, 'k': 1e3, 'm': 1e6, 'g': 1e9} + pattern = "^(\d+(\.\d+)?)(((k|m|g)?(bpsl1|pps|bps))|%)?" # do we allow updates ? +/- if not allow_update: - match = re.match("^(\d+(\.\d+)?)(bps|kbps|mbps|gbps|pps|kpps|mpps|%?)$", val) + pattern += "$" + match = re.match(pattern, val) op = None else: - match = re.match("^(\d+(\.\d+)?)(bps|kbps|mbps|gbps|pps|kpps|mpps|%?)([\+\-])?$", val) + pattern += "([\+\-])?$" + match = re.match(pattern, val) if match: - op = match.group(4) + op = match.group(7) else: op = None result = {} - if match: + if not match: + return None - value = float(match.group(1)) - unit = match.group(3) - + # value in group 1 + value = float(match.group(1)) - - # raw type (factor) - if not unit: - result['type'] = 'raw' - result['value'] = value + # decode unit as whole + unit = match.group(3) - elif unit == 'bps': - result['type'] = 'bps' - result['value'] = value + # k,m,g + factor = match.group(5) - elif unit == 'kbps': - result['type'] = 'bps' - result['value'] = value * 1000 + # type of multiplier + m_type = match.group(6) - elif unit == 'mbps': - result['type'] = 'bps' - result['value'] = value * 1000 * 1000 + # raw type (factor) + if not unit: + result['type'] = 'raw' + result['value'] = value - elif unit == 'gbps': - result['type'] = 'bps' - result['value'] = value * 1000 * 1000 * 1000 + # percentage + elif unit == '%': + result['type'] = 'percentage' + result['value'] = value - elif unit == 'pps': - result['type'] = 'pps' - result['value'] = value + elif m_type == 'bps': + result['type'] = 'bps' + result['value'] = value * factor_table[factor] - elif unit == "kpps": - result['type'] = 'pps' - result['value'] = value * 1000 + elif m_type == 'pps': + result['type'] = 'pps' + result['value'] = value * factor_table[factor] - elif unit == "mpps": - result['type'] = 'pps' - result['value'] = value * 1000 * 1000 + elif m_type == 'bpsl1': + result['type'] = 'bpsl1' + result['value'] = value * factor_table[factor] - elif unit == "%": - result['type'] = 'percentage' - result['value'] = value + if op == "+": + result['op'] = "add" + elif op == "-": + result['op'] = "sub" + else: + result['op'] = "abs" - if op == "+": - result['op'] = "add" - elif op == "-": - result['op'] = "sub" - else: - result['op'] = "abs" - - if result['op'] != 'percentage': - result['value'] = result['value'] / divide_count + if result['op'] != 'percentage': + result['value'] = result['value'] / divide_count - return result + return result - else: - return None def match_multiplier(val): @@ -244,26 +242,24 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'type': int}), PROMISCUOUS: ArgumentPack(['--prom'], - {'help': "sets port promiscuous on", + {'help': "Sets port promiscuous on", 'dest': "prom", 'default': None, 'action': "store_true"}), - TUNABLES: ArgumentPack(['-t'], - {'help': "sets tunable for a profile", + {'help': "Sets tunables for a profile. Example: '-t fsize=100,pg_id=7'", + 'metavar': 'T1=VAL[,T2=VAL ...]', 'dest': "tunables", 'default': None, 'type': decode_tunables}), - NO_PROMISCUOUS: ArgumentPack(['--no_prom'], - {'help': "sets port promiscuous off", + {'help': "Sets port promiscuous off", 'dest': "prom", 'default': None, 'action': "store_false"}), - PORT_LIST: ArgumentPack(['--port', '-p'], {"nargs": '+', 'dest':'ports', @@ -325,6 +321,11 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], 'default': False, 'help': "Starts TUI in xterm window"}), + LOCKED: ArgumentPack(['-l', '--locked'], + {'action': 'store_true', + 'dest': 'locked', + 'default': False, + 'help': "Locks TUI on legend mode"}), FULL_OUTPUT: ArgumentPack(['--full'], {'action': 'store_true', @@ -346,6 +347,14 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], {'action': 'store_true', 'help': "Fetch only streams stats"}), + CPU_STATS: ArgumentPack(['-c'], + {'action': 'store_true', + 'help': "Fetch only CPU utilization stats"}), + + MBUF_STATS: ArgumentPack(['-m'], + {'action': 'store_true', + 'help': "Fetch only MBUF utilization stats"}), + STREAMS_MASK: ArgumentPack(['--streams'], {"nargs": '+', 'dest':'streams', @@ -371,7 +380,9 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], STATS_MASK: ArgumentGroup(MUTEX, [GLOBAL_STATS, PORT_STATS, PORT_STATUS, - STREAMS_STATS], + STREAMS_STATS, + CPU_STATS, + MBUF_STATS], {}) } @@ -384,6 +395,15 @@ class CCmdArgParser(argparse.ArgumentParser): self.cmd_name = kwargs.get('prog') + # hook this to the logger + def _print_message(self, message, file=None): + self.stateless_client.logger.log(message) + + def error(self, message): + self.print_usage() + self._print_message(('%s: error: %s\n') % (self.prog, message)) + raise ValueError(message) + def has_ports_cfg (self, opts): return hasattr(opts, "all_ports") or hasattr(opts, "ports") @@ -391,7 +411,7 @@ class CCmdArgParser(argparse.ArgumentParser): try: opts = super(CCmdArgParser, self).parse_args(args, namespace) if opts is None: - return None + return RC_ERR("'{0}' - invalid arguments".format(self.cmd_name)) if not self.has_ports_cfg(opts): return opts @@ -406,8 +426,9 @@ class CCmdArgParser(argparse.ArgumentParser): # so maybe we have ports configured invalid_ports = list_difference(opts.ports, self.stateless_client.get_all_ports()) if invalid_ports: - self.stateless_client.logger.log("{0}: port(s) {1} are not valid port IDs".format(self.cmd_name, invalid_ports)) - return None + msg = "{0}: port(s) {1} are not valid port IDs".format(self.cmd_name, invalid_ports) + self.stateless_client.logger.log(format_text(msg, 'bold')) + return RC_ERR(msg) # verify acquired ports if verify_acquired: @@ -415,21 +436,25 @@ class CCmdArgParser(argparse.ArgumentParser): diff = list_difference(opts.ports, acquired_ports) if diff: - self.stateless_client.logger.log("{0} - port(s) {1} are not acquired".format(self.cmd_name, diff)) - return None + msg = "{0} - port(s) {1} are not acquired".format(self.cmd_name, diff) + self.stateless_client.logger.log(format_text(msg, 'bold')) + return RC_ERR(msg) # no acquire ports at all if not acquired_ports: - self.stateless_client.logger.log("{0} - no acquired ports".format(self.cmd_name)) - return None - + msg = "{0} - no acquired ports".format(self.cmd_name) + self.stateless_client.logger.log(format_text(msg, 'bold')) + return RC_ERR(msg) return opts + except ValueError as e: + return RC_ERR("'{0}' - {1}".format(self.cmd_name, str(e))) + except SystemExit: # recover from system exit scenarios, such as "help", or bad arguments. - return None + return RC_ERR("'{0}' - {1}".format(self.cmd_name, "no action")) def get_flags (opt): @@ -469,4 +494,4 @@ def gen_parser(stateless_client, op_name, description, *args): if __name__ == "__main__": - pass
\ No newline at end of file + pass diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py index 7e0bf9e4..bfb96950 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py @@ -27,7 +27,10 @@ class TextCodesStripper: def strip (s): return re.sub(TextCodesStripper.pattern, '', s) -def format_num (size, suffix = "", compact = True, opts = ()): +def format_num (size, suffix = "", compact = True, opts = None): + if opts is None: + opts = () + txt = "NaN" if type(size) == str: @@ -61,6 +64,9 @@ def format_time (t_sec): if t_sec < 0: return "infinite" + if t_sec == 0: + return "zero" + if t_sec < 1: # low numbers for unit in ['ms', 'usec', 'ns']: |