summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils
diff options
context:
space:
mode:
authoritraviv <itraviv@cisco.com>2016-07-31 11:56:41 +0300
committeritraviv <itraviv@cisco.com>2016-07-31 11:56:41 +0300
commit893d0feef9ba6fa3fb36c49f4b5bcad47cb2bf60 (patch)
tree689a09fa656f990672d2d62143dc173a46fe0316 /scripts/automation/trex_control_plane/stl/trex_stl_lib/utils
parentabf329075bd14f5f41c3753d560260ac809ec4f3 (diff)
parentdceb010b01e9f8a0e9c905370d39f149f01cab7e (diff)
Merge branch 'master' into scapy_server
Diffstat (limited to 'scripts/automation/trex_control_plane/stl/trex_stl_lib/utils')
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/common.py1
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py161
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py8
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']: